summaryrefslogtreecommitdiff
path: root/cwebhook.c
blob: 5dd6126bc103d04f41bf171c3f1a61bb5b715f24 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <inttypes.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <locale.h>
#include <poll.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <cjson/cJSON.h>
#include "structs.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;
}