// SERVER!!!!!!!!!!!! /* Trasformare il server dell'esercizio precedente in concorrente Modificare il client in modo che accetti nomi simbolici Modificare il server in modo che stampi l'indirizzo IP e la porta del client da cui provengono le stringhe */ #include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int lfd, cfd,n,pid[20],status,i=0,t,j; struct sockaddr_in servaddr,cl; socklen_t dim=sizeof(cl); char buff[256]="",name[16]; if(argc<2) printf("Errore: Inserire numero porta\n"), exit(1); if ((lfd=socket(AF_INET,SOCK_STREAM,0))<0) perror("socket"), exit(1); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(atoi(argv[1])); if (bind(lfd,(struct sockaddr *) &servaddr,sizeof(servaddr))<0) perror("bind"), exit(1); if(fcntl(lfd,F_SETFL,O_NONBLOCK)<0) //rendo il socket non bloccante perror("fcntl"), exit(1); while(1){ status=0; if ( listen(lfd, 1024) < 0 ) perror("listen"), exit(1); while ((cfd=accept(lfd,(struct sockaddr *)&cl,&dim))<0){ //questa accept è non bloccante t=waitpid(-1,&status,WNOHANG); //aspetto che un qualsiasi dei miei figli termini (non bloccandomi se non è terminato nessuno) if(status>0){ //se un figlio è terminato con un valore positivo (cioè ha ricevuto 'close'), il padre deve terminare for(j=0;j IP:%s Porta:%d\n",i+1,name,ntohs(cl.sin_port)); fflush(NULL); if((pid[i]=fork())==0){ //se sto nel figlio close(lfd); while ((n=read(cfd,buff,256))!=0) { //esce quando il client inserisce exit o close (la read su un socket vuoto ritorna 0) if (n<0) perror("read"), exit(0); printf("Client %d: ",i+1); fflush(0); if(write(STDOUT_FILENO,buff,n)<0) perror("write"), exit(1); if(strncmp(buff,"close\n",6)==0) //se ho ricevuto 'close' esco con un numero diverso per avvertire il padre exit(1); } exit(0); } ++i; close(cfd); } return 1; } // CLIENT!!!!!!!!!! /* Trasformare il server dell'esercizio precedente in concorrente Modificare il client in modo che accetti nomi simbolici Modificare il server in modo che stampi l'indirizzo IP e la porta del client da cui provengono le stringhe */ #include #include #include #include #include #include #include #include int main(int argc, char* argv[]){ struct sockaddr_in sad; char buf[256],name[16]; int sockfd,n; struct hostent* host; if(argc<3) printf("Errore: Inserire Indirizzo IP e porta!\n"), exit(1); if((host=gethostbyname(argv[1]))==NULL) perror("gethostbyname"), exit(1); if(!inet_ntop(AF_INET,host->h_addr_list[0],name,16)) perror("inet_ntop"), exit(1); printf("Nome simbolico %s convertito in IP:%s\n",argv[1],name); if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0) perror("socket"), exit(0); if(!inet_aton(name,&sad.sin_addr)) perror("inet_aton"), exit(1); sad.sin_family=AF_INET; sad.sin_port=htons(atoi(argv[2])); if(connect(sockfd,(struct sockaddr *) &sad, sizeof(sad))<0) perror("connect"), exit(1); printf("Mi sono collegato sulla porta %d\n",atoi(argv[2])); while((n=read(STDIN_FILENO,buf,256))>=0 && strncmp(buf,"exit\n",5)!=0){ if(write(sockfd,buf,n) #include #include #include #include #include #include #include int main(int argc, char* argv[]){ struct sockaddr_in sad; char buf[256],name[16]; int sockfd,n; struct hostent* host; if(argc<3) printf("Errore: Inserire Indirizzo IP e porta!\n"), exit(1); if((host=gethostbyname(argv[1]))==NULL) perror("gethostbyname"), exit(1); if(!inet_ntop(AF_INET,host->h_addr_list[0],name,16)) perror("inet_ntop"), exit(1); printf("Nome simbolico %s convertito in IP:%s\n",argv[1],name); if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0) perror("socket"), exit(0); if(!inet_aton(name,&sad.sin_addr)) perror("inet_aton"), exit(1); sad.sin_family=AF_INET; sad.sin_port=htons(atoi(argv[2])); if(connect(sockfd,(struct sockaddr *) &sad, sizeof(sad))<0) perror("connect"), exit(1); printf("Mi sono collegato sulla porta %d\n",atoi(argv[2])); while((n=read(STDIN_FILENO,buf,256))>=0 && strncmp(buf,"exit\n",5)!=0){ if(write(sockfd,buf,n) #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int lfd, cfd,n,pid[20],status,i=0,t,j; struct sockaddr_in servaddr,cl; socklen_t dim=sizeof(cl); char buff[256]="",name[16]; if(argc<2) printf("Errore: Inserire numero porta\n"), exit(1); if ((lfd=socket(AF_INET,SOCK_STREAM,0))<0) perror("socket"), exit(1); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(atoi(argv[1])); if (bind(lfd,(struct sockaddr *) &servaddr,sizeof(servaddr))<0) perror("bind"), exit(1); if(fcntl(lfd,F_SETFL,O_NONBLOCK)<0) //rendo il socket non bloccante perror("fcntl"), exit(1); while(1){ status=0; if ( listen(lfd, 1024) < 0 ) perror("listen"), exit(1); while ((cfd=accept(lfd,(struct sockaddr *)&cl,&dim))<0){ //questa accept è non bloccante t=waitpid(-1,&status,WNOHANG); //aspetto che un qualsiasi dei miei figli termini (non bloccandomi se non è terminato nessuno) if(status>0){ //se un figlio è terminato con un valore positivo (cioè ha ricevuto 'close'), il padre deve terminare for(j=0;j IP:%s Porta:%d\n",i+1,name,ntohs(cl.sin_port)); fflush(NULL); if((pid[i]=fork())==0){ //se sto nel figlio close(lfd); while ((n=read(cfd,buff,256))!=0) { //esce quando il client inserisce exit o close (la read su un socket vuoto ritorna 0) if (n<0) perror("read"), exit(0); printf("Client %d: ",i+1); fflush(0); if(write(STDOUT_FILENO,buff,n)<0) perror("write"), exit(1); if(strncmp(buff,"close\n",6)==0) //se ho ricevuto 'close' esco con un numero diverso per avvertire il padre exit(1); } exit(0); } ++i; close(cfd); } return 1; } 43.976769924164 // SERVER!!!!!!!!!!!! /* SHELL REMOTA */ #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int lfd, cfd,n,pid,fd,n1,n2,i; struct sockaddr_in servaddr,cl; socklen_t dim=sizeof(cl); char buff[256]="",name[16],passwd[50],pwbuf[50],*cmd[50],*p,out[4096]; if(argc<2) printf("Inserire numero porta\n"), exit(1); if ((lfd=socket(AF_INET,SOCK_STREAM,0))<0) perror("socket"), exit(1); servaddr.sin_family=AF_INET; if(!inet_aton("127.0.0.1",&servaddr.sin_addr)) perror("inet_aton"), exit(1); servaddr.sin_port=htons(atoi(argv[1])); if (bind(lfd,(struct sockaddr *) &servaddr,sizeof(servaddr))<0) perror("bind"), exit(1); if((fd=open("filepwd",O_RDONLY))<0) //apro il file in cui risiede la password perror("open"), exit(1); if((n1=read(fd,pwbuf,50))<0) //e ne salvo il contenuto in pwbuf perror("read"), exit(1); close(fd); while(1){ if ( listen(lfd, 1024) < 0 ) perror("listen"), exit(1); printf("In attesa di connessioni...\n"); fflush(0); if ((cfd=accept(lfd,(struct sockaddr *)&cl,&dim))<0) perror("accept"), exit(1); if(!inet_ntop(AF_INET,&(cl.sin_addr.s_addr),name,16)) perror("inet_ntop"), exit(1); printf("IP:%s Porta:%d\nControllo password in corso...\n",name,ntohs(cl.sin_port)); fflush(NULL); //INIZIO VERIFICA PASSWORD if( (n2=read(cfd,passwd,50)) <=0) //leggo la password inviatami dal client perror("read"), exit(1); if(n1!=n2 || strncmp(passwd,pwbuf,n1)!=0){ //confronto prima le lunghezze delle due password e poi se necessario il contenuto printf("La password non corrisponde!\n"); fflush(0); if(write(cfd,"error",5)<0) perror("write"), exit(1); //avviso il client di non aver digitato la giusta password continue; //continuo ad ascoltare altre connessioni pendenti } printf("Autenticazione avvenuta con successo.\n"); fflush(0); if(write(cfd,"right",5)<0) perror("write"), exit(1); //avviso il client dell'avvenuta autenticazione //FINE VERIFICA PASSWORD if((pid=fork())<0) perror("fork"), exit(1); if(pid==0){ //se sto nel figlio devo occuparmi del singolo client close(lfd); while ((n=read(cfd,buff,256))!=0) { //esce quando il client inserisce exit o close if (n<0) perror("read"), exit(1); //INIZIO ACQUISIZIONE COMANDO (con le opzioni e gli argomenti) p = strtok(buff," "); i=0; while (p != NULL){ cmd[i]=p; p = strtok(NULL," "); i++; } cmd[--i]=NULL; //FINE ACQUISIZIONE COMANDO if(strcmp(cmd[0],"close")==0) //se il client ha inserito close, il server termina exit(0); //altrimenti deve eseguire il comando e lo fa creando un figlio apposta comunicando con lui tramite una pipe int fd[2]; if(pipe(fd)<0) perror("pipe"), exit(1); if( (pid=fork())<0 ) perror("fork"), exit(1); if(pid==0){ //se sto nel figlio devo eseguire il comando reidirizzando l'output e l'error nella pipe close(fd[0]); dup2(fd[1],STDOUT_FILENO); dup2(fd[1],STDERR_FILENO); if(execvp(cmd[0],cmd)<0) perror("execvp"), exit(1); close(fd[1]); exit(1); } else{ //se sto nel padre devo aspettare la terminazione del figlio, leggere dalla pipe e scrivere nel socket close(fd[1]); wait(NULL); int letti; if( (letti=read(fd[0],out,4096)) <0) perror("read"), exit(1); if(write(cfd,out,letti) #include #include #include #include #include #include #include int main(int argc, char* argv[]){ struct sockaddr_in sad; char buf[256],name[16],passw[50],check[15],risp[4096]; int sockfd,n,k; struct hostent* host; if(argc<3) printf("Inserire Indirizzo IP e porta!\n"), exit(1); if((host=gethostbyname(argv[1]))==NULL) perror("gethostbyname"), exit(1); if(!inet_ntop(AF_INET,host->h_addr_list[0],name,16)) perror("inet_ntop"), exit(1); printf("Nome simbolico %s convertito in IP:%s\n",argv[1],name); if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0) perror("socket"), exit(0); if(!inet_aton(name,&sad.sin_addr)) perror("inet_aton"), exit(1); sad.sin_family=AF_INET; sad.sin_port=htons(atoi(argv[2])); if(connect(sockfd,(struct sockaddr *) &sad, sizeof(sad))<0) perror("connect"), exit(1); printf("Mi sono collegato sulla porta %d\n",atoi(argv[2])); //INIZIO SESSIONE PASSWORD printf("Inserisci password: "); fflush(0); if((n=read(STDIN_FILENO,passw,50))<0) perror("read"), exit(1); //leggo la password if(write(sockfd,passw,n)=0 && strncmp(buf,"exit\n",5)!=0){ if(write(sockfd,buf,n)