/* TESTO Si realizzi in ambiente Unix/C il server della seguente interazione tra processi : -il sistema consiste di due tipi di processi: un processo server Ps e i processi clienti Pci; -per la comunicazione tra Ps e i processi clienti Pci vengono utilizzate socket Stream; -il server Ps offre un servizio concorrente (un figlio per ogni connessione) alla porta 987 oppure 9876 (motivare la scelta della porta utilizzata); -il client invia una stringa del tipo cmd1 | cmd2 (digitata dall'utente) affinch`e un opportuna coppia di processi sul server realizzi il piping dei comandi cmd1 e cmd2 ; -lo standard output del processo che realizza cmd2 deve essere ridiretto sulla socket connessa affinch`e sia ricevuto e visualizzato dal cliente ; -a partire dal momento in cui riceve un segnale SIGUSR1, il server Ps deve memorizzare in un file di testo (denominato server-log.txt) gli indirizzi IP dei clienti che richiedono il servizio. Come generico client Pci, si suggerisce l'utilizzo del programma telnet, invocato come telnet localhost numeroportaserver. Una volta connessi al server, scrivere ad esempio ls | wc nel terminale del telnet per verificare il funzionamento del server. Deve essere utilizzata la gestione affidabile dei segnali. */ #include #include #include #include #include #include #include #include #include #include #include #include //le porte sotto il 1024 sono riservate #define PORT 9876 //descrittore del file server-log.txt int f=0; //Funzione di gestione segnali. void handler() { //FILE ///////////////////////// // if(!f) if((f=open("server-log.txt",O_CREAT|O_WRONLY|O_TRUNC))<0) perror("open file"); /////////////////////////////// } int main() { char * env[]={NULL,(char *)0}; char buffer[256]="",app[256]=""; char * buffer2; char * nome_cli; struct sigaction sig; struct sockaddr_in server,client; int sock,msgsock; int lenght; int pid,p[2]; printf("Sono il server con pid %d\n",getpid()); //SOCKET ////////////////////// // //preparo la struttura sockaddr_in per settare i parametri della socket sock=socket(AF_INET,SOCK_STREAM,0); //creo la socket if(sock<0) { perror("creazione stream socket"); exit(-1); } //preparo la struttura sockaddr_in per settare i parametri della socket server.sin_family=AF_INET; //internet protocol server.sin_addr.s_addr=INADDR_ANY; //ascolto da tutte le interfacce server.sin_port=htons(PORT); //e dalla porta specificata if(bind(sock,(struct sockaddr *)&server,sizeof(server))<0) { perror("binding stream socket"); exit(-1); } //leggo la porta che mi e' stata effettivamente assegnata lenght=sizeof(server); if(getsockname(sock,(struct sockaddr *)&server,(socklen_t *)&lenght)<0)//leggo il nome della socket { perror("getting socket name"); exit(-1); } printf("Socket port # %d\n",ntohs(server.sin_port)); listen(sock,5); //massimo di 5 connesioni in attesa //////////////////////////////// //SEGNALI ////////////////////// // sig.sa_handler = handler; //gestore del segnale sigemptyset(&sig.sa_mask); sig.sa_flags=SA_RESTART; sigaction(SIGUSR1,&sig,NULL); //////////////////////////////// //ciclo infinito del server in attesa di connessioni do { msgsock=accept(sock,(struct sockaddr *)&client,(socklen_t *)&lenght);//attendo connesioni... if(msgsock == -1) { perror("accept"); exit(-1); } //se e' stato ricevuto un segnale il descrittore f e' diverso da zero if(f) { //leggo il nome del client nome_cli=inet_ntoa(client.sin_addr); //lo scrivo bel file write(f,nome_cli,strlen(nome_cli)); fflush(NULL); } if((pid=fork())<0) //creo il figlio che gestira' la connessione { perror("fork figlio gestore connessione"); exit(-1); } if(pid==0) //sono il figlio? { ///////////////////////////// //CODICE FIGLIO GESTORE printf("Sono il gestore della connessione con pid %d\n",getpid()); //ciclo del gestore della connessione: continua a leggere le stringhe del client e ad eseguire i comandi richiesti do { //resetto i buffer memset(app,0,sizeof(app)); memset(buffer,0,sizeof(buffer)); //leggo la stringa che mi manda il client con i comandi da eseguire if(read(msgsock,app,sizeof(app))<0) { perror("reading message"); exit(-1); } //tolgo gli spazi e i caratteri aggiunti da telnet... sicuramente c'era un modo migliore!! int i=0,j=0; do { if(app[i]!=' ' && app[i]!='\r' && app[i]!='\n') buffer[j++]=app[i]; } while(++i