void client_exec(Client* client, int i, ClientSet* clients, NoticeBoard* board) { char buffer[512]; memset(buffer, 0, 512); if (difftime(time(NULL), client->last_recv) > 30 * 60) { disconnect(client); return; } int bytes_recv = recv(client->socket, buffer, 511, 0); if ((bytes_recv == 0) || (bytes_recv == -1 && errno != EAGAIN)) { disconnect(client); //clients->size--; //memmove(client, client + sizeof(Client), // *(clients->clients) - client); } if (bytes_recv != -1) { client->last_recv = time(NULL); } if (starts(buffer, "read")) { Command_Read(*client, clients, board); } else if (starts(buffer, "post")) { Command_Post(*client, clients, board, buffer); } else if (starts(buffer, "time")) { Command_Time(*client); } else if (starts(buffer, "online")) { Command_Online(*client, clients); } else if (starts(buffer, "nick")) { Command_Nick(client, clients, buffer); } else if (starts(buffer, "debug")) { Command_Debug(client, clients, board); } else if (starts(buffer, "help")) { Command_Help(*client); } else if (starts(buffer, "motd")) { send_motd(client); } }
int begin_connection(int fd, t_user *root) { char *nickname; char *tmp1; char *tmp2; char hostname[1024]; gethostname(hostname, 1024); if ((nickname = get_nickname(fd, root)) == NULL || !(tmp1 = str_concat(":Welcome to the Internet Relay Network ", nickname, "")) || !(tmp2 = str_concat(":Your host is ", hostname, " running version 1.0"))) return (-1); send_response(fd, "001", tmp1); send_response(fd, "002", tmp2); send_response(fd, "003", ":This server was created 04/2014"); send_response(fd, "004", ":So nice to see you here"); free(tmp1); free(tmp2); send_motd(fd, hostname); return (0); }
// Befehle des Clients empfangen void serve_client(int c) { char buffer[BUFFER_SIZE]; memset(&buffer, 0, sizeof(buffer)); int n_bytes; send_motd(c); while ( (n_bytes = recv(c, buffer, sizeof(buffer), 0)) > 0) { // CRLF entfernen -> Wird bei Telnet mitgesendet! if (strtok(buffer, "\r\n")) { buffer[strlen(buffer)] = '\0'; } printf("[Server] Got command: %s\n", buffer); // Befehl untersuchen if ( strncmp(buffer, "VERSION", BUFFER_SIZE) == 0) { // Kernel-Ver. char procbuf[1024]; memset(&procbuf, 0, sizeof(procbuf)); FILE* procfd = fopen("/proc/version", "r"); while ( !feof(procfd) ) { fread(&procbuf, 1, 1, procfd); send(c, procbuf, strlen(procbuf), 0); } } else if (strncmp(buffer, "ID", BUFFER_SIZE) == 0) { // Prozess-ID char response[30]; memset(&response, 0, sizeof(response)); sprintf(response, "PID des Servers: %d\n", getpid()); send(c, response, strlen(response), 0); } else if (strncmp(buffer, "END", BUFFER_SIZE) == 0) { // Beenden send(c, "Goodbye.\n", 10, 0); close(c); } else if (strncmp(buffer, "SEND", strlen("SEND")) == 0) { // Daten empfangen // Producer char* data = strstr(buffer, " ")+1; // +1 wegen des Leerzeichens if (data == NULL) break; printf("[Server] Producer: Position %i, Daten %s\n", buffercount, data); pthread_mutex_lock(&mutex); // Puffer sperren while (buffercount == 5) { // Puffer ist voll, warten auf Consumer printf("[Server] Buffer is full, waiting for consumption...\n"); pthread_cond_wait(&space_available, &mutex); } int copylen = strlen(data); //memset(&globalbuffer[buffercount], 0, sizeof(globalbuffer[buffercount])); // Leeren strncpy(globalbuffer[buffercount++], data, copylen); pthread_cond_signal(&items_available); // Benachrichtigen, dass Inhalt da ist pthread_mutex_unlock(&mutex); send(c, "OK\n", strlen("OK\n"), 0); } else if (strncmp(buffer, "RECEIVE", BUFFER_SIZE) == 0) { // Daten senden pthread_mutex_lock(&mutex); while (buffercount == 0) { // Puffer ist leer, warten auf Producer printf("[Server] Buffer is empty, waiting for production...\n"); pthread_cond_wait(&items_available, &mutex); } buffercount--; printf("[Server] Consumer: Position %d\n", buffercount); send(c, globalbuffer[buffercount], strlen(globalbuffer[buffercount]), 0); send(c, "\n", 3, 0); pthread_cond_signal(&space_available); // Benachrichtigen, dass wieder Platz frei ist pthread_mutex_unlock(&mutex); } else { // unbekannt printf("[Server] Client sent unknown command: %s\n", buffer); } memset(&buffer, 0, sizeof(buffer)); } return; }
void server_exec(Socket server, SockAddrIn server_addr, ClientSet* clients, NoticeBoard* board) { int i; if (listen(server, 5) == -1) { error("Could not listen on socket"); exit(1); } while (running) { usleep(100000); /* -- Accepting connections -- */ socklen_t sz = sizeof(server_addr); Socket new_socket = accept(server, (SockAddr*)&server_addr, &sz); /* Error handling, most likely EAGAIN since we're using * non blocking sockets. */ if (new_socket == -1) { if (errno != EAGAIN) { error("Could not accept connection"); } } else { int j = 0; fcntl(new_socket, F_SETFL, O_NONBLOCK); Client* c = ClientSet_Add(clients, new_socket); if (c == NULL) continue; memset(c->properties.nick, 0, NICK_MAXLEN); strcpy(c->properties.nick, "user"); for (i = 0; i < clients->size; i++) { if (&clients->clients[i] == c || clients->clients[i].state == DISCONNECTED) continue; if (!strcmp(clients->clients[i].properties.nick, c->properties.nick)) { j++; sprintf(c->properties.nick, "user(%d)", j); i = 0; } } SockAddr peer_address; socklen_t addrlen = sizeof(peer_address); int has_error = getpeername(new_socket, &peer_address, &addrlen); if (has_error == -1) { error("Error getting peer name"); } SockAddrIn *addr_in = (struct sockaddr_in *)&peer_address; c->ip_string = ipaddr(*addr_in); printf("Client connected (%s)\n", c->ip_string); send_motd(c); } /* -- Reading data -- */ for (i = 0; i < clients->size; i++) { if (clients->clients[i].state == DISCONNECTED) { Client_Destroy(&clients->clients[i]); continue; } client_exec(&(clients->clients[i]), i, clients, board); } } }