00001
00009 #include "server.h"
00010
00016 void Close(int fd)
00017 {
00018 int return_value;
00019 return_value=close(fd);
00020 if(return_value<0)
00021 {
00022 fprintf(stderr, "Cannot close\n");
00023 }
00024 }
00025
00030 void close_properly(int signal)
00031 {
00032 int i;
00033
00034 for(i = 0; i <= maxi; i++)
00035 {
00036 if(client[i].fd < 0)
00037 continue;
00038 shutdown(client[i].fd, 2);
00039 }
00040
00041
00042 mysql_close(connection1);
00043
00044 Close(listen_file_descriptor);
00045 exit(0);
00046 }
00047
00055 ssize_t Write(int fd, const void *buf, size_t count)
00056 {
00057 ssize_t return_value;
00058 return_value=write(fd,buf,count);
00059 if(return_value < 0)
00060 {
00061 fprintf(stderr, "Write failed\n");
00062 }
00063 return return_value;
00064 }
00065
00074 int Socket(int domain, int type, int protocol)
00075 {
00076 int return_value;
00077 return_value = socket(domain, type, protocol);
00078 if(return_value < 0)
00079 {
00080 strcpy(err_msg, "Cannot open socket.\n");
00081 success = 0;
00082 }
00083 return return_value;
00084 }
00085
00092 void Bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
00093 {
00094 int return_value;
00095 return_value= bind(sockfd,my_addr,addrlen);
00096 if(return_value < 0)
00097 {
00098 strcpy(err_msg, "Cannot bind");
00099 success = 0;
00100 }
00101 }
00102
00107 void Listen(int sockfd, int backlog)
00108 {
00109 int return_value;
00110 return_value = listen(sockfd, backlog);
00111 if(return_value < 0)
00112 {
00113 strcpy(err_msg, "Cannot listen");
00114 success = 0;
00115 }
00116 }
00117
00126 int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
00127 {
00128 int file_descriptor;
00129 file_descriptor = accept(sockfd, addr, addrlen);
00130 if(file_descriptor < 0)
00131 {
00132 fprintf(stderr, "accept() failed.");
00133 exit(1);
00134 }
00135 return file_descriptor;
00136 }
00137
00138
00145 ssize_t Read(int fd, void *buf, size_t count)
00146 {
00147 ssize_t characters_read;
00148 characters_read = read(fd, buf, count);
00149 if(characters_read < 0)
00150 {
00151 fprintf(stderr, "Can't read\n");
00152 }
00153 return characters_read;
00154 }
00155
00161 int isNickExists(char * nick)
00162 {
00163 int i;
00164
00165 for(i = 0; i <= maxi; i++)
00166 {
00167 if(client[i].fd < 0)
00168 {
00169 continue;
00170 }
00171 if(strcasecmp(client[i].nick, nick) == 0)
00172 {
00173 return 1;
00174 }
00175 }
00176
00177 return 0;
00178 }
00179
00184 void insert_row(char * query)
00185 {
00186 int result;
00187
00188 result = mysql_query (connection1, query);
00189 if (result!=0)
00190 {
00191 fprintf (stderr, "Could not insert data as %d: %s\n",
00192 mysql_errno (connection1),
00193 mysql_error (connection1));
00194 close_properly(1);
00195 }
00196 }
00197
00201 void write_all(char *data)
00202 {
00203 int i;
00204 const time_t timer = time(NULL);
00205 char tmp[BUFFER];
00206 char tm[BUFFER];
00207 char query[BUFFER];
00208 struct transmit_unit trs_blk;
00209
00210 strcpy(tm, ctime(&timer));
00211 tm[strlen(tm) - 1] = 0;
00212
00213
00214 strcpy(trs_blk.ip, ip);
00215 strcpy(trs_blk.nick, nick);
00216 strcpy(trs_blk.time, tm);
00217 sprintf(tmp, "%s", data);
00218 strcpy(trs_blk.msg, tmp);
00219
00220
00221 sprintf(tmp, "[%s] <%s>:%s\n", tm, nick, data);
00222 gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, tmp, -1, "blue_fg", "lmarg", NULL);
00223
00224
00225 sprintf(query, "insert into cs3002_table (timestamp, message, client_ip, client_nick) VALUES ('%s', '%s', '%s', '%s')", tm, data, ip, nick);
00226 insert_row(query);
00227
00228
00229 for(i = 0; i <=maxi; i++)
00230 {
00231 if(client[i].fd < 0)
00232 continue;
00233 Write(client[i].fd, &trs_blk, sizeof(struct transmit_unit));
00234 }
00235 }
00236
00242 void add_widget_with_label(GtkContainer *box, gchar *caption, GtkWidget *widget)
00243 {
00244 GtkWidget *label = gtk_label_new(caption);
00245 GtkWidget *hbox = gtk_hbox_new(TRUE, 4);
00246
00247 gtk_container_add(GTK_CONTAINER (hbox), label);
00248 gtk_container_add(GTK_CONTAINER (hbox), widget);
00249 gtk_container_add(box, hbox);
00250 }
00251
00257 void end_program(GtkWidget *widget1, gpointer data)
00258 {
00259 int i;
00260
00261 for(i = 0; i <= maxi; i++)
00262 {
00263 if(client[i].fd < 0)
00264 continue;
00265
00266 shutdown(client[i].fd, 2);
00267 }
00268
00269
00270 mysql_close(connection1);
00271
00272 Close(listen_file_descriptor);
00273
00274 gtk_main_quit();
00275 }
00276
00282 void onExit(GtkWidget *widget1, gpointer data)
00283 {
00284 exit(1);
00285 }
00286
00287
00290 void mysql_connect_create_table()
00291 {
00292 int result;
00293 connection1 = mysql_init (NULL);
00294 if(mysql_real_connect(connection1, "localhost", "cs3002_user", "cs3002_password", "cs3002_db", 0, NULL, 0))
00295 {
00296 printf ("Database Connection successful\n");
00297 result = mysql_query (connection1, "create table cs3002_table (id integer NOT NULL AUTO_INCREMENT PRIMARY KEY, timestamp varchar(4096), message varchar(4096), client_ip varchar(4096), client_nick varchar(4096))");
00298 }
00299 else
00300 {
00301 fprintf (stderr, "Connection failed\n");
00302 if (mysql_errno (connection1))
00303 {
00304 fprintf (stderr, "Connection error %d: %s\n",
00305 mysql_errno (connection1),
00306 mysql_error (connection1));
00307 }
00308 exit(1);
00309 }
00310 }
00311
00318 void connect_server(GtkWidget *widget1, gpointer data)
00319 {
00320 struct sockaddr_in server_address;
00321 GtkWidget *dialog;
00322 success = 1;
00323 printf("Server Starting..\n");
00324 listen_file_descriptor = Socket(AF_INET, SOCK_STREAM, 0);
00325 if(success == 1)
00326 {
00327 bzero(&server_address, sizeof(server_address));
00328 server_address.sin_family = AF_INET;
00329 server_address.sin_addr.s_addr = htonl(INADDR_ANY);
00330 server_address.sin_port = htons(atoi(gtk_entry_get_text(GTK_ENTRY(entry_port))));
00331 Bind(listen_file_descriptor, (struct sockaddr *) &server_address, sizeof(server_address));
00332 }
00333
00334 if(success == 1)
00335 {
00336 Listen(listen_file_descriptor, 10);
00337 }
00338 if(success == 1)
00339 {
00340 gtk_main_quit();
00341 }
00342 else
00343 {
00344 dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,"%s", err_msg);
00345 gtk_dialog_run (GTK_DIALOG (dialog));
00346 gtk_widget_destroy (dialog);
00347 }
00348 }
00349
00354 void * start_server(void * arg)
00355 {
00356 int connection_file_descriptor;
00357 int socket_file_descriptor;
00358 int nready;
00359 char input_data[BUFFER];
00360 char temp_buffer[BUFFER];
00361 int i, k, maxfd, n;
00362 gboolean valid;
00363 gchar *nick_name;
00364
00365 socklen_t clilen;
00366
00367 struct sockaddr_in client_address;
00368 struct sigaction act1;
00369 struct client_data end_client;
00370
00371 fd_set read_set, all_set;
00372
00373 gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "Server started...\n", -1, "blue_fg", "lmarg", NULL);
00374
00375
00376 act1.sa_handler = close_properly;
00377 sigemptyset(&act1.sa_mask);
00378 act1.sa_flags=0;
00379 sigaction(SIGINT, &act1, 0);
00380
00381
00382 maxfd = listen_file_descriptor;
00383 maxi = -1;
00384
00385 for(i = 0; i < FD_SETSIZE; i++)
00386 {
00387 client[i].fd = -1;
00388 strcpy(client[i].ip, "");
00389 strcpy(client[i].nick,"");
00390 }
00391
00392 FD_ZERO(&all_set);
00393 FD_SET(listen_file_descriptor, &all_set);
00394
00395 while(1)
00396 {
00397 read_set = all_set;
00398 nready = select(maxfd+1, &read_set, NULL, NULL, NULL);
00399
00400
00401 if(FD_ISSET(listen_file_descriptor, &read_set))
00402 {
00403 clilen = sizeof(client_address);
00404
00405 connection_file_descriptor = Accept(listen_file_descriptor, (struct sockaddr *) &client_address, &clilen);
00406
00407 if((n = Read(connection_file_descriptor, input_data, BUFFER)) == 0)
00408 {
00409 printf("Failed init\n");
00410 shutdown(connection_file_descriptor, 2);
00411 }
00412 else
00413 {
00414 input_data[n] = '\0';
00415 if(isNickExists(input_data))
00416 {
00417 printf("Failed in nick\n");
00418 shutdown(connection_file_descriptor, 2);
00419 }
00420 else
00421 {
00422 for (i = 0; i < FD_SETSIZE; i++)
00423 {
00424 if (client[i].fd < 0)
00425 {
00426
00427 client[i].fd = connection_file_descriptor;
00428 strcpy(client[i].ip, inet_ntoa(client_address.sin_addr));
00429 strcpy(client[i].nick, input_data);
00430
00431
00432 gtk_list_store_append(list_store, &t_iter);
00433 gtk_list_store_set (list_store, &t_iter, 0, client[i].nick, 1, client[i].ip, -1);
00434
00435 break;
00436 }
00437 }
00438
00439 if(i == FD_SETSIZE)
00440 {
00441 shutdown(connection_file_descriptor, 2);
00442 }
00443 else
00444 {
00445
00446 FD_SET(connection_file_descriptor, &all_set);
00447
00448
00449 if(connection_file_descriptor > maxfd)
00450 {
00451 maxfd = connection_file_descriptor;
00452 }
00453
00454
00455 if(i > maxi)
00456 {
00457 maxi = i;
00458 }
00459
00460
00461 end_client.fd = -1;
00462 strcpy(end_client.ip, "");
00463 strcpy(end_client.nick, "");
00464
00465
00466 for(k = 0; k <= maxi; k++)
00467 {
00468 if(client[k].fd < 0)
00469 continue;
00470
00471 Write(connection_file_descriptor, &client[k], sizeof(struct client_data));
00472 }
00473
00474 Write(connection_file_descriptor, &end_client, sizeof(struct client_data));
00475
00476 for(k = 0; k <= 50; k++);
00477
00478 sprintf(temp_buffer, "connected..");
00479 strcpy(nick, client[i].nick);
00480 strcpy(ip, client[i].ip);
00481 write_all(temp_buffer);
00482 }
00483 }
00484 }
00485
00486
00487 if(--nready <= 0)
00488 {
00489 continue;
00490 }
00491 }
00492
00493
00494 for(i = 0; i <= maxi; i++)
00495 {
00496 if((socket_file_descriptor = client[i].fd) < 0)
00497 {
00498 continue;
00499 }
00500
00501 if(FD_ISSET(socket_file_descriptor, &read_set))
00502 {
00503 if ((n = Read(socket_file_descriptor, input_data, BUFFER)) <= 0)
00504 {
00505
00506 Close(socket_file_descriptor);
00507 FD_CLR(socket_file_descriptor, &all_set);
00508
00509 sprintf(temp_buffer, "disconnected..");
00510 strcpy(nick, client[i].nick);
00511 strcpy(ip, client[i].ip);
00512
00513
00514 client[i].fd = -1;
00515 strcpy(client[i].nick ,"");
00516 strcpy(client[i].ip,"");
00517
00518 write_all(temp_buffer);
00519
00520
00521 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list_store), &t_iter);
00522 while(valid)
00523 {
00524 gtk_tree_model_get(GTK_TREE_MODEL(list_store), &t_iter, 0, &nick_name, -1);
00525 if(strcmp(nick_name, nick) == 0)
00526 {
00527 gtk_list_store_remove(list_store, &t_iter);
00528 g_free(nick_name);
00529 break;
00530 }
00531 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(list_store), &t_iter);
00532 g_free(nick_name);
00533 }
00534
00535 }
00536 else
00537 {
00538
00539 input_data[n] = '\0';
00540 sprintf(temp_buffer, "%s", input_data);
00541 strcpy(nick, client[i].nick);
00542 strcpy(ip, client[i].ip);
00543
00544 write_all(temp_buffer);
00545 }
00546
00547
00548 if (--nready <= 0)
00549 {
00550 break;
00551 }
00552 }
00553 }
00554 }
00555
00556
00557 }
00558
00568 int main(int argc, char * argv[])
00569 {
00570 GtkWidget *window;
00571 GtkWidget *window1;
00572 GtkWidget *mainbox;
00573 GtkWidget *view1;
00574 GtkWidget *view2;
00575 GtkWidget *scrolled_window1;
00576 GtkWidget *scrolled_window2;
00577 GtkWidget *button_connect;
00578 GtkWidget *vbox;
00579 GtkCellRenderer *renderer;
00580
00581 pthread_t child1;
00582 int return_value;
00583
00584 gtk_init(&argc, &argv);
00585
00586
00587
00588 window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00589 gtk_window_set_default_size(GTK_WINDOW(window1), 300, 200);
00590 g_signal_connect(GTK_OBJECT(window1), "delete_event", GTK_SIGNAL_FUNC(onExit), NULL);
00591
00592 vbox = gtk_vbox_new(TRUE, 5);
00593 entry_port = gtk_entry_new();
00594 button_connect = gtk_button_new_with_label("Connect");
00595
00596 add_widget_with_label(GTK_CONTAINER(vbox), "Enter the Listening Port Number : ", entry_port);
00597 gtk_box_pack_start(GTK_BOX(vbox), button_connect, TRUE, FALSE, 5);
00598 gtk_container_add(GTK_CONTAINER(window1), vbox);
00599 g_signal_connect(GTK_OBJECT(button_connect), "clicked", GTK_SIGNAL_FUNC(connect_server), NULL);
00600
00601 gtk_widget_show_all(window1);
00602 gtk_main();
00603
00604
00605 gtk_widget_destroy (window1);
00606
00607
00608
00609 window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
00610 gtk_window_set_title(GTK_WINDOW(window), "LAN-Messenger Server");
00611 gtk_window_set_default_size(GTK_WINDOW(window),1040,600);
00612 g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(end_program),NULL);
00613
00614
00615 mainbox = gtk_hbox_new (TRUE, 2);
00616
00617
00618 view1 = gtk_text_view_new();
00619 gtk_text_view_set_editable(GTK_TEXT_VIEW(view1), FALSE);
00620 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view1));
00621 gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0);
00622 gtk_text_buffer_create_tag(buffer, "blue_fg", "foreground", "blue", NULL);
00623 gtk_text_buffer_create_tag(buffer, "lmarg", "left_margin", 5, NULL);
00624
00625
00626 scrolled_window1=gtk_scrolled_window_new(NULL, NULL);
00627
00628 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window1), view1);
00629
00630
00631
00632 view2 = gtk_tree_view_new ();
00633 renderer = gtk_cell_renderer_text_new ();
00634 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view2), -1, "Nick", renderer, "text", 0, NULL);
00635
00636 renderer = gtk_cell_renderer_text_new ();
00637 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view2), -1, "Ip Address", renderer, "text", 1, NULL);
00638
00639 list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
00640 gtk_tree_view_set_model (GTK_TREE_VIEW (view2), GTK_TREE_MODEL(list_store));
00641
00642
00643
00644 scrolled_window2=gtk_scrolled_window_new(NULL, NULL);
00645
00646 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window2), view2);
00647
00648 gtk_box_pack_start (GTK_BOX (mainbox), scrolled_window1, TRUE, TRUE, 0);
00649 gtk_box_pack_start (GTK_BOX (mainbox), scrolled_window2, TRUE, TRUE, 0);
00650 gtk_container_add (GTK_CONTAINER (window), mainbox);
00651 gtk_widget_show_all (window);
00652
00653 mysql_connect_create_table();
00654
00655
00656 return_value = pthread_create(&child1, NULL, start_server, NULL);
00657 if(return_value !=0)
00658 {
00659 perror("Thread 1 creation failed");
00660 exit(EXIT_FAILURE);
00661 }
00662
00663 gtk_main();
00664 return 0;
00665 }