#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 */ } } } }