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

📄 myftpserver.c

📁 实现LINUX下的一个简单FTP协议。用PASSWORD.c来维护一个用户表
💻 C
📖 第 1 页 / 共 2 页
字号:
				flag2 =1;
				if(cmd_arg_mount == 2){
					download_server2client(datafd,cmd_arg_array[1],0);
					write(datafd,"get over!",9);
				} else if(cmd_arg_mount ==3){
					if(!strcmp(cmd_arg_array[2],"assci")||!strcmp(cmd_arg_array[2],"ASSCI") ){
						download_server2client(datafd,cmd_arg_array[1],0);
						write(datafd,"get over!",9);
					}
					else if(!strcmp(cmd_arg_array[2],"bin")||!strcmp(cmd_arg_array[2],"BIN") ){
						download_server2client(datafd,cmd_arg_array[1],1);
						write(datafd,"get over!",9);
					}
				} else	{
					write(datafd,"enter error!",12);
				}

		}
			
		if (!flag2) {
			write(datafd,"please input the right cmd!",27);
		}
		
		// 将操作结果发送客户端
			
		// 将当前路径发送给客户端
		
		// 接受操作命令
		//getchar()
		
		}//arg_mount;
	}// while
	//pthread_exit(0);
}


// 已测试
int get_index_of(char *str,char ch) {
	int i = 0;
	int flag = 0;
	while(str[i] != ch && str[i]!='\0') {
		i++;
	};
	if (str[i] != '\0') return i;
	else return -1;
}


int get_strindex_of(char *str1,char *str2) {
	int str1_len,str2_len;
	str1_len = strlen(str1)-1;
	str2_len = strlen(str2)-1;
	if (str1_len < str2_len) return -1;
	int start_index,flag,p;
	for (start_index = 0;start_index<= str1_len-str2_len; start_index++) {
		flag =  0; p = 0;
		while(p <= str2_len && str1[start_index+p] == str2[p]) {
			p++;
		}
		if (p>str2_len) return start_index;
	}	
	return -1;
}


// 已测试 
// 实例:get_str_between("abc",str,0,2)后的str="ab"
int get_str_between(char *str,char *strcpy,int start,int end) {
	if (start > end) return -1;
	int i = 0;
	for (;i<=strlen(strcpy);i++) {
		strcpy[i] = '\0';
	}
	i = start;
	for (;i<=end;i++) {
		strcpy[i-start] = str[i];
	}
	strcpy[i-start-1]='\0';
	return end-start+1;
}

void clear_n(char *str) {
	if (str[strlen(str)-1] == '\n') {
		str[strlen(str)-1] = '\0';
	}
}

// 已测试
int get_argc_argv(char *cmd,char* arg_array[]) {
	char array[512][512]={""};
	int strlength;
	char strcmd[512] = "";
	strcpy(strcmd,cmd);
	strlength = strlen(strcmd);
	int st_index = 0;
	int end_index = 0;
	int mount = 0;
	while (st_index <= strlength) {	
		while (end_index <= strlength && strcmd[end_index] == ' ') {
			end_index++;
		}
		if (end_index > strlength) break;
		st_index = end_index;

		while (end_index <= strlength && strcmd[end_index] != ' ' ) {
			end_index++;
		}
		mount++;
		get_str_between(strcmd,array[mount-1],st_index,end_index);
		arg_array[mount-1]=array[mount-1];
		st_index = end_index;
	}
 return mount;
}


		

//验证身份
int checkclient(int sockfd,int data_fd){
	int clientfd,infoclient_addrlen;
	struct sockaddr_in infoclient_addr;
	char client_message[20]="";
	char usrname[12]="";
	char psword[12]="";
	char severip[12]="";
	char port[12]="";
	int flag = 0;
	infoclient_addrlen = sizeof(infoclient_addr);
	while(1){
		//printf("\nwaiting...\n");
		// 等待用户连接 
		clientfd = accept(sockfd,(struct sockaddr *)&infoclient_addr,&infoclient_addrlen);
		//printf("\naccepted!\n");
		
		sleep(1);
		// 接受用户信息

		//if(read(clientfd,client_message,sizeof(client_message))) {
                if (1) {
			// 解析

			//get_param(client_message,usrname,psword,severip,port);

			// 验证身份
			/*flag = checkpassword(usrname,psword);
			if (flag == 0){
				//失败返回错误信息并断开连接
				write(sockfd,FAIL_FLAG,strlen(FAIL_FLAG));
				close(sockfd);
			}*/

			//pthread_mutex_lock(&mutex);
			if(positv_cltnum == 5){//是否超过最大连接数
				//超过返回错误信息,断开连接
			}
			if(positv_cltnum <5){	//合法
				   // 总客户数加1
				positv_cltnum++;  // 活动客户数加1
				//成功连接提供服务

			if(clientfd) {
					client_op(clientfd,data_fd);
				}
			}
		}
	}
	return clientfd;
}


