218 static struct irc_chan_callbacks _chan_callbacks = { |
217 static struct irc_chan_callbacks _chan_callbacks = { |
219 .on_self_join = NULL, |
218 .on_self_join = NULL, |
220 .on_msg = NULL, |
219 .on_msg = NULL, |
221 }; |
220 }; |
222 |
221 |
|
222 /** |
|
223 * Release resources associated with the given irc_log_chan without doing any clean shutdown stuff |
|
224 */ |
|
225 static void irc_log_chan_destroy (struct irc_log_chan *chan_ctx) |
|
226 { |
|
227 // remove any handlers/callbacks |
|
228 irc_cmd_remove(&chan_ctx->chan->handlers, _chan_cmd_handlers, chan_ctx); |
|
229 irc_chan_remove_callbacks(chan_ctx->chan, &_chan_callbacks, chan_ctx); |
|
230 |
|
231 // free ourselves |
|
232 free(chan_ctx); |
|
233 } |
|
234 |
|
235 /** |
|
236 * Begin logging the given channel |
|
237 */ |
|
238 static err_t irc_log_chan (struct irc_log_ctx *ctx, struct irc_chan *chan, struct error_info *err) |
|
239 { |
|
240 struct irc_log_chan *chan_ctx; |
|
241 |
|
242 // alloc |
|
243 if ((chan_ctx = calloc(1, sizeof(*chan_ctx))) == NULL) |
|
244 return SET_ERROR(err, ERR_CALLOC); |
|
245 |
|
246 // store |
|
247 chan_ctx->ctx = ctx; |
|
248 chan_ctx->chan = chan; |
|
249 |
|
250 // add low-level handlers |
|
251 if ((ERROR_CODE(err) = irc_cmd_add(&chan_ctx->chan->handlers, _chan_cmd_handlers, chan_ctx))) |
|
252 goto error; |
|
253 |
|
254 // add channel callbacks |
|
255 if ((ERROR_CODE(err) = irc_chan_add_callbacks(chan_ctx->chan, &_chan_callbacks, chan_ctx))) |
|
256 goto error; |
|
257 |
|
258 // log an OPEN message |
|
259 // XXX: move this to when we first JOIN the channel |
|
260 if ((ERROR_CODE(err) = irc_log_event(ctx, chan_ctx->chan, NULL, "OPEN", NULL, NULL))) |
|
261 goto error; |
|
262 |
|
263 // ok |
|
264 log_info("logging channel %s:%s", chan_ctx->chan->net->info.network, irc_chan_name(chan_ctx->chan)); |
|
265 |
|
266 return SUCCESS; |
|
267 |
|
268 error: |
|
269 // cleanup |
|
270 irc_log_chan_destroy(chan_ctx); |
|
271 |
|
272 return ERROR_CODE(err); |
|
273 } |
|
274 |
|
275 /** |
|
276 * Allocate and initialize an irc_log_ctx. This doesn't do very much, the real magic happens in irc_log_conf. |
|
277 */ |
223 static err_t irc_log_init (struct nexus *nexus, void **ctx_ptr, struct error_info *err) |
278 static err_t irc_log_init (struct nexus *nexus, void **ctx_ptr, struct error_info *err) |
224 { |
279 { |
225 struct irc_log_ctx *ctx; |
280 struct irc_log_ctx *ctx; |
226 |
281 |
227 // allocate |
282 // allocate |
228 if ((ctx = calloc(1, sizeof(*ctx))) == NULL) |
283 if ((ctx = calloc(1, sizeof(*ctx))) == NULL) |
229 return SET_ERROR(err, ERR_CALLOC); |
284 return SET_ERROR(err, ERR_CALLOC); |
230 |
285 |
231 // initialize |
|
232 memset(ctx, 0, sizeof(*ctx)); |
|
233 |
|
234 // store |
286 // store |
235 ctx->nexus = nexus; |
287 ctx->nexus = nexus; |
236 |
288 |
237 log_info("module initialized"); |
289 log_info("module initialized"); |
238 |
290 |
239 // ok |
291 // ok |
240 *ctx_ptr = ctx; |
292 *ctx_ptr = ctx; |
241 |
293 |
242 return SET_ERROR(err, SUCCESS); |
294 return SUCCESS; |
243 } |
295 } |
244 |
296 |
245 /** |
297 /** |
246 * Process the irc_log.db_info config option. |
298 * Process the irc_log.db_info config option. |
247 * |
299 * |
274 * handlers/callbacks fails, or sending the initial INSERT-OPEN query fails. |
326 * handlers/callbacks fails, or sending the initial INSERT-OPEN query fails. |
275 */ |
327 */ |
276 static err_t irc_log_conf_channel (struct irc_log_ctx *ctx, char *value, struct error_info *err) |
328 static err_t irc_log_conf_channel (struct irc_log_ctx *ctx, char *value, struct error_info *err) |
277 { |
329 { |
278 const char *network, *channel; |
330 const char *network, *channel; |
279 |
331 struct irc_chan *chan; |
280 struct irc_log_chan *chan_ctx; |
|
281 |
332 |
282 // parse required args |
333 // parse required args |
283 if ((network = strsep(&value, ":")) == NULL) |
334 if ((network = strsep(&value, ":")) == NULL) |
284 RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid <network> for irc_log.channel"); |
335 RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid <network> for irc_log.channel"); |
285 |
336 |
292 |
343 |
293 // have a db configured? |
344 // have a db configured? |
294 if (!ctx->db) |
345 if (!ctx->db) |
295 RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "irc_log.channel used without any irc_log.db_info"); |
346 RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "irc_log.channel used without any irc_log.db_info"); |
296 |
347 |
297 // alloc |
|
298 if ((chan_ctx = calloc(1, sizeof(*chan_ctx))) == NULL) |
|
299 return SET_ERROR(err, ERR_CALLOC); |
|
300 |
|
301 // store |
|
302 chan_ctx->ctx = ctx; |
|
303 |
|
304 // get the channel? |
348 // get the channel? |
305 if ((chan_ctx->chan = irc_client_get_chan(ctx->nexus->client, network, channel)) == NULL) |
349 if ((chan = irc_client_get_chan(ctx->nexus->client, network, channel)) == NULL) |
306 JUMP_SET_ERROR_STR(err, ERR_MODULE_CONF, "unknown channel name"); |
350 RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "unknown channel name"); |
307 |
351 |
308 // add low-level handlers |
352 // begin logging it |
309 if ((ERROR_CODE(err) = irc_cmd_add(&chan_ctx->chan->handlers, _chan_cmd_handlers, chan_ctx))) |
353 if (irc_log_chan(ctx, chan, err)) |
310 goto error; |
354 return ERROR_CODE(err); |
311 |
355 |
312 // add channel callbacks |
356 // ok |
313 if ((ERROR_CODE(err) = irc_chan_add_callbacks(chan_ctx->chan, &_chan_callbacks, chan_ctx))) |
357 return SUCCESS; |
314 goto error; |
|
315 |
|
316 // log an OPEN message |
|
317 // XXX: move this to when we first JOIN the channel |
|
318 if ((ERROR_CODE(err) = irc_log_event(ctx, chan_ctx->chan, NULL, "OPEN", NULL, NULL))) |
|
319 goto error; |
|
320 |
|
321 // ok |
|
322 log_info("logging channel %s:%s", chan_ctx->chan->net->info.network, irc_chan_name(chan_ctx->chan)); |
|
323 |
|
324 return SUCCESS; |
|
325 |
|
326 error: |
|
327 // XXX: remove callbacks |
|
328 assert(!chan_ctx->chan); |
|
329 |
|
330 free(chan_ctx); |
|
331 |
|
332 return ERROR_CODE(err); |
|
333 } |
358 } |
334 |
359 |
335 /** |
360 /** |
336 * Set a config option |
361 * Set a config option |
337 */ |
362 */ |