OSSP CVS Repository

ossp - Check-in [477]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 477
Date: 2001-May-19 22:14:15 (local)
2001-May-19 20:14:15 (UTC)
User:rse
Branch:
Comment: Give us a clue how the handler functions actually should look now that we have l2_param_parse() and friends available. So to help Peti in approaching milestone 2 for Monday, I felt free to implement l2_handler_file for us, based on raw Unix I/O.
Tickets:
Inspections:
Files:
ossp-pkg/l2/l2_ch_file.c      1.2 -> 1.3     134 inserted, 5 deleted

ossp-pkg/l2/l2_ch_file.c 1.2 -> 1.3

--- l2_ch_file.c 2001/05/11 17:07:52     1.2
+++ l2_ch_file.c 2001/05/19 20:14:15     1.3
@@ -30,42 +30,171 @@
 #include "l2.h"
 #include "l2_p.h"
 
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+/* declare private channel configuration */
+typedef struct {
+    int   fd;
+    char *path;
+    int   append;
+    long  perm;
+} l2_ch_file_t;
+
+/* create channel */
 static int hook_create(l2_context_t *ctx)
 {
+    l2_ch_file_t *cfg;
+
+    /* allocate private channel configuration */
+    if ((cfg = (l2_ch_file_t *)malloc(sizeof(l2_ch_file_t))) == NULL)
+        return L2_ERROR;
+
+    /* initialize configuration with reasonable defaults */
+    cfg->fd     = -1; 
+    cfg->path   = NULL; 
+    cfg->append = TRUE; 
+    cfg->perm   = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); 
+
+    /* link private channel configuration into channel context */
+    ctx->vp = cfg;
+
     return L2_OK;
 }
 
+/* configure channel */
 static int hook_configure(l2_context_t *ctx, const char *fmt, va_list ap)
 {
-    return L2_OK;
+    l2_ch_file_t *cfg;
+    l2_param_t pa[3]; 
+    l2_error_t rv;
+
+    /* parameter checks */
+    if (ctx == NULL)
+        return L2_ERROR;
+    if ((cfg = (l2_ch_file_t *)ctx->vp) == NULL)
+        return L2_ERROR;
+
+    /* feed and call generic parameter parsing engine */
+    L2_PARAM_SET(pa[0], path,   CHARPTR, &cfg->path);
+    L2_PARAM_SET(pa[1], append, INT,     &cfg->append);
+    L2_PARAM_SET(pa[1], perm,   LONG,    &cfg->perm);
+    L2_PARAM_END(pa[2]);
+    rv = l2_param_parse(pa, fmt, ap);
+
+    return rv;
 }
 
-static int hook_open(l2_context_t *ctx, l2_channel_t *below)
+/* open channel */
+static int hook_open(l2_context_t *ctx, l2_channel_t *downstream)
 {
+    l2_ch_file_t *cfg;
+    int mode;
+
+    /* parameter checks */
+    if (ctx == NULL)
+        return L2_ERROR;
+    if ((cfg = (l2_ch_file_t *)ctx->vp) == NULL)
+        return L2_ERROR;
+    if (cfg->path == NULL)
+        return L2_ERROR;
+
+    /* open channel file */
+    mode = O_WRONLY|O_CREAT;
+    if (cfg->append)
+        mode |= O_APPEND;
+    if ((cfg->fd = open(cfg->path, mode, cfg->perm)) == -1)
+        return L2_ERROR;
+
+    /* optionally open downstream channel, too */
+    if (downstream != NULL)
+        if (l2_channel_open(downstream) == L2_ERROR)
+            return L2_ERROR;
+
     return L2_OK;
 }
 
-static int hook_write(l2_context_t *ctx, l2_channel_t *below, 
+/* write to channel */
+static int hook_write(l2_context_t *ctx, l2_channel_t *downstream, 
                       const char *buf, size_t buf_size)
 {
+    l2_ch_file_t *cfg;
+
+    /* parameter checks */
+    if (ctx == NULL)
+        return L2_ERROR;
+    if ((cfg = (l2_ch_file_t *)ctx->vp) == NULL)
+        return L2_ERROR;
+    if (cfg->fd == -1)
+        return L2_ERROR;
+
+    /* write message to channel file */
+    if (write(cfg->fd, buf, buf_size) == -1)
+        return L2_ERROR;
+
+    /* optionally write to downstream channel, too */
+    if (downstream != NULL)
+        if (l2_channel_write(downstream, buf, buf_size) == L2_ERROR)
+            return L2_ERROR;
+
     return L2_OK;
 }
 
-static int hook_flush(l2_context_t *ctx, l2_channel_t *below)
+/* flush channel */
+static int hook_flush(l2_context_t *ctx, l2_channel_t *downstream)
 {
+    /* NOP for this channel, because Unix I/O files are unbuffered! */
+
+    /* optionally flush downstream channel, too */
+    if (downstream != NULL)
+        if (l2_channel_flush(downstream) == L2_ERROR)
+            return L2_ERROR;
+
     return L2_OK;
 }
 
-static int hook_close(l2_context_t *ctx, l2_channel_t *below)
+/* close channel */
+static int hook_close(l2_context_t *ctx, l2_channel_t *downstream)
 {
+    l2_ch_file_t *cfg;
+
+    /* optionally close downstream channel, too */
+    if (downstream != NULL)
+        if (l2_channel_close(downstream) == L2_ERROR)
+            return L2_ERROR;
+
+    /* parameter checks */
+    if (ctx == NULL)
+        return L2_ERROR;
+    if ((cfg = (l2_ch_file_t *)ctx->vp) == NULL)
+        return L2_ERROR;
+    if (cfg->fd == -1)
+        return L2_ERROR;
+
+    /* close channel file */
+    close(cfg->fd);
+    cfg->fd = -1;
+
     return L2_OK;
 }
 
+/* destroy channel */
 static int hook_destroy(l2_context_t *ctx)
 {
+    /* parameter checks */
+    if (ctx == NULL)
+        return L2_ERROR;
+    if (ctx->vp == NULL) 
+        return L2_ERROR;
+
+    /* destroy channel configuration */
+    free(ctx->vp);
+
     return L2_OK;
 }
 
+/* exported channel handler structure */
 l2_handler_t l2_handler_file = {
     hook_create,
     hook_configure,

CVSTrac 2.0.1