/* myserver.c */ #include #include #include #include #include #include #include #include #include #include /* Linux/UNIX */ #include /* Linux/UNIX */ #include #include #include #include #define MAXCHAR 1000 #define BUF 1024 bool startsWith(const char *pre, const char *str) { size_t lenpre = strlen(pre), lenstr = strlen(str); return lenstr < lenpre ? false : memcmp(pre, str, lenpre) == 0; } void mstore_data(const char *filepath, const char *data) { FILE *fp = fopen(filepath, "ab"); if (fp != NULL) { fputs(data, fp); fclose(fp); } } int countFiles(char path[]) { int file_count = 0; DIR * dirp; struct dirent * entry; dirp = opendir(path); /* There should be error handling after this */ while ((entry = readdir(dirp)) != NULL) { if (entry->d_type == DT_REG) { /* If the entry is a regular file */ file_count++; } } closedir(dirp); return file_count; } void *threadFun(void *arg){ int new_socket = *((int *)arg); char buffer[BUF]; pthread_detach(pthread_self()); if(new_socket > 0){ strcpy(buffer, "Welcome to myserver, Please enter your command:\n"); send(new_socket, buffer, strlen(buffer),0); } do { int size = recv (new_socket, buffer, BUF-1, 0); if( size > 0) { buffer[size] = '\0'; //Überprüfen welchen command der client eingegeben hat, // wenn command nicht zutreffend error zurücksenden if(startsWith("send", buffer) == true) { char delimiter[] = ";"; char *ptr; //den buffer mit dem seperator splitten ptr = strtok(buffer, delimiter); int counter = 0; char filename1[] = ""; char filename2[] = ""; char sender[8] = ""; char content[] = ""; char empfaenger[8] = ""; char betreff[80] = ""; char nid[100] = ""; //timestamp als ersten teil der id erstellen char ts[20]; time_t now = time(NULL); strftime(ts, 20, "%Y-%m-%d%H:%M:%S", localtime(&now)); //den gesplitteten buffer schritt für schritt durchgehen while(ptr != NULL) { //printf("Abschnitt gefunden: %s\n", ptr); //sender auslesen, ordner für sender erstellen, wenn nicht vorhanden if (counter == 1) { struct stat st = {0}; char dir[] = "./data/postausgang/"; strcat(dir, ptr); if (stat(dir, &st) == -1) { mkdir(dir, 0700); } strcat(sender, ptr); printf("1 %s \n", ptr); } //empfänger auslesen, ordner für empfänger erstellen, wenn nicht vorhanden if (counter == 2) { struct stat st2 = {0}; char dir2[] = "./data/posteingang/"; strcat(dir2, ptr); if (stat(dir2, &st2) == -1) { mkdir(dir2, 0700); } strcat(empfaenger, ptr); printf("2 %s \n" , ptr); } //betreff auslesen, id (ts) fertigstellen, //2 dateien erstellen für sender und empfänger mit ts als filename if (counter == 3) { //printf("3 %s \n", ptr); strcat(betreff, ptr); strcat(ts, betreff); //Pfad erstellen für den sender und file erstellen char fb[100] = "touch ./data/postausgang/"; strcat(fb, "/"); strcat(fb, sender); strcat(fb, "/"); strcat(fb, ts); printf("PATH: %s \n", fb); system(fb); //Pfad erstellen für den empfänger und file erstellen strcpy(fb, "touch ./data/posteingang/"); strcat(fb, "/"); strcat(fb, empfaenger); strcat(fb, "/"); strcat(fb, ts); printf("PATH: %s \n", fb); system(fb); } //buffer in files schreiben if (counter == 4) { //printf("4 %s \n", ptr); //file content für den empfänger erstellen char fp[100] = "./data/posteingang/"; char content1[1000] = ""; strcpy(content1, "ID: "); strcat(content1, ts); strcat(content1, "\n"); strcat(content1, "Received from: "); strcat(content1, sender); strcat(content1, "\n"); strcat(content1, "Betreff: "); strcat(content1, betreff); strcat(content1, "\n"); strcat(content1, "Message: "); strcat(content1, ptr); strcat(fp, empfaenger); strcat(fp, "/"); strcat(fp, ts); //content in das file storen mstore_data(fp, content1); //file content für den sender erstellen char content2[1000] = ""; strcpy(content2, "ID: "); strcat(content2, ts); strcat(content2, "\n"); strcat(content2, "Sent to: "); strcat(content2, empfaenger); strcat(content2, "\n"); strcat(content2, "Betreff: "); strcat(content2, betreff); strcat(content2, "\n"); strcat(content2, "Message: "); strcat(content2, ptr); strcpy(fp, "./data/postausgang/"); strcat(fp, sender); strcat(fp, "/"); strcat(fp, ts); //content2 in das file storen mstore_data(fp, content2); } counter = counter + 1; // naechsten Abschnitt erstellen ptr = strtok(NULL, delimiter); } //printf ("\n Message received: \n %s", buffer); //OK an den client zurücksenden char suc[] = "OK"; send(new_socket , suc , strlen(suc) , 0 ); } else if(startsWith("del", buffer) == true) { printf("delete: %s ", buffer); char delimiter[] = ";"; char *ptr; ptr = strtok(buffer, delimiter); int counter = 0; char username[8] = ""; char nid[80] = ""; char p[20] = ""; char path[100] = ""; while(ptr != NULL) { //username speichern if(counter == 1) { strcat(username, ptr); } //post ein- oder ausgang speichern if(counter == 2) { strcpy(p, ptr); } //nid speichern, den path string erstellen, rm -rf path ausführen if(counter == 3) { strcat(nid, ptr); if(strcmp(p, "postausgang") == 0) { strcpy(path, "rm -rf ./data/postausgang/"); } if(strcmp(p, "posteingang") == 0) { strcpy(path, "rm -rf ./data/posteingang/"); } strcat(path, username); strcat(path, "/"); strcat(path, nid); system(path); } counter = counter + 1; // naechsten Abschnitt erstellen ptr = strtok(NULL, delimiter); } //OK an client zurücksenden char resBuff[BUF] = "OK\n"; send(new_socket, resBuff, strlen(resBuff),0); strcpy(buffer, ""); } //read else if(startsWith("read", buffer) == true) { char delimiter[] = ";"; char *ptr; ptr = strtok(buffer, delimiter); int counter = 0; char username[8] = ""; char nid[80] = ""; char betreff[80] = ""; char folder[20] = ""; while(ptr != NULL) { if(counter == 1) { //username speichern strcat(username, ptr); } //postein- oder ausgang speichern if(counter == 2) { strcpy(folder, ptr); } //nid speichern, file mit dem path lesen und an client zzrücksenden if(counter == 3) { //nid strcat(nid, ptr); strcpy(betreff, nid); char filename[] = "./data/"; strcat(filename, folder); strcat(filename, "/"); strcat(filename, username); strcat(filename, "/"); strcat(filename, nid); printf("PATH: %s", filename); FILE *ptr_file; char buf[1000]; char res[1000]; ptr_file = fopen(filename,"r"); if (!ptr_file) perror("File Open error!"); while (fgets(buf,1000, ptr_file)!=NULL) { strcat(res, buf); } fclose(ptr_file); // and send that buffer to client printf("%s", res); send(new_socket , res, strlen(res), 0 ); } counter = counter + 1; // naechsten Abschnitt erstellen ptr = strtok(NULL, delimiter); } } //list else if(startsWith("list", buffer) == true) { char delimiter[] = ";"; char *ptr; ptr = strtok(buffer, delimiter); int counter = 0; char username[8] = ""; char p[20] = ""; char path[100] = ""; while(ptr != NULL) { //username speichern if(counter == 1) { strcat(username, ptr); } //postein - oder ausgang speichern if(counter == 2) { strcat(p, ptr); if(strcmp(p, "postausgang") == 0) { strcpy(path, "./data/postausgang/"); } if(strcmp(p, "posteingang") == 0) { strcpy(path, "./data/posteingang/"); } strcat(path, username); strcat(path, "/"); DIR *d; struct dirent *dir; char filenames[1000] = ""; //Messages zählen int fc = countFiles(path); char str[1000]; //int in string konverten sprintf(str, "%d", fc); strcat(filenames, str); strcat(filenames, ";"); //file lesen d = opendir(path); if (d) { while ((dir = readdir(d)) != NULL) { strcat(filenames, dir->d_name); strcat(filenames, ";"); } closedir(d); //an client senden send(new_socket , filenames , strlen(filenames) , 0 ); strcpy(buffer, ""); } } counter = counter + 1; // naechsten Abschnitt erstellen ptr = strtok(NULL, delimiter); } }else { printf("error"); char err[] = "ERR"; send(new_socket , err , strlen(err) , 0 ); } //printf ("\n content: \n %s", buffer); } else if (size == 0) { printf("Client closed remote socket\n"); break; } else { perror("recv error"); char err[] = "ERR"; send(new_socket , err , strlen(err) , 0 ); } } while (strncmp (buffer, "quit", 4) != 0); close (new_socket); pthread_exit(NULL); } int main (int argc, char **argv) { int create_socket, new_socket; socklen_t addrlen; char buffer[BUF]; int size; struct sockaddr_in address, cliaddress; if( argc < 3 ){ printf("Usage: %s S Port Verzeichniss\n", argv[0]); exit(EXIT_FAILURE); } create_socket = socket (AF_INET, SOCK_STREAM, 0); memset(&address,0,sizeof(address)); address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons (atoi(argv[1])); if (bind ( create_socket, (struct sockaddr *) &address, sizeof (address)) != 0) { perror("bind error"); return EXIT_FAILURE; } listen (create_socket, 5); addrlen = sizeof (struct sockaddr_in); //Verzeichniss erstellen mkdir(argv[2], 0711); pthread_t tid; int i = 0; while (1) { printf("Waiting for connections...\n"); new_socket = accept ( create_socket, (struct sockaddr *) &cliaddress, &addrlen ); if (new_socket > 0) { printf ("Client connected from %s:%d...\n", inet_ntoa (cliaddress.sin_addr),ntohs(cliaddress.sin_port)); } if (pthread_create(&tid, NULL, threadFun, &new_socket) != 0) { perror("Failed to create thread"); exit(EXIT_FAILURE); } } close (create_socket); return EXIT_SUCCESS; }