WS_CON.C
资源名称:wnftpsrc.zip [点击查看]
上传用户:dansui
上传日期:2007-01-04
资源大小:71k
文件大小:40k
源码类别:
Ftp客户端
开发平台:
WINDOWS
- #include "ws_glob.h"
- #include "winftp.h"
- #include <stdio.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <io.h>
- #include <fcntl.h>
- #include <sysstat.h>
- #include <time.h>
- // extern int errno;
- extern BOOL bAborted; // timer routine may set this
- extern BOOL bDebugLog;
- char szDbgLogFile[_MAX_PATH];
- //***********************************************************************
- //***********************************************************************
- int WriteDebugLog (int nCode, int nRetCode, LPSTR lpStr)
- {
- FILE *fp;
- FARPROC lpfnMsgProc;
- int nRC;
- if (!bDebugLog) return 0;
- if (lstrlen (szDbgLogFile)==0)
- {
- lstrcpy (szDlgPrompt,"Enter log file name:");
- lstrcpy (szDlgEdit, "C:\WNFTPDBG.LOG");
- lpfnMsgProc = MakeProcInstance ((FARPROC) WS_InputMsgProc, hInst);
- nRC = DialogBox (hInst, (LPSTR) "DLG_INPUT", hWndMain, lpfnMsgProc);
- FreeProcInstance (lpfnMsgProc);
- if (nRC==IDCANCEL) return 0;
- lstrcpy (szDbgLogFile, szDlgEdit);
- }
- fp = fopen (szDbgLogFile, "at");
- switch (nCode)
- {
- case 0: fprintf (fp, "SEND: %sn", lpStr); break;
- case 1: fprintf (fp, "RESULT: %4d %3d %-16s %sn", nRetCode, iCode,
- (nRetCode==FTP_PRELIM) ? "Prelim" :
- (nRetCode==FTP_COMPLETE) ? "Complete" :
- (nRetCode==FTP_CONTINUE) ? "Continue" :
- (nRetCode==FTP_RETRY) ? "Retry" :
- (nRetCode==FTP_ERROR) ? "Error" : "Unknown",
- lpStr); break;
- }
- fclose (fp);
- return 0;
- }
- //***********************************************************************
- // Print statistics on the transfer
- //***********************************************************************
- void PrintTransferStatus (LPSTR lpTyp, LONG lBytes, long nSecs)
- {
- LONG lSecs = nSecs;
- if (lSecs==0) lSecs=1;
- DoPrintf ("%sed %ld characters in %ld seconds (%ld bytes/sec)", lpTyp,
- lBytes, (long) nSecs, (long) lBytes/lSecs);
- }
- static UINT nDirNum=0;
- //***********************************************************************
- // Send in a Command line and return a code indicating type of reply
- // 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, BOOL bForce)
- {
- 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 (bDebugLog) WriteDebugLog (0, iRetCode, cmdstring);
- switch (bForce)
- {
- case TRUE : if (ForcePacket (ctrl_skt,cmdstring)!=-1) iRetCode = ReadDisplayLine (ctrl_skt);
- case FALSE: if (SendPacket (ctrl_skt,cmdstring)!=-1) iRetCode = ReadDisplayLine (ctrl_skt);
- }
- if (bDebugLog) WriteDebugLog (1, iRetCode, cmdstring);
- }
- return iRetCode; // 0 - 5
- }
- //***********************************************************************
- // Send in a Command line and return a code indicating type of reply
- //***********************************************************************
- int command (SOCKET ctrl_skt, char *fmt,...)
- {
- va_list args;
- char szBuf[90];
- va_start (args, fmt);
- vsprintf (szBuf, fmt, args);
- va_end (args);
- return getreply (ctrl_skt, szBuf, FALSE);
- }
- //***********************************************************************
- // Send in a Command line and return a code indicating type of reply
- //***********************************************************************
- int ForceCommand (SOCKET ctrl_skt, char *fmt,...)
- {
- va_list args;
- char szBuf[90];
- va_start (args, fmt);
- vsprintf (szBuf, fmt, args);
- va_end (args);
- return getreply (ctrl_skt, szBuf, TRUE);
- }
- //***********************************************************************
- // 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)
- {
- char szPath[100];
- if (command (ctrl_skt,"CWD %s",path)==FTP_ERROR)
- {
- if (iCode==500) command (ctrl_skt,"XCWD %s",path);
- else
- {
- lstrcpy (szPath, path);
- ConvertTargetDir (szPath, 95);
- command (ctrl_skt,"CWD %s", szPath);
- }
- }
- return(iCode/100);
- }
- //***********************************************************************
- // process System Type
- //***********************************************************************
- int DoSystemCommand (SOCKET ctrl_skt)
- {
- LPSTR lp;
- char szBuf[100];
- if (command (ctrl_skt,"SYST")!=FTP_ERROR)
- {
- lstrcpy (szBuf, szMsgBuf);
- strupr (szBuf);
- if (strstr (szBuf, "UNIX") != NULL) nHostType = HOST_UNIX;
- else if (strstr (szBuf, "ULTRIX") != NULL) nHostType = HOST_UNIX;
- else if (strstr (szBuf, "MVS") != NULL) nHostType = HOST_MVS;
- else if (strstr (szBuf, "QVT") != NULL) nHostType = HOST_QVT;
- else if (strstr (szBuf, "NCSA") != NULL) nHostType = HOST_NCSA;
- else if (strstr (szBuf, "CHAMELEON")!=NULL) nHostType = HOST_CHAMELEON;
- else if (strstr (szMsgBuf, "VMS") != NULL)
- {
- lp = strstr (szMsgBuf, "MultiNet");
- nHostType = (lp!=NULL)? HOST_VMS_MULTINET : HOST_VMS_UCX;
- }
- }
- 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)
- {
- char szPath[100];
- if (command (ctrl_skt,"MKD %s",pathname)==FTP_ERROR)
- {
- if (iCode==500) command (ctrl_skt,"XMKD %s",pathname);
- else
- {
- lstrcpy (szPath, pathname);
- ConvertTargetDir (szPath, 95);
- command (ctrl_skt,"MKD %s", szPath);
- }
- }
- return(iCode/100);
- }
- //***********************************************************************
- // process RMD
- //***********************************************************************
- int DoRMD(SOCKET ctrl_skt,LPSTR pathname)
- {
- char szPath[100];
- if (command (ctrl_skt,"RMD %s",pathname)==FTP_ERROR)
- {
- if (iCode==500) command (ctrl_skt,"XRMD %s",pathname);
- else
- {
- lstrcpy (szPath, pathname);
- ConvertTargetDir (szPath, 95);
- command (ctrl_skt,"RMD %s", szPath);
- }
- }
- return(iCode/100);
- }
- //***********************************************************************
- // process DELE
- //***********************************************************************
- int DoDELE(SOCKET ctrl_skt,LPSTR pathname)
- {
- command(ctrl_skt,"DELE %s",pathname);
- return(iCode/100);
- }
- //***********************************************************************
- // Send the Quit Command
- //***********************************************************************
- int DoDisconnect (SOCKET ctrl_skt)
- {
- int nRC=-1;
- if (ctrl_skt!=INVALID_SOCKET)
- {
- nRC=command (ctrl_skt, "quit");
- shutdown (ctrl_skt, 2);
- }
- return nRC;
- }
- //***********************************************************************
- // 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,bIs5000;
- LPSTR szAcctAttempt="Attempting to send Account Password...";
- //***********************************************************************
- // initial connection
- //***********************************************************************
- SOCKET DoConnect (LPSTR lpHost)
- {
- int iLength,iRetCode;
- int iFlag=1;
- SOCKET ctrl_skt;
- LPSTR lpSite;
- if (bConnected)
- {
- DoAddLine("Already connected!");
- return (INVALID_SOCKET);
- }
- //***************************************************************
- // if connecting through a Firewall Host, trick the connect code
- // into connecting to the FireWall Host instead.
- //***************************************************************
- if (bFireWall)
- {
- if (lstrlen (szFireWallHost)==0)
- {
- DoPrintf ("FireWall Host name not specified. Can not Connect.");
- SetDebugWindowText (lpDebugWindow);
- return INVALID_SOCKET;
- }
- lpHost = szFireWallHost;
- }
- bHELP=bIs5000=FALSE;
- SetDebugWindowText ("WINFTP Connecting...");
- lpSite = lpHost;
- //***************************************************************
- // let other routines know that we are busy
- //***************************************************************
- bCmdInProgress++;
- //***************************************************************
- // create a connected socket
- //***************************************************************
- if ((ctrl_skt=connectTCP (lpHost,"ftp"))==INVALID_SOCKET)
- {
- DoPrintf ("Connection to %s failed", lpHost);
- bCmdInProgress--;
- SetDebugWindowText (lpDebugWindow);
- 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);
- SetDebugWindowText (lpDebugWindow);
- 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) bIs5000=TRUE;
- }
- //***************************************************************
- // if it succeeded
- //***************************************************************
- if (iRetCode!=FTP_COMPLETE)
- {
- DoPrintf ("Unknown open msg "%s" %u",szMsgBuf,iCode);
- // allow other processes to work
- bCmdInProgress--;
- DoClose ((SOCKET) ctrl_skt);
- SetDebugWindowText (lpDebugWindow);
- return (INVALID_SOCKET);
- }
- 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--;
- if (bFireWall)
- {
- if ((iRetCode=command(ctrl_skt,"USER %s", szFireWallUserID))==FTP_CONTINUE)
- {
- iRetCode = command (ctrl_skt, "PASS %s", szFireWallUserPass);
- }
- if (iRetCode!=FTP_COMPLETE)
- {
- DoPrintf ("Failed to log in to Firewall Host %s", lpHost);
- DoClose ((SOCKET) ctrl_skt);
- return INVALID_SOCKET;
- }
- //***************************************************************
- //Okay, gets here if logged in to FireWall Host
- //***************************************************************
- wsprintf (szString, "site %s", lpSite);
- if ((iRetCode=command (ctrl_skt, szString))==FTP_ERROR)
- {
- DoPrintf ("Could not connect to %s through FireWall Host", lpSite);
- DoClose ((SOCKET) ctrl_skt);
- bConnected=0;
- return INVALID_SOCKET;
- }
- //***************************************************************
- // if here, we did get through to remote host, so do regular login
- //***************************************************************
- bConnected=1;
- }
- //***************************************************************
- // send our userid
- //***************************************************************
- SetDebugWindowText ("WINFTP UserName");
- if ((iRetCode=command (ctrl_skt, "USER %s", szUserID))==FTP_CONTINUE)
- {
- //***************************************************************
- // if the remote system requires a password, send it.
- //***************************************************************
- SetDebugWindowText ("WINFTP Password");
- iRetCode = command (ctrl_skt,"PASS %s",szPassWord);
- //***************************************************************
- // If the system requires an account password
- //***************************************************************
- if (bAccount)
- {
- nAcctType = 3;
- switch (nAcctType)
- {
- case 0: break;
- case 1: if (iRetCode!=FTP_CONTINUE) break;
- case 2: DoAddLine (szAcctAttempt);
- if ((iRetCode=command (ctrl_skt, "ACCOUNT"))==FTP_CONTINUE)
- {
- iRetCode = command (ctrl_skt, szAccountPass);
- } break;
- case 3: if (iRetCode!=FTP_CONTINUE) break;
- case 4: DoAddLine (szAcctAttempt);
- wsprintf (szString, "ACCT %s", szAccountPass);
- iRetCode=command (ctrl_skt, szString);
- break;
- }
- }
- }
- //***************************************************************
- // if we are successfully logged on,.....
- //***************************************************************
- if (iRetCode!=FTP_COMPLETE)
- {
- DoPrintf ("Could not log on to remote host %s", lpSite);
- DoClose ((SOCKET) ctrl_skt);
- SetDebugWindowText (lpDebugWindow);
- MessageBox (hWndMain, szMsgBuf+4, "Login Failed", MB_OK);
- return INVALID_SOCKET;
- }
- bConnected=1;
- wsprintf (szString,"WINFTP: %s",szRemoteHost);
- SetWindowText (hWndMain, szString);
- SetDebugWindowText (lpDebugWindow);
- return ctrl_skt;
- }
- //***********************************************************************
- //***********************************************************************
- int DoDirList (SOCKET ctrl_skt,LPSTR szCMD)
- {
- int nRC,nBell;
- nBell=bBell; bBell=0;
- if (lstrlen (szCurrentDir)>0) unlink (szCurrentDir);
- wsprintf (szCurrentDir, szTmpDirFile, nDirNum++);
- nRC = RetrieveFile (ctrl_skt, szCMD, szCurrentDir, 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
- // read the control channel (should return 1xx if it worked)
- iRetCode = command ((SOCKET) ctrl_skt, szCMD);
- if (iRetCode==FTP_PRELIM)
- {
- // wait for connection back to us on the listen socket
- nTimerID = SetTimer (hWndMain, 10, uiTimeOut, 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);
- nTimerID = -1;
- // if it failed, we have to quit this
- if (data_socket==INVALID_SOCKET)
- {
- ReportWSError("accept",WSAGetLastError());
- listen_socket = DoClose (listen_socket);
- iRetCode = FTP_ERROR;
- }
- else
- {
- // we don't need the listener socket anymore
- // inform user of the connection
- listen_socket = DoClose (listen_socket);
- DoPrintf ("[%u] accept from %s port %u", data_socket,
- inet_ntoa (saSockAddr1.sin_addr), ntohs (saSockAddr1.sin_port));
- // copy the file and close the socket
- iRetCode = SendMass (data_socket, localfile, stype==TYPE_I);
- data_socket = DoClose (data_socket);
- // read the close control message (should return 2xx)
- switch (iRetCode)
- {
- case FTP_ABORT: break; //ForcePacket (ctrl_skt, "ABOR"); break;
- default : iRetCode = ReadDisplayLine (ctrl_skt);
- }
- }
- }
- else
- {
- listen_socket = DoClose (listen_socket);
- iRetCode=0;
- if (bBell) MessageBeep (MB_ICONEXCLAMATION);
- }
- }
- else
- {
- listen_socket = DoClose (listen_socket);
- iRetCode=FTP_ERROR;
- if (bBell) MessageBeep (MB_ICONEXCLAMATION);
- }
- return iRetCode;
- }
- //*****************************************************************************
- //*****************************************************************************
- void ExtractFileSize()
- {
- char szBuf[100];
- LONG nSiz=0;
- LPSTR lp;
- lstrcpy (szBuf, szMsgBuf);
- strupr (szBuf);
- if ((lp=strstr (szBuf, " BYTES"))!=NULL)
- {
- *lp-- = ' ';
- while (*lp==' ') lp--;
- while (isdigit (*lp)) lp--;
- if (*lp!=' ') lp++;
- nSiz = atol (lp);
- if (nSiz>0)
- {
- CreateXferWindow();
- SetTotalBytes (nSiz);
- }
- }
- }
- //*****************************************************************************
- //*****************************************************************************
- 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)
- {
- switch (rtype)
- {
- case TYPE_L: command(ctrl_skt,"TYPE L 8"); break;
- default : 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
- // read the control channel (should return 1xx if it worked)
- //*************************************************************
- iRetCode = command ((SOCKET)ctrl_skt,szCMD);
- if (iRetCode==FTP_PRELIM)
- {
- // wait for connection back to us on the listen socket
- ExtractFileSize();
- iLength = sizeof (saSockAddr1);
- nTimerID = SetTimer (hWndMain, 10, uiTimeOut, NULL);
- // get our data connection
- data_socket = accept (listen_socket, (struct sockaddr far *) &saSockAddr1,
- (int far *)&iLength);
- // turn off the timeout timer
- KillTimer (hWndMain, 10);
- nTimerID = -1;
- // 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 (iRetCode!=FTP_ABORT)
- {
- //************************************************
- // close the data socket
- // read the close control message (should return 2xx)
- //************************************************
- if (shutdown (data_socket, 2)!=0) ReportWSError ("ShutDown", WSAGetLastError());
- data_socket = DoClose (data_socket);
- iRetCode = ReadDisplayLine (ctrl_skt);
- }
- else
- {
- //************************************************
- // Transfer was aborted, try to shut down gracefully
- //************************************************
- // ForcePacket (ctrl_skt, "ABOR");
- shutdown (data_socket, 2);
- data_socket = DoClose (data_socket);
- }
- }
- }
- 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;
- }
- linger.l_onoff = TRUE;
- linger.l_linger = 0;
- // Patch to make Lanera Stack work
- //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, nRetCode;
- if (sockfd==INVALID_SOCKET) return -1;
- if ((bCmdInProgress)&&(lstrcmpi (msg, "quit")!=0))
- {
- DoAddLine ("Command already in progress, ignored New Cmd");
- return -1;
- }
- bCmdInProgress++;
- i=lstrlen (msg);
- lstrcpy (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, &nRetCode);
- bCmdInProgress--;
- return i;
- }
- //***********************************************************************
- //***********************************************************************
- int ForcePacket (SOCKET sockfd, LPSTR msg)
- {
- int i, nRetCode;
- if (sockfd==INVALID_SOCKET) return -1;
- bCmdInProgress++;
- i=lstrlen (msg);
- lstrcpy (szSendPkt, msg);
- // append a CRLF to the end of outgoing messages
- if (szSendPkt[i-1]!='n') lstrcat (szSendPkt, "rn"), i += 2;
- i = sendstr (sockfd, szSendPkt, i, &nRetCode);
- 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.
- // count the lines in the response
- bCmdInProgress++;
- iMultiLine++;
- // initialize some variables, go read the line
- do
- {
- iContinue=0;
- iRetCode = ReadLine (sockfd);
- //switch (iRetCode)
- //{
- // case 257: ConvertSourceDir
- //}
- // if it wasn't a valid value or the 4th char was a hyphen
- // then it is a continuation line
- if (iRetCode<100 || iRetCode>599 || szMsgBuf[3]=='-') iContinue=1;
- // send the line we read to our user/debug window
- DoAddLine (szMsgBuf);
- // if the timer killed it
- if (bAborted) { iCode=iRetCode=421; iContinue=0; break; }
- // we only want to set the real return code in certain situations
- if ((iMultiLine==1 || iCode==0) && iRetCode>99 && iRetCode<600)
- iCode = iRetCode;
- // allow for continuation lines
- }
- while ((iContinue==1) || (iCode>0 && iMultiLine>1 && iRetCode!=iCode));
- // ReadDisplayLine (sockfd);
- // count back down our multiline reponses
- iMultiLine--;
- // allow other processes to run
- bCmdInProgress--;
- if (bAborted) return FTP_ABORT;
- //************************************************
- // return only the first char of return code
- //************************************************
- if (iCode>99 && iCode<600) return (iCode/100);
- else return 0;
- UNREFERENCED_PARAMETER (c);
- UNREFERENCED_PARAMETER (s);
- }
- //***********************************************************************
- // 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 nI;
- int iNumBytes,iN1,iN2,iN3;
- int iBytesRead;
- int iRetCode;
- int i;
- char *s, szTrim[5] = " rn";
- 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;
- nTimerID = -1;
- // zero our receive buffer
- memset (szMsgBuf, 0, 4096);
- // initialize some variables
- szBuf=szMsgBuf; iBytesRead=0; iRetCode=0;
- // set our timeout
- nTimerID = SetTimer (hWndMain, 10, uiTimeOut, 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...
- iNumBytes=recv (sockfd, (LPSTR) szBuf, 82, MSG_PEEK);
- while (iBytesRead<4000 && (iNumBytes>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);
- nTimerID = -1;
- iN1 = iNumBytes;
- // must terminate the string so strchr doesn't go wild.
- szBuf[iNumBytes]=' ';
- // find a LF in the input if it exists
- for (nI=0; nI<iNumBytes; nI++)
- {
- if (szBuf[nI]==0 || szBuf[nI]==0x0a || (bIs5000 && (szBuf[nI]==0x0d)))
- {
- iNumBytes=nI+1;
- 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. NOTE: this is not really
- // in keeping with RFC 959 as the line MUST end with CRLF but I work with
- // a system (UNISYS 5000) that only returns a LF and no CR at the end of lines.
- if(*(szBuf-1)==0x0a || (bIs5000 && *(szBuf-1)==0x0d)) break;
- // otherwise reset the timer and go read more characters
- nTimerID = SetTimer (hWndMain, 10, uiTimeOut, NULL);
- iNumBytes=recv (sockfd, (LPSTR) szBuf, 82, MSG_PEEK);
- }
- // if we are here, we have a line or an error or there was nothing to read
- // in any case terminate what we have
- KillTimer(hWndMain, 10);
- nTimerID = -1;
- *szBuf=0;
- //*******************************************************
- // find the retcode at the beginning of the line
- //*******************************************************
- if (iNumBytes!=SOCKET_ERROR)
- {
- c=szMsgBuf[3];
- szMsgBuf[3]=0;
- iRetCode = atoi (szMsgBuf);
- szMsgBuf[3]=c;
- }
- else
- {
- int nError = WSAGetLastError();
- switch (nError)
- {
- case WSAEINTR :
- case WSAENETRESET:
- case WSAESHUTDOWN:
- case WSAENETDOWN :
- case WSAECONNABORTED:
- case WSAECONNRESET:
- case WSAEINVAL :
- case WSAENOTSOCK : bAborted=TRUE; break;
- }
- }
- //*******************************************************
- // if the timer killed it or was somehow aborted
- //*******************************************************
- if (bAborted) iRetCode=421;
- // strip trailing blanks, CR's and LF's
- i = lstrlen (szMsgBuf) - 1;
- while ((i>1) && (strchr (szTrim, szMsgBuf[i])!=NULL)) szMsgBuf[i--]=0, i;
- // unmark our progress
- bCmdInProgress--;
- return iRetCode;
- UNREFERENCED_PARAMETER (iN3);
- UNREFERENCED_PARAMETER (s);
- }
- //***********************************************************************
- // 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);
- }
- #ifdef WIN32
- #define OPENFIL(x) _lopen (x, OF_READ | OF_SHARE_DENY_NONE)
- #else
- #define OPENFIL(x) _lopen (x, READ)
- #endif
- //***********************************************************************
- // Return the size of the specified file
- //***********************************************************************
- LONG GetFileLength (LPSTR lpName, int iFileHandle)
- {
- #ifdef WIN32
- WIN32_FIND_DATA wfDat;
- HANDLE hFile;
- LONG lSize;
- hFile=FindFirstFile (lpName, &wfDat);
- if (hFile==INVALID_HANDLE_VALUE) return (LONG) -1;
- FindClose (hFile);
- lSize = (wfDat.nFileSizeHigh << 32) + wfDat.nFileSizeLow;
- return lSize;
- #else
- return _filelength (iFileHandle);
- #endif
- }
- //***********************************************************************
- // send a file through the data socket
- //***********************************************************************
- int SendMass (SOCKET sockfd, LPSTR szFileName, BOOL binaryflag)
- {
- int iNumBytes;
- int iRetCode;
- int iFileHandle;
- long lBytesWritten, lBytesToGo;
- time_t ttStart;
- time_t ttStop;
- // if we don't have a socket, return an error
- if (sockfd==INVALID_SOCKET || !(bConnected)) return FTP_ERROR;
- // turn on a flag so other routines know we have a command in progress
- // initialize some vars
- bCmdInProgress++;
- lBytesWritten=0l; iRetCode=FTP_ERROR;
- // Open the local file for transmit.
- if ((iFileHandle=OPENFIL (szFileName))== -1)
- {
- DoPrintf ("Could not open file %s (%u)", szFileName, errno);
- if (bBell) MessageBeep (MB_ICONEXCLAMATION);
- }
- else
- {
- // get the start time
- ttStart=time(NULL);
- iRetCode = FTP_COMPLETE;
- lBytesToGo=GetFileLength (szFileName, iFileHandle);
- SetTotalBytes (lBytesToGo);
- DoPrintf ("Transferring %ld bytes", (long) lBytesToGo);
- SetXferWindowText (szFileName);
- // loop to send output to remote end
- while (((iNumBytes=_lread (iFileHandle, szMsgBuf, 512))>0)
- &&(iRetCode!=FTP_ERROR)&&(iRetCode!=FTP_ABORT)&&(!bAborted))
- {
- // count the characters that we have sent out
- lBytesWritten += (LONG) sendstr (sockfd, szMsgBuf, iNumBytes, &iRetCode);
- wsprintf (szString, "%lu", lBytesWritten);
- SendMessage (hTxtLBytes, WM_SETTEXT, 0, (LPARAM)(LPCSTR) szString);
- SetXmitBytes (lBytesWritten);
- }
- // if the output file is open, close it
- _lclose (iFileHandle);
- switch (iRetCode)
- {
- case FTP_ERROR: DoPrintf ("Error on Transfer, aborted"); break;
- case FTP_ABORT: DoPrintf ("Transfer aborted by User"); break;
- default : // show the user how we did
- // get the finish time
- ttStop=time(NULL);
- SendMessage (hTxtLBytes, WM_SETTEXT, 0, (LPARAM) NULL);
- PrintTransferStatus ("Transmitt", lBytesWritten, (LONG) ttStop-ttStart);
- iRetCode=FTP_COMPLETE;
- 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 szFileName,BOOL binaryflag)
- {
- int iNumBytes;
- int iRetCode;
- int iFileHandle;
- long lBytesRead;
- time_t ttStart;
- time_t ttStop;
- // if we don't have a socket, return an error
- // otherwise turn on a flag so other routines know about cmd in progress
- if(sockfd==INVALID_SOCKET || !(bConnected)) return 0;
- bCmdInProgress++;
- //************************************************
- // make sure we don't mistakenly think we timed out
- // initialize some vars
- //************************************************
- KillTimer (hWndMain, 10); bAborted=FALSE;
- nTimerID = -1;
- lBytesRead=0l; iRetCode=0;
- //***********************************************************************
- // at the moment we are ignoring the fact that the local destination file
- // may not open correctly.
- //***********************************************************************
- if ((iFileHandle=_lcreat (szFileName,0))== -1)
- {
- DoPrintf ("Failed to create file %s (%u)", szFileName,errno);
- bCmdInProgress--;
- return FTP_ERROR;
- }
- //************************************************
- // get the start time
- //************************************************
- SetXferWindowText (szFileName);
- ttStart = time (NULL);
- // loop to receive input from remote end
- iNumBytes = recv (sockfd, (LPSTR)szMsgBuf, 4000, 0);
- while (!bAborted && (iNumBytes>0) && (iNumBytes!=SOCKET_ERROR))
- {
- //************************************************
- // write what we received if the file is open
- // and count the characters that we received
- //************************************************
- _lwrite (iFileHandle, szMsgBuf, iNumBytes);
- lBytesRead += iNumBytes;
- SetXmitBytes (lBytesRead);
- wsprintf (szString, "%lu", lBytesRead);
- SendMessage (hTxtRBytes, WM_SETTEXT, 0, (LPARAM)(LPCSTR) szString);
- if (!bAborted) iNumBytes = recv (sockfd, (LPSTR) szMsgBuf, 4000, 0);
- }
- //************************************************
- // get the finish time
- // if the output file is open, close it
- //************************************************
- ttStop = time (NULL);
- if (iFileHandle != -1) _lclose (iFileHandle);
- if (bAborted) _unlink (szFileName), DoPrintf ("Delete partially downloaded file");
- //************************************************
- // if we had a recv error, let us know about it
- //************************************************
- if (iNumBytes==SOCKET_ERROR)
- {
- ReportWSError ("Recv", iRetCode=WSAGetLastError());
- if (lBytesRead==0l)
- {
- if(bBell) MessageBeep (MB_ICONEXCLAMATION);
- }
- }
- else
- {
- //************************************************
- // show the user how we did
- // turn off our command in progress flag
- //************************************************
- SendMessage (hTxtRBytes, WM_SETTEXT, 0, (LPARAM) NULL);
- PrintTransferStatus ("Receiv", lBytesRead, (LONG) ttStop-ttStart);
- if (bBell) MessageBeep (MB_OK);
- iRetCode = (bAborted) ? FTP_ABORT : FTP_COMPLETE;
- }
- bCmdInProgress--;
- return iRetCode;
- }