#include #include #include #include #include #include #include #include #include #include #include #include #include #define MESSAGESIZE 1024 #define DEFAULTPORT 9876 /* E' porta non privilegiata , mentre 987 e' privilegiata e utilizzazbile solo da processi di root */ int got_sigusr1=0; void sig_handler(int signo) { got_sigusr1=1; printf("Ricevuto SIGUSR1: inizio a registrare gli accessi dei clienti\n"); } main(int argc, char *argv[]) { int sock, length , reuse=1; struct sockaddr_in server, client; struct hostent *hp,*gethostbyname(); struct sigaction act; int msgsock, rval,sval1,sval2, i, pid; int piped[2]; time_t now; char message[MESSAGESIZE],*p; char cmd1[128]; char cmd2[128]; char *args[2]; char *badrequest_message="Errore: il comando inviato non ha la forma prevista cmd1|cmd2\n"; char *welcome_message="Prego immettere un'espressione del tipo cmd1|cmd2\n"; // if(system("uname -a | grep 64 >/dev/null ; if $? echo \"Questo programma non funziona correttamente sulle versioni a 64 bit di Linux\"")); if(system("uname -a | grep 64 >/dev/null") == 0) { fprintf(stderr,"Questa versione del programma non funziona correttamente sulle versioni a 64 bit di Linux"); exit(-1); } FILE *fp=NULL; if(argc !=1) { fprintf(stderr,"Usage: %s\n",argv[0]); exit(-1); } /* Gestione segnali */ act.sa_handler= sig_handler ; sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART ; if(sigaction(SIGUSR1,&act,NULL)<0) { perror("sigaction: "); exit(2); } /* Crea la socket STREAM */ sock= socket(AF_INET,SOCK_STREAM,0); if(sock<0) { perror("opening socket: "); exit(1); } /* Name socket using wildcards */ server.sin_family = AF_INET; server.sin_addr.s_addr= INADDR_ANY; server.sin_port = htons(DEFAULTPORT); if (reuse) { int on = 1; // printf("setsockopt(SO_REUSEADDR)\n"); if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { perror("setsockopt(SO_REUSEADDR) รจ fallita"); } } if (bind(sock,(struct sockaddr *)&server,sizeof server)<0) { perror("binding socket: "); exit(1); } /* Find out assigned port and print out */ length= sizeof server; if(getsockname(sock,(struct sockaddr *)&server,&length)<0) { perror("getsockname: "); exit(1); } printf("Server attivo sulla porta #%d\n",ntohs(server.sin_port)); /* Pronto ad accettare connessioni */ listen(sock,4); do{ /* Attesa di una connessione */ msgsock= accept(sock,(struct sockaddr *)&client,(int *)&length); if(got_sigusr1) { if(fp == NULL) { if((fp=fopen("server-log.txt","w"))==NULL) { perror("opening log file: "); exit(-1); } } now= time(0); fprintf(fp,"%s - cliente %s port %d si e' connesso\n",ctime(&now),inet_ntoa(client.sin_addr), ntohs(client.sin_port) ); fflush(fp); } if(fork()==0) { close(sock); write(msgsock,welcome_message,strlen(welcome_message)+1); if(( rval = read(msgsock,message,sizeof message))<0) { perror("reading from socket: "); exit(-1); } if(!rval) { fprintf(stderr,"Il cliente %s (porta %d) ha chiuso inaspettamente la connessione\n",inet_ntoa(client.sin_addr), ntohs(client.sin_port)); exit(-2); } // "ls|wc" "ls |wc" "ls | wc" p= strchr(message,'|'); if(p == NULL) { if( (p = strchr(message,'\r')) != NULL) *p = '\0'; if( (p = strchr(message,'\n')) != NULL) *p = '\0'; fprintf(stderr,"Richiesta incomprensibile (%s) dal cliente %s (porta %d):\n manca il carattere obbligatorio |\n", message, inet_ntoa(client.sin_addr), ntohs(client.sin_port)); // fprintf(stderr,"Richiesta incomprensibile (%s) dal cliente: manca il carattere obbligatorio |\n", message); // printf("DEBUG 2 %x (%x)\n",p,p-message); write(msgsock,badrequest_message, strlen(badrequest_message)+1); exit(-3); } *p='\0'; sval1= sscanf(message,"%s",cmd1); if(p < &message[MESSAGESIZE]) sval2= sscanf(p+1,"%s",cmd2); if(sval1 != 1 || sval2 != 1) { fprintf(stderr,"Richiesta incomprensibile (%s) dal cliente %s (porta %d): impossibile leggere il cmd1 e/o il cmd2 \n", inet_ntoa(client.sin_addr), ntohs(client.sin_port) ); write(msgsock,badrequest_message, strlen(badrequest_message)+1); exit(-3); } if(pipe(piped)<0) { perror("creating pipe: "); exit(-4); } // system(message); troppo facile if( (pid=fork())<0) { perror("forking2: "); exit(-5); } if(pid==0) { /* Nipote */ close(1); dup(piped[1]); close(piped[0]); close(piped[1]); args[0]=cmd1; args[1]=NULL; execvp(cmd1,args); fprintf(stderr,"execvp di %s e' fallito: %s\n",cmd1,strerror(errno)); exit(-6); } else { close(0); dup(piped[0]); close(piped[0]); close(piped[1]); close(1); dup(msgsock); close(msgsock); args[0]=cmd2; args[1]=NULL; execvp(cmd2,args); fprintf(stderr,"execvp di %s e' fallito: %s\n",cmd2,strerror(errno)); exit(-7); } } else {close(msgsock);} } while(1); }