rendered paste body#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <unistd.h>#include <string.h>#include <signal.h>#include <sys/wait.h>#include <arpa/inet.h>#include <fcntl.h>#include <ctype.h>#include "errlib.h"#include "sockwrap.h"#define DEFAULT_PORT 12345#define DEFAULT_CHILDREN 2#define MAXBUFL 255#define LISTENQ 15//Struttura per PID figlitypedef struct client{ pid_t pid;}child;char *prog;int port, children, connection;//Array dinamico per PID figlichild *queue=NULL;//Controllo correttezza parametrivoid check_args (int argc, char *argv[]){ switch (argc) { case 1: port=DEFAULT_PORT; children=DEFAULT_CHILDREN; break; case 2: if (sscanf(argv[1],"-p%d",&port)==1) { if (port<1024 || port>65536) { err_quit ("(%s) error - Port %d is not between 1024 - 65536\r\n", prog, port);//per porte alte sballa } children=DEFAULT_CHILDREN; break; } if (sscanf(argv[1],"-n%d",&children)==1) { if (children<0 || children>65536) { err_quit ("(%s) error - Children %d are not between 0 - 65536\r\n", prog, children); } port=DEFAULT_PORT; break; } if (sscanf(argv[1],"-n%d",&children)!=1 || sscanf (argv[1],"-p%d",&port)!=1){ err_quit ("Usage: %s [-nMAXCHILDRENNUMBER] [-pPORTNUMBER]", prog); break; } case 3: if (sscanf(argv[1],"-n%d",&children)==1) { if (children<0 || children>65536) { err_quit ("(%s) error - Children %d are not between 0 - 65536\r\n", prog, children); } if (sscanf(argv[2],"-p%d",&port)==1) { if (port<1024 || port>65536) { err_quit ("(%s) error - Port %d is not between 1024 - 65536\r\n", prog, port); } break; } } if (sscanf(argv[1],"-p%d",&port)==1) { if (port<1024 || port>65536) { err_quit ("(%s) error - Port %d is not between 1024 - 65536\r\n", prog, port); } if (sscanf(argv[2],"-n%d",&children)==1) { if (children<0 || children>65536) { err_quit ("(%s) error - Children %d are not between 0 - 65536\r\n", prog, children); } break; } } if(sscanf (argv[1],"-n%d",&children)!=1 || sscanf (argv[1],"-p%d",&port)!=1){ if(sscanf (argv[2],"-p%d",&port)!=1 || sscanf (argv[2],"-n%d",&children)!=1){ err_quit ("Usage: %s [-nMAXCHILDRENNUMBER] [-pPORTNUMBER]", prog); break; } } default: err_quit ("Usage: %s [-nMAXCHILDRENNUMBER] [-pPORTNUMBER]", prog); } #ifdef TRACE err_msg ("(%s) info - TCP Port: %d\r\n", prog, port); err_msg ("(%s) info - Max Children number: %d\r\n", prog, children); #endif}//Inserimento PID dei figli nell'array void pid_queue(pid_t p){ int i=0; for (i=0; i<children; i++) { if (queue[i].pid == 0) { queue[i].pid = p; i++; connection++; } }#ifdef TRACE err_msg ("(%s) info - Child number %d (pid: %d) saved\r\n", prog, connection, p);#endif} //Estrazione PID dei figli dall'arrayvoid pid_unqueue(pid_t p){ int i; for (i=0; i<children; i++) { if (queue[i].pid == p) { queue[i].pid = 0;#ifdef TRACE err_msg ("(%s) info - Child number %d (pid: %d) deleted\r\n", prog, connection, p);#endif i--; --connection; } }}//Gestione segnali void sigchld_h (int signum){ pid_t pid; int status; //signal(SIGCHLD, sigchld_h); while ((pid = waitpid(-1,&status,WNOHANG)) > 0){#ifdef TRACE err_msg ("(%s) info - Child number %d (pid: %d) terminated with status %d\r\n", prog, connection, pid, status);#endif //; // occhio a questo punto e virgola pid_unqueue(pid); }#ifdef TRACE err_msg ("(%s) info - Number of children currently connected: %d\r\n", prog, connection);#endif}void sigint_h (int signum){#ifdef TRACE err_msg ("(%s) info - Server shut down\r\n", prog);#endif exit(0);} void sigterm_h (int signum)// funziona?{ int i; for (i=0; i<children; i++) { if (queue[i].pid != 0) {#ifdef TRACE err_msg ("(%s) info - Child number %d (pid: %d) is being killed\r\n", prog, i, queue[i].pid);#endif kill (queue[i].pid, SIGKILL); } }} void calc (int connfd, int nbyte){ char buf[MAXBUFL]; size_t n; uint8_t num1_8=0, num2_8=0; uint16_t num1_16=0, num2_16=0; //memset(buf, '\0', sizeof(buf)); #ifdef TRACE err_msg ("(%s) info - Waiting for operation from child number %d...\r\n", prog, connection+1);//?#endif while ((n = Readline (connfd, buf, sizeof(buf)-1)) > 0) { char op1; int a, b, q; buf[n] = '\0'; //switch(nbyte) //{ //case 1: if (sscanf(buf,"%c %d %d",&op1,&a,&b) < 3 || sscanf(buf,"%c %d %d",&op1,&a,&b) > 3) { if (op1=='Q') { Close(connfd); } else snprintf (buf, sizeof(buf), "E\r\n"); } else { if(op1=='+') snprintf (buf, sizeof(buf), "=%d\r\n", a+b); if(op1=='-') snprintf (buf, sizeof(buf), "=%d\r\n", a-b); if(op1=='*') snprintf (buf, sizeof(buf), "=%d\r\n", a*b); if(op1=='/'){ q=a/b; if(q!=0) snprintf (buf, sizeof(buf), "=%d\r\n", a/b); else snprintf (buf, sizeof(buf), "U\r\n"); } } //break; //case 2: //break; Writen (connfd, buf, strlen(buf)); //} }}void hello (int connfd){ char buf[MAXBUFL]; size_t n; int byte=0;//mettere byte in uint8_t char ch; memset(buf, '\0', sizeof(buf));//? while ((n = Readline (connfd, buf, sizeof(buf)-1)) > 0)//legge oltre due dati { buf[n] = '\0'; if (sscanf(buf,"%c %d", &ch,&byte) < 2 || sscanf(buf,"%c %d", &ch,&byte) > 2) //if(n<2 || n>2) { if (ch=='Q') { Close(connfd); } else { snprintf (buf, sizeof(buf), "E\r\n"); Writen (connfd, buf, strlen(buf)); } } else { if (ch=='H') { if (byte == 1 || byte == 2) { snprintf (buf, sizeof(buf), "?\r\n"); Writen (connfd, buf, strlen(buf)); calc(connfd, byte); } else { snprintf (buf, sizeof(buf), "E\r\n"); Writen (connfd, buf, strlen(buf)); } } else { snprintf (buf, sizeof(buf), "E\r\n"); Writen (connfd, buf, strlen(buf)); } } }}int main (int argc, char *argv[]){ int listenfd, connfd; struct sockaddr_in servaddr, cliaddr; char buffer[MAXBUFL];//? socklen_t cliaddrlen; pid_t pid; uint8_t out=255, in=0; prog = argv[0]; check_args(argc, argv); queue = (child *) malloc(children*sizeof(child)); /*if(queue == NULL) { err_quit("(%s) error - Malloc failed\r\n", prog); }*/ memset ((void *) queue, 0, children*sizeof(child));//? memset(buffer, '\0', sizeof(buffer));//? listenfd = Socket (AF_INET, SOCK_STREAM, 0); memset (&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(port); Bind (listenfd, (SA*) &servaddr, sizeof(servaddr)); Listen (listenfd, LISTENQ);#ifdef TRACE err_msg ("(%s) info - Socket created, waiting for connections ...\r\n", prog);#endif signal (SIGCHLD, sigchld_h); signal (SIGTERM, sigterm_h); signal (SIGINT, sigint_h); while (1) { cliaddrlen = sizeof(cliaddr); connfd = Accept (listenfd, (SA*) &cliaddr, &cliaddrlen);#ifdef TRACE err_msg ("(%s) info - New connection from client %s:%u\r\n", prog, inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));#endif if(connection>=children) { snprintf (buffer, sizeof(buffer), "%u\r\n", out); Writen (connfd, buffer, strlen(buffer)); Close (connfd); } else { snprintf (buffer, sizeof(buffer), "%u\r\n", in); Writen (connfd, buffer, strlen(buffer)); if ((pid = Fork()) == 0) // this is the child { Close (listenfd); hello (connfd); Close (connfd); exit (0); } else // this is the parent { pid_queue(pid); Close (connfd);#ifdef TRACE err_msg ("(%s) info - Child number %d (pid:%d) spawned\r\n", prog, connection, pid); err_msg ("(%s) info - Waiting for HELLO from child number %d ...\r\n", prog, connection); #endif } } } exit (0);}