?? ftpdlib.c
字號:
if (ftpdCmdSend (pSlot, sock, 550, messages [MSG_DIR_ERROR], (int) &pBuf[5], 0, 0, 0, 0, 0) == ERROR) goto connectionLost ; renFile[0] = EOS ; continue ; } if (ftpdCmdSend (pSlot, sock, 250, messages [MSG_RNTO_OK], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost ; renFile[0] = EOS ; } else if (strncmp (pBuf, "DELE", 4) == 0) { ftpPathNormalize ( pSlot, &pBuf[5], newPath, &pFileName ); ftpdDebugMsg ("DELE %s\n", (int)pFileName,0,0,0); if( ftpPathAccessVerify(pSlot, pFileName, O_WRONLY) == ERROR ) { if (ftpdCmdSend (pSlot, sock, 550, messages [MSG_GUEST_ACCESS], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; continue; } if( remove( pFileName ) != OK ) { if (ftpdCmdSend (pSlot, sock, 550, messages [MSG_FILE_ERROR], (int) &pBuf[5], 0, 0, 0, 0, 0) == ERROR) goto connectionLost ; continue; } else { if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_DELE_OK], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost ; } } else if ((strncmp (pBuf, "MKD", 3) == 0) || (strncmp (pBuf, "XMKD", 4) == 0) ) { if(strncmp (pBuf, "MKD", 3) == 0) ftpPathNormalize ( pSlot, &pBuf[4], newPath, &pFileName ); else ftpPathNormalize ( pSlot, &pBuf[5], newPath, &pFileName ); ftpdDebugMsg ("MKD %s\n", (int)pFileName,0,0,0); if( ftpPathAccessVerify(pSlot, pFileName, O_WRONLY) == ERROR ) { if (ftpdCmdSend (pSlot, sock, 550, messages [MSG_GUEST_ACCESS], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; continue; } if( mkdir( pFileName ) != OK ) { if (ftpdCmdSend (pSlot, sock, 550, messages [MSG_MKD_ERROR], (int) &pBuf[4], 0, 0, 0, 0, 0) == ERROR) goto connectionLost ; continue; } else { if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_MKD_OK], (int) &pBuf[4], 0, 0, 0, 0, 0) == ERROR) goto connectionLost ; } } else if ((strncmp (pBuf, "RMD", 3) == 0) || (strncmp (pBuf, "XRMD", 4) == 0) ) { char *pDir ; if(strncmp (pBuf, "RMD", 3) == 0) pDir = pBuf+4 ; else pDir = pBuf+5 ; ftpPathNormalize ( pSlot, pDir, newPath, &pFileName ); ftpdDebugMsg ("RMD %s\n", (int)pFileName,0,0,0); if( ftpPathAccessVerify(pSlot, pFileName, O_WRONLY) == ERROR ) { if (ftpdCmdSend (pSlot, sock, 550, messages [MSG_GUEST_ACCESS], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; continue; } if( rmdir( pFileName ) != OK ) { if (ftpdCmdSend (pSlot, sock, 550, messages [MSG_FILE_ERROR], (int) pDir, 0, 0, 0, 0, 0) == ERROR) goto connectionLost ; continue; } else { if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_RMD_OK], (int) pDir, 0, 0, 0, 0, 0) == ERROR) goto connectionLost ; } } else if ((strncmp (pBuf, "CWD", 3) == 0)|| (strncmp (pBuf, "CDUP", 4) == 0)|| (strncmp (pBuf, "XCWD", 4) == 0)|| (strncmp (pBuf, "XCUP", 4) == 0) ) { struct stat st; /* for stat() system call */ /* change directory */ if(strncmp (pBuf, "CWD", 3) == 0) ftpPathNormalize ( pSlot, &pBuf[4], newPath, &dirName ); else if( strncmp (pBuf, "XCWD", 4) == 0) ftpPathNormalize ( pSlot, &pBuf[5], newPath, &dirName ); else ftpPathNormalize ( pSlot, "..", newPath, &dirName ); if( ftpPathAccessVerify(pSlot, newPath, O_RDONLY) == ERROR ) { if (ftpdCmdSend (pSlot, sock, 550, messages [MSG_GUEST_ACCESS], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; continue; } /* verify that this is indeed a directory we can handle */ if( (stat( newPath, &st ) != OK ) || !S_ISDIR (st.st_mode)) { if (ftpdCmdSend (pSlot, sock, 501, messages[MSG_DIR_NOT_PRESENT], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost ; continue; } /* remember where we are */ (void) strncpy (pSlot->curDirName, newPath, MAX_FILENAME_LENGTH); /* notify successful chdir */ if (ftpdCmdSend (pSlot, sock, 250, messages [MSG_CHANGED_DIR], (int)ftpdPathForPrint(pSlot,newPath), 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } else if (strncmp (pBuf, "TYPE", 4) == 0) { /* we only support BINARY and ASCII representation types */ if (pBuf [5] == 'I' || pBuf [5] == 'i' || pBuf [5] == 'L' || pBuf [5] == 'l') { pSlot->status |= FTPD_BINARY_TYPE; pSlot->status &= ~FTPD_ASCII_TYPE; if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_TYPE_BINARY], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } else if (pBuf [5] == 'A' || pBuf [5] == 'a') { pSlot->status |= FTPD_ASCII_TYPE; pSlot->status &= ~FTPD_BINARY_TYPE; if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_TYPE_ASCII], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } else { if (ftpdCmdSend (pSlot, sock, 504, messages [MSG_PARAM_BAD], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } } else if (strncmp (pBuf, "PORT", 4) == 0) { /* client specifies the port to be used in setting up * active data connections later on (see ftpdDataConnGet ()). * format: first four decimal digits separated by commas * indicate the internet address; the last two decimal * digits separated by a comma represents hi and low * bytes of a port number. */ (void) sscanf (&pBuf [5], "%d,%d,%d,%d,%d,%d", &portNum [0], &portNum [1], &portNum [2], &portNum [3], &portNum [4], &portNum [5]); pSlot->dataAddr.sin_port = portNum [4] * 256 + portNum [5]; /* convert port number to network byte order */ pSlot->dataAddr.sin_port = htons (pSlot->dataAddr.sin_port); /* Set remote host to given value. */ value = (portNum [0] << 24) | (portNum [1] << 16) | (portNum [2] << 8) | portNum [3]; pSlot->dataAddr.sin_addr.s_addr = htonl (value); if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_PORT_SET], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } else if ((strncmp (pBuf, "PWD", 3) == 0) || (strncmp (pBuf, "XPWD", 4) == 0)) { /* get current working directory */ (void) strcpy (pBuf, pSlot->curDirName); if (ftpdCmdSend (pSlot, sock, 257, messages [MSG_CUR_DIR], (int)ftpdPathForPrint(pSlot,pBuf), 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } else if (strncmp (pBuf, "STRU", 4) == 0) { /* specify the file structure */ /* we only support normal byte stream oriented files; * we don't support IBM-ish record block oriented files */ if (pBuf [5] == 'F' || pBuf [5] == 'f') { if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_FILE_STRU], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } else { if (ftpdCmdSend (pSlot, sock, 504, messages [MSG_PARAM_BAD], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } } else if (strncmp (pBuf, "MODE", 4) == 0) { /* specify transfer mode */ /* we only support stream mode -- no block or compressed mode */ if (pBuf [5] == 'S' || pBuf [5] == 's') { if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_STREAM_MODE], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } else { if (ftpdCmdSend (pSlot, sock, 504, messages [MSG_PARAM_BAD], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } } else if (strncmp (pBuf, "ALLO", 4) == 0 || strncmp (pBuf, "ACCT", 4) == 0) { /* allocate and account commands are not need */ if (ftpdCmdSend (pSlot, sock, 202, messages [MSG_ALLOC_ACCOUNT], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } else if (strncmp (pBuf, "PASV", 4) == 0) { int outval1; int outval2; int outval3; int outval4; int outval5; int outval6; /* client wants to connect to us instead of waiting * for us to make a connection to its data connection * socket */ ftpdSockFree (&pSlot->dataSock); /* we need to open a socket and start listening on it * to accommodate his request. */ if ((pSlot->dataSock = socket (AF_INET, SOCK_STREAM, 0)) < 0) { if (ftpdCmdSend (pSlot, sock, 425, messages [MSG_PASSIVE_ERROR], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; continue ; } addrLen = sizeof (pSlot->dataAddr); /* SPR # 1318, 5897 - lrn: * in order to avoid reporting a NULL IP address * to PASV requestor, get our local IP address * from the control connection, yielding an IP * most probable to work with the data connection too * and use this IP for bind() as well as PASV response. */ if (getsockname (pSlot->cmdSock, (struct sockaddr *) &pSlot->dataAddr, &addrLen) < 0) { /* Couldn't find address for local end of connection. */ if (ftpdCmdSend (pSlot, sock, 425, messages [MSG_PASSIVE_ERROR], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } /* * Find an ephemeral port for the expected connection * and initialize connection queue. */ pSlot->dataAddr.sin_port = htons (0); addrLen = sizeof (struct sockaddr_in); if (bind (pSlot->dataSock, (struct sockaddr *)&pSlot->dataAddr, sizeof (struct sockaddr_in)) < 0 || getsockname (pSlot->dataSock, (struct sockaddr *) &pSlot->dataAddr, &addrLen) < 0 || listen (pSlot->dataSock, 1) < 0) { ftpdSockFree (&pSlot->dataSock); if (ftpdCmdSend (pSlot, sock, 425, messages [MSG_PASSIVE_ERROR], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; continue; } /* we're passive, let us keep that in mind */ pSlot->status |= FTPD_PASSIVE; value = pSlot->dataAddr.sin_addr.s_addr; outval1 = ( (u_char *)&value)[0]; outval2 = ( (u_char *)&value)[1]; outval3 = ( (u_char *)&value)[2]; outval4 = ( (u_char *)&value)[3]; /* Separate port number into bytes. */ outval5 = ( (u_char *)&pSlot->dataAddr.sin_port)[0]; outval6 = ( (u_char *)&pSlot->dataAddr.sin_port)[1]; /* tell the client to which port to connect */ if (ftpdCmdSend (pSlot, pSlot->cmdSock, 227, messages [MSG_PASSIVE_MODE], outval1, outval2, outval3, outval4, outval5, outval6) == ERROR) goto connectionLost; } else if (strncmp (pBuf, "NOOP", 4) == 0) { /* don't do anything */ if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_NOOP_OKAY], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } else { /* unrecognized command or command not supported */ if (ftpdCmdSend (pSlot, sock, 500, messages [MSG_BAD_COMMAND], 0, 0, 0, 0, 0, 0) == ERROR) goto connectionLost; } } /* * Processing halted due to pending server shutdown. * Remove all resources and exit. */ ftpdSessionDelete (pSlot); return (OK);connectionLost: ftpdDebugMsg ("FTP Control connection error, closed.\n", 0,0,0,0); ftpdSessionDelete (pSlot); return (ERROR); }/********************************************************************************* ftpdDataConnGet - get a fresh data connection socket for FTP data transfer** FTP uses upto two connections per session (as described above) at any* time. The command connection (cmdSock) is maintained throughout the* FTP session to pass the request command strings and replies between* the client and the server. For commands that require bulk data transfer* such as contents of a file or a list o
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -