home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- Windows Sockets Client Application Support Module
-
- Written by:
- John A. Junod Internet: <junodj@gordon-emh2.army.mil>
- 267 Hillwood Street <zj8549@trotter.usma.edu>
- Martinez, GA 30907 Compuserve: 72321,366
-
- This program executable and all source code is released into the public
- domain. It would be nice (but is not required) to give me a little
- credit for any use of this code.
-
- THE INFORMATION AND CODE PROVIDED IS PROVIDED AS IS WITHOUT WARRANTY
- OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE. IN NO EVENT SHALL JOHN A. JUNOD BE LIABLE FOR ANY DAMAGES
- WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS
- OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF JOHN A. JUNOD HAS BEEN
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
- *****************************************************************************/
-
- #include "ws_glob.h"
- #include "ws_ftp.h"
- #include <stdio.h>
- #include <stdarg.h>
- #include <ctype.h>
- #include <io.h>
- #include <fcntl.h>
- #include <sys\stat.h>
- #include <time.h>
-
- extern int errno;
- extern int nHostType;
- extern BOOL bAborted; // timer routine may set this
-
- /*
- // send a message on the control socket, read and display the resulting
- // message and return the result value
- */
- int getreply(SOCKET ctrl_skt,LPSTR cmdstring)
- {
- int iRetCode=0;
-
- iCode=0;
- if(strncmp(cmdstring,"PASS ",5)==0)
- DoAddLine("PASS xxxxxx");
- else
- DoAddLine(cmdstring);
- if(ctrl_skt==INVALID_SOCKET) {
- DoAddLine("Not connected");
- } else {
- if(SendPacket(ctrl_skt,cmdstring)!=-1)
- iRetCode=ReadDisplayLine(ctrl_skt);
- }
- return(iRetCode); // 0 - 5
- }
-
- int command(SOCKET ctrl_skt, char *fmt,...)
- {
- va_list args;
- char szBuf[90];
- int iRetCode;
-
- va_start(args,fmt);
- vsprintf(szBuf,fmt,args);
- va_end(args);
- return(getreply(ctrl_skt,szBuf));
- }
-
- // return a string pointer to ON or OFF based on the flag
- char *onoff(BOOL flag)
- {
- if(flag) return("ON"); else return("OFF");
- }
-
- // process CWD
- int DoCWD(SOCKET ctrl_skt,LPSTR path)
- {
- if(command(ctrl_skt,"CWD %s",path)==FTP_ERROR && iCode==500) {
- command(ctrl_skt,"XCWD %s",path);
- }
- return(iCode/100);
- }
-
- // proces PWD
- int DoPWD(SOCKET ctrl_skt)
- {
- if(command(ctrl_skt,"PWD")==FTP_ERROR && iCode==500) {
- command(ctrl_skt,"XPWD");
- }
- return(iCode/100);
- }
-
- // process MKD
- int DoMKD(SOCKET ctrl_skt,LPSTR pathname)
- {
- if(command(ctrl_skt,"MKD %s",pathname)==FTP_ERROR && iCode==500) {
- command(ctrl_skt,"XMKD %s",pathname);
- }
- return(iCode/100);
- }
-
- // process RMD
- int DoRMD(SOCKET ctrl_skt,LPSTR pathname)
- {
- if(command(ctrl_skt,"RMD %s",pathname)==FTP_ERROR && iCode==500)
- command(ctrl_skt,"XRMD %s",pathname);
- return(iCode/100);
- }
-
- // process DELE
- int DoDELE(SOCKET ctrl_skt,LPSTR pathname)
- {
- command(ctrl_skt,"DELE %s",pathname);
- return(iCode/100);
- }
-
- // process user command
- int DoQUOTE(SOCKET ctrl_skt,LPSTR string)
- {
- if(strncmp(string,"LIST",4)==0 ||
- strncmp(string,"NLST",4)==0)
- DoDirList(ctrl_skt,string);
- else
- command(ctrl_skt,string);
- return(iCode/100);
- }
-
- // process chmod
- int DoCHMOD(SOCKET ctrl_skt,LPSTR modes,LPSTR filename)
- {
- return(command(ctrl_skt,"SITE CHMOD %s %s",modes,filename));
- }
-
- extern BOOL bHELP;
-
- // initial connection
- SOCKET DoConnect(LPSTR host)
- {
- int iLength,iRetCode;
- int iFlag=1;
- SOCKET ctrl_skt;
-
- if(bConnected) {
- DoAddLine("Already connected!");
- return(INVALID_SOCKET);
- }
- // let other routines know that we are busy
- bCmdInProgress++;
-
- bHELP=FALSE;
-
- // create a connected socket
- if((ctrl_skt=connectTCP(host,"ftp"))==INVALID_SOCKET) {
- // DoAddLine("connection failed");
- bCmdInProgress--;
- return(INVALID_SOCKET);
- }
- // get information about local end of the connection
- iLength = sizeof (saCtrlAddr);
- if (getsockname(ctrl_skt,(struct sockaddr *)&saCtrlAddr, &iLength)
- ==SOCKET_ERROR)
- {
- ReportWSError("getsockname",WSAGetLastError());
- bCmdInProgress--;
- DoClose(ctrl_skt);
- return(INVALID_SOCKET);
- }
- // show remote end address
- DoPrintf("[%u] from %s port %u",ctrl_skt,
- inet_ntoa(saCtrlAddr.sin_addr),
- ntohs(saCtrlAddr.sin_port));
- // get initial message from remote end
- while((iRetCode=ReadDisplayLine(ctrl_skt))==FTP_PRELIM)
- if(strstr(szMsgBuf,"(EXOS")!=NULL && nHostType==0)
- nHostType=DLG_HOST_U5000-6000;
- // if it succeeded
- if(iRetCode==FTP_COMPLETE) {
- if (setsockopt(ctrl_skt, SOL_SOCKET, SO_OOBINLINE,
- (LPSTR)&iFlag, sizeof(iFlag))==SOCKET_ERROR)
- {
- ReportWSError("setsockopt",WSAGetLastError());
- }
- // have to reset this so "command" will work
- bCmdInProgress--;
- // send our userid
- if((iRetCode=command(ctrl_skt,"USER %s",szUserID))==FTP_CONTINUE)
- {
- // if the remote system requires a password, send it.
- iRetCode=command(ctrl_skt,"PASS %s",szPassWord);
- }
- // if we are successfully logged on,.....
- if(iRetCode!=FTP_COMPLETE)
- {
- DoAddLine("logon failure, so quitting");
- DoClose((SOCKET)ctrl_skt);
- return(INVALID_SOCKET);
- }
- bConnected=1;
- } else {
- DoPrintf("unk open msg \"%s\" %u",szMsgBuf,iCode);
- // allow other processes to work
- bCmdInProgress--;
- DoClose((SOCKET)ctrl_skt);
- return(INVALID_SOCKET);
- }
- wsprintf(szString,"WS_FTP %s",szRemoteHost);
- SetWindowText(hWndMain,szString);
- return (ctrl_skt);
- }
-
- int DoDirList(SOCKET ctrl_skt,LPSTR szCMD)
- {
- int nRC,nBell;
- nBell=bBell; bBell=0;
- nRC=RetrieveFile(ctrl_skt,szCMD,szTmpFile,TYPE_A);
- bBell=nBell;
- return(nRC);
- }
-
- int SendFile(SOCKET ctrl_skt,LPSTR szCMD,LPSTR localfile,char stype)
- {
- int iRetCode;
- int iLength;
-
- iCode=0;
- // if we don't have a valid control socket, can't do anything
- if(ctrl_skt==INVALID_SOCKET) {
- DoAddLine("no ctrl_skt, ignored");
- return(0);
- }
- // if we are doing something, don't try to do this
- if(bCmdInProgress) {
- DoAddLine("command in process, ignored");
- return(0);
- }
- // if the requested type is not the same as the default type
- if(cType!=stype) {
- if(stype==TYPE_L)
- command(ctrl_skt,"TYPE L 8");
- else
- command(ctrl_skt,"TYPE %c",stype);
- cType=stype;
- }
- // create a listener socket, if it is successful
- if((listen_socket=GetFTPListenSocket(ctrl_skt))!=INVALID_SOCKET) {
- // send command to see the result of this all
- iRetCode=command((SOCKET)ctrl_skt,szCMD);
- // read the control channel (should return 1xx if it worked)
- if(iRetCode==FTP_PRELIM) {
- // wait for connection back to us on the listen socket
- SetTimer(hWndMain,10,uiTimeOut*1000,NULL);
- // get our data connection
- iLength=sizeof(saSockAddr1);
- data_socket=accept(listen_socket,(struct sockaddr far *)&saSockAddr1,
- (int far *)&iLength);
- // turn off the timeout timer
- KillTimer(hWndMain,10);
- // if it failed, we have to quit this
- if(data_socket==INVALID_SOCKET) {
- ReportWSError("accept",WSAGetLastError());
- listen_socket=DoClose(listen_socket);
- iRetCode=0;
- } else {
- // we don't need the listener socket anymore
- listen_socket=DoClose(listen_socket);
- // inform user of the connection
- DoPrintf("[%u] accept from %s port %u", data_socket,
- inet_ntoa(saSockAddr1.sin_addr),ntohs(saSockAddr1.sin_port));
- // copy the file
- iRetCode=SendMass(data_socket,localfile,stype==TYPE_I);
- // close the socket
- data_socket=DoClose(data_socket);
- // read the close control message (should return 2xx)
- iRetCode=ReadDisplayLine(ctrl_skt);
- }
- } else {
- listen_socket=DoClose(listen_socket);
- iRetCode=0;
- if(bBell) MessageBeep(MB_ICONEXCLAMATION);
- }
- } else {
- listen_socket=DoClose(listen_socket);
- iRetCode=0;
- if(bBell) MessageBeep(MB_ICONEXCLAMATION);
- }
- return(iRetCode);
- }
-
- int RetrieveFile(SOCKET ctrl_skt,LPSTR szCMD,LPSTR localfile,char rtype)
- {
- int iRetCode;
- int iLength;
-
- iCode=0;
- // if we don't have a valid control socket, can't do anything
- if(ctrl_skt==INVALID_SOCKET) {
- DoAddLine("no ctrl_skt, ignored");
- return(0);
- }
- // if we are doing something, don't try to do this
- if(bCmdInProgress) {
- DoAddLine("command in process, ignored");
- return(0);
- }
- // if the requested type is not the same as the default type
- if(cType!=rtype) {
- if(rtype==TYPE_L)
- command(ctrl_skt,"TYPE L 8");
- else
- command(ctrl_skt,"TYPE %c",rtype);
- cType=rtype;
- }
- // create a listener socket, if it is successful
- if((listen_socket=GetFTPListenSocket(ctrl_skt))!=INVALID_SOCKET) {
- // send command to see the result of this all
- iRetCode=command((SOCKET)ctrl_skt,szCMD);
- // read the control channel (should return 1xx if it worked)
- if(iRetCode==FTP_PRELIM) {
- // wait for connection back to us on the listen socket
- SetTimer(hWndMain,10,uiTimeOut*1000,NULL);
- // get our data connection
- iLength=sizeof(saSockAddr1);
- data_socket=accept(listen_socket,(struct sockaddr far *)&saSockAddr1,
- (int far *)&iLength);
- // turn off the timeout timer
- KillTimer(hWndMain,10);
- // if it failed, we have to quit this
- if(data_socket==INVALID_SOCKET) {
- ReportWSError("accept",WSAGetLastError());
- listen_socket=DoClose(listen_socket);
- iRetCode=0;
- } else {
- // we don't need the listener socket anymore
- listen_socket=DoClose(listen_socket);
- // inform user of the connection
- DoPrintf("[%u] accept from %s port %u", data_socket,
- inet_ntoa(saSockAddr1.sin_addr),ntohs(saSockAddr1.sin_port));
- // copy the file
- iRetCode=ReadMass(data_socket,localfile,rtype==TYPE_I);
- // shut the data socket down
- if(shutdown(data_socket,2)!=0)
- ReportWSError("shutdown",WSAGetLastError());
- // close the data socket
- data_socket=DoClose(data_socket);
- // read the close control message (should return 2xx)
- iRetCode=ReadDisplayLine(ctrl_skt);
- }
- } else {
- listen_socket=DoClose(listen_socket);
- iRetCode=0;
- if(bBell) MessageBeep(MB_ICONEXCLAMATION);
- }
-
- } else {
- listen_socket=DoClose(listen_socket);
- iRetCode=0;
- if(bBell) MessageBeep(MB_ICONEXCLAMATION);
- }
- return(iRetCode);
- }
-
- // user close routine
- SOCKET DoClose(SOCKET sockfd)
- {
- LINGER linger;
-
- if(sockfd!=INVALID_SOCKET) {
- if(WSAIsBlocking()) {
- DoPrintf("[%u] Cancelled blocking call",sockfd);
- WSACancelBlockingCall();
- bAborted=TRUE;
- }
- /*
- if(shutdown(sockfd,2)==SOCKET_ERROR)
- ReportWSError("shutdown",WSAGetLastError());
- */
- linger.l_onoff = TRUE;
- linger.l_linger = 0;
- setsockopt(sockfd,SOL_SOCKET,SO_LINGER,
- (LPSTR)&linger,sizeof(linger) );
- if(closesocket(sockfd)==SOCKET_ERROR)
- ReportWSError("closesocket",WSAGetLastError());
- else {
- DoPrintf("[%u] Socket closed.",sockfd);
- sockfd=INVALID_SOCKET;
- }
- }
-
- if(sockfd!=INVALID_SOCKET)
- DoPrintf("[%u] Failed to close socket.",sockfd);
-
- return(sockfd);
- }
-
- int SendPacket(SOCKET sockfd,LPSTR msg)
- {
- int i;
-
- if(sockfd==INVALID_SOCKET) return(-1);
- if(bCmdInProgress) {
- DoAddLine("command in progress, ignored");
- return (-1);
- }
- bCmdInProgress++;
- i=strlen(msg);
- strcpy(szSendPkt,msg);
- // append a CRLF to the end of outgoing messages
- szSendPkt[i++]='\r';
- szSendPkt[i++]='\n';
- szSendPkt[i]=0;
- i=sendstr(sockfd,szSendPkt,i);
- bCmdInProgress--;
- return (i);
- }
-
- int iMultiLine=0;
- // read a reply (may be multi line) and display in debug window
- int ReadDisplayLine(SOCKET sockfd)
- {
- int iRetCode;
- int iContinue;
- char *s;
- char c;
-
- // can't do anything if we don't have a socket
- if(sockfd==INVALID_SOCKET) return(0);
- // let other routine know that we are doing something right now.
- bCmdInProgress++;
- // count the lines in the response
- iMultiLine++;
- // initialize some variables
- iContinue=0;
- // go read the line
- iRetCode=ReadLine(sockfd);
- // if it wasn't a valid value or the 4th char was a hyphen
- if(iRetCode<100 || iRetCode>599 || szMsgBuf[3]=='-')
- // then it is a continuation line
- iContinue=1;
- // send the line we read to our user/debug window
- DoAddLine((LPSTR)&szMsgBuf[0]);
- // DoPrintf("iRetCode=%u, iContinue=%u",iRetCode,iContinue);
- // if the timer killed it
- if(bAborted) { iCode=iRetCode=421; iContinue=0; }
- // we only want to set the real return code in certain situations
- if((iMultiLine==1 || iCode==0) && iRetCode>99 && iRetCode<600)
- iCode=iRetCode;
- // handle continuation lines
- if(iContinue==1 || (iCode>0 && iMultiLine>1 && iRetCode!=iCode))
- ReadDisplayLine(sockfd);
- // count back down our multiline reponses
- iMultiLine--;
- // allow other processes to run
- bCmdInProgress--;
- // return only the first char of return code
- if(iCode>99 && iCode<600)
- return (iCode/100);
- else return 0;
- }
-
- // read a reply line back in from the sockfd and return the
- // value at the beginning of the first line.
- int ReadLine(SOCKET sockfd)
- {
- LPSTR szBuf;
- int nIndex;
- int iNumBytes,iN1,iN2,iN3;
- int iBytesRead;
- int iRetCode;
- int i;
- char *s;
- char c;
-
- // can't do anything if we don't have a socket
- if(sockfd==INVALID_SOCKET) return(0);
- // let other routines know that we are doing something right now.
- bCmdInProgress++;
- // make sure we don't mistakenly think we timed out
- KillTimer(hWndMain,10); bAborted=FALSE;
- // zero our receive buffer
- memset(szMsgBuf,0,4096);
- // initialize some variables
- szBuf=szMsgBuf; iBytesRead=0; iRetCode=0;
- // set our timeout
- SetTimer(hWndMain,10,uiTimeOut*1000,NULL);
- // this routine is a little better as it read 80 characters at a time
- // (if it works:-) Here we PEEK at what is available, find the LF etc...
- while(iBytesRead<4000 && (iNumBytes=recv(sockfd,(LPSTR)szBuf,82,MSG_PEEK))>0)
- {
- // Trumpet WinSock Alpha 15 always returns the len (82) from a recv
- // with MSG_PEEK. I suppose this is an error??? The spec doesn't say
- // that MSG_PEEK returns something different than normal.
- KillTimer(hWndMain,10);
- iN1=iNumBytes;
- // must terminate the string so strchr doesn't go wild.
- szBuf[iNumBytes]=0;
- // find a LF in the input if it exists
- //
- for(nIndex=0;nIndex<iNumBytes;nIndex++)
- if(szBuf[nIndex]==0 || szBuf[nIndex]==0x0a) {
- iNumBytes=nIndex+1;
- break;
- }
- // have to treat the UNISYS 5000 (EXOS driver) special. It sends a
- // line with a CR at end and no LF and then follows it up with a
- // separate packet that has a CR/LF. Usually this second packet is
- // not there when we peek but is when we read (answers my question
- // about the second receive containing new data!!... jaj 931024)
- if(iNumBytes>80 && nHostType==(DLG_HOST_U5000-6000))
- for(nIndex=0;nIndex<iNumBytes;nIndex++)
- if(szBuf[nIndex]==0x0d) {
- iNumBytes=nIndex+2;
- break;
- }
- iN2=iNumBytes;
- // otherwise read up to the full length of what the first recv saw.
- // Wonder what happens here if the second receive actually returns more
- // characters than the first receive and there was a LF in the extra data?
- iNumBytes=recv(sockfd,(LPSTR)szBuf,iNumBytes,0);
- // again, terminate the string
- szBuf[iNumBytes]=0;
- DoPrintf("[%u] readline %u - %u - %u %s",sockfd,iN1,iN2,iNumBytes,szBuf);
- // bump the receive buffer pointer
- szBuf+=iNumBytes;
- // count the bytes that we have read so far
- iBytesRead+=iNumBytes;
- // if the last character read was a LF, then stop.
- if(*(szBuf-1)==0x0a)
- break; // '\n') break;
- // otherwise reset the timer and go read more characters
- SetTimer(hWndMain,10,uiTimeOut*1000,NULL);
- }
- // if we are here, we have a line or an error or there was nothing to read
- KillTimer(hWndMain,10);
- // in any case terminate what we have
- *szBuf=0;
- // find the retcode at the beginning of the line
- c=szMsgBuf[3]; szMsgBuf[3]=0; iRetCode=atoi(szMsgBuf); szMsgBuf[3]=c;
- // if the timer killed it
- if(bAborted) iRetCode=421;
- // strip trailing blanks, CR's and LF's
- while((i=strlen(szMsgBuf))>2 &&
- (szMsgBuf[i-1]==0x0a || szMsgBuf[i-1]==0x0d || szMsgBuf[i-1]==' '))
- szMsgBuf[i-1]=0;
- // unmark our progress
- bCmdInProgress--;
-
- return(iRetCode);
- }
-
- // based on WINTEL (ftp.c) and BSD (ftp.c)
- SOCKET GetFTPListenSocket(SOCKET ctrl_skt)
- {
- SOCKET listen_skt;
- int iLength;
- int iRetCode;
- char *a,*p;
- int iFlag=1;
-
- // create a data socket
- if((listen_skt=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
- {
- ReportWSError("socket create",WSAGetLastError());
- return (INVALID_SOCKET);
- }
- // let system pick an unused port. we tell remote end with PORT cmd
- DoPrintf("[%u] going to listen %s port %u",listen_skt,
- inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));
-
- if(bSendPort) {
- saCtrlAddr.sin_port=htons(0);
- saCtrlAddr.sin_family=AF_INET;
- saCtrlAddr.sin_addr.s_addr=0;
- } else
- // otherwise we attempt to reuse our ctrl_skt
- if(setsockopt(listen_skt,SOL_SOCKET,SO_REUSEADDR,
- (char *)&iFlag,sizeof(iFlag))==SOCKET_ERROR)
- {
- ReportWSError("setsockopt",WSAGetLastError());
- closesocket(listen_skt);
- return(INVALID_SOCKET);
- }
- // Bind name to socket
- if( bind((SOCKET)listen_skt,(LPSOCKADDR)&saCtrlAddr,
- (int)sizeof(struct sockaddr))==SOCKET_ERROR)
- {
- ReportWSError("bind",WSAGetLastError());
- closesocket(listen_skt);
- return (INVALID_SOCKET);
- }
- // get the port name that we got for later transmission in PORT cmd
- iLength=sizeof(saCtrlAddr);
- if(getsockname(listen_skt,(struct sockaddr *)&saCtrlAddr,&iLength)<0)
- {
- ReportWSError("getsockname",WSAGetLastError());
- closesocket(listen_skt);
- return(INVALID_SOCKET);
- }
- // invoke listener
- if(listen(listen_skt,1)!=0)
- {
- ReportWSError("listen",WSAGetLastError());
- closesocket(listen_skt);
- return(INVALID_SOCKET);
- }
-
- // inform remote end about our port that we created.
- if(bSendPort)
- {
- struct sockaddr_in saTmpAddr;
- int iLength;
-
- iLength = sizeof (saTmpAddr);
- if (getsockname(ctrl_skt,(LPSOCKADDR)&saTmpAddr, &iLength)
- ==SOCKET_ERROR)
- {
- ReportWSError("getsockname",WSAGetLastError());
- }
-
- a = (char *)&saTmpAddr.sin_addr;
- p = (char *)&saCtrlAddr.sin_port;
- #define UC(b) (((int)b)&0xff)
- if((iRetCode=command(ctrl_skt,"PORT %d,%d,%d,%d,%d,%d",
- UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
- UC(p[0]), UC(p[1])))!=FTP_COMPLETE) {
- DoPrintf("[%u] remote end didn't understand our port command.",listen_skt);
- return(listen_skt);
- }
- }
- DoPrintf("[%u] listener %s port %u",listen_skt,
- inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));
- return(listen_skt);
- }
-
- // send a file through the data socket
- int SendMass(SOCKET sockfd,LPSTR filename,BOOL binaryflag)
- {
- int iNumBytes;
- int iRetCode;
- int iFileHandle;
- long lBytesWritten;
- time_t ttStart,ttStop,ttDiff;
-
- iRetCode=0;
- // if we don't have a socket, return an error
- if(sockfd==INVALID_SOCKET || !(bConnected)) return 0;
- // turn on a flag so other routines know we have a command in progress
- bCmdInProgress++;
- // initialize some vars
- lBytesWritten=0l; iRetCode=0;
- // at the moment we are ignoring the fact that the local destination file
- // may not open correctly.
- if((iFileHandle=_lopen(filename,READ))== -1) {
- DoPrintf("failed to open file %s (%u)",filename,errno);
- if(bBell) MessageBeep(MB_ICONEXCLAMATION);
- } else {
- // get the start time
- ttStart=time(NULL);
- // loop to send output to remote end
- while((iNumBytes=_lread(iFileHandle,szMsgBuf,512))>0)
- {
- // this forces binary mode at the moment
- iRetCode=sendstr(sockfd,szMsgBuf,iNumBytes);
- // count the characters that we received
- lBytesWritten+=iNumBytes;
-
- wsprintf(szString,"%lu",lBytesWritten);
- SendMessage(hTxtLBytes,WM_SETTEXT,0,(LPARAM)szString);
- }
- // get the finish time
- ttStop=time(NULL);
- // if the output file is open, close it
- _lclose(iFileHandle);
- // show the user how we did
- SendMessage(hTxtLBytes,WM_SETTEXT,0,(LPARAM)NULL);
- ttDiff=ttStop-ttStart;
- if(ttDiff==0l) ttDiff=1l;
- DoPrintf("Transmitted %ld bytes in %ld secs, %ld bps, transfer %s",
- lBytesWritten,(long)ttDiff,
- lBytesWritten*8l/(long)(ttDiff),
- (iFileHandle==-1)?"failed":"succeeded");
- iRetCode=TRUE;
- if(bBell) MessageBeep(MB_OK);
- }
- // turn off our command in progress flag
- bCmdInProgress--;
-
- return (iRetCode);
- }
-
- // read information from the data socket into a file.
- int ReadMass(SOCKET sockfd,LPSTR filename,BOOL binaryflag)
- {
- int iNumBytes;
- int iRetCode;
- int iFileHandle;
- long lBytesRead;
- time_t ttStart,ttStop,ttDiff;
-
- // if we don't have a socket, return an error
- if(sockfd==INVALID_SOCKET || !(bConnected)) return 0;
- // turn on a flag so other routines know we have a command in progress
- bCmdInProgress++;
- // make sure we don't mistakenly think we timed out
- KillTimer(hWndMain,10); bAborted=FALSE;
- // initialize some vars
- lBytesRead=0l; iRetCode=0;
- // at the moment we are ignoring the fact that the local destination file
- // may not open correctly.
- if((iFileHandle=_lcreat(filename,0))== -1)
- DoPrintf("failed to open file %s (%u)",filename,errno);
- // get the start time
- ttStart=time(NULL);
- // loop to receive input from remote end
- while(!bAborted && (iNumBytes=recv(sockfd,(LPSTR)szMsgBuf,4000,0))>0)
- {
- // write what we received if the file is open
- if(iFileHandle!= -1)
- _lwrite(iFileHandle,szMsgBuf,iNumBytes);
- // count the characters that we received
- lBytesRead+=iNumBytes;
- // update screen
- wsprintf(szString,"%lu",lBytesRead);
- SendMessage(hTxtRBytes,WM_SETTEXT,0,(LPARAM)szString);
- }
- // get the finish time
- ttStop=time(NULL);
- // if the output file is open, close it
- if(iFileHandle != -1) _lclose(iFileHandle);
- // if we had a recv error, let us know about it
- if(iNumBytes==SOCKET_ERROR)
- {
- ReportWSError("recv",WSAGetLastError());
- if(lBytesRead==0l)
- {
- if(bBell) MessageBeep(MB_ICONEXCLAMATION);
- bCmdInProgress--;
- return(FALSE);
- }
- }
- SendMessage(hTxtRBytes,WM_SETTEXT,0,(LPARAM)NULL);
-
- ttDiff=ttStop-ttStart;
- if(ttDiff==0l) ttDiff=1l;
- // show the user how we did
- DoPrintf("Received %ld bytes in %ld secs, %ld bps, transfer %s",
- lBytesRead,(long)ttDiff,
- lBytesRead*8l/(long)ttDiff,
- (iFileHandle==-1 || bAborted)?"failed":"succeeded");
-
- if(bBell) MessageBeep(MB_OK);
- // turn off our command in progress flag
- bCmdInProgress--;
-
- return (TRUE);
- }
-
-