rendered paste body#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#include <sys/un.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <arpa/inet.h>#include <pthread.h>#include <ctype.h>#include <string.h>#include <netdb.h>#define MAX_THREADS 5//#define SERVER "mail.informatik.htw-dresden.de"#define SERVER "localhost"#include "server.h"pthread_t threads[MAX_THREADS];int jthreads[MAX_THREADS];int s;int main(int argc, char *argv[]){ int i, ns; unsigned int fromlen; struct sockaddr_in servAd; struct sockaddr_in clieAd; unsigned short port; void * value; fd_set fds; struct timeval tv; int erg; port = atoi(argv[1]); memset(jthreads,0,sizeof(jthreads)); if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { perror("server: socket"); return -1; } memset(&servAd,0,sizeof(servAd)); servAd.sin_family = AF_INET; servAd.sin_addr.s_addr = htonl(INADDR_ANY); servAd.sin_port = htons(port); if (bind(s, (struct sockaddr *)&servAd, sizeof(servAd)) < 0) { perror("server: bind"); return -1; } printf("opened socket as fd (%d) for family (%d)\n",s,servAd.sin_family); if (listen(s, 2) < 0) { perror("server: listen"); return -1; } for (;;) { for(i=0;i<MAX_THREADS;i++){ if(jthreads[i]==1){ pthread_join(threads[i],&value); threads[i]=0; jthreads[i]=0; } } FD_ZERO(&fds); FD_SET(s,&fds); tv.tv_sec=0; tv.tv_usec=500000; erg=select(s+1,&fds,NULL,NULL,&tv); if(erg==0) continue; else if(erg<0) perror("server: select"); for(i=0; i<MAX_THREADS;i++){ if(threads[i]==0) break; } if(i==MAX_THREADS){ usleep(10000); continue; } printf("stelle: %d\n",i); fromlen=sizeof(struct sockaddr); ns = accept(s,(struct sockaddr *)&clieAd, &fromlen); if ( ns < 0) perror("server: accept"); printf("Handling client %s\n",inet_ntoa(clieAd.sin_addr)); erg=pthread_create(&threads[i],0, (void*)client, (void*) &ns); if(erg!=0) perror("server: pthread_create"); } close(s);}int checkmail(char * ret){ ret = strtok(ret,"\015\012"); char mail [128]; strcpy(mail,ret); if(strchr(ret,'<')!=NULL){ ret++; strtok(ret,">"); } int len = 0, len2 = 0; if(strchr(ret,' ')!=NULL) return 0; if(strchr(ret,'.')==NULL) return 0; if(strchr(ret,'@')==NULL) return 0; len=strlen(strrchr(ret,'.'))-1; if(len<2) return 0; len2=strlen(strchr(ret,'@'))-1; if(len2-len-1<3) return 0; if(strlen(ret)-len2-1<1) return 0; if(strchr(mail,'<')!=NULL) ret--; strcpy(ret,mail); return 1;}void client(void* arg){ int len=0,erg,i; int so = *((int*)arg); char buf[128]; struct timeval tv; fd_set fds; char * helo = (char *)malloc(1); char * from = (char *)malloc(1); char * to = (char *)malloc(1); char * data = (char *)malloc(1); char * ret = (char *)malloc(1024); char * test = (char *)malloc(128); char * text = (char *)malloc(128); int status=0; struct hostent * host; send(so, "220 localhost server\n", 22, 0); memset(buf,0,sizeof(buf)); for(;;){ memset(ret,0,sizeof(ret)); memset(buf,0,sizeof(buf)); FD_ZERO(&fds); FD_SET(so,&fds); tv.tv_sec=10; tv.tv_usec=0; erg=select(so+1,&fds,NULL,NULL,&tv); if(erg==0) continue; else if(erg<0) perror("server: select"); len = read(so,buf,127); printf("|%s|\n",buf); if(len<=2) continue; for(i=0;i<len;i++) buf[i]=tolower(buf[i]); buf[127]='\0'; if(strncmp(buf,"quit",4)==0){ send(so, "221 See you later\n", 18, 0); close(so); for(i=0;i<MAX_THREADS;i++){ if(threads[i]==pthread_self()) break; } jthreads[i]=1; pthread_exit(0); free(helo); free(from); free(to); free(data); free(ret); host=NULL; }else if(strncmp(buf,"rset",4)==0){ helo=""; from=""; to=""; data=""; memset(buf,0,sizeof(buf)); host=NULL; status=0; }else if(strncmp(buf,"noop",4)==0){ send(so, "250 OK\n", 7, 0); }else if(strncmp(buf,"vrfy",4)==0){ if(strlen(buf)<8){ send(so, "501 Syntax: VRFY adress\n", 24, 0); continue; } strtok(buf," "); ret = strtok(NULL,"\n\0"); send(so, "252 ", 4, 0); send(so, ret, strlen(ret)-1, 0); send(so, "\n", 1, 0); }else if(strncmp(buf,"expn",4)==0){ if(strlen(buf)<8){ send(so, "501 Syntax: EXPN adress\n", 24, 0); continue; } strtok(buf," "); ret = strtok(NULL,"\n\0"); send(so, "252 ", 4, 0); send(so, ret, strlen(ret)-1, 0); send(so, "\n", 1, 0); }else if(strncmp(buf,"helo",4)==0){ strtok(buf," "); ret = strtok(NULL,"\n\0"); memset(test,0,sizeof(test)); strncpy(test,ret,strlen(ret)-1); host = gethostbyname(test); if(!host){ send(so, "501 Bad hostname\n", 18, 0); continue; } free(helo); helo = (char *)malloc(strlen(test)); strncpy(helo,test,strlen(test)+1); strcpy(text,"250 Hello "); strcat(text,helo); strcat(text,", nice to meet you\n"); send(so, text, strlen(text), 0); free(text); free(test); status=1; }else if(strncmp(buf,"mail from:",10)==0){ if(status==0&&strlen(helo)>0) helo=""; strtok(buf,":"); ret = strtok(NULL,"\n\0"); if(!checkmail(ret)){ send(so, "501 Bad adress syntax\n", 22, 0); continue; } free(from); from = (char *)malloc(strlen(ret)); strncpy(from,ret,strlen(ret)+1); send(so, "250 Sender OK\n", 14, 0); status=2; }else if(strncmp(buf,"rcpt to:",8)==0){ if(status==0||status==1){ send(so, "503 Mail first\n", 15, 0); continue; } strtok(buf,":"); ret = strtok(NULL,"\n\0"); if(!checkmail(ret)){ send(so, "501 Bad adress syntax\n", 22, 0); continue; } if(strlen(to)>0&&status==3){ to=(char*)realloc(to,strlen(ret)+strlen(to)+1); strcat(to,","); strcat(to,ret); } else{ free(to); to = (char *)malloc(strlen(ret)); strncpy(to,ret,strlen(ret)+1); } send(so, "250 Recipient OK\n", 17, 0); status=3; }else if(strncmp(buf,"data",4)==0){ if(status==0||status==1){ send(so, "503 Mail first\n", 15, 0); continue; } if(status==2){ send(so, "554 Error: no valid recipients\n", 31, 0); continue; } send(so, "354 End data with <CR><LF>.<CR><LF>\n", 36, 0); strcpy(data,""); while(read(so,buf,127)){ printf("|%s|\n",buf); if(strncmp(buf,".\015\012",3)==0) break; data=(char*)realloc(data,strlen(buf)+strlen(data)+1); strcat(data,buf); bzero(buf,128); } send(so, "250 Message accepted for delivery\n", 34, 0); status=4; }else{ send(so, "502 Error: command not implemented\n", 35, 0); } if(status==4){ printf("erhalten:\nHelo: %s\nMail From: %s\nRCPT to: %s\ndata\n%s\n",helo,from,to,data); int status2=0; int sock; struct hostent * host = gethostbyname("localhost"); if(host){ struct sockaddr_in server; struct in_addr a; unsigned long addr; if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) perror("client: socket"); memset(&server,0,sizeof(server)); bcopy(*host->h_addr_list,(char*)&a,sizeof(a)); addr=inet_addr(inet_ntoa(a)); memcpy((char *)&server.sin_addr, &addr, sizeof(addr)); server.sin_family = AF_INET; server.sin_port = htons(25); if(connect(sock,(struct sockaddr*)&server,sizeof(server))<0) perror("client: connect"); while(status2<4){ bzero(buf,128); switch(status2){ case 0: if(read(sock,buf,127)<0) perror("ERROR: reading"); printf("%s",buf); strcpy(text,"helo "); strcat(text,helo); break; case 1: strcpy(text,"mail from:"); strncat(text,from,strlen(from)); break; case 2: break; case 3: strcpy(text,""); strncat(text,data,strlen(data)-1); break; } if(status2==3){ send(sock, "data\015\012", 6, 0); if(read(sock,buf,127)<0) perror("ERROR: reading"); printf("%s",buf); char * tok; tok = strtok(data,"\012"); while(tok!=NULL){ strcpy(text,tok); strcat(text,"\012"); send(sock, text, strlen(text), 0); tok=strtok(NULL,"\012"); } send(sock, ".\015\012",3, 0); if(read(sock,buf,127)<0) perror("ERROR: reading"); printf("%s",buf); } if(status2==2){ char * tok; tok = strtok(to,","); while(tok!=NULL){ strcpy(text,"rcpt to:"); strcat(text,tok); strcat(text,"\015\012"); send(sock, text, strlen(text), 0); if(read(sock,buf,127)<0) perror("ERROR: reading"); printf("%s",buf); tok=strtok(NULL,","); } } else if(status2<2){ strcat(text,"\015\012"); send(sock, text, strlen(text), 0); if(read(sock,buf,127)<0) perror("ERROR: reading"); printf("%s",buf); } status2++; } close(sock); } else perror("host unreacheble\n"); helo=""; from=""; to=""; data=""; host=NULL; status=0; } }}