//Ben Anderson //Chris Guernsey /*---------------------------------------------------------------------------*/ /* Usage: */ /* */ /* Runs an instance of a new shell that restricts runable commands */ /* based on the UID of user */ /*---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #include #include "protocol.h" #define MAXDATASIZE 8192 // max number of bytes we can get at once extern int optind; extern char *optarg; int getField(int fd, char *buf){ int i,ret; char ch; ch=' '; i=0; while(ch!=EOF){ ret=read(fd,&ch,1); buf[i++]=ch; if(i >= 8000 && ch == '\n'){ return (0); } if(ret==0){ return(1);} } buf[--i]='\0'; return(0); } int FileSize( const char * szFileName ) { struct stat fileStat; int err = stat( szFileName, &fileStat ); if (0 != err) return 0; return fileStat.st_size; } char * listFiles(int sockfd){ msg_buffer buffer; int rec; bzero((char*)buffer.data,8192); buffer.opcode = op_list_directory; buffer.ack_nack = 0; buffer.subcode = 0; buffer.length = 0; write(sockfd, (char *)&buffer, buffer.length+6); bzero((char*)buffer.data,8192); rec = read(sockfd,(char *)&buffer,8192); if(rec<0){ perror("ERROR reading from socket"); } //if(rec!=-1){ //printf("%s\n",(char*)buffer.data); //printf("File list successful\n"); //} return (char *) buffer.data; } int readFile(int sockfd, char *filename){ msg_buffer buffer; int rec,response; bzero((char*)buffer.data,8192); buffer.opcode = op_open_file_input; buffer.ack_nack = 0; buffer.subcode = 0; buffer.length = strlen(filename); strcpy((char *)buffer.data,filename); write(sockfd, (char *)&buffer, buffer.length+6); bzero((char*)buffer.data,8192); rec = read(sockfd,(char *)&buffer,8192); if(rec<0){ perror("ERROR reading from socket"); } if(rec!=-1){ printf("%s\n",(char*)buffer.data); printf("File opened for input\n"); response = buffer.subcode; } printf("%d\n",response); response = buffer.subcode; bzero((char*)buffer.data,8192); buffer.opcode = op_read_file; buffer.ack_nack = 0; buffer.subcode = response; buffer.length = 8192; write(sockfd, (char *)&buffer, buffer.length+6); bzero((char*)buffer.data,8192); rec = read(sockfd,(char *)&buffer,8192); if(rec<0){ perror("ERROR reading from socket"); } if(rec!=-1){ printf("%s\n",(char*)buffer.data); printf("File read successful\n"); } } int xfer(int sockfd, char * filename, char * filedata,bool first,int response){ int rec,r; msg_buffer buffer; msg_buffer buffer2; char message[100]; char * files = listFiles(sockfd); char * temp = strstr(files,filename); if(first){ if(temp != NULL){ temp[strlen(temp)-1] = '\0'; } else if(temp == NULL){ temp = ""; } if(strcmp(temp,filename)!=0){ bzero((char*)buffer.data,8192); buffer.opcode = op_open_file_output; buffer.ack_nack = 0; buffer.subcode = 0; buffer.length = strlen(filename); strcpy((char *)buffer.data,filename); write(sockfd, (char *)&buffer, buffer.length+6); bzero((char*)buffer.data,8192); rec = read(sockfd,(char *)&buffer,8192); if(rec<0){ perror("ERROR reading from socket"); } strcpy(message,(char*)buffer.data); if(rec!=-1){ printf("%s\n",(char*)buffer.data); printf("File opened for output\n"); } response = buffer.subcode; } /* bzero((char*)buffer.data,8192); buffer.opcode = op_open_file_input; buffer.ack_nack = 0; buffer.subcode = 0; buffer.length = strlen(filename); strcpy((char *)buffer.data,filename); write(sockfd, (char *)&buffer, buffer.length+6); bzero((char*)buffer.data,8192); rec = read(sockfd,(char *)&buffer,8192); if(rec<0){ perror("ERROR reading from socket"); } if(rec!=-1){ printf("%s\n",(char*)buffer.data); printf("File opened for input\n"); } r = buffer.subcode; printf("r = %d and response = %d\n",r,response); */ bzero(buffer2.data,8192); buffer2.opcode = op_write_file; buffer2.ack_nack = 0; if(response !=0){ buffer2.subcode = response; } else{ buffer2.subcode = r; } buffer2.length = strlen(filedata); strcpy((char *)buffer2.data,filedata); //printf("%s\n",filedata); write(sockfd, (char *)&buffer2, buffer2.length+6); bzero((char*)buffer2.data,8192); rec = read(sockfd,(char *)&buffer2,8192); if(rec<0){ perror("ERROR reading from socket"); } if(rec!=-1){ printf("%s\n",(char*)buffer2.data); printf("File write successful\n"); } if(response !=0){ return response; } else{ return r; } } else{ /* bzero((char*)buffer.data,8192); buffer.opcode = op_open_file_input; buffer.ack_nack = 0; buffer.subcode = 0; buffer.length = strlen(filename); strcpy((char *)buffer.data,filename); write(sockfd, (char *)&buffer, buffer.length+6); bzero((char*)buffer.data,8192); rec = read(sockfd,(char *)&buffer,8192); if(rec<0){ perror("ERROR reading from socket"); } if(rec!=-1){ printf("%s\n",(char*)buffer.data); printf("File opened for input\n"); } r = buffer.subcode; printf("r = %d and response = %d\n",r,response); */ bzero(buffer2.data,8192); buffer2.opcode = op_write_file; buffer2.ack_nack = 0; if(response !=0){ buffer2.subcode = response; } else{ buffer2.subcode = r; } buffer2.length = strlen(filedata); strcpy((char *)buffer2.data,filedata); //printf("%s\n",filedata); write(sockfd, (char *)&buffer2, buffer2.length+6); bzero((char*)buffer2.data,8192); rec = read(sockfd,(char *)&buffer2,8192); if(rec<0){ perror("ERROR reading from socket"); } if(rec!=-1){ printf("%s\n",(char*)buffer2.data); printf("File write successful\n"); } bzero((char*)buffer.data,8192); buffer.opcode = op_close_file; buffer.ack_nack = 0; if(response !=0){ buffer2.subcode = response; } else{ buffer2.subcode = r; } buffer.length = strlen(filename); strcpy((char *)buffer.data,filename); write(sockfd, (char *)&buffer, buffer.length+6); bzero((char*)buffer.data,8192); rec = read(sockfd,(char *)&buffer,8192); if(rec<0){ perror("ERROR reading from socket"); } if(rec!=-1){ printf("%s\n",(char*)buffer.data); printf("File close successful\n"); } if(response !=0){ return response; } else{ return r; } } } int main(int argc, char *argv[]) { int i,t,fd,rec,filelength,endofFile,response,PORT,rep; char *opts="hpiafld:"; int sockfd, numbytes; char buf[MAXDATASIZE]; struct hostent *hostname; struct sockaddr_in their_addr; struct sockaddr_in my_addr; int print=0; char * filename = ""; char ch; char * userID= ""; char * opcode = ""; char message[100]; bool r1 = false; bool r2 = false; bool r3 = false; bool transfer = false; bool list = false; bool del = false; bool logged = false; bool resolved = false; bool first = false; bool readme = false; bool dorl = false; bool fused = false; char filedata[8192]; int addrlen=sizeof(their_addr); msg_buffer buffer; msg_buffer buffer2; msg_buffer buffer3; i=0; while ((ch=getopt(argc,argv,opts))!=-1){ if (ch=='h') { if(!r1){ i+=2; if ((hostname=gethostbyname(argv[i])) == NULL) { // get the host info herror("gethostbyname"); exit(1); r1=true; } } else{ printf("Host already defined\n"); exit(1); } r1=true; } if (ch=='p') { if(r2==0){ i+=2; PORT = atoi(argv[i]); r2=true; } else{ printf("Port already defined\n"); exit(1); } } if (ch=='i') { if(!r3){ i+=2; userID = argv[i]; r3=true; } else{ printf("User already defined\n"); exit(1); } } if (ch=='f') { if(!dorl){ transfer = true; i+=2; filename = argv[i]; filelength = FileSize(filename); fd = open(filename, O_RDONLY); fused = true; } else{ printf("-f can not be used with -d or -l\n"); exit(1); } } if (ch=='l') { if(!fused){ i++; list = true; dorl = true; } else{ printf("-l can not be used with -f\n"); exit(1); } } if (ch=='d') { if(!fused){ i++; del = true; dorl = true; } else{ printf("-d can not be used with -f\n"); exit(1); } } if(ch == 'a'){ i+=2; filename = argv[i]; readme = true; } } if(r1 && r2 && r3){ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } their_addr.sin_family = AF_INET; // host byte order their_addr.sin_port = htons(PORT); // short, network byte order their_addr.sin_addr = *((struct in_addr *)hostname->h_addr); if (connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } strcpy(message,opcode); strcat(message,userID); buffer.opcode = op_hello; buffer.ack_nack = 1; buffer.subcode = 0; buffer.length = strlen(message); strcpy((char*)buffer.data,message); write(sockfd, (char *)&buffer, buffer.length+6); bzero((char*)buffer.data,8192); rec = read(sockfd,(char *)&buffer,8192); if(rec<0){ perror("ERROR reading from socket"); } strcpy(message,(char*)buffer.data); if(rec!=-1){ printf("%s\n",message); printf("Login successful\n"); } resolved = true; } else if(r1 && r2 && !r3){ /* if(fork() == 0) { execvp("/usr/bin/clear", argv); exit(1);}*/ while(!logged){ userID = getpass("Enter your user id\n"); printf("%s \n", userID); if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } their_addr.sin_family = AF_INET; // host byte order their_addr.sin_port = htons(PORT); // short, network byte order their_addr.sin_addr = *((struct in_addr *)hostname->h_addr); if (connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } strcpy(message,opcode); strcat(message,userID); buffer.opcode = op_hello; buffer.ack_nack = 1; buffer.subcode = 0; buffer.length = strlen(message); strcpy((char*)buffer.data,message); write(sockfd, (char *)&buffer, buffer.length+6); bzero((char*)buffer.data,8192); rec = read(sockfd,(char *)&buffer,8192); if(rec<0){ perror("ERROR reading from socket"); } strcpy(message,(char*)buffer.data); if(buffer.ack_nack==1){ logged = true; } } resolved = true; } if(list){ char * templist = listFiles(sockfd); printf("%s\n",templist); } if(del){ bzero((char*)buffer.data,8192); buffer.opcode = op_erase_files; buffer.ack_nack = 0; buffer.subcode = 0; buffer.length = 0; write(sockfd, (char *)&buffer, buffer.length+6); bzero((char*)buffer.data,8192); rec = read(sockfd,(char *)&buffer,8192); if(rec<0){ perror("ERROR reading from socket"); } if(rec!=-1){ printf("%s\n",(char*)buffer.data); printf("File remove successful\n"); } response = buffer.length; } bzero(message,80); if(transfer){ i=0; t=0; while(true){ endofFile=getField(fd,filedata); //printf("%s\n",filedata); if(i>0){ first = false; } else{ first = true; } t = xfer(sockfd,filename,filedata,first,t); bzero(filedata,strlen(filedata)); if(endofFile){ break; } i++; } } if(readme){ readFile(sockfd,filename); } close(sockfd); return 0; }