All pastes #416712 Raw Edit

Mine

public c v1 · immutable
#416712 ·published 2007-03-30 12:11 UTC
rendered paste body
/** Homework 1 - Server* by Labianca Fabio Nino */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <string.h>#include <signal.h>#include <sys/wait.h>#include <fcntl.h>#include <ctype.h>#include "errlib.h"#include "sockwrap.h"#include "mywrappers.h"#include "wrappers.h"#define DEFAULT_PORT 12345#define DEFAULT_CHILDREN 2#define MAXBUFL 255#define LISTENQ 15/* * Struttura per memorizzare PID dei figli */typedef struct client{	pid_t pid;}child;/* * Dichiarazione variabili globali */child *queue=NULL;  /* coda figli */char *prog;int port=DEFAULT_PORT, children=DEFAULT_CHILDREN, connection=0;/* * Controllo che la stringa contenga solo numeri */int check_num (char *s){char temp_var[MAXBUFL];int j=0;	memset (temp_var, '\0', MAXBUFL);    strncpy (temp_var, s, MAXBUFL-1);#ifdef TRACE	err_msg ("(%s) info - Stringa %s | Lunghezza %d\r\n", prog, s, strlen(temp_var));#endif	for (j=0; j<strlen(temp_var); j++) {		if ( !isdigit(temp_var[j]) ) 		{#ifdef TRACE				err_msg ("(%s) error - '%c' is not a digit\r\n", prog, temp_var[j]);#endif			err_quit ("Usage: %s [-nMAXCHILDRENNUMBER] [-pPORTNUMBER]", prog);		}	    }    return 0;}/* * Controllo correttezza parametri */void check_args (int argc, char *argv[]){ int i=0, status=0;#ifdef TRACE	err_msg ("(%s) info - argc %d\r\n", prog, argc);#endif    if (argc>1) {        for (i=1; i<argc; i++ ){            if ( (sscanf(argv[i],"-p%d",&port)==1) && ( status!=1 ) )	        {				check_num(argv[i]+2);	            if (port<1024 || port>=65536) 				{#ifdef TRACE	err_msg ("(%s) error - Port %d is not between 1024 - 65535\r\n", prog, port);#endif						err_quit ("Usage: %s [-nMAXCHILDRENNUMBER] [-pPORTNUMBER]", prog);				}                status=1;            }            else {				if ( (sscanf(argv[i],"-n%d",&children)==1) && ( status!=2 ) )				{					check_num(argv[i]+2);					if (children<=0 || children>=65536)					{#ifdef TRACE	err_msg ("(%s) error - Child %d is not between 1 - 65535\r\n", prog, children);#endif						err_quit ("Usage: %s [-nMAXCHILDRENNUMBER] [-pPORTNUMBER]", prog);					}					status=2;				}				else  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;				connection++;			break;		}	}}/* * Estrazione PID dei figli dall'array*/void 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			--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		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){int i;		for (i=0; i<children; i++)    {		if (queue[i].pid == 0) continue;#ifdef TRACE	err_msg("(%s) info - chiusura in corso di %d", prog, queue[i].pid);#endif		kill(queue[i].pid, SIGKILL);    }}/* * Invia la  E di errore sul socket*/void send_err(int connfd){	    Writen (connfd, "E", 1);    return;}/* * Funzione che esegue i calcoli */void calc (int connfd, uint8_t nbyte){char buf[MAXBUFL], ch;size_t n;int8_t   num1_8=0,  num2_8=0,  ris8=0;uint16_t num1_16=0, num2_16=0, ris16=0;#ifdef TRACE    err_msg ("(%s) info - Waiting for operation from child number %d ...\r\n", prog, connection+1);#endif	while ((n = myReadn (connfd, buf, 1)) > 0)	{		ch = buf[0];		if (nbyte==1) 		{			myReadn (connfd, buf, 2*sizeof(int8_t));            memcpy ((void *) &num1_8, buf, sizeof(int8_t));            memcpy ((void *) &num2_8, buf+sizeof(int8_t), sizeof(int8_t));#ifdef TRACE    err_msg("(%s) info - op: %c num1: %u num2: %u\r\n", prog, ch, (int8_t)num1_8, (int8_t)num2_8);#endif				    if(ch=='+')			{				//if ( (int)(num1_8+num2_8) != (int) ( (int8_t)(num1_8+num2_8) ) ) 					//	  {                      //      memcpy (buf, "V", sizeof(char));                        //    Writen (connfd, buf, sizeof(char));						  //}                          //else						  //{							//memcpy (buf, "=", sizeof(char));                            ris8=(num1_8+num2_8);                            //memcpy (buf+sizeof(char), (void*)&ris8, sizeof(int8_t));							memcpy (buf, (void*)&ris8, sizeof(int8_t));#ifdef TRACE    err_msg("(%s) info - ris8: %u\r\n", prog, (int8_t)ris8);#endif                            //Writen (connfd, buf, sizeof(char)+sizeof(int8_t));							Writen (connfd, buf, sizeof(int8_t));						  //}                          //break;/*            switch(ch)			{				case '+': if ( (int)(num1_8+num2_8) != (int) ( (int8_t)(num1_8+num2_8) ) ) 						  {                            memcpy (buf, "V", sizeof(char));                            Writen (connfd, buf, sizeof(char));						  }                          else						  {							memcpy (buf, "=", sizeof(char));                            ris8=(num1_8+num2_8);                            memcpy (buf+sizeof(char), (void*)&ris8, sizeof(int8_t));                            Writen (connfd, buf, sizeof(char)+sizeof(int8_t));						  }                          break;                case '-': if ( (int)(num1_8-num2_8) != (int) ( (int8_t)(num1_8-num2_8) ) )						  {                            memcpy (buf, "V", sizeof(char));                            Writen (connfd, buf, sizeof(char));}                          else                          {							memcpy (buf, "=", sizeof(char));                            ris8=(num1_8-num2_8);                            memcpy (buf+sizeof(char), (void*)&ris8, sizeof(int8_t));                            Writen (connfd, buf, sizeof(char)+sizeof(int8_t));						  }                          break;                case '*': if ( (int)(num1_8*num2_8) != (int) ( (int8_t)(num1_8*num2_8) ) )						  {                            memcpy (buf, "V", sizeof(char));                            Writen (connfd, buf, sizeof(char));						  }                          else                          { 							memcpy (buf, "=", sizeof(char));                            ris8=(num1_8*num2_8);                            memcpy (buf+sizeof(char), (void*)&ris8, sizeof(int8_t));                            Writen (connfd, buf, sizeof(char)+sizeof(int8_t));}                          break;                case '/': if ( (int8_t)num2_8==0 )							send_err(connfd);                          else if ( (int)(num1_8/num2_8) != (int) ( (int8_t)(num1_8/num2_8) ) )						  {                            memcpy (buf, "V", sizeof(char));                            Writen (connfd, buf, sizeof(char));						  }                          else  if ( ( (int8_t)num1_8==0) || ( ( (int8_t)(num1_8/num2_8) )==0 ) )						  {                            memcpy (buf, "U", sizeof(char));                            Writen (connfd, buf, sizeof(char));						  }                          else                          { 							memcpy (buf, "=", sizeof(char));                            ris8=(num1_8/num2_8);                            memcpy (buf+sizeof(char), (void*)&ris8, sizeof(int8_t));                            Writen (connfd, buf, sizeof(char)+sizeof(int8_t));						  }                          break;*/                //default: send_err(connfd);						  //break;            }        }        if (nbyte==2) {            myReadn (connfd, buf, 4);            memcpy ((void *) &num1_16, buf, sizeof(uint16_t));            num1_16=ntohs(num1_16);            memcpy ((void *) &num2_16, buf+sizeof(uint16_t), sizeof(uint16_t));            num2_16=ntohs(num2_16);#ifdef TRACE	err_msg("(%s) info - op: %c num1: %u num2: %u\r\n", prog, ch, num1_16, num2_16);#endif            switch(ch)			{                case '+': if ( (int)(num1_16+num2_16) != (int) ( (uint16_t)(num1_16+num2_16) ) )                            memcpy (buf, "V", sizeof(char));                          else                          {							memcpy (buf, "=", sizeof(char));                            ris16=htons(num1_16+num2_16);                            memcpy (buf+sizeof(char), (void*)&ris16, sizeof(uint16_t));                            Writen (connfd, buf, sizeof(char)+sizeof(uint16_t));						  }                          break;                case '-': if ( (int)(num1_16-num2_16) != (int) ( (uint16_t)(num1_16-num2_16) ) )				          {                            memcpy (buf, "V", sizeof(char));                            Writen (connfd, buf, sizeof(char));						  }                          else                          { 						    memcpy (buf, "=", sizeof(char));                            ris16=htons(num1_16-num2_16);                            memcpy (buf+sizeof(char), (void*)&ris16, sizeof(uint16_t));                            Writen (connfd, buf, sizeof(char)+sizeof(uint16_t));						  }                          break;                case '*': if ( (int)(num1_16*num2_16) != (int) ( (uint16_t)(num1_16*num2_16) ) )				          {                            memcpy (buf, "V", sizeof(char));                            Writen (connfd, buf, sizeof(char));						  }                          else                          { 							memcpy (buf, "=", sizeof(char));                            ris16=htons(num1_16*num2_16);                            memcpy (buf+sizeof(char), (void*)&ris16, sizeof(uint16_t));                            Writen (connfd, buf, sizeof(char)+sizeof(uint16_t));						  }                          break;                case '/': if ( (uint16_t)num2_16==0 )                            send_err(connfd);                          else if ( (int)(num1_16/num2_16) != (int) ( (uint16_t)(num1_16/num2_16) ) ) 						  {                            memcpy (buf, "V", sizeof(char));                            Writen (connfd, buf, sizeof(char));						  }                          else  if ( ( (uint16_t)num1_16==0) || ( ( (uint16_t)(num1_16/num2_16) )==0 ) )						  {                            memcpy (buf, "U", sizeof(char));                            Writen (connfd, buf, sizeof(char));						  }                          else                          {							memcpy (buf, "=", sizeof(char));                            ris16=htons(num1_16/num2_16);                            memcpy (buf+sizeof(char), (void*)&ris16, sizeof(uint16_t));                            Writen (connfd, buf, sizeof(char)+sizeof(uint16_t));						  }                          break;                default: send_err(connfd);						  break;            }		}		memset(buf, '\0', sizeof(buf));	}	return;}/*  * Funzione che invia msg di hello  */void hello (int connfd){char buf[MAXBUFL],ch;size_t n;uint8_t byte=0;	memset(buf, '\0', sizeof(buf));    while ((n = myReadn (connfd, buf, 1) > 0))    {        ch=buf[0];        if (ch!=' ')		{            if (ch=='Q') return;            if (ch=='H')            {				myReadn (connfd, buf, sizeof (uint8_t));                memcpy ((void *) &byte, buf, sizeof (uint8_t));                if (byte==1 || byte==2)                {					memset(buf, '\0', sizeof(buf));                    snprintf (buf, sizeof(buf), "?\r\n");                    Writen (connfd, buf, strlen(buf));#ifdef TRACE						err_msg("(%s) info - Numero catturato: %d - lancio Calcolo(); \r\n", prog, (uint8_t)byte);#endif                    calc(connfd, byte);                }				else send_err(connfd);            }else send_err(connfd);        }else send_err(connfd);    }	return;}/* * main function */int main (int argc, char *argv[]){/* identificatori dei socket */int listenfd, connfd;/* dati connessioni */struct sockaddr_in servaddr, cliaddr;char buffer[MAXBUFL];socklen_t cliaddrlen;pid_t pid;uint8_t out=255, in=0;/* dati per la SETSOCKOPT */int on=1;struct linger ling;	prog = argv[0];		check_args(argc, argv);	queue = (child *)Malloc(children*sizeof(child));	memset ((void *) queue, 0, children*sizeof(child));	memset(buffer, '\0', sizeof(buffer));	listenfd = Socket (AF_INET, SOCK_STREAM, 0);	/* permette il riuso immediato di un indirizzo ip */	Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));	ling.l_onoff=0;	ling.l_linger=0;	/* se rimangono dei dati sul canale in chiusura tenta di inviarli lo stesso */	Setsockopt(listenfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));	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)		{			Writen (connfd, &out, sizeof(uint8_t));//IMP			Close (connfd);		}		else		{			Writen (connfd, &in, sizeof(uint8_t));			if ((pid = myFork()) == 0) /* this is the child */ 			{				Close (listenfd);				signal(SIGCHLD, SIG_DFL);				signal(SIGTERM, SIG_DFL);				signal(SIGINT, SIG_DFL);				hello (connfd);				Close (connfd);				exit (0);			}			else /* this is the parent */			{				Close (connfd);				pid_queue(pid);#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);}