42 printf(" --ssl / -S use SSL\n"); |
44 printf(" --ssl / -S use SSL\n"); |
43 printf(" --log-database database connection string for logging\n"); |
45 printf(" --log-database database connection string for logging\n"); |
44 printf(" --log-channel channel to log\n"); |
46 printf(" --log-channel channel to log\n"); |
45 } |
47 } |
46 |
48 |
|
49 /** |
|
50 * Context for async nexus operation |
|
51 */ |
|
52 struct nexus_ctx { |
|
53 /** The libevent base */ |
|
54 struct event_base *ev_base; |
|
55 |
|
56 /** The one IRC network */ |
|
57 struct irc_net *net; |
|
58 }; |
|
59 |
|
60 void on_sigint (evutil_socket_t sig, short what, void *arg) |
|
61 { |
|
62 struct nexus_ctx *ctx = arg; |
|
63 |
|
64 (void) sig; |
|
65 (void) what; |
|
66 |
|
67 if (ctx->net && ctx->net->conn && !ctx->net->conn->quitting) { |
|
68 log_info("Quitting..."); |
|
69 |
|
70 // quit it |
|
71 irc_net_quit(ctx->net, "Goodbye, cruel world ;("); |
|
72 |
|
73 } else { |
|
74 log_error("Aborting"); |
|
75 |
|
76 // die |
|
77 if (ctx->net) { |
|
78 irc_net_destroy(ctx->net); |
|
79 ctx->net = NULL; |
|
80 } |
|
81 |
|
82 // exit |
|
83 event_base_loopexit(ctx->ev_base, NULL); |
|
84 } |
|
85 } |
|
86 |
47 int main (int argc, char **argv) |
87 int main (int argc, char **argv) |
48 { |
88 { |
49 int opt, option_index; |
89 int opt, option_index; |
50 struct event_base *ev_base; |
90 struct nexus_ctx ctx; |
51 struct irc_net *net; |
91 struct signals *signals; |
52 struct error_info err; |
92 struct error_info err; |
53 |
93 |
54 struct irc_net_info net_info = { |
94 struct irc_net_info net_info = { |
55 .network = NULL, |
95 .network = NULL, |
56 .hostname = DEFAULT_HOST, |
96 .hostname = DEFAULT_HOST, |
111 return EXIT_FAILURE; |
151 return EXIT_FAILURE; |
112 } |
152 } |
113 } |
153 } |
114 |
154 |
115 // initialize libevent |
155 // initialize libevent |
116 if ((ev_base = event_base_new()) == NULL) |
156 if ((ctx.ev_base = event_base_new()) == NULL) |
117 FATAL("event_base_new"); |
157 FATAL("event_base_new"); |
|
158 |
|
159 // initialize signal handlers |
|
160 if ((ERROR_CODE(&err) = signals_create(&signals, ctx.ev_base))) |
|
161 FATAL("signals_create"); |
118 |
162 |
119 // initialize sock module |
163 // initialize sock module |
120 if (sock_init(ev_base, &err)) |
164 if (sock_init(ctx.ev_base, &err)) |
121 FATAL_ERROR(&err, "sock_init"); |
165 FATAL_ERROR(&err, "sock_init"); |
122 |
166 |
123 // the IRC network |
167 // the IRC network |
124 if (irc_net_create(&net, &net_info, &err)) |
168 if (irc_net_create(&ctx.net, &net_info, &err)) |
125 FATAL_ERROR(&err, "irc_net_create"); |
169 FATAL_ERROR(&err, "irc_net_create"); |
|
170 |
|
171 // add our signal handlers |
|
172 if ( |
|
173 (ERROR_CODE(&err) = signals_add(signals, SIGPIPE, &signals_ignore, signals)) |
|
174 || (ERROR_CODE(&err) = signals_add(signals, SIGINT, &on_sigint, &ctx)) |
|
175 ) |
|
176 FATAL_ERROR(&err, "signals_add"); |
126 |
177 |
127 // logging? |
178 // logging? |
128 if (log_info.db_info || log_chan_info.channel) { |
179 if (log_info.db_info || log_chan_info.channel) { |
129 // get the channel |
180 // get the channel |
130 if (log_chan_info.channel && (log_info.channel = irc_net_add_chan(net, &log_chan_info)) == NULL) |
181 if (log_chan_info.channel && (log_info.channel = irc_net_add_chan(ctx.net, &log_chan_info)) == NULL) |
131 FATAL("irc_net_add_chan"); |
182 FATAL("irc_net_add_chan"); |
132 |
183 |
133 // init the irc_log module |
184 // init the irc_log module |
134 if ((ERROR_CODE(&err) = irc_log_init(ev_base, &log_info))) |
185 if ((ERROR_CODE(&err) = irc_log_init(ctx.ev_base, &log_info))) |
135 FATAL_ERROR(&err, "irc_log_init"); |
186 FATAL_ERROR(&err, "irc_log_init"); |
136 } |
187 } |
137 |
188 |
138 // run event loop |
189 // run event loop |
139 if (event_base_dispatch(ev_base)) |
190 if (event_base_dispatch(ctx.ev_base)) |
140 FATAL("event_base_dispatch"); |
191 FATAL("event_base_dispatch"); |
141 |
192 |
142 // ok, no cleanup |
193 // ok, no cleanup |
143 return 0; |
194 return 0; |
144 } |
195 } |