Startpunkten

This commit is contained in:
2026-03-05 13:31:50 +01:00
commit 86a20ae0e1
16 changed files with 1305 additions and 0 deletions

247
Lab4/dbserver.c Normal file
View File

@@ -0,0 +1,247 @@
#include "db.h"
void Kill_Process() {
kill(0, SIGTERM);
exit(0);
}
void P(char *lockfile) { /* Proberen */
int tempfd;
while((tempfd = creat(lockfile, 0)) < 0); /* Försök skapa låsfilen */
close(tempfd);
}
void V(char *lockfile) { /* Verhogen */
unlink(lockfile);
}
printsin(struct sockaddr_in *sin, char *m1, char *m2 ) {
struct hostent *gethostbyaddr(), *h;
printf ("%s %s\n", m1, m2);
printf ("Family %d addr %x port %d\n", sin -> sin_family,
ntohl(sin -> sin_addr.s_addr), ntohs(sin -> sin_port));
h = gethostbyaddr((char *)&sin->sin_addr, sizeof(int), AF_INET);
printf ("Symbolic host name <%s>\n",h->h_name);
}
void doAdd(msg *myMsg) {
int fd, i=0;
printf("Adding %s\n", myMsg->name);
P(READLOCK);
if((fd = open(FILENAME, O_CREAT|O_WRONLY|O_APPEND, PERMS)) < 0) {
myMsg->op = NACK; /* Return error to client */
exit(1);
}
write(fd, &myMsg->nr, NRSIZE);
write(fd, &myMsg->name, NAMESIZE);
if((close(fd)) < 0) {
myMsg->op = NACK;
V(READLOCK);
return;
}
myMsg->op = ACK;
V(READLOCK);
}
void doDel(msg *myMsg) {
int i=0, j=0, file, temp;
struct stat st1;
struct stat st2;
long a, b;
char c, nr[NRSIZE], name[NAMESIZE];
P(READLOCK);
P(WRITELOCK);
if((file = open(FILENAME, O_RDONLY)) < 0) {
myMsg->op = NACK;
return;
}
if((temp = open(TMPFILE, O_RDWR|O_CREAT|O_TRUNC, PERMS)) < 0) {
myMsg->op = NACK;
return;
}
while(read(file, nr, NRSIZE) > 0) {
read(file, name, NAMESIZE);
if(strcmp(nr, myMsg->nr) != 0) {
write(temp, nr, NRSIZE);
write(temp, name, NAMESIZE);
}
}
fstat(file, &st1);
a = st1.st_size;
fstat(temp, &st2);
b = st2.st_size;
if((close(file)) < 0) {
myMsg->op = NACK;
return;
}
if((close(temp)) < 0) {
myMsg->op = NACK;
return;
}
if((temp = open(TMPFILE, O_RDONLY)) < 0) {
myMsg->op = NACK;
return;
}
if((file = open(FILENAME, O_RDWR|O_CREAT|O_TRUNC, PERMS)) < 0) {
myMsg->op = NACK;
return;
}
while(read(temp, &c ,1) > 0){
write(file, &c, 1);
}
if((close(file)) < 0) {
myMsg->op = NACK;
return;
}
if((close(temp)) < 0) {
myMsg->op = NACK;
return;
}
if((unlink(TMPFILE)) < 0) {
myMsg->op = NACK;
return;
}
V(WRITELOCK);
V(READLOCK);
if(a == b) {
myMsg->op = NACK;
return;
}
myMsg->op = ACK;
}
void doFindNumber(msg *myMsg) {
int file;
char nr[NRSIZE], name[NAMESIZE];
P(READLOCK);
if((file = open(FILENAME, O_RDONLY)) < 0) {
myMsg->op = NACK;
return;
}
while(read(file, nr, NRSIZE) > 0){
read(file, name, NAMESIZE);
if(strcmp(name, myMsg->name) == 0) {
myMsg->op = PRN;
strcpy(myMsg->nr, nr);
V(READLOCK);
return;
}
}
myMsg->op = NACK;
close(file);
V(READLOCK);
return;
}
void doFindName(msg *myMsg) {
int file;
char nr[NRSIZE], name[NAMESIZE];
P(READLOCK);
if((file = open(FILENAME, O_RDONLY)) < 0) {
myMsg->op = NACK;
return;
}
while(read(file, nr, NRSIZE) > 0){
read(file, name, NAMESIZE);
printf("\n nr=%s, myMsg->nr=%s",nr, myMsg->nr);
if(strcmp(nr, myMsg->nr) == 0) {
myMsg->op = PRN;
strcpy(myMsg->name, name);
V(READLOCK);
return;
}
}
close(file);
V(READLOCK);
myMsg->op = NACK;
}
void doExit(msg *myMsg, int data_sockfd) {
printf("Quitting...\n");
close(data_sockfd);
exit(0);
}
main() {
int listener, childpid, data_sockfd, status, client_length, length;
msg myMsg;
struct sockaddr_in srvr_addr, client_addr;
signal(SIGCHLD, SIG_IGN);
signal(SIGINT, Kill_Process);
/*signal(SIGTERM, Kill_Process);*/
if((listener = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
perror("server: can't open stream socket");
exit(0);
}
bzero((char *) &srvr_addr, sizeof(srvr_addr));
srvr_addr.sin_family = AF_INET;
srvr_addr.sin_addr.s_addr = htons(INADDR_ANY);
srvr_addr.sin_port = 27015;
if(bind(listener, (struct sockaddr *)&srvr_addr, sizeof(srvr_addr)) < 0) {
perror("server: can't bind local address");
exit(0);
}
/* Print out the port number assigned to this process by bind(). */
length = sizeof(srvr_addr);
if(getsockname(listener, (struct sockaddr *)&srvr_addr, &length) < 0) {
perror("server: can't get sockname");
exit(0);
}
printf("Port number %d\n", ntohs(srvr_addr.sin_port));
listen(listener,10);
for(;;) {
/* Wait for a connection from a client process */
client_length = sizeof(client_addr);
if ((data_sockfd=accept(listener,
(struct sockaddr *)&client_addr, &length)) < 0) {
perror("server: accept error");
exit(0);
}
printsin(&client_addr,"\nRSTREAM", "accepted connection from");
if((childpid = fork()) < 0) {
perror("server: fork error");
exit(0);
}
else if(childpid == 0) { /* Child process */
close(listener);
while(1) {
read(data_sockfd, &myMsg, sizeof(myMsg));
switch(myMsg.op) {
case 1: doAdd(&myMsg);
write(data_sockfd, &myMsg, sizeof(myMsg));
break;
case 2: doDel(&myMsg);
write(data_sockfd, &myMsg, sizeof(myMsg));
break;
case 3: doFindNumber(&myMsg);
write(data_sockfd, &myMsg, sizeof(myMsg));
break;
case 4: doFindName(&myMsg);
write(data_sockfd, &myMsg, sizeof(myMsg));
break;
case 5: doExit(&myMsg, data_sockfd);
default: break;
}
myMsg.op = ACK; /* töm struktens op så den inte är kvar till switchen */
}
}
}
}