📄 myftpclient.c
字号:
#include "common.h"#define LOCAL_IP "192.168.0.74"struct client_state{ int isCmdConnected; int isTsfConnected; short server_port; unsigned int server_addr;};int csock;int dlsock;int dtsock;struct sockaddr_in server_cmd_addr;struct sockaddr_in serverdl;struct sockaddr_in serverdt;struct client_state cs;int get_command( char * buf, int buflen){ printf("\033[1;32mfancy ftp>\033[m"); int h; h = getline(&buf, &buflen, stdin); buf[h-1] = '\0'; return( strlen(buf));}int parse_command(char *cmd){ int len = strlen(cmd); int end; end = 0; while (end<len && cmd[end]!=' ') { cmd[end] = toupper(cmd[end]); end++; } if (end == 0) return 0; else if (strncmp(cmd,"LS",end)==0 || strncmp(cmd, "DIR", end)==0) return 1; else if (strncmp(cmd, "CD", end)==0) return 2; else if (strncmp(cmd, "QUIT", end)==0) return 3; else if (strncmp(cmd, "GET", end)==0) return 4; else if (strncmp(cmd, "PUT", end)==0) return 5; else if (strncmp(cmd, "NOOP", end)==0) return 6; else if (strncmp(cmd, "PWD", end)==0) return 7; else if (strncmp(cmd, "OPEN", end)==0) return 8; else if (strncmp(cmd, "CLOSE", end)==0) return 9; else if (strncmp(cmd, "HELP", end)==0 || strncmp(cmd, "?", end)==0) return 10; else if (strncmp(cmd, "LLS", end)==0) return 11; else return 0;} void * accept_data_connection(void * arg){ int addrlen = sizeof(serverdt); // struct sockaddr_in temp; dtsock = accept(dlsock, (struct sockaddr *) &serverdt, &addrlen); check_error(dtsock, "accept");}void handle_port_cmd(){ int h; dlsock = socket(AF_INET, SOCK_STREAM, 0); int opt = 1; h = setsockopt(dlsock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)); check_error(h, "setsockopt of data listen socket"); //serverdl.sin_family = AF_INET; // serverdl.sin_addr.s_addr = htonl(INADDR_ANY); //serverdl.sin_port = htons(current_data_port++); int addrlen = sizeof(serverdl); h = getsockname(dlsock, (struct sockaddr*)&serverdl, &addrlen); check_error(h ,"getsockname"); serverdl.sin_family = AF_INET; inet_aton(LOCAL_IP, &(serverdl.sin_addr)); // serverdl.sin_addr.s_addr = htonl(INADDR_ANY); unsigned short listenport = LISTEN_PORT; do { serverdl.sin_port = htons( listenport ++); } while (bind(dlsock, (struct sockaddr*)&serverdl, sizeof(serverdl))<0); h = listen(dlsock,10); check_error(h, "listen"); pthread_t accept_thread; pthread_create(&accept_thread, NULL, accept_data_connection, NULL); char cmd_buff[TELNET_LENGTH]; unsigned long dl_ip; inet_aton(LOCAL_IP,(struct in_addr *) &(dl_ip)); unsigned short dl_port = serverdl.sin_port; sprintf(cmd_buff, "PORT %d,%d,%d,%d,%d,%d", (dl_ip&0xFF), (dl_ip&0x0000FF00)>>8, (dl_ip&0x00FF0000)>>16, dl_ip>>24, dl_port&0xFF,dl_port>>8); send_command(cmd_buff, csock); printf("[Fancy FTP]%s\n", cmd_buff); //ss.isPassive = 1; // h = pthread_join(accept_thread, NULL); check_error(h, "pthread_join"); receive_reply(cmd_buff,TELNET_LENGTH,csock); printf("[Fancy FTP]Establish data transfer connection from through PORT\n");}void get_port(char *arg){ int a[6]; sscanf(arg, "%d,%d,%d,%d,%d,%d", a, a+1, a+2, a+3, a+4, a+5); cs.server_port = (short)((a[4])+(a[5]<<8)); cs.server_addr = (unsigned long)((a[0])+(a[1]<<8)+(a[2]<<16)+(a[3]<<24)); printf("[Fancy FTP]Server data translation address is %s:%d\n", inet_ntoa(cs.server_addr), ntohs(cs.server_port));}void establish_data_connection(){ char buff1[TELNET_LENGTH]; char buff2[TELNET_LENGTH]; strcpy(buff1,"PASV"); send_command(buff1, csock); receive_reply(buff1, TELNET_LENGTH, csock); if (strncmp(buff1, "227", 3)!=0) { puts("Server not support passive mode.\nUse PORT Command Instead."); handle_port_cmd(); // return; } else { char *p1, *p2; p1 = strchr(buff1,'('); p2 = strrchr(buff1, ')'); strncpy(buff2, p1+1, p2-p1+1); get_port(buff2); int h; dtsock = socket(AF_INET, SOCK_STREAM, 0); check_error(dtsock, "socket of transfer"); serverdt.sin_family = AF_INET; serverdt.sin_port = cs.server_port; serverdt.sin_addr.s_addr = cs.server_addr; h = connect(dtsock, (struct sockaddr*)&serverdt, sizeof(serverdt)); check_error(h, "connect data address"); printf("[Fancy FTP]Establish data connect to %s:%d\n", inet_ntoa(serverdt.sin_addr.s_addr), ntohs(serverdt.sin_port)); }}void list_dir(char *arg){ if (!cs.isCmdConnected) { puts("Not Connected."); return; } char buff1[TELNET_LENGTH]; //establish_data_connection(); handle_port_cmd(); strcpy(buff1, "LIST"); if (arg[0]!='\0') { strcat(buff1, " "); strcat(buff1, arg); } send_command(buff1, csock); receive_reply(buff1, TELNET_LENGTH, csock); if (buff1[0]=='1') { receive_data(dtsock); } close(dtsock); receive_reply(buff1, TELNET_LENGTH, csock); }void retr_file(char *arg){ if (!cs.isCmdConnected) { puts("Not Connected."); return; } char buff1[TELNET_LENGTH]; char rpy_buff[TELNET_LENGTH]; strcpy(buff1, "TYPE A"); send_command(buff1, csock); receive_reply(buff1, TELNET_LENGTH, csock); establish_data_connection(); sprintf(buff1, "RETR %s", arg); send_command(buff1, csock); printf("[Fancy FTP]Get file: %s\n", arg); receive_reply(buff1, TELNET_LENGTH, csock); if (buff1[0]=='1') { FILE *fl; fl = fopen(arg, "w"); receive_file(fl, dtsock); fclose(fl); close(dtsock); receive_reply(buff1, TELNET_LENGTH, csock); } else close(dtsock);}void stor_file(char *arg){ if(!cs.isCmdConnected) { puts("Not Connected."); return; } FILE *fl; fl = fopen(arg, "r"); if(fl == 0) { puts("File not found."); return; } char buff1[TELNET_LENGTH]; char rpy_buff[TELNET_LENGTH]; strcpy(buff1, "TYPE A"); send_command(buff1, csock); receive_reply(buff1, TELNET_LENGTH, csock); establish_data_connection(); sprintf(buff1, "STOR %s", arg); send_command(buff1, csock); printf("[Fancy FTP]Put file: %s\n", arg); receive_reply(buff1, TELNET_LENGTH, csock); if(buff1[0] == '1') { send_file(fl, dtsock); close(dtsock); receive_reply(buff1, TELNET_LENGTH, csock); } else close(dtsock); fclose(fl);}void list_local(){ struct dirent **eps; int n; char line_buff[TELNET_LENGTH]; n = scandir("./", &eps, one, alphasort); if (n >= 0) { int cnt; struct stat s; for (cnt = 0; cnt < n; ++cnt) { strcpy(line_buff, eps[cnt]->d_name); stat(line_buff, &s); char pbuff[32]; if (!S_ISREG(s.st_mode) && !S_ISDIR(s.st_mode)) continue; permission(s.st_mode, pbuff); struct passwd *uinfo; struct group *ginfo; uinfo = getpwuid(s.st_uid); ginfo = getgrgid(s.st_gid); char tbuff[256]; struct tm* t; t = localtime(&s.st_mtime); strftime(tbuff, 1024, "%b %d %k:%M", t); sprintf(line_buff, "%s%3d %s %s %12d %s %s\r\n", pbuff, s.st_nlink, uinfo->pw_name, ginfo->gr_name, s.st_size, tbuff, eps[cnt]->d_name); printf("%s", line_buff); } } else perror ("Couldn't open the directory");}int parse_server_addr(char * arg, char * user, char * pass){ char *p1, *p2, *p3; p1 = strchr(arg, '@'); int flag = 1; if (p1!=NULL) { p2 = strchr(arg, ':'); if (p2>p1) flag = 0; else { strncpy(user, arg, p2-arg); user[p2-arg] = '\0'; strncpy(pass, p2+1, p1-p2-1); pass[p1-p2-1] = '\0'; } p1++; } else p1 = arg; p2 = strchr(p1, ':'); char tmp[TELNET_LENGTH]; if (flag) { if (p2==NULL) { printf("%s\n",p1); if (inet_aton(p1, &server_cmd_addr.sin_addr)==0) flag=0; server_cmd_addr.sin_port = htons(21); } else { strncpy(tmp, p1, p2-p1); tmp[p2-p1] = '\0'; printf("%s\n", tmp); if (inet_aton(tmp, &server_cmd_addr.sin_addr)==0) { flag = 0; } server_cmd_addr.sin_port = htons(atoi(p2+1)); } printf("[Fancy FTP]Server address %s:%d\n", inet_ntoa(server_cmd_addr.sin_addr.s_addr), ntohs(server_cmd_addr.sin_port)); } if (flag==0) { printf("[Fancy FTP]Error, usage: open [user:pass@]host[:port] with correct address!\n"); return -1; } server_cmd_addr.sin_family = AF_INET; return 0;}void open_cmd_connection(char *arg){ char user[64] = "", pass[64] = ""; char tmp[TELNET_LENGTH]; int h; h = parse_server_addr(arg, user, pass); if(h<0) { puts( "parse server addr"); return; } csock = socket(PF_INET, SOCK_STREAM, 0); h = connect(csock, (struct sockaddr*)&server_cmd_addr, sizeof(server_cmd_addr)); receive_reply(tmp, TELNET_LENGTH, csock); if (h<0) { printf("Connection Refused.\n"); cs.isCmdConnected = 0; return; } int t; if (user[0]=='\0') { printf("User:"); t = 64; fgets(user, 64, stdin); int len = strlen(user); user[len-1] = '\0'; } if (pass[0]=='\0') { printf("Pass:"); t = 64; fgets(pass, 64, stdin); int len = strlen(pass); pass[len-1] = '\0'; } printf("[Fancy FTP]user<%s> pass<%s>\n", user, pass); sprintf(tmp, "USER %s", user); send_command(tmp, csock); receive_reply(tmp, TELNET_LENGTH ,csock); sprintf(tmp, "PASS %s", pass); send_command(tmp, csock); receive_reply(tmp, TELNET_LENGTH, csock); if (tmp[0]=='2') { cs.isCmdConnected = 1; } else cs.isCmdConnected = 0;}void user_pi(){ char cmd_buff[TELNET_LENGTH]; char rpy_buff[TELNET_LENGTH]; char param_buff[TELNET_LENGTH]; char *para; while (1) { int len = get_command(cmd_buff, TELNET_LENGTH); int cmd_id = parse_command(cmd_buff); printf("[Fancy FTP]Receive command: <%s>(%d)\n", cmd_buff, cmd_id); switch (cmd_id) { case 0: puts("\033[1;31mError: Command not recognized\033[m"); break; //Syntax error case 1: //ls, dir parse_parameters(cmd_buff, 1, param_buff); list_dir(param_buff); break; case 2: //cd if (!cs.isCmdConnected) {puts("Not connected."); break;} parse_parameters(cmd_buff, 1 ,param_buff); if (strcmp(param_buff,"..")==0) strcpy(cmd_buff,"CDUP"); else sprintf(cmd_buff,"CWD %s", param_buff); send_command(cmd_buff, csock); receive_reply(rpy_buff, TELNET_LENGTH, csock); break; case 3: //quit if (cs.isCmdConnected) { sprintf(cmd_buff, "QUIT"); send_command(cmd_buff, csock); receive_reply(rpy_buff, TELNET_LENGTH, csock); close(csock); cs.isCmdConnected = 0; } break; case 4: //get if (!cs.isCmdConnected) {puts("Not connected."); break;} parse_parameters(cmd_buff, 1, param_buff); retr_file(param_buff); break; case 5: //put if (!cs.isCmdConnected) {puts("Not connected."); break;} parse_parameters(cmd_buff, 1, param_buff); stor_file(param_buff); break; case 6: //noop if (!cs.isCmdConnected) {puts("Not connected."); break;} strcpy(cmd_buff, "NOOP"); send_command(cmd_buff, csock); receive_reply(rpy_buff, TELNET_LENGTH, csock); break; case 7: //pwd if (!cs.isCmdConnected) {puts("Not connected."); break;} strcpy(cmd_buff, "PWD"); send_command(cmd_buff, csock); receive_reply(rpy_buff, TELNET_LENGTH, csock); break; case 8: //open if(!cs.isCmdConnected) { parse_parameters(cmd_buff, 1, param_buff); open_cmd_connection(param_buff); } else { puts("\033[1;31mError: Already Connected to An FTP Server\033[m"); } break; case 9: //close if(cs.isCmdConnected) { sprintf(cmd_buff, "QUIT"); send_command(cmd_buff, csock); receive_reply(rpy_buff, TELNET_LENGTH, csock); close(csock); cs.isCmdConnected = 0; } else { puts("Not connected."); } break; case 10: //help && ? printf("Support Commands:\nopen cd quit close\npwd noop ls lls\nhelp\n"); if (!cs.isCmdConnected) {break;} strcpy(cmd_buff, "HELP"); send_command(cmd_buff, csock); receive_reply(rpy_buff, TELNET_LENGTH, csock); break; case 11: //lls list_local(); break; } if (cmd_id==3) break; } close(csock);}int main(int argc, char * argv[]){ if(argc == 2) { open_cmd_connection(argv[1]); } user_pi(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -