//So I can compile/debug ;) int main() { int a = 42; int b = 1337; int c = 214; int d = 1234; int e = 5005; int f = 69; int place = 3; printf("---------------\n|** Excist ***|\n---------------\n"); printf("%d\n", llist_excist()); printf("---------------\n|*** Begin ***|\n---------------\n"); llist_add(&a); llist_add(&b); llist_add(&c); llist_add(&d); llist_add(&e); printf("---------------\n|** Excist ***|\n---------------\n"); printf("%d\n", llist_excist()); //printf("Derde waarde: %d\n", *nodeList.firstNode->nextNode->nextNode->value); printf("---------------\n|*No of items*|\n---------------\n"); printf("%d\n", llist_nrItems()); printf("---------------\n|**Print func*|\n---------------\n"); llist_show(); printf("---------------\n|*Add on place|\n---------------\n"); llist_add_on_place(&place,&f); printf("---------------\n|**Print func*|\n---------------\n"); llist_show(); printf("---------------\n|**Delet func*|\n---------------\n"); llist_remove(42); llist_show(); printf("---------------\n|** Excist ***|\n---------------\n"); printf("%d\n", llist_excist()); printf("---------------\n|**Clear func*|\n---------------\n"); llist_clear(); printf("---------------\n|** Excist ***|\n---------------\n"); printf("%d\n", llist_excist()); return 0; }
int main() { node entry = node_new(28); list head = NULL; int i = 0; while(i < 5) { llist_append(head,new_node(5*i++)); } llist_append(head,entry); while(i < 8) { llist_append(head,new_node(5*i++)); } llist_show(head); return 0; }
/* * Main program */ int main(int argc, char *argv[]) { int i = 0; int ret = 0; struct sockaddr_in client_address; int client_sockfd = 0; pthread_t threads[MAX_THREADS]; /* Parse commandline args */ params = malloc(sizeof(cmd_params)); ret = parse_cmd_args(&argc, argv); if (params->help) { display_help_page(); exit(0); } if (params->version) { display_version_info(); exit(0); } if (ret < 0) { if (ret == -2) logline(LOG_ERROR, "Error: Invalid port range specified (-p)"); if (ret == -6) logline(LOG_ERROR, "Error: Invalid log level option specified (-l)."); logline(LOG_ERROR, "Use the -h option if you need help."); exit(ret); } /* Set log level */ switch (params->loglevel) { case 1: set_loglevel(LOG_ERROR); break; case 2: set_loglevel(LOG_INFO); break; case 3: set_loglevel(LOG_DEBUG); break; default: set_loglevel(LOG_ERROR); } /* Setup signal handler */ signal(SIGINT, shutdown_server); signal(SIGTERM, shutdown_server); /* Show banner and stuff */ show_gnu_banner(); /* Startup the server listener */ if (startup_server() < 0) { logline(LOG_ERROR, "Error during server startup. Please consult debug log for details."); exit(-1); } /* Post ready message */ logline(LOG_INFO, "Server listening on %s, port %d", params->ip, params->port); switch (params->loglevel) { case LOG_ERROR: logline(LOG_INFO, "Log level set to ERROR"); break; case LOG_INFO: logline(LOG_INFO, "Log level set to INFO"); break; case LOG_DEBUG: logline(LOG_INFO, "Log level set to DEBUG"); break; default: logline(LOG_INFO, "Unknown log level specified"); break; } /* Handle connections */ while (1) { logline(LOG_INFO, "Waiting for incoming connection..."); /* Accept a client connection */ client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, (socklen_t *)&client_len); if (client_sockfd > 0) { logline(LOG_INFO, "Server accepted new connection on socket id %d", client_sockfd); /* A connection between a client and the server has been established. * Now create a new thread and handover the client_sockfd */ pthread_mutex_lock(&curr_thread_count_mutex); if (curr_thread_count < MAX_THREADS) { /* Prepare client infos in handy structure */ client_info *ci = (client_info *)malloc(sizeof(client_info)); ci->sockfd = client_sockfd; ci->address = client_address; sprintf(ci->nickname, "anonymous_%d", client_sockfd); /* Add client info to linked list */ llist_insert(&list_start, ci); llist_show(&list_start); /* Pass client info and invoke new thread */ ret = pthread_create(&threads[curr_thread_count], NULL, (void *)&proc_client, (void *)&client_sockfd); /* only pass socket id ? */ if (ret == 0) { pthread_detach(threads[curr_thread_count]); curr_thread_count++; /* Notify server and clients */ logline(LOG_INFO, "User %s joined the chat.", ci->nickname); logline(LOG_DEBUG, "main(): Connections used: %d of %d", curr_thread_count, MAX_THREADS); } else { free(ci); close(client_sockfd); } } else { logline(LOG_ERROR, "Max. connections reached. Connection limit is %d. Connection dropped.", MAX_THREADS); close(client_sockfd); } pthread_mutex_unlock(&curr_thread_count_mutex); } else { /* Connection could not be established. Post error and exit. */ perror(strerror(errno)); exit(-3); } } free(params); return 0; }
/* * Process a chat message coming from a chat client. */ void process_msg(char *message, int self_sockfd) { char buffer[1024]; regex_t regex_quit; regex_t regex_nick; regex_t regex_msg; regex_t regex_me; regex_t regex_who; int ret; char newnick[20]; char oldnick[20]; char priv_nick[20]; struct list_entry *list_entry = NULL; struct list_entry *nick_list_entry = NULL; struct list_entry *priv_list_entry = NULL; int processed = FALSE; size_t ngroups = 0; size_t len = 0; regmatch_t groups[3]; memset(buffer, 0, 1024); memset(newnick, 0, 20); memset(oldnick, 0, 20); memset(priv_nick, 0, 20); /* Load client info object */ list_entry = llist_find_by_sockfd(&list_start, self_sockfd); /* Remove \r\n from message */ chomp(message); /* Compile regex patterns */ regcomp(®ex_quit, "^/quit$", REG_EXTENDED); regcomp(®ex_nick, "^/nick ([a-zA-Z0-9_]{1,19})$", REG_EXTENDED); regcomp(®ex_msg, "^/msg ([a-zA-Z0-9_]{1,19}) (.*)$", REG_EXTENDED); regcomp(®ex_me, "^/me (.*)$", REG_EXTENDED); regcomp(®ex_who, "^/who$", REG_EXTENDED); /* Check if user wants to quit */ ret = regexec(®ex_quit, message, 0, NULL, 0); if (ret == 0) { /* Notify */ send_broadcast_msg("%sUser %s has left the chat server.%s\r\n", color_magenta, list_entry->client_info->nickname, color_normal); logline(LOG_INFO, "User %s has left the chat server.", list_entry->client_info->nickname); pthread_mutex_lock(&curr_thread_count_mutex); curr_thread_count--; logline(LOG_DEBUG, "process_msg(): Connections used: %d of %d", curr_thread_count, MAX_THREADS); pthread_mutex_unlock(&curr_thread_count_mutex); /* Remove entry from linked list */ logline(LOG_DEBUG, "process_msg(): Removing element with sockfd = %d", self_sockfd); llist_remove_by_sockfd(&list_start, self_sockfd); /* Disconnect client from server */ close(self_sockfd); /* Free memory */ regfree(®ex_quit); regfree(®ex_nick); regfree(®ex_msg); regfree(®ex_me); /* Terminate this thread */ pthread_exit(0); } /* Check if user wants to change nick */ ngroups = 2; ret = regexec(®ex_nick, message, ngroups, groups, 0); if (ret == 0) { processed = TRUE; /* Extract nickname */ len = groups[1].rm_eo - groups[1].rm_so; strncpy(newnick, message + groups[1].rm_so, len); strcpy(oldnick, list_entry->client_info->nickname); strcpy(buffer, "User "); strcat(buffer, oldnick); strcat(buffer, " is now known as "); strcat(buffer, newnick); /* Change nickname. Check if nickname already exists first. */ nick_list_entry = llist_find_by_nickname(&list_start, newnick); if (nick_list_entry == NULL) { change_nickname(oldnick, newnick); send_broadcast_msg("%s%s%s\r\n", color_yellow, buffer, color_normal); logline(LOG_INFO, buffer); } else { send_private_msg(oldnick, "%sCHATSRV: Cannot change nickname. Nickname already in use.%s\r\n", color_yellow, color_normal); logline(LOG_INFO, "Private message from CHATSRV to %s: Cannot change nickname. Nickname already in use", oldnick); } } /* Check if user wants to transmit a private message to another user */ ngroups = 3; ret = regexec(®ex_msg, message, ngroups, groups, 0); if (ret == 0) { processed = TRUE; /* Extract nickname and private message */ len = groups[1].rm_eo - groups[1].rm_so; memcpy(priv_nick, message + groups[1].rm_so, len); len = groups[2].rm_eo - groups[2].rm_so; memcpy(buffer, message + groups[2].rm_so, len); /* Check if nickname exists. If yes, send private message to user. * If not, ignore message. */ priv_list_entry = llist_find_by_nickname(&list_start, priv_nick); if (priv_list_entry != NULL) { send_private_msg(priv_nick, "%s%s:%s %s%s%s\r\n", color_green, list_entry->client_info->nickname, color_normal, color_red, buffer, color_normal); logline(LOG_INFO, "Private message from %s to %s: %s", list_entry->client_info->nickname, priv_nick, buffer); } } /* Check if user wants to say something about himself */ ngroups = 2; ret = regexec(®ex_me, message, ngroups, groups, 0); if (ret == 0) { processed = TRUE; strcpy(buffer, list_entry->client_info->nickname); /* Prepare message */ len = groups[1].rm_eo - groups[1].rm_so; strcat(buffer, " "); strncat(buffer, message + groups[1].rm_so, len); /* Broadcast message */ send_broadcast_msg("%s%s%s\r\n", color_cyan, buffer, color_normal); logline(LOG_INFO, buffer); } /* Check if user wants a listing of currently connected clients */ ret = regexec(®ex_who, message, 0, NULL, 0); if (ret == 0) { processed = TRUE; int socklen = sizeof(list_entry->client_info->address); logline(LOG_INFO, "%s requested the client list", list_entry->client_info->nickname); char **nicks = malloc(sizeof(*nicks) * 1000); int i; for (i = 0; i < 1000; i++) nicks[i] = malloc(sizeof(**nicks) * 30); int count = llist_get_nicknames(&list_start, nicks); memset(buffer, 0, 1024); for (i = 0; i < count; i++) { sprintf(buffer, "%s%s%s%s", buffer, color_magenta, nicks[i], color_normal); if(i != (count - 1)) sprintf(buffer, "%s, ", buffer); if(i == (count - 1)) sprintf(buffer, "%s\r\n", buffer); free(nicks[i]); } sendto(list_entry->client_info->sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&(list_entry->client_info->address), (socklen_t)socklen); free(nicks); } /* Broadcast message */ if (processed == FALSE) { send_broadcast_msg("%s%s:%s %s\r\n", color_green, list_entry->client_info->nickname, color_normal, message); logline(LOG_INFO, "%s: %s", list_entry->client_info->nickname, message); } /* Dump current user list */ llist_show(&list_start); /* Free memory */ regfree(®ex_quit); regfree(®ex_nick); regfree(®ex_msg); regfree(®ex_me); regfree(®ex_who); }
int main(int argc, char argv[]) { int ret = 0; struct sockaddr_in client_address; int client_fd = 0; printf("\n"); printf("Welcome to Chat Server....\n"); memset(&serverStats, 0, sizeof(struct ServerStats_t)); serverStats.max_threads = MAX_THREADS; // start the main and make the server listen on port 12345 if (server_socket_init() == -1) { printf("An error occured. Closing program \n"); return 1 ; } //server_wait_client(server_fd); while(1) { //int rfd; int *arg; char ipstr[INET6_ADDRSTRLEN]; int port; int new_sd; int ret =0; struct sockaddr_storage remote_info ; pthread_t threads[MAX_THREADS]; socklen_t addr_size; addr_size = sizeof(addr_size); new_sd = accept(server_fd, (struct sockaddr *) &remote_info, &addr_size); getpeername(new_sd, (struct sockaddr*)&remote_info, &addr_size); // deal with both IPv4 and IPv6: if (remote_info.ss_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in *)&remote_info; port = ntohs(s->sin_port); inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); } else { // AF_INET6 struct sockaddr_in6 *s = (struct sockaddr_in6 *)&remote_info; port = ntohs(s->sin6_port); inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr); } printf("\n"); if(new_sd >= 0) { printf("Server accepted new connection on socket id :%d\n", new_sd); /* A connection between a client and the server has been established. * Now create a new thread and handover the client_sockfd */ pthread_mutex_lock(&curr_thread_count_mutex); if (curr_thread_count < MAX_THREADS) { /* Prepare client infos in handy structure */ client_info *ci = (client_info *)malloc(sizeof(client_info)); ci->sockfd = new_sd; ci->address = remote_info; sprintf(ci->nickname, "Client_%d\n", new_sd); /* Add client info to linked list */ llist_insert(&list_start, ci); llist_show(&list_start); /* System Monitoring Statistics Counter : Increments the number of active_connections counter. Shows the number of active clients*/ serverStats.num_of_active_connections++; /* Pass client info and invoke new thread */ ret = pthread_create(&threads[curr_thread_count], NULL, (void *)&server_read_client, (void *)&new_sd); /* only pass socket id ? */ if (ret == 0) { serverStats.num_of_clients_serviced++; pthread_detach(threads[curr_thread_count]); curr_thread_count++; /* Notify server and clients */ printf("User %s joined the chat.\n", ci->nickname); printf("Connections used: %d of %d\n", curr_thread_count, MAX_THREADS); } else { serverStats.num_of_conn_dropped++; llist_remove_by_sockfd(&list_start, new_sd); serverStats.num_of_active_connections--; free(ci); close(new_sd); } } else { serverStats.num_of_conn_dropped++; printf("Max. connections reached. Connection limit is %d. Connection dropped.\n", MAX_THREADS); close(new_sd); } pthread_mutex_unlock(&curr_thread_count_mutex); } else { /* Connection could not be established. Post error and exit. */ //perror(strerror(errno)); printf("Error creating socket\n"); exit(-1); } } return 0; }
/* * Process a chat message coming from a chat client. */ void process_msg(char *message, int self_sockfd) { char buffer[BUF_SIZE_1K]; char statsBuf[BUF_SIZE_1K]; regex_t regex_quit; regex_t regex_nick; regex_t regex_msg; //regex_t regex_me; regex_t regex_stats; int ret; char newnick[20]; char oldnick[20]; char priv_nick[20]; struct list_entry *list_entry = NULL; struct list_entry *nick_list_entry = NULL; struct list_entry *priv_list_entry = NULL; int processed = FALSE; size_t ngroups = 0; size_t len = 0; regmatch_t groups[3]; memset(buffer, 0, BUF_SIZE_1K); memset(newnick, 0, 20); memset(oldnick, 0, 20); memset(priv_nick, 0, 20); /* Load client info object */ list_entry = llist_find_by_sockfd(&list_start, self_sockfd); /* Remove \r\n from message */ chomp(message); /* Compile regex patterns */ regcomp(®ex_quit, "^/logout$", REG_EXTENDED); regcomp(®ex_nick, "^/chatName ([a-zA-Z0-9_]{1,19})$", REG_EXTENDED); regcomp(®ex_msg, "^/privateMessage ([a-zA-Z0-9_]{1,19}) (.*)$", REG_EXTENDED); regcomp(®ex_stats, "^/showStats$", REG_EXTENDED); /* Check if user wants to quit */ ret = regexec(®ex_quit, message, 0, NULL, 0); if (ret == 0) { /* Notify */ send_broadcast_msg("\n%sUser: %s has left the chat server.%s\n\r\n", color_magenta, list_entry->client_info->nickname, color_normal); printf("\nUser: %s has left the chat server.\n", list_entry->client_info->nickname); pthread_mutex_lock(&curr_thread_count_mutex); curr_thread_count--; pthread_mutex_unlock(&curr_thread_count_mutex); /* Remove entry from linked list */ llist_remove_by_sockfd(&list_start, self_sockfd); serverStats.num_of_active_connections--; /* Disconnect client from server */ close(self_sockfd); /* Free memory */ regfree(®ex_quit); regfree(®ex_nick); regfree(®ex_msg); regfree(®ex_stats); /* Terminate this thread */ pthread_exit(0); } /* Check if user wants to change nick */ ngroups = 2; ret = regexec(®ex_nick, message, ngroups, groups, 0); if (ret == 0) { processed = TRUE; /* Extract nickname */ len = groups[1].rm_eo - groups[1].rm_so; strncpy(newnick, message + groups[1].rm_so, len); strcpy(oldnick, list_entry->client_info->nickname); strcpy(buffer, "User: "******" is now known as - "); strcat(buffer, newnick); /* Change nickname. Check if nickname already exists first. */ nick_list_entry = llist_find_by_nickname(&list_start, newnick); if (nick_list_entry == NULL) { change_nickname(oldnick, newnick); send_broadcast_msg("\n\n%s\n%s\n%s\n\r\n", color_yellow, buffer, color_normal); printf("Broadcast Message is sent for username change\n"); } else { send_private_msg(oldnick, "%sCHATSRV: Cannot change nickname. Nickname already in use.%s\r\n", color_yellow, color_normal); printf("Private message from CHATSRV to %s: Cannot change nickname. Nickname already in use\n", oldnick); } } /* Check if user wants to transmit a private message to another user */ ngroups = 3; ret = regexec(®ex_msg, message, ngroups, groups, 0); if (ret == 0) { processed = TRUE; /* Extract nickname and private message */ len = groups[1].rm_eo - groups[1].rm_so; memcpy(priv_nick, message + groups[1].rm_so, len); len = groups[2].rm_eo - groups[2].rm_so; memcpy(buffer, message + groups[2].rm_so, len); /* Check if nickname exists. If yes, send private message to user. * If not, ignore message. */ priv_list_entry = llist_find_by_nickname(&list_start, priv_nick); if (priv_list_entry != NULL) { send_private_msg(priv_nick, "%s %s:\n%s %s %s %s\r\n", color_green, list_entry->client_info->nickname, color_normal, color_red, buffer, color_normal); printf("Private message from %s to %s: %s\n", list_entry->client_info->nickname, priv_nick, buffer); } } /* Check if user wants to say something about himself */ ngroups = 2; //TODO: ret = regexec(®ex_stats, message, ngroups, groups, 0); if (ret == 0) { processed = TRUE; int socklen = sizeof(list_entry->client_info->address); printf("%s requested the client list\n", list_entry->client_info->nickname); char **nicks = malloc(sizeof(*nicks) * 1000); int i; for (i = 0; i < 1000; i++) nicks[i] = malloc(sizeof(**nicks) * 30); int count = llist_get_nicknames(&list_start, nicks); memset(buffer, 0, BUF_SIZE_1K); for (i = 0; i < count; i++) { sprintf(buffer, "%s%s%s%s", buffer, color_magenta, nicks[i], color_normal); if(i != (count - 1)) sprintf(buffer, "%s, ", buffer); if(i == (count - 1)) sprintf(buffer, "%s\r\n", buffer); free(nicks[i]); } memset(statsBuf, 0, BUF_SIZE_1K); sprintf(statsBuf, "Max threads: %d\nNumber of active connections: %d\nNumber of clients serviced: %d\nNumber of clients dropped:%d\n",serverStats.max_threads, serverStats.num_of_active_connections,serverStats.num_of_clients_serviced, serverStats.num_of_conn_dropped); printf("Server Stats : \n%s\n", statsBuf); sendto(list_entry->client_info->sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&(list_entry->client_info->address), (socklen_t)socklen); sendto(list_entry->client_info->sockfd, statsBuf, strlen(statsBuf), 0, (struct sockaddr *)&(list_entry->client_info->address), (socklen_t)socklen); free(nicks); } /* Broadcast message */ if (processed == FALSE) { send_broadcast_msg("%s%s:%s %s\r\n", color_green, list_entry->client_info->nickname, color_normal, message); printf("%s: %s", list_entry->client_info->nickname, message); } /* Dump current user list */ llist_show(&list_start); /* Free memory */ regfree(®ex_quit); regfree(®ex_nick); regfree(®ex_msg); regfree(®ex_stats); }