/* \brief Closes gracefully (more or less) the program. This function is called: - when we're running in console - when we're running as a Win32 service (in case we press STOP) It is not called when we are running as a daemon on UNIX, since we do not define a signal in order to terminate gracefully the daemon. This function makes a fast cleanup (it does not clean everything, as you can see from the fact that it uses kill() on UNIX), closes the main socket, free winsock resources (on Win32) and exits the program. */ void main_cleanup(int sign) { #ifndef WIN32 // Sends a KILL signal to all the processes // that share the same process group (i.e. kills all the childs) kill(0, SIGKILL); #endif // FULVIO (bug) // Here we close only the latest 'sockmain' created; if we opened more than one waiting sockets, // only the latest one is closed correctly. if (sockmain) closesocket(sockmain); sock_cleanup(); /* This code is executed under the following conditions: - SIGTERM: we're under UNIX, and the user kills us with 'kill -15' (no matter is we're a daemon or in a console mode) - SIGINT: we're in console mode and the user sends us a Ctrl+C (SIGINT signal), no matter if we're UNIX or Win32 In all these cases, we have to terminate the program. The case that still remains is if we're a Win32 service: in this case, we're a child thread, and we want just to terminate ourself. This is because the exit(0) will be invoked by the main thread, which is blocked waiting that all childs terminates. We are forced to call exit from the main thread otherwise the Win32 service control manager (SCM) does not work well. */ if ( (sign == SIGTERM) || (sign == SIGINT) ) exit(0); else return; }
void cleanup() { for(int i = 0; i < LINECOUNT; i++) { free(lines[i]); } free(lines); sock_cleanup(); }
void syl_cleanup(void) { /* remove temporary files */ remove_all_files(get_tmp_dir()); remove_all_files(get_mime_tmp_dir()); #if GLIB_CHECK_VERSION(2, 6, 0) g_log_set_default_handler(g_log_default_handler, NULL); #endif close_log_file(); sock_cleanup(); if (app) { g_object_unref(app); app = NULL; } }
int main(int argc, char *argv[]) { char ErrBuf[1024]; int CurrentParam; char *Address, *Port; bool IsServer; int AddressFamily; int TransportProtocol; // Initialization IsServer= true; Address= NULL; Port= NULL; AddressFamily= AF_UNSPEC; TransportProtocol= SOCK_STREAM; CurrentParam= 1; while (CurrentParam < argc) { // This is an option if (argv[CurrentParam][0] == '-') { switch (argv[CurrentParam][1]) { case 'h': Usage(); return -1; break; case 's': IsServer= 1; break; case 'c': IsServer= 0; break; case 'u': TransportProtocol= SOCK_DGRAM; break; case 'p': Port= get_parameter(argc, argv, &CurrentParam); break; case 'a': Address= get_parameter(argc, argv, &CurrentParam); break; case 'f': { char *AddrFamily; AddrFamily= get_parameter(argc, argv, &CurrentParam); break; if (AddrFamily != NULL) { AddressFamily= atoi(AddrFamily); if ( (AddressFamily != 4) && (AddressFamily != 6)) printf("Only IPv4 and IPv6 protocols are supported"); else { if (AddressFamily == 4) AddressFamily= AF_INET; else AddressFamily= AF_INET6; } }; }; break; default: { printf ("Option '-%c' not recognized.\n\n", argv[CurrentParam][1]); Usage(); break; } } // Move to the next option CurrentParam++; } } if (Port == NULL) { printf("The port has not been specified.\n\n"); Usage(); return -1; } if ((!IsServer) && (Address == NULL)) { printf("The address has not been specified.\n\n"); Usage(); return -1; } // Initializes socket library if (sock_init(ErrBuf, sizeof(ErrBuf)) == sockFAILURE) { printf("Error initializing SockUtils library: %s\n", ErrBuf); return -1; } printf("\n\n"); if (IsServer) Server(Address, Port, AddressFamily, TransportProtocol); else Client(Address, Port, AddressFamily, TransportProtocol); // Deallocates socket library sock_cleanup(); printf("\n\nNow exiting from the program.\n\n"); return 0; }
/** * @brief Entry point for the program * * Parses arguments for program mode and responds appropriately. * * Preconditions: Proper arguments have been supplied * * Postconditions: * * @param argc Number of arguments supplied * @param argv List of arguments supplied * @return Exit status */ int main(int argc, char **argv) { struct sigaction sigact; struct pipe_res pipe_res; struct shmem_res shmem_res; struct sock_res sock_res; char mode; if (argc < ARGC_MIN) { usage(); } memset(&sigact, 0, sizeof(struct sigaction)); sigact.sa_handler = handle_signal; if (sigaction(SIGQUIT, &sigact, NULL) == -1) { perror("Could not set SIGQUIT handler"); } if (sigaction(SIGHUP, &sigact, NULL) == -1) { perror("Could not set SIGHUP handler"); } if (sigaction(SIGINT, &sigact, NULL) == -1) { perror("Could not set SIGINT handler"); } sigact.sa_handler = SIG_IGN; if (sigaction(SIGPIPE, &sigact, NULL) == -1) { perror("Could not set SIGPIPE handler"); } mode = argv[MODE_ARG][0]; // Only need the first character switch (mode) { case 'p': // Pipe stuff if (pipe_init(argc, argv, &pipe_res) == false) { collect_computes(&pipe_res); exit(EXIT_FAILURE); } pipe_report(&pipe_res); pipe_cleanup(&pipe_res); break; case 'm': // Shmem stuff if (shmem_init(argc, argv, &shmem_res) == false) { exit(EXIT_FAILURE); } while (1) { // Loop until signaled to shut down if (exit_status != EXIT_SUCCESS) { fputs("\r", stderr); break; } } shmem_cleanup(&shmem_res); break; case 's': // Socket stuff if (sock_init(argc, argv, &sock_res) == false) { exit(EXIT_FAILURE); } sock_report(&sock_res); sock_cleanup(&sock_res); break; default: usage(); break; } exit(EXIT_SUCCESS); }
void listen_loop(int do_init) { struct client_struct* new_client; struct np_sock npsock = {.count = 0}; int ret; struct timespec ts; #ifdef NP_SSH ssh_bind sshbind = NULL; #endif #ifdef NP_TLS SSL_CTX* tlsctx = NULL; #endif /* Init */ if (do_init) { #ifdef NP_SSH np_ssh_init(); #endif #ifdef NP_TLS np_tls_init(); #endif if ((ret = pthread_create(&netopeer_state.data_tid, NULL, data_thread, NULL)) != 0) { nc_verb_error("%s: failed to create a thread (%s)", __func__, strerror(ret)); return; } if ((ret = pthread_create(&netopeer_state.netconf_rpc_tid, NULL, netconf_rpc_thread, NULL)) != 0) { nc_verb_error("%s: failed to create a thread (%s)", __func__, strerror(ret)); return; } } /* Main accept loop */ do { new_client = NULL; /* Binds change check */ if (netopeer_options.binds_change_flag) { /* BINDS LOCK */ pthread_mutex_lock(&netopeer_options.binds_lock); sock_cleanup(&npsock); sock_listen(netopeer_options.binds, &npsock); netopeer_options.binds_change_flag = 0; /* BINDS UNLOCK */ pthread_mutex_unlock(&netopeer_options.binds_lock); if (npsock.count == 0) { nc_verb_warning("Server is not listening on any address!"); } } #ifdef NP_SSH sshbind = np_ssh_server_id_check(sshbind); #endif #ifdef NP_TLS tlsctx = np_tls_server_id_check(tlsctx); #endif #ifndef DISABLE_CALLHOME /* Callhome client check */ if (callhome_client != NULL) { /* CALLHOME LOCK */ pthread_mutex_lock(&callhome_lock); new_client = callhome_client; callhome_client = NULL; /* CALLHOME UNLOCK */ pthread_mutex_unlock(&callhome_lock); } #endif /* Listen client check */ if (new_client == NULL) { new_client = sock_accept(&npsock); } /* New client full structure creation */ if (new_client != NULL) { /* Maximum number of sessions check */ if (netopeer_options.max_sessions > 0) { ret = 0; #ifdef NP_SSH ret += np_ssh_session_count(); #endif #ifdef NP_TLS ret += np_tls_session_count(); #endif if (ret >= netopeer_options.max_sessions) { nc_verb_error("Maximum number of sessions reached, droppping the new client."); new_client->to_free = 1; switch (new_client->transport) { #ifdef NP_SSH case NC_TRANSPORT_SSH: client_free_ssh((struct client_struct_ssh*)new_client); break; #endif #ifdef NP_TLS case NC_TRANSPORT_TLS: client_free_tls((struct client_struct_tls*)new_client); break; #endif default: nc_verb_error("%s: internal error (%s:%d)", __func__, __FILE__, __LINE__); } free(new_client); /* sleep to prevent clients from immediate connection retry */ usleep(netopeer_options.response_time*1000); continue; } } switch (new_client->transport) { #ifdef NP_SSH case NC_TRANSPORT_SSH: ret = np_ssh_create_client((struct client_struct_ssh*)new_client, sshbind); if (ret != 0) { new_client->to_free = 1; client_free_ssh((struct client_struct_ssh*)new_client); } break; #endif #ifdef NP_TLS case NC_TRANSPORT_TLS: ret = np_tls_create_client((struct client_struct_tls*)new_client, tlsctx); if (ret != 0) { new_client->to_free = 1; client_free_tls((struct client_struct_tls*)new_client); } break; #endif default: nc_verb_error("Client with an unknown transport protocol, dropping it."); new_client->to_free = 1; ret = 1; } /* client is not valid, some error occured */ if (ret != 0) { free(new_client); continue; } /* add the client into the global clients structure */ /* GLOBAL WRITE LOCK */ pthread_rwlock_wrlock(&netopeer_state.global_lock); client_append(&netopeer_state.clients, new_client); /* GLOBAL WRITE UNLOCK */ pthread_rwlock_unlock(&netopeer_state.global_lock); } } while (!quit && !restart_soft); /* Cleanup */ sock_cleanup(&npsock); #ifdef NP_SSH ssh_bind_free(sshbind); #endif #ifdef NP_TLS SSL_CTX_free(tlsctx); #endif if (!restart_soft) { if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { nc_verb_warning("%s: failed to get time (%s)", strerror(errno)); } ts.tv_sec += THREAD_JOIN_QUIT_TIMEOUT; /* wait for all the clients to exit nicely themselves */ if ((ret = pthread_timedjoin_np(netopeer_state.netconf_rpc_tid, NULL, &ts)) != 0) { nc_verb_warning("%s: failed to join the netconf RPC thread (%s)", __func__, strerror(ret)); if (ret == ETIMEDOUT) { pthread_cancel(netopeer_state.netconf_rpc_tid); } } if ((ret = pthread_timedjoin_np(netopeer_state.data_tid, NULL, &ts)) != 0) { nc_verb_warning("%s: failed to join the SSH data thread (%s)", __func__, strerror(ret)); if (ret == ETIMEDOUT) { pthread_cancel(netopeer_state.data_tid); } } #ifdef NP_SSH np_ssh_cleanup(); #endif #ifdef NP_TLS np_tls_cleanup(); #endif } } int main(int argc, char** argv) { struct sigaction action; sigset_t block_mask; char *aux_string = NULL, path[PATH_MAX]; int next_option; int daemonize = 0, len; int listen_init = 1; struct np_module* netopeer_module = NULL, *server_module = NULL; /* initialize message system and set verbose and debug variables */ if ((aux_string = getenv(ENVIRONMENT_VERBOSE)) == NULL) { netopeer_options.verbose = NC_VERB_ERROR; } else { netopeer_options.verbose = atoi(aux_string); } aux_string = NULL; /* for sure to avoid unwanted changes in environment */ /* parse given options */ while ((next_option = getopt(argc, argv, OPTSTRING)) != -1) { switch (next_option) { case 'd': daemonize = 1; break; case 'h': print_usage(argv[0]); break; case 'v': netopeer_options.verbose = atoi(optarg); break; case 'V': print_version(argv[0]); break; default: print_usage(argv[0]); break; } } /* set signal handler */ sigfillset (&block_mask); action.sa_handler = signal_handler; action.sa_mask = block_mask; action.sa_flags = 0; sigaction(SIGINT, &action, NULL); sigaction(SIGQUIT, &action, NULL); sigaction(SIGABRT, &action, NULL); sigaction(SIGTERM, &action, NULL); sigaction(SIGHUP, &action, NULL); nc_callback_print(clb_print); /* normalize value if not from the enum */ if (netopeer_options.verbose > NC_VERB_DEBUG) { netopeer_options.verbose = NC_VERB_DEBUG; } nc_verbosity(netopeer_options.verbose); /* go to the background as a daemon */ if (daemonize == 1) { if (daemon(0, 0) != 0) { nc_verb_error("Going to background failed (%s)", strerror(errno)); return EXIT_FAILURE; } openlog("netopeer-server", LOG_PID, LOG_DAEMON); } else { openlog("netopeer-server", LOG_PID|LOG_PERROR, LOG_DAEMON); } /* make sure we were executed by root */ if (geteuid() != 0) { nc_verb_error("Failed to start, must have root privileges."); return EXIT_FAILURE; } /* * this initialize the library and check potential ABI mismatches * between the version it was compiled for and the actual shared * library used. */ LIBXML_TEST_VERSION /* initialize library including internal datastores and maybee something more */ if (nc_init(NC_INIT_ALL | NC_INIT_MULTILAYER) < 0) { nc_verb_error("Library initialization failed."); return EXIT_FAILURE; } server_start = 1; restart: /* start NETCONF server module */ if ((server_module = calloc(1, sizeof(struct np_module))) == NULL) { nc_verb_error("Creating necessary NETCONF server plugin failed!"); return EXIT_FAILURE; } server_module->name = strdup(NCSERVER_MODULE_NAME); if (module_enable(server_module, 0)) { nc_verb_error("Starting necessary NETCONF server plugin failed!"); free(server_module->name); free(server_module); return EXIT_FAILURE; } /* start netopeer device module - it will start all modules that are * in its configuration and in server configuration */ if ((netopeer_module = calloc(1, sizeof(struct np_module))) == NULL) { nc_verb_error("Creating necessary Netopeer plugin failed!"); module_disable(server_module, 1); return EXIT_FAILURE; } netopeer_module->name = strdup(NETOPEER_MODULE_NAME); if (module_enable(netopeer_module, 0)) { nc_verb_error("Starting necessary Netopeer plugin failed!"); module_disable(server_module, 1); free(netopeer_module->name); free(netopeer_module); return EXIT_FAILURE; } server_start = 0; nc_verb_verbose("Netopeer server successfully initialized."); listen_loop(listen_init); /* unload Netopeer module -> unload all modules */ module_disable(server_module, 1); module_disable(netopeer_module, 1); /* main cleanup */ if (!restart_soft) { /* close libnetconf only when shutting down or hard restarting the server */ nc_close(); } if (restart_soft) { nc_verb_verbose("Server is going to soft restart."); restart_soft = 0; listen_init = 0; goto restart; } else if (restart_hard) { nc_verb_verbose("Server is going to hard restart."); len = readlink("/proc/self/exe", path, PATH_MAX); path[len] = 0; xmlCleanupParser(); execv(path, argv); } /* *Free the global variables that may *have been allocated by the parser. */ xmlCleanupParser(); return EXIT_SUCCESS; }
static void sock_listen(const struct np_bind_addr* addrs, struct np_sock* npsock) { const int optVal = 1; const socklen_t optLen = sizeof(optVal); char is_ipv4; struct sockaddr_storage saddr; struct sockaddr_in* saddr4; struct sockaddr_in6* saddr6; if (addrs == NULL || npsock == NULL) { return; } if (npsock->count > 0) { sock_cleanup(npsock); } /* * Always have the last pollfd structure ready - * this way we can reuse it safely (continue;) * every time an error occurs during its * modification. */ npsock->count = 1; npsock->pollsock = calloc(1, sizeof(struct pollfd)); npsock->transport = calloc(1, sizeof(NC_TRANSPORT)); /* for every address and port a pollfd struct is created */ for (;addrs != NULL; addrs = addrs->next) { npsock->transport[npsock->count-1] = addrs->transport; if (strchr(addrs->addr, ':') == NULL) { is_ipv4 = 1; } else { is_ipv4 = 0; } npsock->pollsock[npsock->count-1].fd = socket((is_ipv4 ? AF_INET : AF_INET6), SOCK_STREAM, 0); if (npsock->pollsock[npsock->count-1].fd == -1) { nc_verb_error("%s: could not create socket (%s)", __func__, strerror(errno)); continue; } if (setsockopt(npsock->pollsock[npsock->count-1].fd, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal, optLen) != 0) { nc_verb_error("%s: could not set socket SO_REUSEADDR option (%s)", __func__, strerror(errno)); continue; } bzero(&saddr, sizeof(struct sockaddr_storage)); if (is_ipv4) { saddr4 = (struct sockaddr_in*)&saddr; saddr4->sin_family = AF_INET; saddr4->sin_port = htons(addrs->port); if (inet_pton(AF_INET, addrs->addr, &saddr4->sin_addr) != 1) { nc_verb_error("%s: failed to convert IPv4 address \"%s\"", __func__, addrs->addr); continue; } if (bind(npsock->pollsock[npsock->count-1].fd, (struct sockaddr*)saddr4, sizeof(struct sockaddr_in)) == -1) { nc_verb_error("%s: could not bind \"%s\" (%s)", __func__, addrs->addr, strerror(errno)); continue; } } else { saddr6 = (struct sockaddr_in6*)&saddr; saddr6->sin6_family = AF_INET6; saddr6->sin6_port = htons(addrs->port); if (inet_pton(AF_INET6, addrs->addr, &saddr6->sin6_addr) != 1) { nc_verb_error("%s: failed to convert IPv6 address \"%s\"", __func__, addrs->addr); continue; } if (bind(npsock->pollsock[npsock->count-1].fd, (struct sockaddr*)saddr6, sizeof(struct sockaddr_in6)) == -1) { nc_verb_error("%s: could not bind \"%s\" (%s)", __func__, addrs->addr, strerror(errno)); continue; } } if (listen(npsock->pollsock[npsock->count-1].fd, 5) == -1) { nc_verb_error("%s: unable to start listening on \"%s\" (%s)", __func__, addrs->addr, strerror(errno)); continue; } npsock->pollsock[npsock->count-1].events = POLLIN; npsock->pollsock = realloc(npsock->pollsock, (npsock->count+1)*sizeof(struct pollfd)); bzero(npsock->pollsock+npsock->count, sizeof(struct pollfd)); npsock->transport = realloc(npsock->transport, (npsock->count+1)*sizeof(NC_TRANSPORT)); ++npsock->count; } /* the last pollsock is not valid */ --npsock->count; }
void riack_cleanup() { sock_cleanup(); }
/* * Last function, exit with grace. */ void End_game(void) { player_t *pl; char msg[MSG_LEN]; #if !defined(_WINDOWS) if (termsig != 0) warn("Terminating on signal %d", termsig); #endif record = rrecord; playback = rplayback; /* Could be called from signal handler */ if (ShutdownServer == 0) { warn("Shutting down..."); snprintf(msg, sizeof(msg), "shutting down: %s", ShutdownReason); } else snprintf(msg, sizeof(msg), "server exiting"); teamcup_game_over(); while (NumPlayers > 0) { /* Kick out all remaining players */ pl = Player_by_index(NumPlayers - 1); if (pl->conn == NULL) Delete_player(pl); else Destroy_connection(pl->conn, msg); } record = playback = 0; while (NumSpectators > 0) { pl = Player_by_index(spectatorStart + NumSpectators - 1); Destroy_connection(pl->conn, msg); } record = rrecord; playback = rplayback; if (options.recordMode != 0) { options.recordMode = 0; Init_recording(); } /* Tell meta server that we are gone. */ Meta_gone(); Contact_cleanup(); /* Ranking. */ Rank_write_webpage(); Rank_write_rankfile(); Free_players(); Free_shots(); World_free(); Free_cells(); Free_options(); Log_game("END"); sock_cleanup(); #if !defined(_WINDOWS) if (termsig != 0) { signal(termsig, SIG_DFL); raise(termsig); } #endif exit(0); }