📄 ftpcmd.c
字号:
//printf("父进程 connfd=%d\n",pasv_listen_socket);
//printf("父进程 datatran_socket=%d\n",pasv_datatrans_socket);
close(pasv_datatrans_socket);
close(pasv_listen_socket);
}
}
else
{
//printf("主动模式下 下载数据");
//以下是 主动传输模式下数据下载
if(strcmp(file_name,"")!=0)
{
if((child_pid=fork())==0)
{
if(Send_Data(datatrans_socket,file_name)>0)
{
//当数据发送成功
close(datatrans_socket);
Respond(226,"File send OK.");
}
else
{
//数据发送不成功
close(datatrans_socket);
}
To_Send_Signal_Start_Timeout();//开启超时
exit(1);
}
else
{
close(datatrans_socket);
}
}
}
offset=0;//当成功断点下载后,要将偏移量设成0
return 1;
}
int do_appe(char *param) ////APPE模式断点 上传
{
//被动模式 上传
transfers_mode=1;//采用APPE断点续传模式
char file_name[512]={0};
//int pid;
stop_timeout(0);//关闭超时
Intercept_Parameter(file_name,param);
g_isupload=1;
if(IsPASV==1)
{
//在被动模式下边要通过accept来接收客户端发送过来进行数据传输的的请求
struct sockaddr_in cliaddr;
//int socket;//这个套接字是用来在被动模式下进行数据传送用的
pasv_datatrans_socket=accept_socket(pasv_listen_socket,&cliaddr); //在被动模式下 datatrans_socket套接字是监听套接字
if(strcmp(file_name,"")!=0)
{
if((child_pid=fork())==0)
{
int stat;
stat=Accept_Data(pasv_datatrans_socket,file_name);
close(pasv_datatrans_socket);
if(stat>0)
{
Respond(150,"Ok to send data.");
}
close(pasv_listen_socket);
To_Send_Signal_Start_Timeout();//开启超时
exit(1);
}
close(pasv_datatrans_socket);//把父进程 中的pasv_datatrans_socket套接字关掉
close(pasv_listen_socket);//把父进程 中的pasv_listen_socket套接字关掉
}
}
else
{
//printf("主动模式下 下载数据");
//以下是 主动传输模式下数据下载
if(strcmp(file_name,"")!=0)
{
if((child_pid=fork())==0)
{
if(Accept_Data(datatrans_socket,file_name)>0)
{
//当数据发送成功
close(datatrans_socket);
Respond(150,"Ok to send data.");
}
else
{
//数据发送不成功
close(datatrans_socket);
}
To_Send_Signal_Start_Timeout();//开启超时
exit(1);
}
else
{
close(datatrans_socket);//把父进程 中的datatrans_socket套接字关掉
}
}
}
return 1;
}
/*
int do_appe(char *param)//APPE模式断点 上传
{
transfers_mode=1;//采用APPE断点续传模式
char file_name[1024];
Intercept_Parameter(file_name,param);
if(strlen(file_name)!=0)
{
if(IsPASV==1)//代表被动传输模式下进行APPE模式续传
{
if((child_pid=fork())==0)
{
//下边做被动模式
struct sockaddr_in cliaddr;
//int socket;//这个套接字是用来在被动模式下进行数据传送用的
pasv_datatrans_socket=accept_socket(pasv_listen_socket,&cliaddr); //在被动模式下 datatrans_socket套接字是监听套接字
if(Accept_Data(pasv_datatrans_socket,file_name))
{
}
close(pasv_listen_socket);
close(pasv_datatrans_socket);
}
}
else
{
//代表主动传输模式下进行APPE模式续传
Accept_Data(datatrans_socket,file_name);
}
}
Respond(150,"Ok to send data.");
return 1;
}
*/
int do_stat(char *param)
{
Respond(211,"Start of stat.");
// printf("211,Stored %d files, %d kBytes Retrieved %d files, %d kBytes.",g_segptr->uptotal,g_segptr->upsize,g_segptr->downtotal
// ,g_segptr->downtotal);
//stored是上传 retrieved是下载
Respond(211,"Stored %d files, %d Bytes Retrieved %d files, %d Bytes.",g_segptr->uptotal,g_segptr->upsize,g_segptr->downtotal,g_segptr->downsize);
Respond(211,"End of status.");
return 1;
}
int do_abor(char *param)
{
// kill(child_pid,SIGKILL);
// Respond(226,"File receive OK.");
// if(IsPASV==1)//被动模式下
// {
// close(pasv_datatrans_socket);
// }
// else
// {
// //主动模式下
// close(datatrans_socket);
// }
// Respond(226,"File receive OK.");
if(g_isupload == 1)
{
//g_segptr->uptotal--;
Up_Total(-1);
g_isupload = 0;
Respond(226,"ABOR command successful.");
}
else if(g_isdownload == 1)
{
//g_segptr->downsize--;
//pid_t pid=getpid();
//kill(pid,SIGUSR1);
//g_overtimeflag=1;
g_isdownload = 0;
if(IsPASV==1)
{
shutdown(datatrans_socket,2);
}
else if(IsPASV==0)
{
shutdown(pasv_datatrans_socket,2);
}
//kill(g_childpid,SIGUSR1);
Respond(226,"ABOR command successful.");
// printf("DDDDDDDDDDd");
fflush(stdout);
//sleep(30);
}
else
{
Respond(225,"No transfer to ABOR.");
}
return 0;
return 1;
}
int do_mode(char *param)//switch transfers mode
{
char buff[20]={0};
Intercept_Parameter(buff,param);
if(strlen(buff) == 0 || toupper(buff[0])=='S')
{
Respond(200, "Switching to Stream Mode.");
}
else
{
Respond(504, "Unrecognised MODE command.");
}
return 1;
}
glob_t glob_buf;
int FileList(int sockfd)
{
int dir_len;
char pattern[2]="*";
int glob_ret;
int i;
file_info_t *file_info;
int num_files;
long long total_blocks;
char *file_name;
int off = 0;
mode_t mode;
time_t now;
struct tm tm_now;
double age;
char date_buf[13];
// char link[FTP_PATH_MAX+1];
char send_buf[1024]={0};
// int link_len;
dir_len = strlen(pattern);
memset(&glob_buf, 0, sizeof(glob_buf));
glob_ret = glob(pattern,GLOB_ERR | GLOB_NOSORT | GLOB_PERIOD,NULL,&glob_buf);
/*glob(),错误处理,详细见man glob*/
if(glob_ret == GLOB_NOSPACE)
{
puts("Error; Out of memory");
return -1;
}
else if (glob_ret == GLOB_NOMATCH)
{
return -1;
}
else if (glob_ret == GLOB_ABORTED)
{
puts("Error; Read error");
return -1;
}
else if (glob_ret != 0)
{
puts("Error; Unknown glob() error");
return -1;
}
/* 分配空间用来储存 */
//file_info = (file_info_t *)alloca(sizeof(file_info_t) * glob_buf.gl_pathc);
file_info = (file_info_t *)malloc(sizeof(file_info_t) * glob_buf.gl_pathc);
if (file_info == NULL)
{
puts("Error; Out of memory");
return -1;
}
/*获得文件名*********************************************/
num_files = 0;
total_blocks = 0;
for (i=0; i<glob_buf.gl_pathc; i++)
{
file_name = glob_buf.gl_pathv[i];
if (memcmp(file_name, pattern, dir_len) == 0)
{
file_name += dir_len;
}
if(lstat(glob_buf.gl_pathv[i], &file_info[num_files].stat) == 0)
{
total_blocks += file_info[num_files].stat.st_blocks;
file_info[num_files].name = file_name;
file_info[num_files].full_path = glob_buf.gl_pathv[i];
num_files++;
}
}
/*********************************************获得文件名*/
/* 获得文件stat ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥*/
// printf("total %lu\r\n",(unsigned long)total_blocks);
time(&now);
for (i=0; i<num_files; i++)
{
if (strcmp(file_info[i].name, ".") == 0 ||strcmp(file_info[i].name, "..") == 0)
{
continue;
}
char perms[] = "----------";
mode = file_info[i].stat.st_mode;
/*获得文件类型*********************************************/
perms[0] = '?';
switch (mode & S_IFMT)
{
case S_IFREG: perms[0] = '-'; break;
case S_IFDIR: perms[0] = 'd'; break;
case S_IFLNK: perms[0] = 'l'; break;
case S_IFIFO: perms[0] = 'p'; break;
//case S_IFSOCK: perms[0] = 's'; break;
case S_IFCHR: perms[0] = 'c'; break;
case S_IFBLK: perms[0] = 'b'; break;
}
/**********************************************获得文件类型*/
/*获得文件属性*********************************************/
if (mode & S_IRUSR) perms[1] = 'r';
if (mode & S_IWUSR) perms[2] = 'w';
if (mode & S_IXUSR) perms[3] = 'x';
if (mode & S_IRGRP) perms[4] = 'r';
if (mode & S_IWGRP) perms[5] = 'w';
if (mode & S_IXGRP) perms[6] = 'x';
if (mode & S_IROTH) perms[7] = 'r';
if (mode & S_IWOTH) perms[8] = 'w';
if (mode & S_IXOTH) perms[9] = 'x';
perms[10] = '\0';
off += sprintf(send_buf+off,"%s ", perms);
/*********************************************获得文件属性*/
/* 获得文件Link和用户属性 ****************************/
off += sprintf (send_buf+off,
" %3d %-8d %-8d ",
file_info[i].stat.st_nlink,
file_info[i].stat.st_uid,
file_info[i].stat.st_gid);
/* ***************************获得文件Link和用户属性*/
/* 获得文件大小 ************************************************/
off += sprintf (send_buf+off , "%8lu ",(unsigned long)file_info[i].stat.st_size);
/*************************************************获得文件大小*/
/* 获得文件日期 **************************************************/
localtime_r(&file_info[i].stat.st_mtime, &tm_now);
age = difftime(now, file_info[i].stat.st_mtime);
if ((age > 60 * 60 * 24 * 30 * 6) || (age < -(60 * 60 * 24 * 30 * 6)))
{
strftime(date_buf, sizeof(date_buf), "%b %e %Y", &tm_now);
}
else
{
strftime(date_buf, sizeof(date_buf), "%b %e %H:%M", &tm_now);
}
off += sprintf (send_buf+off , "%s ", date_buf);
/* *************************************************获得文件日期*/
/* 获得文件名字 */
off += sprintf (send_buf+off , "%s", file_info[i].name);
/* ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ 获得文件stat*/
off += sprintf (send_buf+off ,"%s", "\r\n");
if(off>1024-100)
{
//printf("文件: %s\n",send_buf);
write(sockfd,send_buf,strlen(send_buf));
off = 0;
memset(send_buf,'\0',1024);
}
}/*end for*/
//printf("内容: %s\n",send_buf);
write(sockfd,send_buf,strlen(send_buf));
/* free memory & return */
free(file_info);
globfree(&glob_buf);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -