📄 cmd.c
字号:
#include "my_client.h"#include "function.h"#include "cmd.h"//-------------------------------------------------------------------------------------------------void cmd_quit(){ if(isconnect==1) { send_cmd("QUIT",NULL,client_sockfd); get_reply(client_sockfd); isconnect=0; islogin=0; } printf("byebye!\n"); return;}//-------------------------------------------------------------------------------------------------void cmd_ls(){ if(isconnect==0) { printf("please connect to a ftp server first.\n"); return ; } if(isconnect==1 && islogin==0) { printf("please login first.\n"); return ; } int client_data_sockfd=create_datasock(); if(client_data_sockfd<0) { printf("ls executed failed: create data socket failed.\n"); return; } send_cmd("LIST",NULL,client_sockfd); if(get_reply(client_sockfd)!=150) //说明连接不成功 { close(client_data_sockfd); return; } get_data(client_data_sockfd, 1); close(client_data_sockfd); get_reply(client_sockfd);}//-------------------------------------------------------------------------------------------------void cmd_cd(){ if(isconnect==0) { printf("please connect to a ftp server first.\n"); return ; } if(isconnect==1 && islogin==0) { printf("please login first.\n"); return ; } int num=cmd_format(cmd_buf); printf("cmd_buf:%s\n",cmd_buf); int i=0; char *para=cmd_buf; if(num==1) //说明原来的命令当中没有带参数,需要提示用户输入参数。 { printf("(remote directory)"); fgets(cmd_buf,CMD_BUFFER_SIZE, stdin); printf("cmd_buf2:%s\n",cmd_buf); num=cmd_format(cmd_buf); if(num==0) { printf("usage: cd remote-directory\n"); return; } para=cmd_buf; } else //将para指向第一个参数起始处 { for(i=0;cmd_buf[i]!=' ';i++) ; para=cmd_buf+i+1; } for(i=0;para[i]!=' ' && para[i]!='\0';i++) ; para[i]='\0'; //printf("para:%s\n",para); send_cmd("CWD ",para, client_sockfd); if(get_reply(client_sockfd)==0) printf("fuckinginging\n");}//-------------------------------------------------------------------------------------------------void cmd_get(){ if(isconnect==0) { printf("please connect to a ftp server first.\n"); return ; } if(isconnect==1 && islogin==0) { printf("please login first.\n"); return ; } // 处理命令 得到文件名 char src_file[512]; char dst_file[512]; struct stat file_info; int num=cmd_format(cmd_buf); int local_file; int i=0, j=0; char cover[5]; // 获取src_file(remote) 和 dst_file(local) if(num==1) // 没有带参数 { printf("(remote-file)"); fgets(src_file, 512, stdin); num=cmd_format(src_file); if(num<1) { printf("usage: get remote-file [local-file]\n"); return; } if(num>=2) { for(i=0; src_file[i]!=' ';i++) ; src_file[i]='\0'; strcpy(dst_file,src_file+i+1); for(i=0; dst_file[i]!=' ' && dst_file[i]!='\0'; i++) ; dst_file[i]='\0'; } else { printf("(local-file)"); fgets(dst_file,512,stdin); num=cmd_format(dst_file); if(num<1) { printf("usage: get remote-file [local-file]\n"); return; } else { for(i=0;dst_file[i]!=' ' && dst_file[i]!='\0';i++) ; dst_file[i]='\0'; } } } else if(num==2) //带了一个参数,则认为remote file 和local file 的名字都是这个 { for(i=0; cmd_buf[i]!=' '; i++) ; strcpy(src_file, cmd_buf+i+1); strcpy(dst_file, src_file); } else if(num>=3) //带了两个以上的参数,则认为前两个分别是remote file 和local file 后面的参数则忽略 { for(i=0; cmd_buf[i]!=' '; i++) //找第一个空格,其后就是第一个参数 ; strcpy(src_file, cmd_buf+i+1); for(i=0; src_file[i]!=' '; i++) //找第二个空格,其后就是第二个参数 ; src_file[i]='\0'; strcpy(dst_file, src_file+i+1); for(i=0; dst_file[i]!=' ' && dst_file!='\0';i++) ; dst_file[i]='\0'; } printf("remote-file: %s local-file: %s \n", src_file, dst_file); //判断dst_file是否已经在当前目录下了,若在,则问是否覆盖? if(!stat(dst_file, &file_info)) { printf("local file %s exists: %d bytes\n", dst_file, (int)file_info.st_size); printf("Do you want to cover it? [y/n]"); fgets(cover, sizeof(cover), stdin); fflush(stdin); if(cover[0]!='y' && cover[0]!='Y') { printf("get file %s aborted.\n", src_file); return; } } //在本地目录下打开或创建文件dst_file local_file=open(dst_file, O_CREAT|O_TRUNC|O_WRONLY); if(local_file<0) { printf("open local file %s error!\n", dst_file); return; } //建立一个数据socket,然后分pasv和port两种情况传输文件/* send_cmd("TYPE I",NULL,client_sockfd); //将传输的type设置成binary if(get_reply(client_sockfd)!=200) return;*/ int client_data_sockfd=create_datasock(); if(client_data_sockfd<0) return ; //生成retr命令并发送出去。 send_cmd("RETR ", src_file, client_sockfd); if(get_reply(client_sockfd)!=150) { printf("get %s file error!", src_file); return; } if(passive==1) //PASV { //接收文件 从 client_data_sockfd while(1) { data_length=read(client_data_sockfd, data_buf, DATA_BUFFER_SIZE); if(data_length<=0) break; else write(local_file, data_buf, data_length); } } else //port模式 { int new_sockfd=port_accept(client_data_sockfd); if(new_sockfd<0) return; //说明没有成功建立连接 while(1) { data_length=read(new_sockfd, data_buf, DATA_BUFFER_SIZE); if(data_length<=0) break; else write(local_file, data_buf, data_length); } close(new_sockfd); } close(client_data_sockfd); close(local_file); get_reply(client_sockfd); }//-------------------------------------------------------------------------------------------------void cmd_put(){ if(isconnect==0) { printf("please connect to a ftp server first.\n"); return ; } if(isconnect==1 && islogin==0) { printf("please login first.\n"); return ; } // 处理命令 得到文件名 char src_file[512]; char dst_file[512]; struct stat file_info; int num=cmd_format(cmd_buf); int local_file; int i=0, j=0; char cover[5]; // 获取src_file(local) 和 dst_file(remote) if(num==1) // 没有带参数 { printf("(local-file)"); fgets(src_file, 512, stdin); num=cmd_format(src_file); if(num<1) { printf("usage: put local-file [remote-file]\n"); return; } if(num>=2) { for(i=0; src_file[i]!=' ';i++) ; src_file[i]='\0'; strcpy(dst_file,src_file+i+1); for(i=0; dst_file[i]!=' ' && dst_file[i]!='\0'; i++) ; dst_file[i]='\0'; } else { printf("(remote-file)"); fgets(dst_file,512,stdin); num=cmd_format(dst_file); if(num<1) { printf("usage: put local-file [remote-file]\n"); return; } else { for(i=0;dst_file[i]!=' ' && dst_file[i]!='\0';i++) ; dst_file[i]='\0'; } } } else if(num==2) //带了一个参数,则认为local file 和remote file 的名字都是这个 { for(i=0; cmd_buf[i]!=' '; i++) ; strcpy(src_file, cmd_buf+i+1); strcpy(dst_file, src_file); } else if(num>=3) //带了两个以上的参数,则认为前两个分别是local file 和remote file 后面的参数则忽略 { for(i=0; cmd_buf[i]!=' '; i++) //找第一个空格,其后就是第一个参数 ; strcpy(src_file, cmd_buf+i+1); for(i=0; src_file[i]!=' '; i++) //找第二个空格,其后就是第二个参数 ; src_file[i]='\0'; strcpy(dst_file, src_file+i+1); for(i=0; dst_file[i]!=' ' && dst_file!='\0';i++) ; dst_file[i]='\0'; } printf("local-file: %s remote-file: %s \n", src_file, dst_file); //判断src_file(local)是否在当前目录下,若不在则返回。 if(stat(src_file, &file_info)) { printf("local file %s does not exists: %d bytes\n", src_file, (int)file_info.st_size); printf("put file %s aborted.\n", src_file); return; } //??? 这步不做~~ 判断dst_file(remote)是否在对方目录下,若在则问是否覆盖? //在本地目录下打开文件src_file local_file=open(src_file, O_RDONLY); if(local_file<0) { printf("open local file %s error!\n", src_file); return; } //建立一个数据socket, 然后分pasv和port两种情况传输文件 send_cmd("TYPE I", NULL, client_sockfd); if(get_reply(client_sockfd)!=200) { close(local_file); return; } int client_data_sockfd=create_datasock(); if(client_data_sockfd<0) { close(local_file); return; } send_cmd("STOR ", dst_file, client_sockfd); if(get_reply(client_sockfd)!=150) { printf("put %s file error!\n", src_file); close(local_file); close(client_data_sockfd); return; } if(passive==1) //pasv { while(1) { data_length=read(local_file, data_buf, DATA_BUFFER_SIZE); if(data_length<=0) break; else write(client_data_sockfd, data_buf, data_length); } } else //port { int new_sockfd=port_accept(client_data_sockfd); if(new_sockfd<0) { close(local_file); close(client_data_sockfd); return; } while(1) { printf("write data to data socket...\n"); data_length=read(local_file, data_buf, DATA_BUFFER_SIZE); if(data_length<=0) break; else write(new_sockfd, data_buf, data_length); } close(new_sockfd); } close(client_data_sockfd); close(local_file); get_reply(client_sockfd);}//-------------------------------------------------------------------------------------------------void cmd_help(){ show_command(); return;}//-------------------------------------------------------------------------------------------------int cmd_user() //login登录{ if(isconnect==0) { printf("please connect to a ftp server first.\n"); return ; } //输出提示信息 char buf[64]; char *end; printf("User:(Press Enter for anonymous):"); //获取用户名 fgets(buf, sizeof(buf), stdin); if(buf[0]=='\n') { strncpy(user, "anonymous", 9); user[10]='\0'; } else { end=strchr(buf, '\n'); end[0]='\0'; strcpy(user, buf); } if(send_cmd("USER ", user, client_sockfd)<0) { //输出发送命令出错的信息 printf("username sent error.\n"); return 0; } int reply=get_reply(client_sockfd); if(reply==331) { //输出提示输入密码的信息 printf("Password:(Press Enter for anonymous):");/* //获取密码,不回显 for(int i=0; i<64; i++) { buf[i]=getch(); // include <conio.h> <stdio.h> if(buf[i]=='\n') break; }*/ fgets(buf, sizeof(buf), stdin); if(buf[0]=='\n') { strncpy(password, "anonymous", 9); password[10]='\0'; } else { end=strchr(buf, '\n'); end[0]='\0'; strcpy(password, buf); } if( send_cmd("PASS ",password,client_sockfd)<0 ) { //输出发送命令出错的信息 printf("password sent error.\n"); return 0; } if(get_reply(client_sockfd)!=230) { //输出密码错误 printf("Login failed.\n"); return 0; } else { islogin=1; return 0; } } else if(reply==230) { islogin=1; return 1; } else { //输出用户名错误 printf("Login failed.\n"); return 0; } return 0;}//-------------------------------------------------------------------------------------------------void cmd_lcd(){ int num=cmd_format(cmd_buf); int i=0; char *para=cmd_buf; if(num>1) //将当前目录改成参数所带的目录 { for(i=0;cmd_buf[i]!=' ';i++) ; para=cmd_buf+i+1; for(i=0;para[i]!=' ' && para[1]!='\0'; i++); para[i]='\0'; if(chdir(para)<0) printf("invalid dir\n"); } //输出当前目录 char temp[512]; int size=sizeof(temp); if(getcwd(temp,size)!=NULL) printf("local directory now: %s\n",temp); else printf("Can't get local dir\n");}//-------------------------------------------------------------------------------------------------void cmd_mkdir(){ if(isconnect==0) { printf("please connect to a ftp server first.\n"); return ; } if(isconnect==1 && islogin==0) { printf("please login first.\n"); return ; } int num=cmd_format(cmd_buf); int i=0; char* para=cmd_buf; if(num==1) { printf("(directory name): "); fgets(cmd_buf,CMD_BUFFER_SIZE, stdin); num=cmd_format(cmd_buf); if(num==0) { printf("usage: mkdir directory-name)"); return; } para=cmd_buf; } else //将para指向第一个参数起始处 { for(i=0;cmd_buf[i]!=' ';i++) ; para=cmd_buf+i+1; } for(i=0;para[i]!=' ' && para[i]!='\0';i++) ; para[i]='\0'; //printf("para:%s\n",para); send_cmd("MKD ",para, client_sockfd); get_reply(client_sockfd);}//-------------------------------------------------------------------------------------------------void cmd_rename(){ if(isconnect==0) { printf("please connect to a ftp server first.\n"); return ; } if(isconnect==1 && islogin==0) { printf("please login first.\n"); return ; } int num=cmd_format(cmd_buf); if(num<=2) { printf("usage: rename from-name to-name\n"); return; } int i=0; char *para; for(i=0;cmd_buf[i]!=' ';i++) ; para=cmd_buf+i+1; for(i=0;para[i]!=' ';i++) ; for(i=i+1;para[i]!=' ' && para[i]!='\0'; i++) ; para[i]='\0'; send_cmd("RNFR ",para, client_sockfd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -