www.pudn.com > src.rar > server.c


#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
 
#define CRLF "\r\n" 
#define CALL_RETURN(a)  if ( a == -1) return -1;  
#define SERVER_PORT 3441 
 
int init_std_replies(); 
int ftp_startup();	 
int ftp_process(); 
int ftp_shutdown(); 
int ftp_user(char *username); 
int ftp_pass(char *password); 
int ftp_send(char *filename); 
int ftp_retr(char *filename); 
int ftp_list(); 
int ftp_cwd(char *path); 
int ftp_pwd(); 
int ftp_cdup(); 
int ftp_quit(); 
int ftp_port(); 
int ftp_pasv(); 
int ftp_type(); 
int _ftp_send_reply(char *command, int len); 
int ftp_send_reply(int reply_id); 
int ftp_recv_command(char *buffer, int len); 
int hallo(); 
 
enum { 
	com_conn,com_user,com_pass,com_send,com_retr,com_list,com_cwd,com_pwd,com_quit,com_type,com_pasv,com_port 
}ftp_command; 
 
char *ftp_symbol[] = 
{ 
	"CONN","USER","PASS","STOR","RETR","LIST","CWD","PWD","QUIT","TYPE","PASV","PORT" 
}; 
const int ftp_command_count = 12; 
char command[1000], *command_param; 
 
#define REPLY_COUNT 1000 
char *std_replies[REPLY_COUNT]; 
int std_replies_len[REPLY_COUNT]; 
 
int sock,ctl_sock,data_sock,pasv_sock; 
char peername[100]; 
char cwd[500]; 
 
typedef enum{ 
	false,true 
}bool; 
bool running; 
bool loggedin; 
 
 
char port_addr[40]; 
int port_port; 
enum{ 
	        data_mode_pasv,data_mode_port 
} ftp_data_mode; 
 
 
int main(int argc,char *argv[]) 
{ 
	if( ftp_startup(argc,argv) == -1 ) 
		exit(1); 
		 
	do  
	{ 
		printf("[OPRATE]:Waiting for connection...\n"); 
		ctl_sock = accept(sock,(struct sockaddr*)0,(int*)0); 
		if (ctl_sock == -1) 
			printf("[FAIL]:Accepting failed!!\n"); 
		else 
	  	{ 
			struct sockaddr_in addr; 
			int length; 
		        length	= sizeof(addr); 
			if ( getpeername(ctl_sock,(struct sockaddr*)&addr,&length) == 0 ) 
			{ 
				strcpy(peername,(char*)inet_ntoa(addr.sin_addr)); 
 
			} 
			 
	  		printf("[SUCCEED]:Connection from %s accepted!!\n",peername); 
		  	if( fork() == 0 ) 
			{ 
				ftp_process(); 
				exit(0); 
			} 
	  	} 
	}while(true); 
 
	ftp_shutdown(); 
	exit(0); 
} 
 
int ftp_startup(int argc, char *argv[]) 
{ 
	int length,port; 
	struct sockaddr_in server; 
   	char buf[1024]; 
 
	init_std_replies(); 
 
	getcwd(cwd,sizeof(cwd)); 
	 
   	sock=socket(AF_INET,SOCK_STREAM,0); 
   	if (sock<0) 
   	{ 
		printf("[FAIL]:Opening stream socket failed!!\n"); 
	 	return -1; 
   	} 
   	 
   	server.sin_family=AF_INET; 
 
   	if(argc>1) 
   		server.sin_addr.s_addr = inet_addr(argv[1]); 
   	else 
   		server.sin_addr.s_addr = INADDR_ANY; 
   	 
	if(argc>2) 
   		sscanf(argv[2],"%d",&port); 
   	else 
		port = SERVER_PORT; 
	 
	server.sin_port = htons(port); 
   	 
	printf("[SUCCEED]:Startup ftp service on %s:%d!!\n",argv[1],port); 
 
   	if (bind(sock,(struct sockaddr *)&server,sizeof server)<0) 
   	{ 
   		printf("[FAIL]:Binding stream socket failed!!\n"); 
   		return -1; 
   	} 
   	 
	if ( listen(sock,5) < 0 ) 
	{ 
		printf("[FAIL]:Listening to socket failed!!\n"); 
		return -1; 
	} 
	return 0; 
} 
 
