--- l2_ch_socket.c 2001/08/15 10:36:03 1.4
+++ l2_ch_socket.c 2001/08/26 13:07:27 1.5
@@ -30,42 +30,149 @@
#include "l2.h"
#include "l2_p.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/* declare private channel configuration */
+typedef struct {
+ int iSocket; /* Socket descriptor */
+ int iDomain; /* Hardcoded to support only IPv4 and IPv6 */
+ int iProtocol; /* Hardcoded to support only IPv4 and IPv6 */
+ int iType; /* Hardcoded for writing streams to iSocket */
+ struct sockaddr *pAddr; /* Where do we open a socket? */
+} l2_ch_socket_t;
+
+/* create channel */
static int hook_create(l2_context_t *ctx)
{
+ l2_ch_socket_t *cfg;
+
+ /* allocate private channel configuration */
+ if ((cfg = (l2_ch_socket_t *)malloc(sizeof(l2_ch_socket_t))) == NULL)
+ return L2_ERROR;
+
+ /* initialize configuration with reasonable defaults */
+ cfg->iSocket = 0;
+ cfg->iDomain = PF_INET; /* Internet family */
+ cfg->iType = SOCK_STREAM; /* We write streams reliably */
+ cfg->iProtocol = IPPROTO_TCP; /* TCP socket */
+ cfg->pAddr = NULL;
+
+ /* 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_socket_t *cfg;
+ char pszAddress[L2_MAX_STRING];
+ unsigned short unInport;
+ l2_param_t pa[3];
+ l2_result_t rv;
+
+ unInport = 0;
+
+ /* parameter checks */
+ if ((cfg = (l2_ch_socket_t *)ctx->vp) == NULL)
+ return L2_ERROR;
+
+ /* feed and call generic parameter parsing engine */
+ L2_PARAM_SET(pa[0], address, CHARPTR, pszAddress);
+ L2_PARAM_SET(pa[1], port, USHORT, &unInport);
+/* TODO: Fill in the cfg-> structure after building the socket */
+ L2_PARAM_END(pa[2]);
+ rv = l2_channel_setparams(pa, fmt, ap);
+
+ return rv;
}
+/* open channel */
static int hook_open(l2_context_t *ctx, l2_channel_t *downstream)
{
+ l2_ch_socket_t *cfg;
+
+ /* parameter checks */
+ if ((cfg = (l2_ch_socket_t *)ctx->vp) == NULL)
+ return L2_ERROR;
+
+ /* open channel socket */
+
+ /* optionally open downstream channel, too */
+ if (downstream != NULL)
+ if (l2_channel_open(downstream) == L2_ERROR)
+ return L2_ERROR;
+
return L2_OK;
}
+/* write to channel */
static int hook_write(l2_context_t *ctx, l2_channel_t *downstream,
const char *buf, size_t buf_size)
{
+ l2_ch_socket_t *cfg;
+
+ /* parameter checks */
+ if ((cfg = (l2_ch_socket_t *)ctx->vp) == NULL)
+ return L2_ERROR;
+
+ /* write message to channel socket */
+
+ /* 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;
}
+/* flush channel */
static int hook_flush(l2_context_t *ctx, l2_channel_t *downstream)
{
+ /* optionally flush downstream channel, too */
+ if (downstream != NULL)
+ if (l2_channel_flush(downstream) == L2_ERROR)
+ return L2_ERROR;
+
return L2_OK;
}
+/* close channel */
static int hook_close(l2_context_t *ctx, l2_channel_t *downstream)
{
+ l2_ch_socket_t *cfg;
+
+ /* optionally close downstream channel, too */
+ if (downstream != NULL)
+ if (l2_channel_close(downstream) == L2_ERROR)
+ return L2_ERROR;
+
+ /* parameter checks */
+ if ((cfg = (l2_ch_socket_t *)ctx->vp) == NULL)
+ return L2_ERROR;
+
+ /* close channel socket */
+
return L2_OK;
}
+/* destroy channel */
static int hook_destroy(l2_context_t *ctx)
{
+ /* parameter checks */
+ 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_socket = {
hook_create,
hook_configure,
|