/* B01902062 èĉşç */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "common.h" #include "server.h" #include "proc.h" #include <signal.h> #include <stdio.h> #include <string.h> #include <sys/select.h> #include <sys/time.h> #include <unistd.h> static volatile sig_atomic_t proc_message_request; static volatile sig_atomic_t proc_quit_request; static void proc_quit_request_setter (int signo) { proc_quit_request = 1; } static void proc_message_request_setter (int signo) { proc_message_request = 1; } static void proc_message_print (server* svr, request* req, int maxfd) { putchar ('\n'); printf ( "Dump server information ...\n" #ifdef READ_SERVER " This is read_server\n" #endif #ifdef WRITE_SERVER " This is write_server\n" #endif " Server hostname: %s\n" " Server port: %hu\n" " Server maxfd: %d\n" " Server is listening on fd %d\n", svr->hostname, svr->port, maxfd, svr->listen_fd); puts ("Dump request table ..."); for (int i = 0; i < maxfd; i++) { if (req[i].active) { printf ( " Client %d hostname: %s\n" " Client %d filename: %s\n" " Client %d filename done: %s\n" " Client %d transfer started: %s\n", i, req[i].host, i, req[i].filename, i, req[i].header_done ? "true" : "false", i, req[i].header_accept ? "true" : "false"); } } puts ("Dump file table ..."); for (int i = 0; i < maxfd; i++) { if (svr->file_table->flist[i].active) { printf ( " Entry %d reference count: %d\n" " Entry %d device: %llu\n" " Entry %d inode: %llu\n" " Entry %d file descriptors:", i, svr->file_table->flist[i].ref_count, i, (unsigned long long)svr->file_table->flist[i].fdev, i, (unsigned long long)svr->file_table->flist[i].fino, i); for (int j = 0; j < maxfd; j++) { if (FD_ISSET (j, &svr->file_table->flist[i].fset)) printf (" %d", j); } putchar ('\n'); } } puts ("Type Ctrl-\\ to terminate the server\n"); proc_message_request = 0; } #ifndef HAVE_GETDTABLESIZE static int my_getdtablesize (void) { long rval = sysconf (_SC_OPEN_MAX); if (rval < 0) { # ifdef _POSIX_OPEN_MAX rval = _POSIX_OPEN_MAX # else rval = 20; # endif } return rval; } #endif int main (int argc, char** argv) { if (argc != 2) { fprintf(stderr, "usage: %s [port]\n", argv[0]); exit(1); } // Setup signal handlers struct sigaction signal_action = { .sa_handler = SIG_IGN, .sa_flags = 0 }; sigemptyset (&signal_action.sa_mask); sigaction (SIGPIPE, &signal_action, NULL); signal_action.sa_handler = proc_message_request_setter; sigaction (SIGINT, &signal_action, NULL); signal_action.sa_handler = proc_quit_request_setter; sigaction (SIGQUIT, &signal_action, NULL); // Get file descripter table size #ifdef HAVE_GETDTABLESIZE int maxfd = getdtablesize(); #else int maxfd = my_getdtablesize(); #endif if (maxfd < 0) e_err_exit ("getdtablesize"); // Initialize server server svr; // server server_init(&svr, (unsigned short) atoi(argv[1]), maxfd); // Initialize request table request* requestP = NULL; // point to a list of requests requestP = (request*) e_malloc(sizeof(request) * maxfd); for (int i = 0; i < maxfd; i++) request_init(&requestP[i]); requestP[svr.listen_fd].conn_fd = svr.listen_fd; strcpy(requestP[svr.listen_fd].host, svr.hostname); // Loop for handling connections printf("\nstarting on %.80s, port %d, fd %d, maxfd %d ...\n", svr.hostname, svr.port, svr.listen_fd, maxfd); while (!proc_quit_request) { procconn (&svr, requestP, maxfd, (struct timeval) { 1, 0 }); if (proc_message_request) { proc_message_print (&svr, requestP, maxfd); } } printf("\nquitting...\n"); for (int i = 0; i < maxfd; i++) { if (requestP[i].filename != NULL) { free (requestP[i].filename); requestP[i].filename = NULL; } } free(requestP); server_free(&svr); return 0; }