Startpunkten
This commit is contained in:
247
Lab4/dbserver.c
Normal file
247
Lab4/dbserver.c
Normal 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 */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user