248 lines
5.2 KiB
C
248 lines
5.2 KiB
C
#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 */
|
|
}
|
|
}
|
|
}
|
|
}
|