?? simpleftp.c
字號:
#include "SimpleFTP.h"//-------------------static functions------------------ static int ftpcmd(SimpleFTP *sftp ,const char *s1, const char *s2, FILE *stream, char *buf); // static int ftpcmd(SimpleFTP *sftp ,const char *s1, const char *s2 ,FILE *stream); static int xconnect(const struct sockaddr_in *s_addr); static int xconnect_ftpdata(SimpleFTP *sftp ,const char *buf); static int bb_xopen(const char *pathname, int flags); static size_t bb_full_fd_action(int src_fd, int dst_fd, const size_t size); static ssize_t safe_read(int fd, void *buf, size_t count); static ssize_t safe_write(int fd, const void *buf, size_t count); static int safe_strtoul(char *arg, unsigned long* value); static ssize_t bb_full_write(int fd, const void *buf, size_t len); static int bb_copyfd_size(int fd1, int fd2, const off_t size); static void setError(SimpleFTP *sftp ,char * errStr); char * getLastReply(SimpleFTP *sftp) // { return sftp->reply ; } char * getError(SimpleFTP *sftp) { return sftp->error; } int SimpleFTP_init(SimpleFTP **sftp){ *sftp = (SimpleFTP *) malloc (sizeof(SimpleFTP)); if (*sftp == NULL) { return -1; } (*sftp)->control_stream == 0; memset(&((*sftp)->s_in) ,0 ,sizeof(struct sockaddr_in)); memset(&(*sftp)->reply ,'\0' ,64); memset(&(*sftp)->error ,'\0' ,64); } void SimpleFTP_free(SimpleFTP *sftp){ pclose(sftp->control_stream); // free(sftp->control_stream); free(sftp); }int ftpConnect(SimpleFTP *sftp ,char *user ,char *pass,char *host,int port){ struct hostent *he; char buf[512]; // memset(&s_in,0,sizeof(struct sockaddr_in)); sftp->s_in.sin_family = AF_INET; he = gethostbyname(host); memcpy(&(sftp->s_in.sin_addr),he->h_addr_list[0],he->h_length); sftp->s_in.sin_port = htons(port); sftp->control_stream = fdopen(xconnect(&(sftp->s_in)),"r+"); if(sftp->control_stream == NULL ){ printf("Could not open control stream"); return 0; } if (ftpcmd(sftp ,NULL, NULL, sftp->control_stream, buf) != 220) { printf("%s", buf + 4); return 0; } /* Login to the server */ switch (ftpcmd(sftp ,"USER ", user, sftp->control_stream, buf)) { case 230: break; case 331: if (ftpcmd(sftp ,"PASS ", pass, sftp->control_stream, buf) != 230) { printf("PASS error: %s", buf + 4); return 0; } break; default: { printf("USER error: %s", buf + 4); return 0; } } ftpcmd(sftp ,"TYPE I", NULL, sftp->control_stream, buf); return 1;}void ftpDisconnect(SimpleFTP *sftp ){ char buf[64]; ftpcmd(sftp,"QUIT", NULL, sftp->control_stream,buf);}char * pwd(SimpleFTP *sftp ){ char buf[128]; if(ftpcmd(sftp,"PWD" ,NULL ,sftp->control_stream ,buf) == 257) { char * start = buf + 5; char * end = strrchr(start ,'\"'); int len = end - start ; char * path = (char *)malloc(len + 1); strncpy(path ,start ,len); path[len] = '\0'; return path; }else{ return NULL; }}int cwd(SimpleFTP *sftp ,char *dir){ char buf[64]; return (ftpcmd(sftp,"CWD ", dir, sftp->control_stream ,buf) == 250 );}int stor(SimpleFTP *sftp ,char * local_path){ struct stat sbuf; char buf[512]; int fd_data; int fd_local; int response; /* Connect to the data socket */ if (ftpcmd(sftp,"PASV", NULL, sftp->control_stream, buf) != 227) { printf("PASV error: %s", buf + 4); } fd_data = xconnect_ftpdata(sftp ,buf);/* if (ftpcmd(sftp,"CWD ", server_path, control_stream, buf) != 250) { printf("CWD error: %s", buf + 4); }*/ /* get the local file */ if ((local_path[0] == '-') && (local_path[1] == '\0')) { fd_local = STDIN_FILENO; } else { fd_local = bb_xopen(local_path, O_RDONLY); fstat(fd_local, &sbuf); sprintf(buf, "ALLO %lu", (unsigned long)sbuf.st_size); response = ftpcmd(sftp,buf, NULL, sftp->control_stream, buf); switch (response) { case 200: case 202: break; default: close(fd_local); printf("ALLO error: %s", buf + 4); break; } } response = ftpcmd(sftp,"STOR ", local_path, sftp->control_stream, buf); switch (response) { case 125: case 150: break; default: close(fd_local); printf("STOR error: %s", buf + 4); close(fd_data); return 0; } /* transfer the file */ if (bb_full_fd_action(fd_local, fd_data,0) == -1) { printf("bb_full_fd_action error!\n"); close(fd_data); return 0; } /* close it all down */ close(fd_data); if (ftpcmd(sftp,NULL, NULL, sftp->control_stream, buf) != 226) { printf("error: %s", buf + 4); } return 1;}int get(SimpleFTP *sftp ,const char *local_path ,char * server_path){ char buf[512]; off_t filesize = 0; int fd_data; int fd_local = -1; off_t beg_range = 0; char do_continue = 0; /* Connect to the data socket */ if (ftpcmd(sftp,"PASV", NULL, sftp->control_stream, buf) != 227) { fprintf(stderr,"PASV error: %s", buf + 4); return FALSE; } fd_data = xconnect_ftpdata(sftp , buf); if (ftpcmd(sftp,"SIZE ", server_path, sftp->control_stream, buf) == 213) { unsigned long value = filesize; if (safe_strtoul(buf + 4, &value)){ fprintf(stderr,"SIZE error: %s", buf + 4); return FALSE; } filesize = value; } if ((local_path[0] == '-') && (local_path[1] == '\0')) { fd_local = STDOUT_FILENO; do_continue = 0; } if (do_continue) { struct stat sbuf; if (lstat(local_path, &sbuf) < 0) { fprintf(stderr,"fstat()\n"); return FALSE; } if (sbuf.st_size > 0) { beg_range = sbuf.st_size; } else { do_continue = 0; } } if (do_continue) { sprintf(buf, "REST %ld", (long)beg_range); if (ftpcmd(sftp,buf, NULL, sftp->control_stream, buf) != 350) { do_continue = 0; } else { filesize -= beg_range; } } if (ftpcmd(sftp,"RETR ", server_path, sftp->control_stream, buf) > 150) { fprintf(stderr,"RETR error: %s\n", buf + 4); } /* only make a local file if we know that one exists on the remote server */ if (fd_local == -1) { if (do_continue) { fd_local = bb_xopen(local_path, O_APPEND | O_WRONLY); } else { fd_local = bb_xopen(local_path, O_CREAT | O_TRUNC | O_WRONLY); } } /* Copy the file */ if (bb_copyfd_size(fd_data, fd_local, filesize) == -1) { return FALSE; } /* close it all down */ close(fd_data); if (ftpcmd(sftp,NULL, NULL, sftp->control_stream, buf) != 226) { fprintf(stderr,"ftp error: %s", buf + 4); return FALSE; } //ftpcmd(sftp,"QUIT", NULL, control_stream, buf); return(TRUE);}int bin(SimpleFTP *sftp ){ char buf[64]; return (ftpcmd(sftp,"TYPE I", NULL, sftp->control_stream ,buf) == 200);}int ascii(SimpleFTP *sftp ){ char buf[64]; return (ftpcmd(sftp,"TYPE A", NULL, sftp->control_stream ,buf) == 200);}static int xconnect(const struct sockaddr_in *s_addr){ int s = socket(AF_INET, SOCK_STREAM, 0); if (connect(s, (const struct sockaddr *)s_addr, sizeof(struct sockaddr_in)) < 0) { printf("Unable to connect to remote host (%s)", inet_ntoa(s_addr->sin_addr)); } return s;} static int ftpcmd(SimpleFTP *sftp,const char *s1, const char *s2, FILE *stream, char *buf){ if (verbose_flag && s1 && s2) { fprintf(stdout ,"cmd %s%s\n", s1, s2); } else if(verbose_flag && s1 ){ fprintf(stdout ,"cmd %s\n", s1); } if (s1) { if (s2) { fprintf(stream, "%s%s\n", s1, s2); } else { fprintf(stream, "%s\n", s1); } } do { char *buf_ptr; if (fgets(buf, 510, stream) == NULL) { printf("fgets()"); } buf_ptr = strstr(buf, "\r\n"); if (buf_ptr) { *buf_ptr = '\0'; } } while (! isdigit(buf[0]) || buf[3] != ' '); if( verbose_flag){ fprintf(stdout,"%s\n",buf); } sprintf(sftp->reply,"%s",buf); return atoi(buf);}static int xconnect_ftpdata(SimpleFTP *sftp ,const char *buf){ char *buf_ptr; unsigned short port_num; buf_ptr = strrchr(buf, ','); *buf_ptr = '\0'; port_num = atoi(buf_ptr + 1); buf_ptr = strrchr(buf, ','); *buf_ptr = '\0'; port_num += atoi(buf_ptr + 1) * 256; sftp->s_in.sin_port=htons(port_num); return(xconnect(&(sftp->s_in)));}static int bb_xopen(const char *pathname, int flags){ int ret; ret = open(pathname, flags, 0777); if (ret == -1) { printf("%s", pathname); } return ret;}/* If size is 0 copy until EOF */static size_t bb_full_fd_action(int src_fd, int dst_fd, const size_t size){ size_t read_total = 0; RESERVE_CONFIG_BUFFER(buffer,BUFSIZ); while ((size == 0) || (read_total < size)) { size_t read_try; ssize_t read_actual; if ((size == 0) || (size - read_total > BUFSIZ)) { read_try = BUFSIZ; } else { read_try = size - read_total; } read_actual = safe_read(src_fd, buffer, read_try); if (read_actual > 0) { if ((dst_fd >= 0) && (bb_full_write(dst_fd, buffer, (size_t) read_actual) != read_actual)) { printf("write error! \n"); /* match Read error below */ break; } } else if (read_actual == 0) { if (size) { printf("Unable to read all data"); } break; } else { /* read_actual < 0 */ printf("Read error"); break; } read_total += read_actual; } RELEASE_CONFIG_BUFFER(buffer); return(read_total);}static ssize_t safe_read(int fd, void *buf, size_t count){ ssize_t n; do { n = read(fd, buf, count); } while (n < 0 && errno == EINTR); return n;}static ssize_t bb_full_write(int fd, const void *buf, size_t len){ ssize_t cc; ssize_t total; total = 0; while (len > 0) { cc = safe_write(fd, buf, len); if (cc < 0) return cc; /* write() returns -1 on failure. */ total += cc; buf = ((const char *)buf) + cc; len -= cc; } return total;}static ssize_t safe_write(int fd, const void *buf, size_t count){ ssize_t n; do { n = write(fd, buf, count); } while (n < 0 && errno == EINTR); return n;}static int safe_strtoul(char *arg, unsigned long* value){ char *endptr; int errno_save = errno; assert(arg!=NULL); errno = 0; *value = strtoul(arg, &endptr, 0); if (errno != 0 || *endptr!='\0' || endptr==arg) { return 1; } errno = errno_save; return 0;}static int bb_copyfd_size(int fd1, int fd2, const off_t size){ if (size) { return(bb_full_fd_action(fd1, fd2, size)); } return(0);}static void setError(SimpleFTP *sftp ,char * errStr){ if (errStr) { int size = strlen(errStr); strncpy(sftp->error ,errStr ,size); sftp->error[size] = '\0'; }}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -