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

📄 ftpcmd.c

📁 模拟linux平台下边的vsFtp服务器可以实现文件的断点续传和下载
💻 C
📖 第 1 页 / 共 3 页
字号:
			//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 + -