int ftp_shutdown() 
{ 
	close(sock); 
	return 0; 
} 
 
int _ftp_send_reply(char *command,int len) 
{ 
	printf("%s <-- %s\n",peername,command); 
	if (write(ctl_sock,command, len) == -1) 
	{ 
		printf("[FAIL]:Sending ftp reply failed!!\n"); 
		return -1; 
	} 
	if ( write(ctl_sock,CRLF,2) == -1 ) 
	{ 
		printf("[FAIL]:sending ftp reply CRLF failed!!\n"); 
		return -1; 
	} 
	return 0; 
}     
 
int ftp_send_reply(int reply_id) 
{ 
	char *command = std_replies[reply_id];	 
	int len = std_replies_len[reply_id]; 
	return _ftp_send_reply(command,len); 
} 
 
int ftp_recv_command(char *buffer, int len) 
{ 
	int i; 
	for(i=0;i %s",peername,buffer); 
	for(i=0;ih_addr, hp->h_length); 
			printf("[OPERATE]:Establishing data connection to %s:%d...\n",port_addr,port_port); 
			if (connect(data_sock,(struct sockaddr*)&server,sizeof server)<0) 
			{ 
				printf("[FAIL]:Connecting data socket failed!!\n");              
				return -1; 
			} 
			printf("[SUCCEED]:Data connection established!!\n");              
			return 0; 
		} 
	case data_mode_pasv: 
                { 
			printf("[OPERATE]:Accepting data connection...\n"); 
			data_sock = accept(pasv_sock,(struct sockaddr*)0,(int*)0); 
			if(data_sock == -1) 
			{ 
				printf("[FAIL]:Accepting data socket failed!!\n"); 
				return -1; 
			} 
			return 0; 
		} 
	} 
} 
 
int ftp_close_data_transfer() 
{ 
       close(data_sock); 
       data_sock = 0; 
} 
 
int ftp_retr(char *filename) 
{ 
	char buffer[512]; 
	int  len; 
	FILE *file; 
	 
	file = fopen(filename,"r"); 
	if( file == NULL ) 
	{ 
		printf("open local file"); 
		CALL_RETURN(ftp_send_reply(550)); 
		return -1; 
	} 
	 
	if( ftp_data_mode == data_mode_port ) 
	{ 
		CALL_RETURN(ftp_send_reply(150)); 
	} 
	 
	if( ftp_start_data_transfer() == 0 ) 
	{ 
		if (ftp_data_mode == data_mode_pasv) 
		{ 
			CALL_RETURN(ftp_send_reply(150)); 
		} 
  
		while( (len=fread(buffer,1,sizeof(buffer),file)) >0 ) 
		{ 
			write(data_sock,buffer,len); 
		} 
	} 
	else 
	{ 
		printf("[FAIL]:Fail to start data transfer!!\n"); 
		CALL_RETURN(ftp_send_reply(425)); 
		return -1; 
	} 
	 
	fclose(file); 
	 
	ftp_close_data_transfer(); 
	CALL_RETURN(ftp_send_reply(226)); 
	return 0; 
} 
int ftp_send(char *filename) 
{ 
	char buffer[512]; 
	int  len; 
	FILE *file; 
	file = fopen(filename,"w+"); 
	if( file == NULL ) 
	{ 
		printf("[FAIL]:Opening local file failed!!\n"); 
		return -1; 
	} 
	if( ftp_data_mode == data_mode_port ) 
	{ 
		CALL_RETURN(ftp_send_reply(150)); 
	} 
	if( ftp_start_data_transfer() == 0 ) 
	{        
		if (ftp_data_mode == data_mode_pasv)	 
		{        
			CALL_RETURN(ftp_send_reply(150)); 
		} 
		while( (len=read(data_sock,buffer,sizeof(buffer))) >0 )                
                {        
                        fwrite(buffer,1,len,file); 
		} 
	}    
	else    
	{	 
		printf("[FAIL]:Fail to start data transfer!!\n"); 
		CALL_RETURN(ftp_send_reply(425)); 
		return -1; 
	} 
	fclose(file); 
	ftp_close_data_transfer(); 
	CALL_RETURN(ftp_send_reply(226)); 
	return 0; 
} 
int ftp_list() 
{ 
        char cmd[200]; 
        char buffer[512]; 
        int  len; 
	if( ftp_data_mode == data_mode_port ) 
	{	 
		CALL_RETURN(ftp_send_reply(150)); 
	} 
	if( ftp_start_data_transfer() == 0 ) 
	{ 
		 DIR *dp; 
		 struct dirent *ep; 
 
        if (ftp_data_mode == data_mode_pasv)     
        {        
                CALL_RETURN(ftp_send_reply(150)); 
        } 
	  
		 dp = opendir (cwd); 
		 if (dp != NULL) 
		 { 
		 	while (ep = readdir (dp)) 
			{ 
				write(data_sock,ep->d_name,strlen(ep->d_name)); 
				write(data_sock,CRLF,2); 
			} 
			closedir(dp); 
		 } 
		 else 
			write(data_sock,"Couldn't open the directory.\r\n",30); 
	} 
	else 
	{ 
		printf("[FAIL]:Fail to start data transfer!!\n"); 
                CALL_RETURN(ftp_send_reply(425));		 
		return -1; 
	} 
	 
	CALL_RETURN(ftp_send_reply(226)); 
	ftp_close_data_transfer(); 
	return 0; 
} 
 
