/* myserver.c */ #include #include #include #include #include #include #include #include #include #include /* Linux/UNIX */ #include /* Linux/UNIX */ #include #include #include #include #include #include #define MAXCHAR 1000 #define BUF 1024 char *verzeichnis; // Entfernt das \n und macht \0 daraus void remN(char *s) { char *p2 = s; while(*s != '\0') { if(*s != '\t' && *s != '\n') { *p2++ = *s++; } else { ++s; } } *p2 = '\0'; } //Checkt ob ein dir bereits existiert bool dirExists(const char path[300]){ struct stat st = {0}; char cwd[300]; if (getcwd(cwd, sizeof(cwd)) != NULL) { //printf("Current working dir: %s\n", cwd); } else { perror("getcwd() error"); } strcat(cwd, path); if (stat(cwd, &st) == 0) { printf("\x1b[32mDir: %s exists!\x1b[0m\n", cwd); return true; }else { printf("\x1b[31mDir: %s gibt es NICHT!\x1b[0m\n", cwd); return false; } } //Erstellt ein Dir wenn nicht bereits vorhanden void createDir(const char dir[]){ if(dirExists(dir) == false){ char cwd[300]; if (getcwd(cwd, sizeof(cwd)) != NULL) { //printf("Current working dir: %s\n", cwd); } else { perror("getcwd() error"); } strcat(cwd, dir); if(mkdir(cwd, 0700) == -1) { printf("\x1b[31mFailed to create %s\x1b[0m\n", cwd); perror("mkdir"); exit(EXIT_FAILURE); } else{ printf("\x1b[33mCreated directory: %s\x1b[0m\n", cwd); } } } // Die Denyfiles werden gelöscht -1 ist error int stopDenyUser(char username[10]){ char cwd[300]; if (getcwd(cwd, sizeof(cwd)) != NULL) { //printf("Current working dir: %s\n", cwd); } else { perror("getcwd() error"); } strcat(cwd, "/"); strcat(cwd, verzeichnis); strcat(cwd, "/deny/"); strcat(cwd, username); DIR *d = opendir(cwd); size_t path_len = strlen(cwd); int r = -1; if (d) { struct dirent *p; r = 0; while (!r && (p=readdir(d))) { int r2 = -1; char *buf; size_t len; /* Skip the names "." and ".." as we don't want to recurse on them. */ if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) continue; len = path_len + strlen(p->d_name) + 2; buf = malloc(len); if (buf) { struct stat statbuf; snprintf(buf, len, "%s/%s", cwd, p->d_name); if (!stat(buf, &statbuf)) { if (S_ISDIR(statbuf.st_mode)) r2 = stopDenyUser(buf); else r2 = unlink(buf); } free(buf); } r = r2; } closedir(d); } if (!r) r = rmdir(cwd); return r; } // Zählt wv denys ein user bereits hat int countDenyUser(char username[10]){ char dir[50]; strcpy(dir, "/"); strcat(dir, verzeichnis); strcat(dir, "/deny/"); strcat(dir, username); if (dirExists(dir) == false) { printf("\x1b[31mDIR Exists NICHT!\x1b[0m\n"); return 0; }else { int file_count = 0; DIR * dirp; struct dirent * entry; char cwd[1000]; if (getcwd(cwd, sizeof(cwd)) != NULL) { //printf("Current working dir: %s\n", cwd); } else { perror("getcwd() error"); } strcat(cwd, "/"); strcat(cwd, verzeichnis); strcat(cwd, "/deny/"); strcat(cwd, username); dirp = opendir(cwd); /* 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; } } // Wenn der User 3 Deny Files hat, ist er gesperrt und es kommt true zurück bool userDenied(char username[10]){ if (countDenyUser(username) == 3) { printf("\x1b[31mUser: %s ist gesperrt!\x1b[0m\n", username); return true; }else { printf("\x1b[32mUser: %s ist NICHT gesperrt!\x1b[0m\n", username); return false; } } // Erstellt ein Deny User eintrag void createDenyUser(char username[10]){ char filename[1000]; strcpy(filename, "/"); strcat(filename, verzeichnis); strcat(filename, "/deny/"); strcat(filename, username); createDir(filename); FILE *fp; // Datum besorgen char timeStr[22]; time_t now = time(NULL); struct tm *t = localtime(&now); strftime(timeStr, sizeof(timeStr)-1, "%H:%M:%S", t); char cwd[300]; if (getcwd(cwd, sizeof(cwd)) != NULL) { //printf("Current working dir: %s\n", cwd); } else { perror("getcwd() error"); } // Filename erstellen strcpy(filename, cwd); strcat(filename, "/"); strcat(filename, verzeichnis); strcat(filename, "/deny/"); strcat(filename, username); strcat(filename,"/"); strcat(filename,timeStr); strcat(filename, ".txt"); // File erstellen fp = fopen(filename, "w"); if(fp == NULL){ perror("fopen"); } fprintf(fp, "DENY"); fclose(fp); } // True wenn der user wieder zugelassen werden darf bool checkDeniedUser(char username[10]){ time_t now; time(&now); struct tm*local = localtime(&now); int readHour = 0, readMinutes = 0, readSekundes = 0; char cwd[1000]; if (getcwd(cwd, sizeof(cwd)) != NULL) { //printf("Current working dir: %s\n", cwd); } else { perror("getcwd() error"); } strcat(cwd, "/"); strcat(cwd, verzeichnis); strcat(cwd, "/deny/"); strcat(cwd, username); DIR *d; struct dirent *dir; d = opendir(cwd); if (d) { while ((dir = readdir(d)) != NULL) { if(strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0){ //printf("%s\n", dir->d_name); sscanf(dir->d_name, "%2d:%2d:%2d", &readHour, &readMinutes, &readSekundes); struct tm breakdown = {0}; breakdown.tm_sec = readSekundes; breakdown.tm_hour = readHour; breakdown.tm_min = readMinutes; breakdown.tm_year = local->tm_year; breakdown.tm_mon = local->tm_mon; breakdown.tm_mday = local->tm_mday; time_t result; if ((result = mktime(&breakdown)) == (time_t)-1) { fprintf(stderr, "Could not convert time input to time_t\n"); perror("checkDeniedUser Read time from file"); } double diff_t; diff_t = difftime(now, result); printf("\x1b[34mZeitdifferenz: %f\x1b[0m\n", diff_t); if (diff_t >= 300 || diff_t <= -300) //300 = 5min { return true; } } } closedir(d); } return false; } 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); while ((entry = readdir(dirp)) != NULL) { if (entry->d_type == DT_REG) { file_count++; } } closedir(dirp); return file_count; } int login_user(char username[10], char pw[50]){ //////////////////////////////////////////////////////////////////////////// // LDAP config // anonymous bind with user and pw empty const char *ldapUri = "ldap://ldap.technikum-wien.at:389"; const int ldapVersion = LDAP_VERSION3; // read username (bash: export ldapuser=) char ldapBindUser[256]; char rawLdapUser[128]; strcpy(rawLdapUser, username); sprintf(ldapBindUser, "uid=%s,ou=people,dc=technikum-wien,dc=at", rawLdapUser); // read password (bash: export ldappw=) char ldapBindPassword[256]; strcpy(ldapBindPassword, pw); // search settings const char *ldapSearchBaseDomainComponent = "dc=technikum-wien,dc=at"; const char *ldapSearchFilter = "(uid=if20b20*)"; ber_int_t ldapSearchScope = LDAP_SCOPE_SUBTREE; const char *ldapSearchResultAttributes[] = {"uid", "cn", NULL}; // general int rc = 0; // return code //////////////////////////////////////////////////////////////////////////// // setup LDAP connection // https://linux.die.net/man/3/ldap_initialize LDAP *ldapHandle; rc = ldap_initialize(&ldapHandle, ldapUri); if (rc != LDAP_SUCCESS) { fprintf(stderr, "ldap_init failed\n"); return 0; } printf("\x1b[32mconnected to LDAP server %s\x1b[0m\n", ldapUri); //////////////////////////////////////////////////////////////////////////// // set verison options // https://linux.die.net/man/3/ldap_set_option rc = ldap_set_option( ldapHandle, LDAP_OPT_PROTOCOL_VERSION, // OPTION &ldapVersion); // IN-Value if (rc != LDAP_OPT_SUCCESS) { // https://www.openldap.org/software/man.cgi?query=ldap_err2string&sektion=3&apropos=0&manpath=OpenLDAP+2.4-Release fprintf(stderr, "ldap_set_option(PROTOCOL_VERSION): %s\n", ldap_err2string(rc)); ldap_unbind_ext_s(ldapHandle, NULL, NULL); return 0; } //////////////////////////////////////////////////////////////////////////// // start connection secure (initialize TLS) // https://linux.die.net/man/3/ldap_start_tls_s // int ldap_start_tls_s(LDAP *ld, // LDAPControl **serverctrls, // LDAPControl **clientctrls); // https://linux.die.net/man/3/ldap // https://docs.oracle.com/cd/E19957-01/817-6707/controls.html // The LDAPv3, as documented in RFC 2251 - Lightweight Directory Access // Protocol (v3) (http://www.faqs.org/rfcs/rfc2251.html), allows clients // and servers to use controls as a mechanism for extending an LDAP // operation. A control is a way to specify additional information as // part of a request and a response. For example, a client can send a // control to a server as part of a search request to indicate that the // server should sort the search results before sending the results back // to the client. rc = ldap_start_tls_s( ldapHandle, NULL, NULL); if (rc != LDAP_SUCCESS) { fprintf(stderr, "ldap_start_tls_s(): %s\n", ldap_err2string(rc)); ldap_unbind_ext_s(ldapHandle, NULL, NULL); return 0; } //////////////////////////////////////////////////////////////////////////// // bind credentials // https://linux.die.net/man/3/lber-types // SASL (Simple Authentication and Security Layer) // https://linux.die.net/man/3/ldap_sasl_bind_s // int ldap_sasl_bind_s( // LDAP *ld, // const char *dn, // const char *mechanism, // struct berval *cred, // LDAPControl *sctrls[], // LDAPControl *cctrls[], // struct berval **servercredp); BerValue bindCredentials; bindCredentials.bv_val = (char *)ldapBindPassword; bindCredentials.bv_len = strlen(ldapBindPassword); BerValue *servercredp; // server's credentials rc = ldap_sasl_bind_s( ldapHandle, ldapBindUser, LDAP_SASL_SIMPLE, &bindCredentials, NULL, NULL, &servercredp); if (rc != LDAP_SUCCESS) { fprintf(stderr, "LDAP bind error: %s\n", ldap_err2string(rc)); ldap_unbind_ext_s(ldapHandle, NULL, NULL); return 0; } //////////////////////////////////////////////////////////////////////////// // perform ldap search // https://linux.die.net/man/3/ldap_search_ext_s // _s : synchronous // int ldap_search_ext_s( // LDAP *ld, // char *base, // int scope, // char *filter, // char *attrs[], // int attrsonly, // LDAPControl **serverctrls, // LDAPControl **clientctrls, // struct timeval *timeout, // int sizelimit, // LDAPMessage **res ); LDAPMessage *searchResult; rc = ldap_search_ext_s( ldapHandle, ldapSearchBaseDomainComponent, ldapSearchScope, ldapSearchFilter, (char **)ldapSearchResultAttributes, 0, NULL, NULL, NULL, 500, &searchResult); if (rc != LDAP_SUCCESS) { fprintf(stderr, "LDAP search error: %s\n", ldap_err2string(rc)); ldap_unbind_ext_s(ldapHandle, NULL, NULL); return 0; } // https://linux.die.net/man/3/ldap_count_entries printf("\x1b[34mTotal results: %d\x1b[0m\n", ldap_count_entries(ldapHandle, searchResult)); //////////////////////////////////////////////////////////////////////////// // get result of search // https://linux.die.net/man/3/ldap_first_entry // https://linux.die.net/man/3/ldap_next_entry LDAPMessage *searchResultEntry; for (searchResultEntry = ldap_first_entry(ldapHandle, searchResult); searchResultEntry != NULL; searchResultEntry = ldap_next_entry(ldapHandle, searchResultEntry)) { ///////////////////////////////////////////////////////////////////////// // Base Information of the search result entry // https://linux.die.net/man/3/ldap_get_dn printf("\x1b[35mDN: %s\x1b[0m\n", ldap_get_dn(ldapHandle, searchResultEntry)); ///////////////////////////////////////////////////////////////////////// // Attributes // https://linux.die.net/man/3/ldap_first_attribute // https://linux.die.net/man/3/ldap_next_attribute // // berptr: berptr, a pointer to a BerElement it has allocated to keep // track of its current position. This pointer should be passed // to subsequent calls to ldap_next_attribute() and is used to // effectively step through the entry's attributes. BerElement *ber; char *searchResultEntryAttribute; for (searchResultEntryAttribute = ldap_first_attribute(ldapHandle, searchResultEntry, &ber); searchResultEntryAttribute != NULL; searchResultEntryAttribute = ldap_next_attribute(ldapHandle, searchResultEntry, ber)) { BerValue **vals; if ((vals = ldap_get_values_len(ldapHandle, searchResultEntry, searchResultEntryAttribute)) != NULL) { for (int i = 0; i < ldap_count_values_len(vals); i++) { printf("\t\x1b[35m%s: %s\x1b[0m\n", searchResultEntryAttribute, vals[i]->bv_val); if(strcmp(searchResultEntryAttribute,"uid") == 0){ if(strcmp(vals[i]->bv_val,rawLdapUser) == 0){ printf("\n\n\x1b[32mGEFUNDEN!!!!!!!!!!!!!!!!!\x1b[0m\n\n"); // Free Memory ldap_value_free_len(vals); ldap_memfree(searchResultEntryAttribute); if (ber != NULL){ ber_free(ber, 0); } printf("\n"); ldap_msgfree(searchResult); ldap_unbind_ext_s(ldapHandle, NULL, NULL); return 1; } } } ldap_value_free_len(vals); } // free memory ldap_memfree(searchResultEntryAttribute); } // free memory if (ber != NULL) { ber_free(ber, 0); } printf("\n"); } // free memory ldap_msgfree(searchResult); //////////////////////////////////////////////////////////////////////////// // https://linux.die.net/man/3/ldap_unbind_ext_s // int ldap_unbind_ext_s( // LDAP *ld, // LDAPControl *sctrls[], // LDAPControl *cctrls[]); ldap_unbind_ext_s(ldapHandle, NULL, NULL); return 0; } void *threadFun(void *arg){ int new_socket = *((int *)arg); char buffer[BUF]; pthread_detach(pthread_self()); if(new_socket > 0){ strcpy(buffer, "Welcome to Lukas & Georgs Server, Please type to login:\n"); send(new_socket, buffer, strlen(buffer),0); } bool login = false; do { int size = recv (new_socket, buffer, BUF-1, 0); if( size > 0) { buffer[size] = '\0'; if (login == false) { // Do login if (strncmp("login", buffer, 5) == 0) { char delimiter[] = ";"; char *ptr; //den buffer mit dem seperator splitten ptr = strtok(buffer, delimiter); int counter = 0; char username[10]; char pw[50]; while(ptr != NULL) { if (counter == 1) { strcpy(username, ptr); }else if(counter == 2) { strcpy(pw, ptr); } counter = counter + 1; // naechsten Abschnitt erstellen ptr = strtok(NULL, delimiter); } if(login_user(username, pw) == 1){ printf("\x1b[32mUser: %s hat den Login geschafft!!\x1b[0m\n", username); if(checkDeniedUser(username) == true){ stopDenyUser(username); } if(userDenied(username) == true){ //ERR an den client zurücksenden char err[] = "Client Gesperrt"; send(new_socket , err , strlen(err) , 0 ); }else{ //OK an den client zurücksenden char suc[] = "OK"; login = true; send(new_socket , suc , strlen(suc) , 0 ); stopDenyUser(username); } }else { printf("\x1b[31mUser: %s hat den Login NICHT geschafft!!\x1b[0m\n", username); if(userDenied(username) == false){ createDenyUser(username); //ERR an den client zurücksenden char err[] = "ERR"; send(new_socket , err , strlen(err) , 0 ); }else{ //ERR an den client zurücksenden char err[] = "Client Gesperrt"; send(new_socket , err , strlen(err) , 0 ); if(checkDeniedUser(username) == true){ stopDenyUser(username); } } } } }else{// Is logedin // Ü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 sender[10] = ""; char empfaenger[10] = ""; char betreff[82] = ""; //timestamp als ersten teil der id erstellen char ts[22]; time_t now = time(NULL); strftime(ts, 22, "%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[300] = "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[300] = "./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[10] = ""; char nid[82] = ""; char p[22] = ""; char path[300] = ""; 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[10] = ""; char nid[82] = ""; char betreff[82] = ""; char folder[22] = ""; 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[10] = ""; char p[22] = ""; char path[300] = ""; 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("\x1b[33mClient closed remote socket\x1b[0m\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; 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); //Verzeichnisse erstellen verzeichnis = argv[2]; char tmpVerzeichnis[300]; strcpy(tmpVerzeichnis, "/"); strcat(tmpVerzeichnis, verzeichnis); createDir(tmpVerzeichnis); char denyDir[300]; strcpy(denyDir, tmpVerzeichnis); strcat(denyDir, "/deny"); createDir(denyDir); char postausgang[300]; char posteingang[300]; strcpy(postausgang, tmpVerzeichnis); strcat(postausgang, "/postausgang"); strcpy(posteingang, tmpVerzeichnis); strcat(posteingang, "/posteingang"); createDir(postausgang); createDir(posteingang); pthread_t tid; while (1) { printf("\x1b[34mWaiting for connections...\x1b[0m\n"); new_socket = accept ( create_socket, (struct sockaddr *) &cliaddress, &addrlen ); if (new_socket > 0) { printf ("\x1b[32mClient connected from %s:%d...\x1b[0m\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; }