--- l2_ch_prefix.c 2001/09/05 07:47:12 1.7
+++ l2_ch_prefix.c 2001/09/05 13:56:43 1.8
@@ -27,52 +27,122 @@
** l2_ch_prefix.c: prefixing channel implementation
*/
+#include <time.h>
+
#include "l2.h"
+/* declare private channel configuration */
+typedef struct {
+ char *timefmt;
+ char *timezone;
+ char timebuf[1024];
+} l2_ch_prefix_t;
+
+/* create channel */
static l2_result_t hook_create(l2_context_t *ctx, l2_channel_t *ch)
{
+ l2_ch_prefix_t *cfg;
+
+ /* allocate private channel configuration */
+ if ((cfg = (l2_ch_prefix_t *)malloc(sizeof(l2_ch_prefix_t))) == NULL)
+ return L2_ERROR;
+
+ /* initialize configuration with reasonable defaults */
+ cfg->timefmt = NULL;
+ cfg->timezone = strdup("local");
+
+ /* link private channel configuration into channel context */
+ ctx->vp = cfg;
+
return L2_OK;
}
+/* configure channel */
static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
{
- return L2_OK;
-}
+ l2_ch_prefix_t *cfg = (l2_ch_prefix_t *)ctx->vp;
+ l2_param_t pa[3];
+ l2_result_t rv;
+
+ /* feed and call generic parameter parsing engine */
+ L2_PARAM_SET(pa[0], timefmt, STRING, &cfg->timefmt);
+ L2_PARAM_SET(pa[1], timezone, STRING, &cfg->timezone);
+ L2_PARAM_END(pa[2]);
+ rv = l2_util_setparams(pa, fmt, ap);
+
+ /* argument consistency check */
+ if (rv == L2_OK) {
+ if (cfg->timezone == NULL)
+ return L2_ERROR;
+ if (!( strcmp(cfg->timezone, "local") == 0
+ || strcmp(cfg->timezone, "utc") == 0))
+ return L2_ERROR;
+ }
-static l2_result_t hook_open(l2_context_t *ctx, l2_channel_t *ch)
-{
- return L2_OK;
+ return rv;
}
+/* write to channel */
static l2_result_t hook_write(l2_context_t *ctx, l2_channel_t *ch,
- const char *buf, size_t buf_size)
+ const char *buf, size_t buf_size)
{
- return L2_OK;
-}
+ l2_ch_prefix_t *cfg;
+ l2_channel_t *downstream;
+ time_t t;
+ struct tm *tm;
+ size_t n;
+ l2_result_t rv;
+
+ /* get environment */
+ cfg = (l2_ch_prefix_t *)ctx->vp;
+ downstream = l2_channel_downstream(ch);
+
+ /* optionally provide prefix */
+ if (cfg->timefmt != NULL) {
+ t = time(NULL);
+ if (strcmp(cfg->timezone, "local") == 0)
+ tm = localtime(&t);
+ else if (strcmp(cfg->timezone, "utc") == 0)
+ tm = gmtime(&t);
+ else
+ return L2_ERROR;
+ if ((n = strftime(cfg->timebuf, sizeof(cfg->timebuf), cfg->timefmt, tm)) == 0)
+ return L2_ERROR;
+ if ((rv = l2_channel_write(downstream, cfg->timebuf, n)) != L2_OK)
+ return rv;
+ }
+
+ /* write to downstream channel */
+ if ((rv = l2_channel_write(downstream, buf, buf_size)) != L2_OK)
+ return rv;
-static l2_result_t hook_flush(l2_context_t *ctx, l2_channel_t *ch)
-{
- return L2_OK;
-}
-
-static l2_result_t hook_close(l2_context_t *ctx, l2_channel_t *ch)
-{
return L2_OK;
}
+/* destroy channel */
static l2_result_t hook_destroy(l2_context_t *ctx, l2_channel_t *ch)
{
+ l2_ch_prefix_t *cfg = (l2_ch_prefix_t *)ctx->vp;
+
+ if (cfg->timefmt != NULL)
+ free(cfg->timefmt);
+ if (cfg->timezone != NULL)
+ free(cfg->timezone);
+ free(cfg);
+ ctx->vp = NULL;
+
return L2_OK;
}
+/* exported channel handler structure */
l2_handler_t l2_handler_prefix = {
L2_CHANNEL_FILTER,
hook_create,
hook_configure,
- hook_open,
+ NULL,
hook_write,
- hook_flush,
- hook_close,
+ NULL,
+ NULL,
hook_destroy
};
|