/* File Transfer Homework *** Client *** Author : Giacomo Margaria */ #include #include #include #include #include #include #include #include #include #include #include #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 5 char *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 TRACE err_msg("(%s) [SIGINT] handled",prog); #endif exit(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 [<-pUDP_PORT>] .. ", 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 TRACE err_msg("(%s) %hi file(s) to be sent :",prog,fileno); /* Lists Filenames */ for (n=0;n