#include /* for printf() and fprintf() */ #include /* for socket(), bind(), and connect() */ #include /* for sockaddr_in and inet_ntoa() */ #include /* for atoi() and exit() */ #include /* for memset() */ #include /* for close() */ #include #include #include #include #include #include "server.h" #define MAXPENDING 5 /* Maximum outstanding connection requests */ #define MAX_THREADS 2 /*anzahl maximaler Nutzer */ #define DOMAIN "bla.com" #define BEGRUSSUNG "220 " DOMAIN " moin\n" #define FALSCHE_REIHENFOLGE "503 Bad sequence of commands\n" #define FALSCHES_KOMMANDO "502 Command not implemented\n" #define FALSCHER_PARAMETER "504 Command parameter not implemented\n" #define HELO_OK "250 " DOMAIN " OK\n" #define STANDARD_OK "250 OK\n" #define DATA_OK "354 Start mail input\n" /* defintion der zustande */ #define Z_VERBUNDEN 1 #define Z_HELO 2 #define Z_MAIL 3 #define Z_RECEIPT 4 #define Z_DATA 5 #define Z_QUIT 6 /* anzahl der zustande */ #define BEF_ANZ 6 int servSock; /* Socket descriptor fur server */ char join_thread[MAX_THREADS]; //feld aktiver threads pthread_t threads[MAX_THREADS]; //fehlt abgearbetieter threads pthread_mutex_t mx_join; //semeaphore für exkl. zugriff /* zu jedem zustand gehört ein befehl */ struct zustaende { int zustand; char *kommando; }; struct zustaende befehle[]={ {Z_VERBUNDEN, " "}, {Z_HELO, "HELO"}, {Z_MAIL, "MAIL"}, {Z_RECEIPT, "RCPT"}, {Z_DATA, "DATA"}, {Z_QUIT, "QUIT"} }; /* */ int daten_lesen(int fd, char* buf, int max_len) { struct timeval tv; // struktur für zeitwert fd_set fds; int ret, len; FD_ZERO(&fds); FD_SET(fd, &fds); tv.tv_sec = 10; //10sekunden tv.tv_usec = 0; //plus 0 mikrosekunden ret = select(fd + 1, &fds, NULL, NULL, &tv); //wartet auf ereignis if(ret == 0) return 0; if(ret < 0) { perror("select"); return -1; } memset(buf, 0, max_len); //bufffer wird mit 0 initialisiert len = read(fd, buf, max_len); //lesen von socket und rückgabe anzahl gelesener bytes if(len <=0)return 0; buf[ max_len -1 ]='\0'; return len; } int daten_schreiben(int sock, char* buffer, int len) { int ret=0; ret = write(sock, buffer, len); return ret; } /* baut die verbindung korrekt ab */ int verbindungsabbau(int sock) { int id = pthread_self(); //ermitteln der eigenen Thread ID int i, ret=0; close(sock); //schliessen des Sockets printf("beenden!\n"); /* locked */ pthread_mutex_lock( &mx_join ); for(i=0; i 0 && copy[0] == 0x20) { ptr = strsep(©, " "); len -= (copy-ptr); } if(len < 5) return -1; //abschneiden bis zum @ ptr = strsep(©, "@"); if(ptr == NULL) //kein @ vorhanden return -1; if( (copy-ptr) == 1 ) //@ erstes zeichen return -1; len -= (copy-ptr); if(len <= 0) return -1; //prufen vor dem @ ptr2 = strsep(&ptr, "\"\\;:"); if(ptr2 != NULL) //illegales zeichen gefunden return -1; //prufen nach dem @ ptr = strsep(©, "@\"\\;:"); if(ptr != NULL) //illegales zeichen gefunden return -1; //abschneiden bis zum . ptr = strsep(©, "."); if(ptr == NULL) //kein . vorhanden return -1; if( (copy-ptr) == 1 ) //. erstes zeichen nach @ return -1; len -= (copy-ptr); if(len <= 0) return -1; return 0; } /*uberpruft die empfangenen Kommandos eines Clients aus Syntax */ int prufen(int sock, char* eing, int len, int *zustand) { int i=0, bef_len=0, ret=0; for(i=0; i\n", argv[0]); return -1; } smtpServPort = atoi(argv[1]); /* erstes argument: server port */ /* Socket fur eingehende Verbindungen starten */ if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { perror("socket"); return -1; } /* Construct local address structure */ memset(&smtpServAddr, 0, sizeof(smtpServAddr)); /* Zero out structure */ smtpServAddr.sin_family = AF_INET; /* Internet address family */ smtpServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ smtpServAddr.sin_port = htons(smtpServPort); /* Local port */ /* Bind an lokale adresse */ if (bind(servSock, (struct sockaddr *) &smtpServAddr, sizeof(smtpServAddr)) < 0) { perror("bind() failed"); return -1; } /* socket wird zyklisch abgehort */ if (listen(servSock, MAXPENDING) < 0) { perror("listen() failed"); return -1; } for (;;) /* endloses warten auf Clienten */ { /* locked */ pthread_mutex_lock( &mx_join ); for(i=0; i