src/irc_log.c
changeset 69 6f298b6e0d5f
parent 68 591a574f390e
child 70 a9a4c5e6aa30
equal deleted inserted replaced
68:591a574f390e 69:6f298b6e0d5f
     3 #include "error.h"
     3 #include "error.h"
     4 #include "log.h"
     4 #include "log.h"
     5 
     5 
     6 #include <stdlib.h>
     6 #include <stdlib.h>
     7 #include <string.h>
     7 #include <string.h>
     8 #include <assert.h> //<<< XXX: remove
       
     9 
     8 
    10 #include <event2/event.h>
     9 #include <event2/event.h>
    11 #include <evsql.h>
    10 #include <evsql.h>
    12 
    11 
    13 /**
    12 /**
   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  */