#include "../basic.h" #include void sigchldaction (int signal){ int status, pid; for (pid = waitpid(-1,&status,WNOHANG);pid > 0;pid = waitpid(-1,&status,WNOHANG)){ // server: child terminated } } typedef struct message { char data [50]; char nome [50]; char voto [50]; }t_message; int main(int argc, char **argv) { struct sigaction sigchldstructure; sigchldstructure.sa_handler = sigchldaction; sigchldstructure.sa_flags = 0; sigaction (SIGCHLD, &sigchldstructure, NULL); int listenfd, connfd, n; struct sockaddr_in servaddr; char buff[INET_ADDRSTRLEN]; // client ip grabbed redeable short port; // client port redeable if (argc != 2 ){ printf("usage: daytimesrv \n"); exit(0); } if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("socket error\n"); exit(0); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard address */ servaddr.sin_port = htons(atoi(argv[1])); /* server port */ if( (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0){ printf("bind error\n"); exit(0); } if( listen(listenfd, 5) < 0 ) { printf("listen error\n"); exit(0); } struct sockaddr_in client_addr; unsigned int client_addr_len = sizeof(client_addr); for ( ; ; ) { if( (connfd = accept(listenfd, (struct sockaddr *) &client_addr, &client_addr_len)) < 0) { if(errno == EINTR || errno==ECONNABORTED) continue; printf("accept error\n"); exit(1); } int split = fork(); if ( split < 0) { printf("fork for iterative server failed\n"); exit(-1); } if (split == 0){ close(listenfd); t_message m; // buffer message structure int ridden, wrote; sprintf ( m.data, "Benvenuto" ); wrote = write (connfd, &m, sizeof (m) ); // scrivo benvenuto sul socket // check wrote inet_ntop(AF_INET, &(client_addr.sin_addr), buff, INET_ADDRSTRLEN); // get client address port = ntohs(client_addr.sin_port);// get client port //fprintf (stdout,"%s%c%hu\n",buff,':',port); // print client address and port for ( ; ; ) {// the server child reserve other requests from same client ridden = read (connfd,&m,sizeof(m)); // check read. it's blocking int fd; if (strcmp (m.data, "AGGIUNGI" ) == 0 ){ fd = open ("archivio.txt",O_RDWR | O_APPEND); if (fd < 0){ fd = open ("archivio.txt", O_CREAT | O_RDWR | O_APPEND ,00700); } if (fd < 0){ sprintf ( m.data, "Non posso modificare il database" ); wrote = write (connfd, &m, sizeof (m) ); // scrivo sul socket // check wrote } else { write (fd,(m.nome), strlen ((m.nome))); write (fd," ", 1); write (fd,(m.voto), strlen ((m.voto)) ); write (fd," ", 1); write (fd,buff, strlen (buff)); write (fd,":", 1); char port_char[50]; sprintf (port_char,"%hu",port); write (fd,port_char, strlen (port_char)); write (fd,"\n", 1); sprintf ( m.data, "AGGIUNTO" ); wrote = write (connfd, &m, sizeof (m) ); // scrivo sul socket // check wrote } } else { if (strcmp (m.data, "VERIFICA" ) == 0 ){ fd = open ("archivio.txt",O_RDONLY); if (fd < 0){ sprintf ( m.data, "Non posso leggere il database" ); wrote = write (connfd, &m, sizeof (m) ); // scrivo sul socket // check wrote } else { char line [1000]; char line_nome [50]; char line_voto [50]; char line_ip_port [50]; int returned,found; found = 0; FILE * fdfile = fdopen(fd,"r"); returned = fscanf (fdfile,"%999[^\n]%*c",line); for( ; returned > 0 ; fscanf (fdfile,"%999[^\n]%*c",line) ){ sscanf (line, "%s %s %s", line_nome, line_voto, line_ip_port); if (strcmp (line_nome, m.nome) == 0){ found = 1; sprintf ( m.data, "%s ha sostenuto l'esame con voto %s. Informazione fornita da %s ", line_nome, line_voto, line_ip_port ); wrote = write (connfd, &m, sizeof (m) ); // scrivo sul socket // check wrote break; } } if (found == 0){ sprintf ( m.data, "%s non ha sostenuto l'esame", &(m.nome) ); wrote = write (connfd, &m, sizeof (m) ); // scrivo sul socket // check wrote } } } else { sprintf ( m.data, "Bye" ); wrote = write (connfd, &m, sizeof (m) ); // scrivo sul socket // check wrote break; // end requests from client } } } exit(0); // server child served the client. end } else { close(connfd); } } }