#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> /* * FTP Retrun Code * 200 SUCCESS, 202 command not execute * 220 ready, 230 login * 250 file finish */ int gCmdSock; int gDataSock; char gRevBuf[512]; // ftp cmd static int ftpcmd(const char *s1, const char * s2) { int iRet; char cmdBuf[256] = {0}; if(s1) { sprintf(cmdBuf, (s2?"%s %s \r\n":"%s %s\r\n"+3), s1, s2); send(gCmdSock, cmdBuf, strlen(cmdBuf), 0); } do{ strcpy(gRevBuf, "EOF"); if(recv(gCmdSock, gRevBuf, sizeof(gRevBuf)-2, 0 ) < 0) { return 0; } }while(!isdigit(gRevBuf[0]) || gRevBuf[3] != ' '); gRevBuf[3] = '\0'; iRet = atoi(gRevBuf); gRevBuf[3] = ' '; return iRet; } void printcmd( const char * s1, const char * s2 ) { char cmdBuf[256] = {0}; char gRevBuf[512] = {0}; if(s1) { sprintf(cmdBuf, (s2?"%s %s \r\n":"%s %s\r\n"+3), s1, s2); send(gCmdSock, cmdBuf, strlen(cmdBuf), 0); } do{ strcpy(gRevBuf, "EOF"); if(recv(gCmdSock, gRevBuf, sizeof(gRevBuf)-2, 0 ) < 0) { return; } printf("%s", gRevBuf); }while(1); } void download( char * local_path, char * server_path ) { int rd; char * buf_ptr; int port_num; int fd_local; struct sockaddr_in ftpData_addr; char buffer[4096] = {0}; // Get the port of data tranfor if(ftpcmd("PASV", NULL)!=227) { fprintf(stderr, "Chang passive mode error\n"); return; } printf("Enter passive mode\n"); printf("%s\n", gRevBuf); buf_ptr = strrchr(gRevBuf, ')'); if( buf_ptr ) *buf_ptr = '\0'; buf_ptr = strrchr(gRevBuf, ','); *buf_ptr = '\0'; port_num = atoi(buf_ptr + 1); buf_ptr = strrchr(gRevBuf, ','); *buf_ptr = '\0'; port_num += atoi(buf_ptr + 1) * 256; printf("The data socket port is %d.\n", port_num); // connent the data socket memset(&ftpData_addr, 0, sizeof(ftpData_addr)); ftpData_addr.sin_family = AF_INET; ftpData_addr.sin_addr.s_addr = inet_addr("192.168.0.104"); ftpData_addr.sin_port = htons(port_num); gDataSock = socket(AF_INET, SOCK_STREAM, 0 ); if(gDataSock < 0) { fprintf(stderr, "Create data socket error.\n"); return; } if(connect(gDataSock, (struct sockaddr *)&ftpData_addr, sizeof(ftpData_addr)) < 0) { fprintf(stderr, "Connect data socket error.\n"); return; } if(ftpcmd("RETR", server_path) > 150) { fprintf(stderr, "RETR data error.\n"); return; } fd_local = open( local_path, (O_CREAT | O_TRUNC | O_WRONLY) ); if(fd_local < 0) { fprintf(stderr, "open local file error.\n"); return; } while(1) { rd = recv(gDataSock, buffer, 4096, 0); printf("rd=%d\n",rd); if( rd <= 0 ) break; write(fd_local, buffer, rd); //sleep(1); } if (ftpcmd(NULL, NULL) != 226) { fprintf(stderr, "Trans file error.\n"); return; } close(fd_local); close(gDataSock); } int main() { struct sockaddr_in ftpSrv_addr; int iRet; // Create socket gCmdSock = socket(AF_INET, SOCK_STREAM, 0); if(gCmdSock < 0) { fprintf(stderr, "Create socket error\n"); exit(1); } // Connect to Ftp server memset(&ftpSrv_addr, 0, sizeof(ftpSrv_addr)); ftpSrv_addr.sin_family = AF_INET; ftpSrv_addr.sin_addr.s_addr = inet_addr("192.168.0.104"); ftpSrv_addr.sin_port = htons(21); if(connect(gCmdSock, (struct sockaddr *)&ftpSrv_addr, sizeof(ftpSrv_addr)) < 0) { fprintf(stderr, "Connect socket error\n"); exit(2); } // Check if connect OK if( ftpcmd(NULL, NULL) !=220 ) { fprintf(stderr, "FTP server not ready error\n"); exit(3); } printf("FTP READY!\n"); // Login switch(ftpcmd("USER", "software")) { case 230: break; case 331: if( ftpcmd("PASS", "password")!= 230 ) { fprintf(stderr, "Wrong password\n"); exit(4); } break; default: fprintf(stderr, "Wrong user\n"); exit(4); } // Tansfor mode ftpcmd("TYPE I", NULL); printf("Login Success!\n"); download("upload.iso", "/test/upload.iso"); ftpcmd("QUIT", NULL); close(gCmdSock); return 0; }