rendered paste body/* File Transfer Homework *** Client *** Author : Giacomo Margaria */#include <sys/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/time.h>#include <arpa/inet.h>#include <string.h>#include <stdlib.h>#include <signal.h>#include <netdb.h>#include <fcntl.h> #include <unistd.h>#include "errlib.h"#include "sockwrap.h"#ifdef __CYGWIN__#define uint8_t u_int8_t#define uint16_t u_int16_t#endif#define MAX 1460#define UDP_PORT 1234#define TIMEOUT 5char *prog;/* Prototypes */uint16_t fsize(char *filename);int hostlookup (struct sockaddr_in *udp,struct sockaddr_in *tcp,char *hostname,uint16_t udport);void transfer (int tcpfd,char *filename);/* SIGINT Signal Handler */void sigint_h (int signum) {#ifdef TRACEerr_msg("(%s) [SIGINT] handled",prog);#endifexit(1);}/* File Size */uint16_t fsize(char *filename) { int var;uint16_t size;struct stat nfo; stat(filename,&nfo);var=nfo.st_size;if (var>65535){ size=0; return size;}size=var;/* Coding */size=htons(size);return size;}/* Host Lookup */int hostlookup (struct sockaddr_in *udp,struct sockaddr_in *tcp,char *hostname,uint16_t udport){udp->sin_family = AF_INET;tcp->sin_family = AF_INET;udp->sin_port = htons(udport);if(inet_addr(hostname)==-1){ struct hostent *he; if((he=gethostbyname(hostname))!=(struct hostent *) NULL) { memcpy(&udp->sin_addr,he->h_addr,4); memcpy(&tcp->sin_addr,he->h_addr,4); return 1; }else return 0;}inet_aton(hostname,&udp->sin_addr);inet_aton(hostname,&tcp->sin_addr);return 1;}/* Transfer */void transfer (int tcpfd,char *filename) {char buffer[MAX];int fd,n;unsigned char c;uint8_t skip;uint16_t size;skip=0;/* Opens File */if((fd=open(filename,O_RDONLY))<0) skip=1; /* Gets File Size */if((size=fsize(filename))==0 && skip==0) skip=2; switch(skip) { case 1 :#ifdef TRACE err_msg("(%s) Skipping %s open failed",prog,filename);#endif c='\0'; Write(tcpfd,&c,sizeof(c)); break; case 2 :#ifdef TRACE err_msg("(%s) Skipping %s wrong size",prog,filename);#endif c='\0'; Write(tcpfd,&c,sizeof(c)); Close(fd); break; case 0 : n=0; /* Sends Filename */ while(filename[n]!='\0') { buffer[n]=filename[n]; n++; } buffer[n]='\0'; Write(tcpfd,buffer,n+1);#ifdef TRACE err_msg("(%s) Sending file (%s) [%u] bytes",prog,filename,ntohs(size));#endif /* Sends Filename Size */ Write(tcpfd,&size,sizeof(size)); /* Sends File */ n=Read(fd,buffer,MAX); while ( n>0 ) { Write(tcpfd,buffer,n); n=Read(fd,buffer,MAX); } /* Closes File */ Close(fd); #ifdef TRACE err_msg("(%s) File successfully sent",prog);#endif break;}return;}/* Main */int main (int argc, char *argv[]){/* Sockets FD */int udpfd,tcpfd;/* Sockets Structs */struct sockaddr_in udp,tcp;/* Ports*/uint16_t udport,tcport;/* Flags */int n;unsigned char c[5];struct timeval timeo;uint8_t fileno,counter,reply,shift,retry;fd_set readset;FD_ZERO(&readset);prog = argv[0];if (argc < 3) err_quit ("Usage: %s <server address> [<-pUDP_PORT>] <file1> .. <filen>", prog);/* Analyzing Args */shift=0;if(memcmp("-p",argv[2],2)==0){ shift=1; n=0; while(argv[2][n+2]!='\0' && n<5){ c[n]=argv[2][n+2]; n++; } if(argv[2][n+2]!='\0') err_quit("(%s) Wrong UDP port",prog); c[n]='\0'; n=strtol(c,NULL,0); if( (n<=0) || n>65535 ) /* strtol() failed or port too big */ err_quit("(%s) Wrong UDP port",prog); else memcpy(&udport,&n,2); #ifdef TRACE err_msg("(%s) UDP Port [%u]",prog,udport);#endif}else{ udport=UDP_PORT;#ifdef TRACE err_msg("(%s) UDP Port [%u] (Default)",prog,udport);#endif} /* Gets Number Of Files */fileno = argc-(2+shift);#ifdef TRACEerr_msg("(%s) %hi file(s) to be sent :",prog,fileno);/* Lists Filenames */for (n=0;n<fileno;n++) err_msg( "(%s) %s",prog,argv[n+2+shift] );#endif /* Creates Sockets */udpfd = Socket (AF_INET, SOCK_DGRAM, 0);tcpfd = Socket (AF_INET, SOCK_STREAM, 0);/* Sets sockaddr Structs */memset (&udp, 0, sizeof(udp));memset (&tcp, 0, sizeof(tcp)); FD_SET(udpfd,&readset);if(!hostlookup(&udp,&tcp,argv[1],udport)) err_quit("(%s) Unable to resolve [%s]",prog,argv[1]);#ifdef TRACEelse err_msg("(%s) Connecting to %s [%s]",prog,inet_ntoa(udp.sin_addr),argv[1]);#endifc[0]='F';retry=0;n=-1;timeo.tv_usec=0;timeo.tv_sec=TIMEOUT;/* Sends char To Server */Sendto (udpfd, &c[0], 1, 0, (struct sockaddr *) &udp, sizeof(udp));while (1) {Select(udpfd+1,&readset,NULL,NULL,&timeo);if(FD_ISSET(udpfd,&readset)) {Recvfrom (udpfd,&tcport, sizeof(tcport), 0, NULL, NULL);tcp.sin_port = tcport;#ifdef TRACEerr_msg("(%s) Received TCP Port [%u]",prog,htons(tcport));#endif/* Closes UDP Socket */Close(udpfd);#ifdef TRACEerr_msg("(%s) UDP socket closed",prog);#endif/* Connects To TCP Port */Connect (tcpfd, (struct sockaddr *) &tcp, sizeof(tcp));/* Sends Fileno To Server */Write(tcpfd,&fileno,1);/* Waits For Server Reply */Read(tcpfd,&reply,1);if(reply!=0) err_quit("(%s) Server refused transfer request",prog);#ifdef TRACEelse err_msg("(%s) Server accepted transfer request",prog);#endifcounter=0;while(counter != fileno) {transfer(tcpfd,argv[counter+2+shift]);counter++; }Shutdown(tcpfd,SHUT_WR);n=Read(tcpfd,&c,sizeof(c));#ifdef TRACEif(n==0) err_msg("(%s) Connection closed",prog);else err_msg("(%s) Connection closed badly by server",prog);#endif /* Closes TCP Socket */Close(tcpfd);#ifdef TRACEerr_msg("(%s) TCP socket closed",prog);err_msg("(%s) Exiting",prog);#endifexit(0); }else{ Sendto (udpfd, &c[0], 1, 0, (struct sockaddr *) &udp, sizeof(udp)); if(retry<3){#ifdef TRACE err_msg("(%s) Retrying sendto attempt [%d]",prog,retry+1);#endif retry++;}else{ err_quit("(%s) Exiting UDP reply timeout",prog);}}}}