📄 ftp_client_source_unix.txt
字号:
//====================================================== // cc -o ftpc ftpc.c -lsocket //====================================================== #include "ftp.h" static struct sockaddr_in ftp_server, local_host; static int toflag; static int port = DEFAULT_FTP_PORT; //TIMEOUT single proc static _alarmproc() { signal( SIGALRM, _alarmproc ); toflag = 1; } /************************* ftp private func **************************/ static int _filladdr(const char *host_ip_addr, struct sockaddr_in *host, int port) { struct hostent * server_hostent; if(port <= 0 || port > 65535) return -1; bzero(host, sizeof(struct sockaddr_in)); host->sin_family = AF_INET; if(inet_addr(host_ip_addr) != -1) { host->sin_addr.s_addr = inet_addr(host_ip_addr); } else { if ((server_hostent = gethostbyname(host_ip_addr)) != 0) { memcpy(&host->sin_addr, server_hostent->h_addr,\ sizeof(host->sin_addr)); } else return -1; } host->sin_port = htons(port); return 0; } static int _connect(struct sockaddr_in *sockad, int *sockid) { int sock,i; sock = socket( AF_INET,SOCK_STREAM,IPPROTO_TCP ); if ( sock < 0 ) return -1; //connect to the server signal( SIGALRM, _alarmproc ); alarm( TIMEOUT ); toflag = 0; i = connect(sock, (struct sockaddr *)sockad, sizeof(struct sockaddr_in)); alarm( 0 ); if ( toflag ) return -1; if ( i < 0 ) return -1; *sockid = sock; return 0; } static void _closesock(FTPINFO *ftpinfo, char type) { if ( type == 'C' ) { close(ftpinfo->sockfd); ftpinfo->sockfd = -1; } else { close(ftpinfo->datasd); ftpinfo->datasd = -1; } ftpinfo->reply = -1; if ( (ftpinfo->filedes != stdin) && (ftpinfo->filedes != stdout) ) { fclose(ftpinfo->filedes); ftpinfo->filedes = NULL; } } static int _retuerr(FTPINFO *ftpinfo, char type, char *errmsg) { _closesock(ftpinfo, type); strcpy(ftpinfo->ftp_msg, errmsg); return -1; } //get the server's reply message from sock_fd static int _getreply(FTPINFO *ftpinfo) { int count = 0; char rcv_buf[512]; sprintf(ftpinfo->ftp_msg, ""); signal( SIGALRM, _alarmproc ); alarm( TIMEOUT ); toflag = 0; count=read(ftpinfo->sockfd, rcv_buf, 510); alarm( 0 ); if ( toflag ) { return( _retuerr(ftpinfo, 'C', "_getreply.read error\r\n") ); } if(count > 0) ftpinfo->reply = atoi(rcv_buf); while(1) { if(count <= 0) break; rcv_buf[count]='\0'; if ( strlen(ftpinfo->ftp_msg)+strlen(rcv_buf) < sizeof(ftpinfo->ftp_msg) ) strcat(ftpinfo->ftp_msg, rcv_buf); if ( rcv_buf[count-1] == '\n' ) break; signal( SIGALRM, _alarmproc ); alarm( TIMEOUT ); toflag = 0; count=read(ftpinfo->sockfd, rcv_buf, 510); alarm( 0 ); if ( toflag ) { return( _retuerr(ftpinfo, 'C', "_getreply.read error\r\n") ); } } return 0; } static int _sendcmd(FTPINFO *ftpinfo, const char *option, const char *action) { char send_buf[256]; int send_err, len; if ( option[0] != '\0' ) sprintf(send_buf, "%s %s", action, option); else sprintf(send_buf, "%s", action); strcat(send_buf,"\r\n"); len = strlen(send_buf); signal( SIGALRM, _alarmproc ); alarm( TIMEOUT ); toflag = 0; send_err = send(ftpinfo->sockfd, send_buf, len, 0); alarm( 0 ); if ( toflag ) { return( _retuerr(ftpinfo, 'C', "ftp_command.send error\r\n") ); } return(0); } static int _getlocaport() { int local_port; srand((unsigned)time(NULL)); local_port = rand() % 40000 + 1025; return local_port; } static void _initftpinfo(FTPINFO *ftpinfo) { ftpinfo->filedes = NULL; ftpinfo->transf_type = BINARY; ftpinfo->transf_mode = PASV; strcpy(ftpinfo->ftp_msg, ""); ftpinfo->transf_calc = 0; ftpinfo->sockfd = -1; ftpinfo->datasd = -1; ftpinfo->reply = 0; ftpinfo->debug = 0; ftpinfo->linger = 0; ftpinfo->connected = 0; ftpinfo->ftp_sp = NULL; } /************************ ftp pub func ****************************/ int ftp_setport(const int portnumber) { port = portnumber; return 0; } int ftp_prconnect(FTPINFO *ftpinfo, const char *remhost) { int sockid; _initftpinfo(ftpinfo); ftpinfo->reply = -1; strcpy(ftpinfo->ftp_msg, "ftp_prconnect error\r\n"); if ( _filladdr(remhost, &ftp_server, port) < 0 ) return -1; if ( _connect(&ftp_server, &sockid) < 0 ) return -1; ftpinfo->sockfd = sockid; ftpinfo->reply = 0; if ( _getreply(ftpinfo) < 0 ) return -1; if ( ftpinfo->reply != 220 ) return -1; return 0; } int ftp_command(FTPINFO *ftpinfo,const char *optinfo, const char *action) { if ( _sendcmd(ftpinfo, optinfo, action) < 0 ) return -1; if ( _getreply(ftpinfo) < 0 ) return -1; return(0); } int ftp_user(FTPINFO *ftpinfo, const char *name) { if ( ftp_command(ftpinfo, name, "USER") < 0 ) return -1; if ( ftpinfo->reply != 331 ) return(-1); return 0; } int ftp_passwd(FTPINFO *ftpinfo, const char *password) { if ( ftp_command(ftpinfo, password, "PASS") < 0 ) return -1; if ( ftpinfo->reply != 230 ) return -1; return 0; } int ftp_pasv(FTPINFO *ftpinfo, int *port) { char port_respond[512]; char *buf_ptr; int count,port_num; if ( ftp_command(ftpinfo, NULL, "PASV") < 0 ) return -1; strcpy(port_respond, ftpinfo->ftp_msg); if(ftpinfo->reply == 227) { //get low byte of the port buf_ptr = strrchr(port_respond, ','); port_num = atoi(buf_ptr + 1); *buf_ptr = '\0'; //get high byte of the port buf_ptr = strrchr(port_respond, ','); port_num += atoi(buf_ptr + 1) * 256; *port = port_num; } return 0; } int ftp_port(FTPINFO *ftpinfo, const char *ip, int port) { char ip2[255], portcmd[255], *ss; int i; strcpy(ip2, ip); ss = ip2; while(*ss != '\0') { if ( *ss == '.' ) *ss = ','; ss++; } sprintf(portcmd, "%s,%d,%d", ip2, port/256, port%256); if ( ftp_command(ftpinfo, portcmd, "PORT") < 0 ) return -1; if ( ftpinfo->reply != 200 ) return -1; return(0); } int ftp_dataconn(FTPINFO *ftpinfo) { int get_sock; ftpinfo->reply = -1; ftpinfo->datasd = -1; strcpy(ftpinfo->ftp_msg, "ftp_dataconn error\r\n"); if(ftpinfo->transf_mode) { int data_port; if ( ftp_pasv(ftpinfo, &data_port) < 0 ) return -1; if ( data_port != 0 ) ftp_server.sin_port=htons(data_port); if ( _connect(&ftp_server, &get_sock) < 0 ) return -1; } else { int local_port, addr_len; int on = 1; struct sockaddr_in local; char local_ip[24]; //local_port = _getlocaport(); get_sock = socket(AF_INET, SOCK_STREAM, 0); if(get_sock < 0) return -1; if ( setsockopt(get_sock,SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof(on))< 0) return -1; bzero(&local_host,sizeof(local_host)); local_host.sin_family = AF_INET; //local_host.sin_port = htons(local_port); local_host.sin_port = 0; /* let system pick one */ local_host.sin_addr.s_addr = htonl(INADDR_ANY); if ( bind(get_sock, (struct sockaddr *)&local_host, \ sizeof(local_host)) < 0 ) return -1; if ( listen(get_sock, 1) < 0 ) return -1; { //get local host's ip and port char *a, *p; addr_len = sizeof(local);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -