260 lines
7.1 KiB
C
260 lines
7.1 KiB
C
/* ***************************************** */
|
|
|
|
/* 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);*/
|
|
|
|
}
|
|
|
|
|
|
|