void plus_int(char * str,int number) {
	int len = 0,i=0,j=0,num=0,arr[15]={0};
	num=number;
	len = strlen(str);
	while (num) {
		arr[i++] = num%10;
		num /= 10;
	} 
	for (j=i; j>=0; j--) {
		str[len++] = '1'+arr[j]-1; 
	}
	str[len]='\0';
}


void lpwd(int dataSocketFd){
	int len;
        char currentDirPath[200] = ""; 
	memset(currentDirPath,0,sizeof(currentDirPath));
	getcwd(currentDirPath,sizeof(currentDirPath));
	len = strlen(currentDirPath)+1;
	write(dataSocketFd,currentDirPath,len);
}	

void lmkdir(int dataSocketFd,char *dirName){
	int sentinel_mk;
	struct stat statbuf;
	mode_t modes;
	
	stat(dirName,&statbuf);
	modes = statbuf.st_mode;
	if (S_ISDIR(modes))
		write(dataSocketFd,"dir exist!",10);
	else{
		sentinel_mk = mkdir(dirName,023); //057:属主拥有所有权限,组用户拥有读与执行的权限,其他用户只拥有读权限
		if (sentinel_mk = 1 )
			write(dataSocketFd,"lmkdir successfully!\n",21);
		else 
			write(dataSocketFd,"lmkdir failed!\n",15);
	}
}

void lrmdir(int dataSocketFd,char *dirName){
	int sentinel_rm;
	struct stat statbuf;
	mode_t modes;
	
	stat(dirName,&statbuf);
	modes = statbuf.st_mode;
	if (S_ISDIR(modes)){
		sentinel_rm = rmdir(dirName); 
		if (sentinel_rm = 1 )
			write(dataSocketFd,"lrmdir successfully!\n",21);
		else 
			write(dataSocketFd,"lmkdir failed!\n",15);
	}
	else
		write(dataSocketFd,"ldir didn't exist!\n",19);
}

void ldir(int dataSocketFd){
	char fileName[1024*4*10];
	DIR *dp;
	struct dirent *entry;
	struct stat statbuf;
	int file_counts = 0;// 记录当前目录下文件的个数
	int dir_counts = 0; // 记录当前目录下子目录的个数
	char currentDirPath[200] = "";
	
	memset(currentDirPath,0,sizeof(currentDirPath));
	memset(fileName,0,sizeof(fileName));
	//初始化dir显示标题
	strcat(fileName,"\n");	
	strcat(fileName,"type\t\t");
	strcat(fileName,"uid\t\t");
	strcat(fileName,"name\n");
	getcwd(currentDirPath,sizeof(currentDirPath));
	dp = opendir(currentDirPath);
	//判断当前目录下的文件和子目录,将名称按设定的输出格式放入fileName数组中
	while ((entry = readdir(dp)) != NULL){
		lstat(entry->d_name,&statbuf);
		if (S_ISDIR(statbuf.st_mode)){
			strcat(fileName,"<目  录>\t\t\t");
			strcat(fileName,(char *)entry->d_name);
			strcat(fileName,"\n");
			dir_counts++;
		}
		else{
			strcat(fileName,"<文  件>\t");
			plus_int(fileName,statbuf.st_uid);
			strcat(fileName,"\t\t");
			strcat(fileName,(char *)entry->d_name);
			strcat(fileName,"\n");
			file_counts++;
		}
	}

	strcat(fileName,"文件夹数目 :");
	plus_int(fileName,dir_counts);	
	strcat(fileName,"\n");
	strcat(fileName,"文  件数目:");
	plus_int(fileName,file_counts);
	strcat(fileName,"\n");
	
	
	write(dataSocketFd,fileName,sizeof(fileName));
}

void lcd(int dataSocketFd,char *dirName){
	char currentDirPath[200] = "";

	memset(currentDirPath,0,sizeof(currentDirPath));
	getcwd(currentDirPath,sizeof(currentDirPath));
	//lcd..返回上一级目录
	if (strcmp(dirName,"..") == 0){
		getUpDir(currentDirPath);
		chdir(currentDirPath);
		write(dataSocketFd,"lcd done!",9);
	}
	else{
		chdir(dirName);

		write(dataSocketFd,"lcd done!",9);
	}
}

int getUpDir(char *currentDirPath){
	int pos,len,i;
	char upDirPath[512]="";
	if(currentDirPath == NULL)
		perror("path error");
	len = strlen(currentDirPath);
	for( i = len - 1;i >= 0; i--){
		if (*(currentDirPath+i)=='/'){
			pos = i;
			break;
		}
	}
	get_str_between(currentDirPath,upDirPath,0,(i+1));
	strcpy(currentDirPath,upDirPath);
	return 0;
}


