/* ***************************************** */ /* Laboration 2 i Datakommunikation 2 */ /* RPC-lib */ /* ***************************************** */ /* c_stub.c */ /* Klientapplikation som skickar */ /* kommandon till servern */ /* ***************************************** */ /* Christian Ohlsson, di7chro@cse.kau.se */ /* Stefan Sonesson, di7stes@cse.kau.se */ /* ***************************************** */ #include "header.h" /* Globala variabler */ int fd=-1, sock; /* fd kommer ihåg om någon fil är öppen */ msg myMsg; /* Meddelandet som funktionerna fyller i */ /* ============================================== in_connect() Gör en uppkoppling mot en server ============================================== */ void in_connect() { char *remhost; u_short remport; struct sockaddr_in remote; struct hostent *h; /* Skapa en socket att skicka data på */ if((sock = socket(AF_INET, SOCK_STREAM, 0 )) < 0 ) { perror("client:socket"); exit(1); } remport = 8704; /* Nolla ut structen */ bzero((char *) &remote, sizeof(remote)); remote.sin_family = AF_INET; /* Fyll i hostent structen */ if((h = gethostbyname(myMsg.machine)) == NULL) { perror("client:gethostbyname"); exit(1); } bcopy((char *)h->h_addr, (char *)&remote.sin_addr, h->h_length); remote.sin_port = htons(remport); /* Begär uppkoppling mot servern */ if(connect(sock, (struct sockaddr *)&remote, sizeof(remote)) < 0) { perror("client:connect"); exit(1); } } /* ============================================== in_open() Letar fram server och fil att öppna ============================================== */ int in_open() { int i,j,k=0; char this_machine[BUFSIZE], this_path[BUFSIZE], filename[BUFSIZE]; if(fd<0) { printf("Enter filename: "); fgets(filename, sizeof(filename), stdin); for(i = 0; i < BUFSIZE; i++) { if(filename[i] != '/') this_machine[i] = filename[i]; else { this_machine[i] = 0; break; } } for(; i < BUFSIZE ; i++) { if(filename[i] != 10) { this_path[k] = filename[i]; k++; } else { this_path[k] = 0; break; } } myMsg.op = OP; if(filename[0] == '/') /* Lokal fil */ strcpy(this_machine, "localhost"); strcpy(myMsg.machine, this_machine); strcpy(myMsg.path, this_path); in_connect(myMsg); } else { puts("A file is already open!"); sleep(SLEEPTIME); return FALSE; } return TRUE; } /* ============================================== in_read() Sätter operatorn till READ ============================================== */ int in_read() { if(fd > 0) myMsg.op = RD; else { puts("No file is open!"); sleep(SLEEPTIME); return FALSE; } return TRUE; } /* ============================================== in_write() Frågar hur mycket som skall skrivas och sätter operatorn ============================================== */ int in_write() { char buf[BUFSIZE]; int length = 0; if(fd>0) { printf("How many bytes do you wish to write: "); gets(buf); length = atoi(buf); printf("Enter text: "); if((myMsg.data = (char*)malloc(length)) < 0) { perror("Malloc fel, byt minnesskretsarna, eller skaffa fler\n"); return FALSE; } myMsg.length = length; gets(myMsg.data); myMsg.op = WR; } else { puts("No file is open!"); sleep(SLEEPTIME); return FALSE; } return TRUE; } /* ============================================== in_delete() Sätter operatorn till DELETE ============================================== */ int in_delete() { if(fd > 0) myMsg.op = DEL; else { puts("No file is open!"); sleep(SLEEPTIME); return FALSE; } return TRUE; } /* ============================================== in_close() Sätter operatorn till CLOSE ============================================== */ int in_close() { if(fd > 0) myMsg.op = CL; else { puts("No file is open!"); sleep(SLEEPTIME); return FALSE; } return TRUE; } /* ============================================== showFile() Om data finns i filen skrivs detta ut ============================================== */ void showFile(char *data) { if(myMsg.length > 0) printf("Data:%s\n",data); else puts("File contains no data."); sleep(SLEEPTIME); } /* ============================================== in_quit() Stänger socketen och avslutar ============================================== */ int in_quit() { if(fd > 0) { puts("Close file first."); sleep(SLEEPTIME); return FALSE; } else { puts("QUIT"); close(sock); exit(0); } } void in_exit() { close(sock); puts("Application error, probably due to underpaid programmers"); exit(0); } /* ============================================== main() Anropar funktioner beroende på menyval ============================================== */ main() { char *data; signal(SIGCHLD, SIG_IGN); signal(SIGINT, SIG_IGN); while(TRUE) { if(menu(myMsg)) { if((write(sock, &myMsg, sizeof(myMsg))) < 0) {puts("1");in_exit();} write(sock, myMsg.data, myMsg.length); if((read(sock, &myMsg, sizeof(myMsg))) < 0) /*lyssna efter svar från servern*/ {puts("3");in_exit();} switch(myMsg.op) { case OPN: /* Öppning misslyckades */ puts("Could not open file."); sleep(SLEEPTIME); break; case OPP: /* Öppning gick bra */ printf("File: %s is open", myMsg.path);fflush(stdout); fd = myMsg.fd;sleep(SLEEPTIME); break; case RDN: /* Läsning misslyckades */ puts("Could not read from file."); sleep(SLEEPTIME); break; case RDP: /* Läsning gick bra */ if((data = (char*)malloc(myMsg.length)) == NULL) { puts("Could not read from file.");break;} if((read(sock, data, myMsg.length)) < 0) { puts("Could not read from file");break;} showFile(data);break; case WRN: /* Skrivning misslyckades */ puts("Could not write to file."); sleep(SLEEPTIME);break; case WRP: /* Skrivning gick bra */ printf("%d bytes written.\n", myMsg.length); sleep(SLEEPTIME);break; case DLN: /* Borttagning misslyckades */ puts("Could not delete file."); sleep(SLEEPTIME);break; case DLP: /* Borttagning gick bra */ printf("File %s deleted\n", myMsg.path); fd=-1; sleep(SLEEPTIME);break; case CLN: /* Stängning misslyckades */ puts("Could not close file."); sleep(SLEEPTIME);break; case CLP: /* Stängning gick bra */ printf("File: %s is closed\n", myMsg.path); fd=-1;sleep(SLEEPTIME);close(sock);break; default: puts(".");sleep(SLEEPTIME);break; } } } /*close(sock);*/ }