#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);
}