Files
Datakom2_Lab3/c_stub.c
2026-03-05 13:35:06 +01:00

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);*/
}