int ftp_cwd(char *path) 
{ 
	if ( chdir (path) == 0 ) 
	{ 
		getcwd(cwd,sizeof(cwd)); 
		CALL_RETURN(ftp_send_reply(250)); 
		return 0; 
	} 
	else 
	{ 
		CALL_RETURN(ftp_send_reply(550)); 
		return -1; 
	} 
		 
} 
int ftp_pwd() 
{ 
	char cmd[500]; 
	sprintf(cmd,"257 %s is current directory.",cwd); 
	CALL_RETURN(_ftp_send_reply(cmd,strlen(cmd))); 
	return 0; 
} 
 
int ftp_port() 
{ 
    int i,j,k,p1,p2; 
    char cmd[200]; 
 
    for(i=0,k=0;k<3&&command_param[i]!='\r';++i) 
        if(command_param[i]==',') 
		{ 
			++k; 
			command_param[i]='.'; 
		} 
    for(j=i+1;command_param[j]!='\r'&&command_param[j]!=',';++j); 
    memcpy(port_addr,command_param+1,j-1); 
    port_addr[j-1]='\0'; 
    sscanf(command_param+j+1,"%d,%d",&p1,&p2); 
    port_port=(long)p1*256+p2; 
	printf("data connection at %s:%d\n",port_addr,port_port); 
	CALL_RETURN(ftp_send_reply(200)); 
	ftp_data_mode = data_mode_port; 
    return 0;	 
} 
 
int ftp_pasv() 
{ 
    int i,length,port; 
	long ip; 
    char cmd[200]; 
    struct sockaddr_in server; 
 
    pasv_sock=socket(AF_INET,SOCK_STREAM,0); 
    if (pasv_sock<0) 
    { 
        printf("[FAIL]:Opening data socket failed!!\n"); 
        return -1; 
    } 
    server.sin_family=AF_INET; 
    server.sin_addr.s_addr=INADDR_ANY; 
    server.sin_port=0; 
    if (bind(pasv_sock,(struct sockaddr *)&server,sizeof(server))<0) 
    { 
        printf("[FAIL]:Binding stream socket failed!!\n"); 
        return -1; 
    } 
    length=sizeof(server); 
    if ( getsockname(pasv_sock,(struct sockaddr *)&server,&length)!=0 ) 
    { 
        printf("[FAIL]:Getting data socket port failed!!\n"); 
        return -1; 
    } 
    port = ntohs(server.sin_port); 
 
 
    if ( getsockname(ctl_sock,(struct sockaddr *)&server,&length)!=0 ) 
    { 
        printf("[FAIL]:Getting socket name failed!!\n"); 
        return -1; 
    } 
 
    sprintf(cmd,"227 Entering Passive Mode (%s,%d,%d).",inet_ntoa(server.sin_addr),port/256,port%256); 
    length = strlen(cmd); 
    for(i=0;i