#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "structs.h" #include "str_fns.h" #include "https_server_structs.h" #include "log.h" #include "load_config.h" #include "load_webhooks.h" #include "socket_init.h" #include "https_server.h" server_socket_t ssocket; http_request_data_t hrequest; client_info_t cinfo; webhooks_data_t whinfo; server_config_t sconfig; log_file_t ldata; void safe_exit( int sigc, siginfo_t *s_info, void *ectx ){ if ( ssocket.tls_context != NULL ) SSL_CTX_free( ssocket.tls_context ); if ( ssocket.client_socket_fd > 0 ) close( ssocket.client_socket_fd ); if ( ssocket.socket_fd > 0 ) close( ssocket.socket_fd ); if ( sconfig.config_parsed != NULL ) cJSON_Delete( sconfig.config_parsed ); if ( whinfo.webhooks_parsed != NULL ) cJSON_Delete( whinfo.webhooks_parsed ); if ( ldata.log_file != NULL ) fclose( ldata.log_file ); if ( sigc == 11 || s_info->si_signo == 11 ){ perror( "status" ); fprintf( stderr, "segfault (address: %p)\n", s_info->si_addr ); } return; } struct sigaction s_act; struct sigaction s_p; void sigp_handler( int ecd ){ fprintf( stderr, "Received connection invalid (error code %i)\n", ecd ); return; } int main( int arg_c, char *args[] ){ setlocale( LC_ALL, "C" ); if ( setvbuf(stdout, NULL, _IOLBF, 0) != 0 ){ fputs( "Failed to set stdout to be line buffered\n", stderr ); return EXIT_FAILURE; } if ( setvbuf(stderr, NULL, _IOLBF, 0) != 0 ){ fputs( "Failed to set stderr to be line buffered\n", stderr ); return EXIT_FAILURE; } if ( sigemptyset(&s_act.sa_mask) != 0 ){ perror( "failed to initialize empty set" ); return EXIT_FAILURE; } s_act.sa_flags = SA_SIGINFO | SA_RESTART; s_act.sa_sigaction = &safe_exit; if ( sigemptyset(&s_p.sa_mask) != 0 ){ perror( "failed to initialize empty set" ); return EXIT_FAILURE; } s_p.sa_handler = &sigp_handler; if ( sigaction(SIGSEGV, (const struct sigaction*)&s_act, NULL) != 0 ){ perror( "failed to register SIGSEGV handler" ); return EXIT_FAILURE; } if ( sigaction(SIGINT, (const struct sigaction*)&s_act, NULL) != 0 ){ perror( "failed to register SIGINT handler" ); return EXIT_FAILURE; } if ( sigaction(SIGPIPE, (const struct sigaction*)&s_p, NULL) != 0 ){ perror( "failed to register SIGPIPE handler" ); return EXIT_FAILURE; } if ( arg_c <= 1 ){ fprintf( stdout, "No configuration file specified\nUsage: %s [config file]\n", args[0] ); return EXIT_FAILURE; } fputs( "Loading config\n", stdout ); if ( load_config(args[1], &sconfig) != CONFIG_LOAD_SUCCESS ){ fputs( "Failed to load config\n", stderr ); return EXIT_FAILURE; } fputs( "Config loaded\n", stdout ); fputs( "Initializing log with configured options\n", stdout ); if ( log_init(&sconfig, &ldata) != LOG_INIT_SUCCESS ){ fputs( "Failed to initialize log\n", stderr ); return EXIT_FAILURE; } fputs( "Log initialized\n", stdout ); fputs( "Loading webhooks\n", stdout ); if ( load_webhooks(sconfig.webhooks_file->valuestring, &whinfo) != WH_LOAD_SUCCESS ){ fputs( "Failed to load webhooks\n", stderr ); return EXIT_FAILURE; } fputs( "Webhooks loaded\n", stdout ); fputs( "Initializing socket\n", stdout ); if ( init_socket(&ssocket, &sconfig) != SOCKET_INIT_SUCCESS ){ fputs( "Failed to initialize socket\n", stderr ); return EXIT_FAILURE; } fputs( "Socket initialized\n", stdout ); server_start( &ssocket, &cinfo, &sconfig, &whinfo, &hrequest, &ldata ); fputs( "Server terminated\n", stdout ); return EXIT_SUCCESS; }