//测试过
//通过用户sockfd传送文件
//以5K速度向用户发送数据,成功返回0,失败返回-1
int download_server2client(int clientfd,char *filename,int download_type){//服务器端代码 
	
	FILE *download_file;
	char download_buf[SPEED];
	int nread,nsent,downloadfile_fd,downloadfile_lenth,curr_sent;	
	nsent = 0;
	//printf("\ndownload begin.\n");
	if(download_type == 0){
	//perror("ASSCI\n");
		download_file = fopen(filename,"r");		
		if(download_file == NULL)	{
//			perror("download flie open assci failed.");
			return -1;
		}
	}
	else if(download_type == 1){
//	perror("BIN\n");	
	download_file = fopen(filename,"rb");
		if(download_file == NULL){
//			perror("download file open bin failed.");			
			return -1;			
			}
	}
	lseek(downloadfile_fd,0,SEEK_SET);// //置读写指针到文件头
	downloadfile_fd = fileno(download_file);
	downloadfile_lenth = lseek(downloadfile_fd,0,SEEK_END);//获取文件长度
	write(clientfd,&downloadfile_lenth,sizeof(int));
	lseek(downloadfile_fd,0,SEEK_SET);
	if(downloadfile_lenth == 0){//空文件
//	printf("file is empty.");
	return -1;	
	}
	
	//printf("\nstart to sent...\n");	

	curr_sent = 0;
	do	//以0.5K传输
	{
	nread = read(downloadfile_fd,download_buf,SPEED);
		
		write(clientfd,download_buf,nread);
		curr_sent+=nread;
		usleep(500000);	
		if(nread != 0){		
		//printf("\n%d byte finish...\n",curr_sent);
		}
		else if(curr_sent == downloadfile_lenth){
		
		fclose(download_file);//关闭文件
		close(downloadfile_fd);
		//printf("\ndownload file %s finished.\n",filename);
		return 0;
		}
			
	}while(nread > 0);
	
		
	
}
//接收客户端上传文件

int put_client2server(int clientfd,char *filename,int type){
//判断当前路径是否为指定上传路径
//不是?需要切换到指定路径
	int fd,newfd,nread,nput,filelen;
	FILE *fileput;
	char put_buf[SPEED];	
	fd = open(filename,O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
	if(fd == -1){
//		perror("open error.\n");
		return -1;
		}
	if(type == 0){
//		printf("\nassci.\n");
		fileput = fopen(filename,"w");
		if(fileput == 	NULL){
//			perror("assci fopen error.\n");
			return -1;
			}
	}
	if(type == 1){
		//printf("\nbin.\n");
		fileput = fopen(filename,"wb");
		if(fileput == NULL){
//		 perror("bin fopen error.\n");
		 return -1;
		}
	}
	
	//printf("\nstart to get...\n");
	read(clientfd,&filelen,sizeof(int));
	//printf("\nget file's lenth is %d",filelen);
	
	newfd = fileno(fileput);
	
	nput = 0;	
	do{
	nread = read(clientfd,put_buf,SPEED);
	nput+=nread;
	write(newfd,put_buf,nread);	
	usleep(500000);
	if(nread > 0){
	//printf("\n%d byte put.\n",nput);
	}	
	 if(nput == 0)
		{
//		perror("put failed.\n");
		return -1;
		}
		
      if(nput == filelen){
	close(fd);
	close(newfd);
	fclose(fileput);
        
	return 0;

	}
	}while(nread > 0);

	
}


// 解析用户名、密码、服务器ip、端口
void get_param(char *cmd,char *usrname,char *psword,char *serverip,char *port) {
		char server_add[20] = "";
		int index_usr;
		index_usr = get_index_of(cmd,'@');
		get_str_between(cmd,server_add,index_usr+1,strlen(cmd));
		
		get_str_between(cmd,usrname,0,get_index_of(cmd,':'));
		get_str_between(cmd,psword,get_index_of(cmd,':')+1,index_usr);
	
		get_str_between(server_add,serverip,0,get_index_of(server_add,':'));
		get_str_between(server_add,port, get_index_of(server_add,':')+1,strlen(server_add));

}

int checkpassword(char *clientinfo) {

	char usrnames[512]="";
	char psword[512]="";
	char serverip[512]="";
	char port[512]="";
	get_param(clientinfo,usrnames,psword,serverip,port);

	int i = 0;

	for (; i<all_cltnum; i++) {

		if (!strcmp(usrnames,ALL_USERS[i].usrname) && !strcmp(psword,ALL_USERS[i].psword)) {
			strcpy(POSITIVE_USERS[_current].usrname,ALL_USERS[i].usrname);		
		return 1; 
		}

	}

	return 0;
	
}

⌨️ 快捷键说明

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