📄 ccache_ftp.c
字号:
*/ if ((sendPort) || ((!sendPort) && (!isListening))) { newSocket = PrepareDataConnect(theSocket, sendPort); if (newSocket < 0) return (newSocket); } else newSocket = dataSocket; /* using port command, construct command string */ if (sendPort) { memset(&theAddr, '\0', addrLen); /* get host address and port number to tell FTP server where * to send data */ if (getsockname(newSocket, (struct sockaddr *) &theAddr, &addrLen) < 0) return (GET_SOCKNAME_ERR); if (gethostname(hostName, HOST_NAME_LENGTH) < 0) return (GET_HOSTNAME_ERR); theEntry = gethostbyname(hostName); if (!theEntry) return (GET_HOSTBYNAME_ERR); host = (char *) theEntry->h_addr; port = (char *) &theAddr.sin_port; /* set up final portMessage string */ sprintf(portMessage, "%d,%d,%d,%d,%d,%d", (u_char) host[0], (u_char) host[1], (u_char) host[2], (u_char) host[3], (u_char) port[0], (u_char) port[1]); /* send PORT command */ error = SendMessage(PORT, portMessage, theSocket); free(theEntry); if (error != NO_ERROR) return (error); /* read reply and check for errors */ error = ReadServReply(theSocket, servReply); if (error != NO_ERROR) return (error); error = CheckServReply(PORT_CHK, servReply); if (error != NO_ERROR) { memcpy(errorReply, servReply, SERV_REPLY_LENGTH); return (error); } } else free(theEntry); /* send retrieval command */#if DEBUG > 4 printf("Retrieving: %s\n", fileName);#endif error = SendMessage(RETRIEVE, fileName, theSocket); if (error != NO_ERROR) return (error); /* check for errors */ error = ReadServReply(theSocket, servReply); if (error != NO_ERROR) return (error); error = CheckServReply(RETRIEVE_CHK, servReply); if (error != NO_ERROR) { memcpy(errorReply, servReply, SERV_REPLY_LENGTH); return (error); } /* retrieve the data over the data socket */ error = RetrieveFile(newSocket, data); if (error < 0) return (error); /* check for errors */ error = ReadServReply(theSocket, servReply); if (error != NO_ERROR) return (error); error = CheckServReply(RETRIEVE_CHK, servReply); if (error != NO_ERROR) { memcpy(errorReply, servReply, SERV_REPLY_LENGTH); return (error); } /* might need to close new data socket */ if (sendPort) { close(newSocket); return (NO_ERROR); } else return (newSocket);}/******************************************************************************** function name: InitSocket()**** preconditions: hostAddr contains the address of the host machine running** the FTP server, portNum is the number of the TCP port on** the machine specified by hostName to connect to**** postconditions: socket for client has been created and connection to ** FTP server established**** author/credits: David Merkel, 4/94********************************************************************************/int InitSocket(hostAddr, portNum) u_long hostAddr; /* name of host to connect to */ int portNum; /* TCP port on host to connect to */{ int theSocket; struct sockaddr_in theAddr; struct hostent *theEntry; /* zero out theAddr structure */ memset(&theAddr, '\0', sizeof(theAddr)); /* get a socket */ theSocket = socket(AF_INET, SOCK_STREAM, 0); if (theSocket < 0) return (GET_SOCKET_ERR); theAddr.sin_family = AF_INET; theAddr.sin_port = htons(portNum); /* get hostent for hostAddr */ theEntry = gethostbyaddr((char *) &hostAddr, sizeof(u_long), AF_INET); if (theEntry == NULL) return (GETHOST_ERR); /* copy host information into theAddr */ memcpy(&theAddr.sin_addr.s_addr, theEntry->h_addr, theEntry->h_length); /* establish connection */ if (connect(theSocket, (struct sockaddr *) &theAddr, sizeof(theAddr)) < 0) return (CONNECT_ERR); return (theSocket);}/******************************************************************************** function name: ReadServReply()**** preconditions: theSocket is the control connection for an FTP session,** servReply is preallocated by caller**** postconditions: an FTP reply has been read from theSocket and returned in** servReply, or an error occurred (i.e. timeout) and a negative error** code is returned to caller.**** author/credits: Dave Merkel, 4/94********************************************************************************/int ReadServReply(theSocket, servReply) int theSocket; /* FTP control connection */ char *servReply; /* storage for FTP reply */{ char servText; /* for checking end of reply */ struct timeval timeout; /* for timeout on looking for * reply */ int i = 0, index = 0; int readLength, selectResult; Boolean done = FALSE; /* loop control */ fd_set dataDetect; /* detect data on theSocket */ timeout.tv_usec = 0; /* checking for data on control connection */ while ((!done) && (i < READ_TIMEOUT)) { FD_ZERO(&dataDetect); FD_SET(theSocket, &dataDetect); timeout.tv_sec = timeout.tv_usec = 0; /* poll with select and see if data on theSocket */ selectResult = select(theSocket + 1, &dataDetect, (fd_set *) 0, (fd_set *) 0, &timeout); /* if data present */ if (FD_ISSET(theSocket, &dataDetect)) { /* start reading server reply */ readLength = read(theSocket, servReply + index, SERV_REPLY_LENGTH - index); if (readLength == 0) return (NO_REPLY_PRESENT); /* walk to next index for subsequent reads */ index += readLength; if (index == SERV_REPLY_LENGTH) done = TRUE; i = 0; } /* no data on line, might not be here yet, wait 1 second * and then continue */ else { timeout.tv_sec = 1; timeout.tv_usec = 0; selectResult = select(theSocket + 1, &dataDetect, (fd_set *) 0, (fd_set *) 0, &timeout); i++; } } /* we got our reply, now we must parse out extra text attached * to reply */ if (read(theSocket, &servText, 1)) { /* ReadOutText empties theSocket of extra reply data */ if (servText == MULTI_LINE_CODE) ReadOutText(theSocket, TRUE, servReply); else ReadOutText(theSocket, FALSE, NULL); } return (NO_ERROR);}/******************************************************************************** function name: WriteToSocket()**** preconditions: theSocket is a valid socket, and outBuf is a preallocated** char * holding data to be written to theSocket.**** postconditions: The data in outBuf has been written to theSocket, and the** total number of bytes written to theSocket has been returned to the** caller.**** author/credits: Code written by W. Richard Stevens,** from UNIX Network Programming, c1990, Prentice Hall, pp. 279-280********************************************************************************/int WriteToSocket(theSocket, outBuf, numOfBytes) int theSocket; /* socket to write to */ char *outBuf; /* the data to write to the socket */ int numOfBytes; /* number of bytes inside of outBuf */{ int bytesLeft, bytesWritten, i = 0; bytesLeft = numOfBytes; while (bytesLeft > 0) { bytesWritten = write(theSocket, &outBuf[i], bytesLeft); if (bytesWritten <= 0) return (bytesWritten); bytesLeft -= bytesWritten; i += bytesWritten; } return (numOfBytes - bytesLeft);}/******************************************************************************** function name: SendMessage()**** preconditions: msgType is preallocated, containing the type of message to** send, argument (if needed) is preallocated and constructed by** caller, theSocket is control connection for FTP session **** postconditions: a message of msgType with argument has been sent to ** connected FTP server**** author/credits: Dave Merkel, 4/94********************************************************************************/int SendMessage(msgType, argument, theSocket) char *msgType; /* type of message to send */ char *argument; /* arguments for message */ int theSocket; /* FTP control connection */{ char *theMessage; /* final message buffer */ int msgSize; /* size of message */ int sendLength; /* for checking amount sent */ int msgLen = strlen(msgType); if (msgType == NULL) return (MEMORY_ERROR); /* argument is valid and its length should be added to msgSize */ if (argument != NULL) msgSize = msgLen + strlen(argument) + 3; else msgSize = msgLen + 3; /* allocate message buffer */ theMessage = (char *) malloc(msgSize); if (theMessage == NULL) return (MEMORY_ERROR); /* argument should be added to theMessage */ if (argument != NULL) sprintf(theMessage, "%s %s", msgType, argument); else sprintf(theMessage, "%s", msgType); /* all FTP messages end in CR LF */ theMessage[msgSize - 2] = CARRG_RET; theMessage[msgSize - 1] = LINE_FEED; /* send message */ sendLength = WriteToSocket(theSocket, theMessage, msgSize); free(theMessage); /* make sure all of message was sent */ if (sendLength != msgSize) return (WRITE_TO_SOCK_ERR); else return (NO_ERROR);}/******************************************************************************** function name: ReadOutText()**** preconditions: theSocket is control connection for FTP session, isMultiLine** if we need to read out multi-line reply, theCode is the FTP reply** code that determines where the end of reply is **** postconditions: extra text associated with an FTP server reply is read off** of theSocket and discarded.**** author/credits: Dave Merkel, 4/94********************************************************************************/void ReadOutText(theSocket, isMultiLine, theCode) int theSocket; /* FTP control connection */ Boolean isMultiLine; /* indicates multi-line server response */ char *theCode; /* code to check for on end of reply */{ int whichDigit = 0; /* tracks which digits of theCode * we have found */ Boolean done = FALSE, hasCR = FALSE, lastLine = FALSE; char inChar; int readLength; /* read until end of server reply message */ while (!done) { if ((readLength = read(theSocket, &inChar, 1)) == 1) { /* read one character at a time and check for match with * theCode */ if ((isMultiLine) && (!lastLine)) { switch (whichDigit) { case 0: if (inChar == theCode[0]) whichDigit = 1; break; case 1: if (inChar == theCode[1]) whichDigit = 2; else whichDigit = 0; break; case 2: if (inChar == theCode[2]) whichDigit = 3; else whichDigit = 0; break; case 3: if (inChar == ' ') lastLine = TRUE; else whichDigit = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -