⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simpleftp.c

📁 嵌入式linux下面的ftp程序
💻 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';  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -