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

📄 public.c

📁 linux下的FTP服务器。支持现在主流的FTP客户端软件。增加了一些额外的功能。
💻 C
字号:
#include "Public.h"



// ftp 全局变量结构体
FtpGlobalVar ftp_global_var;

// 配置文件结构体
FtpConfig  ftp_config;


// 共享内存
void * pshare_memory = (void *)0;
struct shared_count * pshm=(void *)0;

int shmid=0;

// 创建共享内存,启用他
int Create_shm(key_t key,size_t size,int shmflag)
{
	int id=shmget(key,size,shmflag);
	if (-1==id)
	{
		perror("shmget failed.\n");
	}
	pshare_memory=(void *)shmat(id,(void *)0,0); // 返回共享内存内的第一个字节指针
	if (pshare_memory==(void *)-1)
	{
		perror("shmat failed");
	}
	pshm = (struct shared_count *)(pshare_memory);
	// 初始化	
	pshm->upload_count=(long)0;
	pshm->download_count=(long)0;
	pshm->upload_bytes=(long)0;
	pshm->download_bytes=(long)0;
}


// 删除共享内存
int Del_shm(int shmid)
{
	
	int id=shmget((key_t)1234,sizeof(struct shared_count),IPC_CREAT | 0666);
	if (shmctl(id,IPC_RMID,NULL)== -1) 
	{
		perror("shmctl -IPC_RMID fail.\n");
	}
}


// 写上传共享内存
int Write_upload_shm(int bytes)
{
	pshm->upload_count+=1;
	pshm->upload_bytes+=bytes;
}

// 写下载共享内存
int Write_download_shm(int bytes)
{
	pshm->download_count+=1;
	pshm->download_bytes+=bytes;
}


int Read_download_shm(struct shared_count *readed_share)
{
	readed_share->download_count=pshm->download_count;
	readed_share->upload_count=pshm->upload_count;
	readed_share->download_bytes=pshm->download_bytes;
	readed_share->upload_bytes=pshm->upload_bytes;
}
// 循环读函数
int read_loop(int sockfd,void * buf ,int size)
{
	int retval;
	int num_read=0;
	while (1)
	{
			retval=read(sockfd,buf+num_read,size);
			if (retval<0)
			{
					if (errno==EINTR)
							continue;
					else
							return retval;
			}
			else if (retval==0)
			{
					return num_read;
			}
			num_read+=retval;
			size-=retval;
			if (size==0)
			{
					return num_read;
			}
	}

	
	


}

// 循环写函数
int write_loop(int sockfd,void * buf ,int size)
{
		int retval;
		int num_written=0;
		while (1)
		{
				retval=write(sockfd,buf+num_written,size);
				if (retval<0)
				{
						if (errno==EINTR)
								continue;
						else
								return retval;
				}
				else if (retval==0)
				{
						return num_written;
				}
				num_written+=retval;
				size-=retval;
				if (size==0)
				{
						return num_written;
				}
		}
}

// 读取一行函数
int readline(int fd, char* buf, int maxlen)
{
	int retval;
	int num_read;
	char* p=buf;
	int num_left = maxlen;
	while (1)
	{
		retval = recv_peek(fd, p, num_left);
		if (retval < 0)
		{
			return retval;
			//printf("recv_peek error\n");
			//exit(1);
		}
		else if (retval == 0)
		{
			return retval;
		}
		num_read = retval;
		
		int i;
		for (i=0; i < num_read; i++)
		{
			if (p[i] == '\n')
			{
				retval = read_loop(fd, p, i+1);
				if (retval!=i+1)
				{
					printf("read_loop error\n");
					exit(1);
				}

				if (p[i] != '\n')
				{
					printf("missing terminator\n");
					exit(1);
				}

				while (*buf != '\n')
				{
					buf++;
				}
				*buf='\0';
				return retval;
			}
		}
		if (num_read > num_left)
		{
			printf("num_read > num_left in readline\n");
			exit(1);
		}
		num_left -= num_read;
		retval = read_loop(fd, p, num_read);
		if (retval != num_read)
		{
			printf("read_loop error\n");
			exit(1);
		}
		p += num_read;
	}
	return -1;
}


// 偷看函数
int recv_peek(int fd, void* buf, int len)
{
	while (1)
	{
		int retval = recv(fd,buf,len,MSG_PEEK);
		if (retval < 0 && errno==EINTR)
		{
			continue;
		}
		return retval;
	}
}

void trap(int n)
{
	printf("trap sem function call !\n");
}

/*上传文件*/
int upload_file(int fd,int sockfd)
{
	char recvbuf[1024];
	int n=0;
	int bytes=0;
	while (1)
	{
		memset(recvbuf,0,sizeof(recvbuf));
		n = read(sockfd,recvbuf,1024);
		if (n==-1)
		{
			if (errno == EINTR)
			{
				continue;
			}
			else
			{
				perror("read error!\n");
				exit(1);
			}
		}
		else if(0==n)
		{
			break; //  读完跳出
		}
		//fputs(recvbuf,pfile); // 测试输出
		write(fd,recvbuf,n);
		bytes+=n;
	}

	// 关闭
	close(sockfd);
	close(fd);


	// 统计
//	Create_shm((key_t)1234,sizeof(struct shared_count),0666 | IPC_CREAT);
	Write_upload_shm(bytes);


	return 0;

}


/* 下载文件*/
int download_file(int fd,int clientfd)
{
	char recvbuf[1024]={0};
	int n=0;
	int bytes=0;
	while (1)
	{
		memset(recvbuf,0,sizeof(recvbuf));
		n=read(fd,recvbuf,1024);
		if (n==-1)
		{
			if (errno==EINTR)
			{
				continue;
			}
			else
			{
				printf("read error\n");
				exit(1);
			}
		}
		else if (n==0)
		{
			break;
		}
		if (write_loop(clientfd,recvbuf,n)!=n)
		{
			printf("write error\n");
			exit(1);
		}
		bytes+=n;
	}

	// 统计
	//Create_shm( (key_t)1234,sizeof(struct shared_count),0666 | IPC_CREAT);
	Write_download_shm(bytes);
}


int inputfile(char * filename,char * msg)
{
	FILE * pfile = fopen(filename,"w+");
	fwrite(msg,1,strlen(msg),pfile);
	fclose(pfile);
}


// 删除右空格
void MoveRightSpace(char * str)
{
	int  i=strlen(str)-1;
	while (1)
	{
		if (i>=0)
		{
			if (32==str[i])
			{
				i--;
			}else
			{
				str[i+1]='\0';
				break;
			}
		}
		else
		{
			break; // 空字符 直接退出
		}
	}
}

// 删除右空格
void MoveLeftSpace(char *str)
{

	int  i=0;
	while (1)
	{
		if (32==str[i])
		{
			//printf("space\n");
			i++;
		}else
		{
			strcpy(str,&str[i]);
			break;
		}
	}
}

// 删除空格
void MoveSpace(char * str)
{
	MoveRightSpace(str);
	MoveLeftSpace(str);
}

/***********************************************
	解析配置行,字符串尾\R\N处理
************************************************/
int Parse_Config_line(char * line,char * res)
{
	int len = strlen(line);
	for (;len>0;len--)
	{
		if (line[len]=='\r')
		{
			line[len]=0;
		}

		if (line[len]=='=')
		{
			strcpy(res,&line[len+1]);
			break;
		}
	}
}



/****************************************************	
	读取配置文件
*****************************************************/
int Read_Config(char * filename,FtpConfig * ftp_config)
{

	FILE * pfile = fopen(filename,"r");
	if (pfile==NULL)
	{
		perror("open configfile fail.\n");
		return -1;
	}
	
	char line[512]={0};
	char res[80]={0};
	while (fgets(line,512,pfile)!=NULL)
	{
			if (strlen(line)==0 || line[0]=='#')
			{
				continue;
			}

			Parse_Config_line(line,res);
			

			if (strstr(line,"ctrl_connect_port")!=NULL)
			{
				ftp_config->ctrl_connect_port = atoi(res);
			}else 
			if (strstr(line,"service_name=")!=NULL)
			{
			//	Parse_Config_line(line,res);
				strcpy(ftp_config->service_name,res);

			}else if (strstr(line,"anonymous_enable=")!=NULL)
			{
				//Parse_Config_line(line,res);
				if (strcmp(res,"YES")==0)
				{
					ftp_config->anonymous_enable=1; 
				}else if (strcmp(res,"NO")==0)
				{
					ftp_config->anonymous_enable=0;
				}else
				{
					ftp_config->anonymous_enable=1; // 默认
				}
				
			}else if (strstr(line,"connect_from_port_20=")!=NULL)
			{
				ftp_config->connect_from_port_20 = atoi(res);
			}else if (strstr(line,"local_enable=")!=NULL)
			{
				if (strcmp(res,"YES")==0)
				{
					ftp_config->local_enable=1; 
				}else if (strcmp(res,"NO")==0)
				{
					ftp_config->local_enable=0;
				}else
				{
					ftp_config->local_enable=1; // 默认
				}
			}else if (strstr(line,"write_enable=")!=NULL)
			{
				if (strcmp(res,"YES")==0)
				{
					ftp_config->write_enable=1; 
				}else if (strcmp(res,"NO")==0)
				{
					ftp_config->write_enable=0;
				}else
				{
					ftp_config->write_enable=1; // 默认
				}
			}else if (strstr(line,"local_umask=")!=NULL)
			{	
				ftp_config->local_umask = atoi(res);
					
			}else if (strstr(line,"anon_upload_enable=")!=NULL)
			{
				if (strcmp(res,"YES")==0)
				{
					ftp_config->anon_upload_enable=1; 
				}else if (strcmp(res,"NO")==0)
				{
					ftp_config->anon_upload_enable=0;
				}else
				{
					ftp_config->anon_upload_enable=1; // 默认
				}
			}else if (strstr(line,"anon_mkdir_enable=")!=NULL)
			{

				if (strcmp(res,"YES")==0)
				{
					ftp_config->anon_mkdir_write_enable=1; 
				}else if (strcmp(res,"NO")==0)
				{
					ftp_config->anon_mkdir_write_enable=0;
				}else
				{
					ftp_config->anon_mkdir_write_enable=1; // 默认
				}

			}else if (strstr(line,"idle_session_timeout=")!=NULL)
			{
				ftp_config->idle_session_timeout =atoi(res);

			}else if (strstr(line,"data_connection_timeout=")!=NULL)
			{
				ftp_config->data_connection_timeout = atoi(res);
			}
	}
	fclose(pfile);
	return 0;
}

⌨️ 快捷键说明

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