src/modules/logwatch_source.c
author Tero Marttila <terom@fixme.fi>
Thu, 28 May 2009 01:17:36 +0300
branchnew-lib-errors
changeset 219 cefec18b8268
parent 157 1e5674d0eec4
permissions -rw-r--r--
some of the lib/transport stuff compiles
#include "logwatch.h"
#include "../fifo.h"
#include "../log.h"

#include <stdlib.h>
#include <string.h>

void logwatch_source_on_line (char *line, void *arg)
{
    struct logwatch_source *source = arg;
    
    // apply it to the logwatch's filters
    logwatch_on_line(source->ctx, source, line);
}

void logwatch_source_on_error (struct error_info *err, void *arg)
{
    struct logwatch_source *source = arg;
    
    // notify
    logwatch_on_error(source->ctx, source, err);

    // drop it
    logwatch_source_destroy(source);
}

static const struct line_proto_callbacks lp_callbacks = {
    .on_line    = logwatch_source_on_line,
    .on_error   = logwatch_source_on_error,
};

const struct logwatch_source* logwatch_source_lookup (struct logwatch *ctx, const char *name)
{
    const struct logwatch_source *source;

    // compare
    TAILQ_FOREACH(source, &ctx->sources, logwatch_sources)
        if (strcmp(source->name, name) == 0)
            return source;

    // not found
    return NULL;
}

/**
 * Initialize with the given transport.
 *
 * In case of errors, this will free the source and transport.
 */
static err_t logwatch_source_init (struct logwatch_source *source, struct logwatch *ctx, const char *name, transport_t *transport, error_t *err)
{
    // duplicate name?
    if (logwatch_source_lookup(ctx, name))
        JUMP_SET_ERROR(err, ERR_DUP_NAME);

    // store
    source->ctx = ctx;
    
    // the name
    if ((source->name = strdup(name)) == NULL)
        JUMP_SET_ERROR(err, ERR_STRDUP);
    
    // create the lp to wrap the sock
    if (line_proto_create(&source->lp, transport, LOGWATCH_SOURCE_LINE_MAX, &lp_callbacks, source, err))
        goto error;

    // add to logwatch_sources
    TAILQ_INSERT_TAIL(&ctx->sources, source, logwatch_sources);
    
    // ok
    return SUCCESS;

error:
    free(source);

    return ERROR_CODE(err);
}

struct logwatch_source* logwatch_open_fifo (struct logwatch *ctx, const char *path, struct error_info *err)
{
    struct logwatch_source *source;
    transport_t *transport = NULL;

    // alloc
    if ((source = calloc(1, sizeof(*source))) == NULL)
        JUMP_SET_ERROR(err, ERR_CALLOC);
    
    // open
    if (fifo_open_read(NULL, &transport, ctx->nexus->ev_base, path, err))
        goto error;
        
    // init
    if (logwatch_source_init(source, ctx, path, transport, err))
        return NULL;

    // ok
    return source;

error:
    if (source)
        // cleanup
        free(source);

    return NULL;
}

void logwatch_source_destroy (struct logwatch_source *source)
{
    // release the line_proto
    if (source->lp)
        line_proto_destroy(source->lp);
        
    // remove from the list
    TAILQ_REMOVE(&source->ctx->sources, source, logwatch_sources);

    // remove any affected filters
    logwatch_filter_remove(source->ctx, source);
    
    // release
    free(source->name);
    free(source);
}