int openSHM() { infoPrint("./catalog.c -----------------------------------------------openSHM(){"); //Shared Memory öffnen fd = shm_open(SHMEM_NAME, O_RDONLY, (mode_t)0600); if (fd < 0) { perror("SHMEM_NAME ist nicht angelegt"); return -1; } infoPrint("Shered Memory vom server aus geöffnet"); //Grösse setzen ftruncate(fd,shmGroesse); infoPrint("Shered Memory Größe gesetzt"); //In Adressraum einbinden Frage = mmap(NULL, shmGroesse, PROT_READ, MAP_SHARED, fd, 0); if(Frage == MAP_FAILED) { perror("SHMEM_NAME kann nicht in Adressraum eingebunden werden"); } infoPrint("Katalog geladen!!!"); infoPrint("./catalog.c -----------------------------------------------openSHM()}"); return fd; }
bool Drawing::init() { //Initialization flag bool success = true; //Initialize SDL if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { //printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() ); infoPrint("SDL could not initialize! SDL_Error:"+string(SDL_GetError())+"!"); success = false; } else { //Create window //cout << "Window Created" << endl; infoPrint("Window Created!"); Window = SDL_CreateWindow( "RayTracing System", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, ScreenWidth, ScreenHeight, SDL_WINDOW_SHOWN ); if( Window == NULL ) { //printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() ); infoPrint("Window could not be created! SDL_Error:"+string(SDL_GetError())+"!"); success = false; } else { //Get window surface ScreenSurface = SDL_GetWindowSurface( Window ); } } return success; }
/** * Thread to handle connection in background and run echo_loop * param: struct client_data* **/ void* echo_thread(void* param) { char dst[INET6_ADDRSTRLEN]; struct client_data * data; data = (struct client_data*)param; /* RTFM: getnameinfo */ getnameinfo((struct sockaddr*)&data->addr, data->addrlen, dst, sizeof(dst), NULL, 0, NI_NUMERICHOST); infoPrint("Connection opened from %s",dst); echo_loop(data->sock); close(data->sock); infoPrint("Connection closed from %s", dst); free(data); pthread_exit(0); return NULL; }
/* * Funktion setzt den Serverport */ void set_port(char* port_str){ int port = atoi(port_str); if((port < 65535) && (port > 0)){ server_port = port; } else { infoPrint("Port muss zwischen 1 - 65535 sein!"); infoPrint("Es wird der Standardport 8111 verwendet"); server_port = 8111; } }
void catalogBrowser() { char *message = "BROWSE\n"; size_t messageLen = strlen(message); char *ptr; char readBuffer[1024]; int i; anzahl_dateien = 0; if(write(stdinPipe[1], message, messageLen) < messageLen) { perror("write"); } read(stdoutPipe[0], readBuffer, sizeof(readBuffer)); /* Ergebnis ausgeben */ infoPrint("Ausgabe des Kindprozesses BROWSE: %s\n", readBuffer); ptr = strtok(readBuffer, "\n"); /*String zerteilen*/ for(i = 0; ptr != NULL; i++) { strncpy (ups[i], ptr, sizeof(ups[1])); ptr = strtok(NULL, "\n"); anzahl_dateien++; } }
/* * Funktion liesst Kataloge aus */ int loadCatalogs(){ // BROWSE_CMD - Kataloge auflisten if(write(stdinPipe[1], BROWSE_CMD, strlen(BROWSE_CMD)) < strlen(BROWSE_CMD)){ errorPrint("Senden der Nachricht über Pipe fehlgeschlagen: "); return 1; } // Zeilenumbruch if(write(stdinPipe[1], "\n", 1) < 1){ errorPrint("Senden der Nachricht über Pipe fehlgeschlagen: "); return 2; } // Katalogname char* catalogname; // Zaehlvariable fuer Anzahl Kataloge int i = 0; int err = 0; while(err > -1){ // Daten aus dem Leseende von stdoutPipe lesen catalogname = readLine(stdoutPipe[0]); // pruefe ob Zeilenumbruch err = strcmp(catalogname, "\n"); if(err > -1){ // Katalog hinzufuegen addCatalog(catalogname, i); i++; } } infoPrint("Kataloge eingelesen: %i", i); return 0; }
// Der Server soll auf dem lokalen System nur einmal gestartet werden koennen. void setSingleInstance(int file){ // lege Datei an file = open("serverInstancePIDFile", O_WRONLY| O_CREAT, 0644); //entweder schreiben oder erstellen struct flock lock; // pruefe ob Datei anlegen erfolgreich if (file < 0) { debugPrint("Cannot create PID file"); exit(1); } debugPrint("Acquiring file write lock"); /* Important: lock before doing any IO */ lock.l_type = F_WRLCK; //Schreibsperre writelock lock.l_whence = SEEK_SET;//an den Dateianfang gesetzt lock.l_start = 0;//an Dateianfang gesetzt lock.l_len = 0; // fcntl - manipulate file descriptor // F_GETLK, F_SETLK and F_SETLKW are used to acquire, release, and test for the existence of record locks if (fcntl(file, F_SETLK, &lock) < 0) { //sperrt ganze Datei fctl(filedeskriptor unserer Datei, sperre setzen, Zeiger auf flock) infoPrint("Server läuft bereits.."); exit(1); } if (ftruncate(file, 0) < 0) { //file wird auf 0 bytes beschnitten infoPrint("Server läuft bereits.."); exit(1); } /*pid holen und in datei schreiben*/ char pidString[32]; snprintf(pidString, sizeof(pidString), "%d\n", (int) getpid()); if(write(file, pidString, strlen(pidString)) < strlen(pidString)){ perror("write"); } if (fsync(file) < 0) { debugPrint("fsync"); } }
/* * Funktion schliesst alle verwendeten Ressourcen und * beendet den Server */ void endServer(){ debugPrint("Beende Server."); // Nachricht an alle Clients senden - sofern welche angemeldet debugPrint("Sende Nachricht an Clients: Server wird beendet."); if(countUser() > 0){ PACKET close_server_packet; close_server_packet.header.type = RFC_ERRORWARNING; close_server_packet.header.length = htons(sizeof(ERROR)); //close_server_packet.content.error.errortype = ERR_SERVER_CLOSE; close_server_packet.content.error.errortype = ERR_FATAL; strncpy(close_server_packet.content.error.errormessage, "Server beendet", 100); // sende Nachricht sendToAll(close_server_packet); debugPrint("Nachricht ueber Serverende an alle Clients verschickt."); } // Socket schliessen if(close(server_socket) == 0){ debugPrint("Serversocket geschlossen."); } else { debugPrint("Konnte Serversocket nicht schliessen."); } // shared memorey // aus Adressraum entfernen munmap(shmData, shmLen); // Filedeskritpor SharedMemory schliessen close(shmHandle); // SharedMemory Objekt entfernen shm_unlink(SHMEM_NAME); debugPrint("Shared Memory entfernt."); // loader beenden if(kill(forkResult, SIGINT) == 0){ debugPrint("Loaderprozess beendet."); } else { debugPrint("Loaderprozess konnte nicht beendet werden."); } // SingleInstance-Datei schliessen und loeschen closeSingleInstance(SingleInstanceFile); if(remove("serverInstancePIDFile") == 0){ debugPrint("SingleInstanceFile geschlossen und geloescht."); } else { debugPrint("Konnte SingleInstanceFile nicht loeschen."); } infoPrint("bye ..."); exit(0); }
/** * Funktion wertet Startparameter aus * param argc - Anzahl der Startparameter * param argv - Startparameter */ void process_commands(int argc, char** argv) { debugPrint("Parsing command line options..."); // Standard Port 8111 char* server_port = { "8111" }; const char* short_options = "hvp:c"; struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "verbose", no_argument, 0, 'v' }, { "port", required_argument, 0, 'p' }, { "catalog", no_argument, 0, 'c' }, { NULL, 0, NULL, 0 } }; int opt_index = 0; int loop = 1; while(loop != 0){ int opt = getopt_long(argc, argv, short_options, long_options, &opt_index); switch(opt){ // zeige Hilfe case 'h': show_help(); exit(1); break; // Verbose case 'v': debugEnable(); infoPrint("debug Ausgabe aktiviert."); break; // Port case 'p': server_port = optarg; break; // Katalog case 'c': catalog_dir = optarg; break; case -1: loop = 0; break; // Option nicht bekannt default: break; } } // Setze Port set_port(server_port); }
void sigfunc(int sig) { char c[2]; if(sig != SIGINT) { return; } else { infoPrint("Wollen sie das Programm beenden (J/N) : "); read(STDIN_FILENO,c,sizeof(char)); if(c[0] != 'j' && c[0] != 'J') { infoPrint("Das Program wird fortgesetzt...\n"); return; } strncpy(errorMessage, "Der Server ist beendet!!!", sizeof(errorMessage)); quitServer(NO_ERROR, 0); } }
/* * Funktion zum Beenden des Servers */ void quitServer(int error, char message[MAX_ERRORMESSAGE]) { int i; int socket, userId; for (i = 0; i < MAX_PLAYER; i++) { socket = getSocketDescr(i); userId = getUserId(i); if(error == ERROR && i != 0 && userId != 99) { send_socket(socket, ErrorWarning, message , error); infoPrint("Schliesse SocketDescr.: %d", socket); close(socket); } } infoPrint("Beende den Server..."); remove("pid_server"); closeSHM(); /*Shared Memory schließen*/ infoPrint("Done!"); exit(0); }
void connect_socket_client(int *sock, char serv_addr[], char port[]){ struct addrinfo *addr_info, *p, hints; int ret; /**Set the socket at the beginning to -1 and change value if connection works!*/ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = 0 /** | AI_ADDRCONFIG */; /**RTFM: getaddrinfo */ ret = getaddrinfo(serv_addr, port, &hints, &addr_info); if (ret){ errorPrint("getaddrinfo: %s", gai_strerror(ret)); exit(1); } p = addr_info; while (p){ char dst[INET6_ADDRSTRLEN]; /**Create socket for found family */ *sock = socket(p->ai_family, p->ai_socktype, 0); /**RTFM: getnameinfo */ getnameinfo(p->ai_addr, p->ai_addrlen, dst, sizeof(dst), NULL, 0, NI_NUMERICHOST); /**Try to connect */ if (connect(*sock, p->ai_addr, p->ai_addrlen) == 0){ infoPrint("Connected"); break; }else{ errorPrint("Error, while trying %s",dst); } p = p->ai_next; } freeaddrinfo(addr_info); }
/* * Singnal handler * http://www.csl.mtu.edu/cs4411.ck/www/NOTES/signal/install.html */ void INThandler(int sig) { //Interrupt Handler char c = '0'; if(sig != SIGINT){ //wenn Signal kein Interrupt ist (bsp. hangup) debugPrint("Signal is not SIGINT."); return; } else { infoPrint("Wollen Sie den Server wirklich beenden? [j/n]: "); c = getchar(); if((c == 'j') || (c == 'J')){ debugPrint("Server soll beendet werden."); endServer(); exit(0); } else { debugPrint("Server soll nicht beendet werden."); return; } } }
/** * Copy all data from fd -> fd * using a buffer of 512 Byte **/ static void echo_loop(int fd) { int ret; static char buf[512]; while (1) { ret = read(fd, buf, sizeof(buf)); infoPrint("official readtest :-)/n"); if (ret == 0) { break; } if (ret < 0) { errorPrint("Cannot read: %s", strerror(errno)); break; } if (write(fd, buf, ret) < ret) { errorPrint("Cannot write: %s", strerror(errno)); break; } } }
/** Start des Servers * param argc Anzahl der Startparameter * param argv Startparameter */ int main(int argc, char ** argv) { // Der Server soll auf dem lokalen System nur einmal gestartet werden koennen. setSingleInstance(SingleInstanceFile); setProgName(argv[0]); // verarbeite Parameter process_commands(argc, argv); // reagiere auf Signal, u.a. STRG + C signal(SIGINT, INThandler); // gebe Gruppennamen aus infoPrint("\n\nServer Gruppe 04 Stroh, Steinbinder, Strohm\n"); // Spielerverwaltung initialisieren initSpielerverwaltung(); // Socket erstellen server_socket = openServerSocket(server_port); if(server_socket == -1){ errorPrint("Server Socket konnte nicht erstellt werden!"); endServer(); exit(0); } // Loader starten + Kataloge laden int loader_start_result = startLoader(); if(loader_start_result != 0){ errorPrint("Fehler beim Starten des Loaders: %i", loader_start_result); endServer(); exit(0); } int loader_load_catalogs_result = loadCatalogs(); if(loader_load_catalogs_result != 0){ errorPrint("Fehler beim Laden der Kataloge: %i", loader_load_catalogs_result); endServer(); exit(0); } // http://pubs.opengroup.org/onlinepubs/7908799/xsh/sem_init.html // Semaphor fuer Spielerliste / Punktestand initialisieren sem_init(&semaphor_score, 0, 0); // Score thread starten pthread_t score_thread; if(pthread_create(&score_thread, NULL, (void*)&score_main, NULL) == -1){ errorPrint("Score_thread konnte nicht erstellt werden!"); endServer(); exit(0); } // starte Login-Thread pthread_t login_thread; if(pthread_create(&login_thread, NULL, (void*)login_main(server_socket), NULL) == -1){ errorPrint("Login_thread konnte nicht erstellt werden!"); endServer(); exit(0); } // beende Server endServer(); return 0; }
int main(int argc, char ** argv) { char *server, *service; struct addrinfo *addr_info, *p, hints; int ret, i; int sockets[128]; int numsockets = 0; setProgName(argv[0]); /* For our infoPrint/errorPrint functions */ if (argc <= 1) { errorPrint("Simple Echo-Server"); errorPrint("Usage: %s [BINDADDR] [SERVICE]", argv[0]); errorPrint("Example: %s localhost 8080", argv[0]); exit(1); } if (argc == 3) { server = argv[1]; service = argv[2]; } else { server = NULL; service = argv[1]; } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE | AI_V4MAPPED; /* RTFM: getaddrinfo */ ret = getaddrinfo(server, service, &hints, &addr_info); if (ret) { errorPrint("Error in getaddrinfo: %s", gai_strerror(ret)); exit(1); } p = addr_info; while (p) { int s; char dst[INET6_ADDRSTRLEN]; char service[INET6_ADDRSTRLEN]; int on = 1; /* Create socket for found family */ s = socket(p->ai_family, p->ai_socktype, 0); if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { errorPrint("Error in setsockopt: %s", strerror(errno)); /* maybe not so fatal, continue */ } if (p->ai_family == AF_INET6) { if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { errorPrint("Error in setsockopt: %s", strerror(errno)); } } /* RTFM: getnameinfo */ getnameinfo(p->ai_addr, p->ai_addrlen, dst, sizeof(dst), service, sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV); infoPrint("Trying %s:%s ... ",dst, service); /* Try to bind socket */ if (bind(s, p->ai_addr, p->ai_addrlen) == 0) { if (listen(s, 1) < 0) { errorPrint("listen failed: %s", strerror(errno)); close(s); } else { infoPrint("bind successful"); sockets[numsockets++] = s; } } else { errorPrint("bind failed: %s", strerror(errno)); close(s); } p = p->ai_next; } freeaddrinfo(addr_info); infoPrint("Waiting for connections..."); accept_loop(sockets, numsockets); for (i=0; i<numsockets; i++) { close(sockets[i]); } return 0; }
/* * Hauptprogramm des Servers */ int main(int argc, char **argv) { unsigned short port = 54321; argc_cp = argc; argv_cp = argv; pid_t forkResult; char pfad[51]; char catalog[51]; /* * Semaphore initialisieren */ sem_init(&uno_semaphore, 0, 0); set_pid(); if(detect_para(&port, pfad, catalog) == -1) { exit(0); } /* *Verhalten des Servers bei Strg+C */ signal(SIGINT,sigfunc); infoPrint("gewählter Port: %d", port); infoPrint("gewählter Pfad: %s", pfad); infoPrint("gewählter Katalog: %s", catalog); /* *Den Programmnamen setzen */ setProgName(argv[0]); infoPrint("Server Gruppe 6/n"); infoPrint("Info: Der Server kann mit STRG-C beendet werden."); infoPrint("--------------------------------------------------------------------------------------------------------------\n"); /* *Socket erstellen */ start_network(port); /* *Pipe erstellen */ if(pipe(stdinPipe) == -1 || pipe(stdoutPipe) == -1) { perror("pipe"); } /* *Kindprozess erstellen */ forkResult = fork(); if(forkResult < 0) { perror("fork"); } /* *Im Kindprozess */ else if(forkResult == 0) { /* *Standardeingabekanal mit dem Pipekanal stdinPipe[0] verbinden */ if(dup2(stdinPipe[0], STDIN_FILENO) == -1) { perror("dup2(stdinPipe[0], STDIN_FILENO)"); } /*Standardausgabekanal mit dem Pipekanal stdinPipe[1] verbinden*/ if(dup2(stdoutPipe[1], STDOUT_FILENO) == -1) { perror("dup2(stdoutPipe[1], STDOUT_FILENO)"); } /* Schließen aller Pipe-Deskriptoren. * Nach dem exec kennt der Kindprozess diese nicht mehr und spricht * die Pipes selbst über stdin und stdout an. */ close(stdinPipe[0]); close(stdinPipe[1]); close(stdoutPipe[0]); close(stdoutPipe[1]); /* *Neues Programm läuft... */ execl("./loader", "loader", "-d", catalog, NULL); /* * ...oder auch nicht, dann war's aber ein Fehler */ perror("exec"); } close(stdinPipe[0]); close(stdoutPipe[1]); pthread_t login_thread_id; /* *Login Thread starten */ if((pthread_create(&login_thread_id, 0, (void*)&login_loop, &socket_desc)) != 0) { perror("Thread_create steht in main.c"); } pthread_t spielstand_thread_id; infoPrint("NACH LOGIN!!!"); /* *Spielstand Thread starten */ if((pthread_create(&spielstand_thread_id, NULL, (void*)&spielstand_thread_main, NULL)) != 0) { perror("Thread_create steht in main.c"); } /* * Warten auf das Ende des Spielstandthreads */ pthread_join(spielstand_thread_id, 0); /* *Server beenden */ quitServer(NO_ERROR, 0); return 0; }
void catalogLoader(char dateiname[MAX_DATEINAME]) { char message[MAX_DATEINAME+5]; char readBuffer[1024]; char *ptr; int i, j=0; memset (readBuffer, 0, sizeof(readBuffer)); strncpy (message, "LOAD ", sizeof (message)); strcat (message, dateiname); strcat (message, "\n"); infoPrint("Message: %s", message); size_t messageLen = strlen(message); if(write(stdinPipe[1], message, messageLen) < messageLen) { perror("write"); } //Anzahl der Fragen ermitteln while(readBuffer[0] != 'L') { if (read(stdoutPipe[0], readBuffer, sizeof(readBuffer)) < 0) { perror("read LOADER"); } for (i=0; readBuffer[i]!= '\n'; i++); readBuffer[i]= '\0'; j++; infoPrint("%i. mal durchgelaufen", j); if (strcmp(readBuffer, "ERROR: CANNOT OPEN FILE") == 0) { infoPrint("%s", readBuffer); quitServer(ERROR, "SHARED MEMORY ERROR"); }else if(strcmp(readBuffer, "ERROR: CANNOT READ FILE") == 0) { infoPrint("%s", readBuffer); quitServer(ERROR, "SHARED MEMORY ERROR"); }else if(strcmp(readBuffer, "ERROR: INVALID CATALOG") == 0) { infoPrint("%s", readBuffer); quitServer(ERROR, "SHARED MEMORY ERROR"); }else if(strcmp(readBuffer, "ERROR: CANNOT USE SHARED MEMORY") == 0) { infoPrint("%s", readBuffer); quitServer(ERROR, "SHARED MEMORY ERROR"); }else if(strcmp(readBuffer, "ERROR: OUT OF MEMORY") == 0) { infoPrint("%s", readBuffer); quitServer(ERROR, "SHARED MEMORY ERROR"); }else if(readBuffer[0] == 'L') { ptr = strtok(readBuffer, "="); ptr = strtok(NULL, "="); anzFragen = atoi(ptr); infoPrint("(catalog.c) Anzahl Fragen: %i", anzFragen); shmGroesse = sizeof(Question)* anzFragen; }else { infoPrint("Unbekannter Fehler :%s", readBuffer); } } }
/* * Helper function performing the login procedure. */ static void loginHandleSocket(int socket) { // Try to receive the first packet from the client rfc response; int receive = receivePacket(socket, &response); if (receive == -1) { errnoPrint("receive"); return; } else if (receive == 0) { errorPrint("Remote host closed connection"); return; } // Check if we received a login request if (equalLiteral(response.main, "LRQ")) { // Check RFC version if (response.loginRequest.version != RFC_VERSION_NUMBER) { sendErrorMessage(socket, "Login Error: Wrong RFC version used"); infoPrint("Login attempt with wrong RFC version: %d", response.loginRequest.version); return; } // Store username string int length = ntohs(response.main.length) - 1; char s[length + 1]; s[length] = '\0'; memcpy(s, response.loginRequest.name, length); // Check Game Phase if (getGamePhase() != PHASE_PREPARATION) { sendErrorMessage(socket, "Login Error: Game has already started"); infoPrint("Login attempt while game has already started: \"%s\"", s); return; } // Detect empty name string if (length == 0) { sendErrorMessage(socket, "Login Error: A username is required"); infoPrint("Login attempt without a name"); return; } // Detect duplicate names for (int i = 0; i < MAX_PLAYERS; i++) { if (userGetPresent(i)) { if (strcmp(userGetName(i), s) == 0) { sendErrorMessage(socket, "Login error: Name already in use"); infoPrint("Login attempt with duplicate name: \"%s\"", s); return; } } } // Detect too many players int pos = userFirstFreeSlot(); if (pos == -1) { sendErrorMessage(socket, "Login Error: Server is full"); infoPrint("Login attempt while server is full: \"%s\"", s); return; } // Write new user data into "database" userSetPresent(pos, 1); userSetName(pos, s); userSetSocket(pos, socket); scoreMarkForUpdate(); // Start client thread for new user int thread = -1; for (int i = 0; i < (1 + MAX_PLAYERS); i++) { if (threadsFree[i] == -1) { thread = i; } } if (pthread_create(&threads[thread], NULL, clientThread, (void*)pos) != 0) { threadsFree[thread] = pos; errnoPrint("pthread_create"); return; } // Send LOK message response.main.type[0] = 'L'; response.main.type[1] = 'O'; response.main.type[2] = 'K'; response.main.length = htons(2); response.loginResponseOK.version = RFC_VERSION_NUMBER; response.loginResponseOK.clientID = (uint8_t)pos; if (send(socket, &response, RFC_LOK_SIZE, 0) == -1) { errnoPrint("send"); return; } } else { errorPrint("Unexpected response: %c%c%c", response.main.type[0], response.main.type[1], response.main.type[2]); return; } }
void loadQuestions(char* name){ char* message; int loaded; // remove shared memorey shm_unlink(SHMEM_NAME); // LOAD_CMD_PREFIX - Katalog laden if(write(stdinPipe[1], LOAD_CMD_PREFIX, strlen(LOAD_CMD_PREFIX)) < strlen(LOAD_CMD_PREFIX)){ errorPrint("Senden der Nachricht über Pipe fehlgeschlagen"); endServer(); exit(0); } // aktiven Katalog uebergeben if(write(stdinPipe[1], name, strlen(name)) < strlen(name)){ errorPrint("Senden der Nachricht über Pipe fehlgeschlagen"); endServer(); exit(0); } // Zeilenumbruch zum Abschluss if (write(stdinPipe[1], "\n", 1) < 1) { errorPrint("Senden der Nachricht über Pipe fehlgeschlagen"); endServer(); exit(0); } // von Pipe lesen ob laden des Katalogs erfolgreich (LOAD_SUCCESS_PREFIX - Katalog mit SIZE Fragen geladen) message = readLine(stdoutPipe[0]); if(strcmp(message, LOAD_SUCCESS_PREFIX) != -1){ infoPrint("Kataloge eingelesen"); // The memmove() function copies n bytes from memory area src to memory area dest memmove(message, message + sizeof(LOAD_SUCCESS_PREFIX) - 1, 50); loaded = atoi(message); infoPrint("Anzahl an eingelesenen Fragen: %i", loaded); } else { errorPrint("Fragen konnten nicht geladen werden"); endServer(); exit(0); } // shm_open() creates and opens a new, or opens an existing, POSIX shared memory object. // returns file descriptor of -1 in case of error shmHandle = shm_open(SHMEM_NAME, O_RDONLY, 0); if(shmHandle == -1){ errorPrint("Konnte Shared Memory nicht erstellen / öffnen!"); endServer(); exit(0); } // Groesse ShareMemory = Anzahl Fragen * Groesse der Fragen shmLen = loaded * sizeof(Question); ftruncate(shmHandle, shmLen); /* * Um ein mittels shm_open geöffnetes Shared Memory Objekt nun tatsächlich verwenden zu können, muss * dieses in den Adressraum des Prozesses eingebunden werden. * Die Funktion mmap bindet eine Datei, ein Gerät oder ein Shared Memory Objekt in den Adressraum * des aufrufenden Prozesses ein. */ // mmap() creates a new mapping in the virtual address space of the calling process. // void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); shmData = mmap(NULL, shmLen, PROT_READ, MAP_SHARED, shmHandle, 0); if(shmData == MAP_FAILED){ errorPrint("Konnte Shared Memory nicht in Adressraum einbinden!"); endServer(); exit(0); } // SharedMemory setShMem(shmData); return; }
// Main program entry point int main(int argc, char **argv) { for (int i = 0; i < (1 + MAX_PLAYERS); i++) threadsFree[i] = -1; setProgName(argv[0]); debugDisable(); infoPrint("Server Gruppe 01"); userInit(); // Create PID lock file or exit if it already exists debugPrint("Making sure we're running only once..."); if (singleton(LOCKFILE) != 0) return 1; // Socket structure that could be modified by the command line arguments struct sockaddr_in server; server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(INADDR_ANY); server.sin_port = htons(PORT); // Use the default port defined in "common"! // Prepare parsing the command line options using getopt() debugPrint("Parsing command line options..."); const char* short_options = "hvp:"; struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "verbose", no_argument, 0, 'v' }, { "port", required_argument, 0, 'p' }, { NULL, 0, NULL, 0 } }; // Actual getopt() loop int option_index = 0; int loop = 1; while (loop != 0) { int c = getopt_long(argc, argv, short_options, long_options, &option_index); switch (c) { // Show help text when using -h case 'h': show_help(); exit(1); break; // Enable verbose (debug) output case 'v': debugEnable(); break; // Set port to listen on case 'p': if(optarg) { if (isOnlyDigits(optarg)) { server.sin_port = htons(atoi(optarg)); } else { errorPrint("Port has to be a decimal number!"); exit(1); } } break; // Unknown option, show error & help message default: case '?': errorPrint("Option not implemented yet -- %s (%c)", argv[optind-1], c); show_help(); exit(1); break; // All options have been parsed case -1: loop = 0; break; } } infoPrint("Serverport: %i", ntohs(server.sin_port)); // Create the pipes that will be used to communicate with the loader debugPrint("Creating Pipes..."); if (!createPipes()) return 1; // Actually fork and run the loader as child process debugPrint("Forking to run loader..."); if (!forkLoader()) return 1; debugPrint("Starting Threads..."); // Start the score agent thread if (pthread_create(&threads[0], NULL, scoreThread, NULL) != 0) { threadsFree[0] = -2; errnoPrint("pthread_create"); return 1; } clientInit(); // Create the listening socket debugPrint("Creating socket..."); int listen_socket = socket(AF_INET, SOCK_STREAM, 0); if (listen_socket == -1) { errnoPrint("socket"); return 1; } // Enable address reusing, so we don't get bind errors int on = 1; setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); // Register our Interrupt Signal handler signal(SIGINT, intHandler); // Store the listening socket in our user database userSetMainSocket(listen_socket); // Actually bind the listening socket if (bind(listen_socket, (struct sockaddr*) &server, sizeof(struct sockaddr_in)) == -1) { errnoPrint("bind"); close(listen_socket); closePipes(); loaderCloseSharedMemory(); return 1; } // Prepare the pselect() timeout data structure fd_set fds; struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = SOCKET_TIMEOUT * 1000000; sigset_t blockset; sigfillset(&blockset); sigdelset(&blockset, SIGINT); // Main thread main loop, waiting for new connections debugPrint("Waiting for connections..."); while (getRunning()) { // Listen to the listening socket if (listen(listen_socket, MAX_QUERYS) == -1) { errnoPrint("listen"); close(listen_socket); closePipes(); loaderCloseSharedMemory(); cleanCategories(); return 1; } // Wait for activity on the listening socket FD_ZERO(&fds); FD_SET(listen_socket, &fds); int retval = pselect(listen_socket + 1, &fds, NULL, NULL, &ts, &blockset); if (retval == -1) { if (errno == EINTR) { // We should exit because the user pressed Ctrl + C close(listen_socket); closePipes(); loaderCloseSharedMemory(); cleanCategories(); return 0; } else { // pselect encountered an error! errnoPrint("select"); close(listen_socket); closePipes(); loaderCloseSharedMemory(); cleanCategories(); return 1; } } else if (retval == 0) { // Nothing happened and pselect timed out continue; } else { // We have a new connection, accept it struct sockaddr_in remote_host; socklen_t sin_size = sizeof(struct sockaddr_in); int client_socket = accept(listen_socket, (struct sockaddr *) &remote_host, &sin_size); if (client_socket == -1) { errnoPrint("accept"); close(listen_socket); closePipes(); loaderCloseSharedMemory(); cleanCategories(); return 1; } debugPrint("Got a new connection! Performing Login..."); loginHandleSocket(client_socket); } } // Clean up behind ourselves close(listen_socket); closePipes(); loaderCloseSharedMemory(); cleanCategories(); pthread_exit(NULL); return 0; }
/* * Funktion um Richtigkeit und vorhanden sein von Startparametern zu überprüfen */ int detect_para(unsigned short *port, char* pfad, char* catalog) { int j; char *_tmp_str; /* * Durchlaufen der Parameterliste */ for(j = 1; j < argc_cp; j++) { /* * Überprüfen ob ein Parameterbefehl -p(Port) angegeben wurde */ if(strcmp(argv_cp[j-1], "-p") == 0) { _tmp_str = argv_cp[j]; /* * Wenn ja, überprüfen ob Stelle danach leer ist, oder nächste Stelle neuer Paramterbefehl ist */ if((strcmp(argv_cp[j-1], "-p") == 0 && argv_cp[j] != NULL) && (strcmp(argv_cp[j-1], "-p") == 0 && _tmp_str[0] != '-')) { /* * Wenn korrekt speichern des Ports zu Weiterverarbeitung aus Parameterliste */ *port = atoi(argv_cp[j]); break; } else { /* * Ausgabe Fehlermeldung */ infoPrint("Ungueltigen Port angegeben!"); return -1; } } else { /* * Wenn kein Paramterbefehl für Port angegeben wurde, verwenden eines als Standard angegebenen Ports */ *port = 54321; } } /* * Durchlaufen der Parameterlist */ for(j = 1; j < argc_cp; j = j + 1) { /* * Überprüfen ob Alternativer Pfad zum loader angegeben wurde */ if(strcmp(argv_cp[j-1], "-l") == 0) { _tmp_str = argv_cp[j]; /* * Wenn ja, Überprüfen ob Eingabe danach leer, oder ein neuer Parameterbefehl ist */ if((argv_cp[j] != NULL) && (_tmp_str[0] != '-')) { /* * Wenn gültige Angabe, Überprüfen ob die Pfadangabe zu lang ist */ if(strlen(argv_cp[j]) > 50) { /* * Fehlermeldung */ infoPrint("Pfad zum Loader zu lange, max 50 Zeichen!"); return -1; } else { /* * Wenn alles korrekt, speicher des Pfades, zur weiterverwendung im Programm */ strncpy (pfad, argv_cp[j], sizeof(char[51])); break; } } else { /* * Wenn Falsche Eingabe, Fehlermeldung */ infoPrint("Falsche angabe von Pfad"); return -1; } } else { /* * Wenn kein Alternativer Loader angegeben wurde, verwenden des Standard-Loaders */ strncpy (pfad , "./loader", sizeof(char[50])); } } /* * Überprüfen ob nur ein Parameter angegben wurde(ein Parameter aufjedenfall, * wegen Aufruf von Programm(./Client) Client == erster Paramter), wenn ja ist kein Katalogverzeichniss angegeben */ if (argc_cp <= 1) { /* * Fehlermeldung */ infoPrint("Keinen Katalogverzeichniss angegeben!"); return -1; } /* * Durchlaufen der Parameterliste */ for(j = 1; j < argc_cp; j++) { _tmp_str = argv_cp[j]; /* * Überprüfen ob Parameterbefehl -c(Katalogverzeichniss) angegeben wurde * und die Stelle danach nicht leer ist, oder die Stelle danach ein neuer Parameterbefehl ist */ if((strcmp(argv_cp[j-1], "-c") == 0 && argv_cp[j] != NULL) && (strcmp(argv_cp[j-1], "-c") == 0 && _tmp_str[0] != '-')) { /* * Wenn Angabe korrekt, überprüfen ob Pfad zum Katalog zu lang ist */ if(strlen(argv_cp[j]) > 50) { /* * Wenn zu lang, Ausgabe Fehlermeldung */ infoPrint("Pfad zum Katalog zu lange, max 50 Zeichen!"); return -1; } else { /* * Wenn alles korrekt, speichern des Pfades zum Katalogverzeichniss zu Weiterverwendung im Programm */ strncpy (catalog, argv_cp[j], sizeof(char[51])); break; } } else { if(j >= argc_cp - 1) { /* * Wenn Liste durchlaufen, aber kein Pfad zum Katalogverzeichniss angegeben wurde */ infoPrint("Kein Katalogverzeichniss angegeben!"); return -1; } } } return 0; }