--- /dev/null
+# Copyright (C) 1994, Index Data I/S
+# All rights reserved.
+# Sebastian Hammer, Adam Dickmeiss
+# $Id: Makefile,v 1.1 1995-03-10 18:22:44 quinn Exp $
+
+SHELL=/bin/sh
+INCLUDE=-I../include -I. -I../asn -I../odr -I../../egate/include -I../../xtimosi/src
+#CFLAGS=-Wall -pedantic -g
+#CFLAGS=-g
+DEFS=$(INCLUDE)
+LIB= server.a
+PO = eventl.o
+CPP=cc -E
+#CC=checkergcc
+
+all: $(LIB)
+
+alll:
+
+$(LIB): $(PO)
+ rm -f $(LIB)
+ ar qc $(LIB) $(PO)
+ ranlib $(LIB)
+
+.c.o:
+ $(CC) -c $(DEFS) $(CFLAGS) $<
+
+clean:
+ rm -f *.[oa] test core mon.out gmon.out errlist tst cli
+
+depend: depend2
+:
+depend1:
+ mv Makefile Makefile.tmp
+ sed '/^#Depend/q' <Makefile.tmp >Makefile
+ $(CPP) $(INCLUDE) -M *.c >>Makefile
+ -rm Makefile.tmp
+
+depend2:
+ $(CPP) $(INCLUDE) -M *.c >.depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
+#Depend --- DOT NOT DELETE THIS LINE
--- /dev/null
+/*
+ * Copyright (C) 1994, Index Data I/S
+ * All rights reserved.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: eventl.c,v $
+ * Revision 1.1 1995-03-10 18:22:44 quinn
+ * The rudiments of an asynchronous server.
+ *
+ */
+
+#include <assert.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <eventl.h>
+
+IOCHAN iochans = 0;
+
+IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags)
+{
+ IOCHAN new;
+
+ if (!(new = malloc(sizeof(*new))))
+ return 0;
+ new->destroyed = 0;
+ new->fd = fd;
+ new->flags = flags;
+ new->fun = cb;
+ return new;
+}
+
+void iochan_destroy(IOCHAN i)
+{
+ i->destroyed = 1;
+}
+
+int event_loop()
+{
+ do
+ {
+ IOCHAN p, nextp;
+ fd_set in, out, except;
+ int res, max;
+
+ FD_ZERO(&in);
+ FD_ZERO(&out);
+ FD_ZERO(&except);
+ for (p = iochans; p; p = p->next)
+ {
+ if (p->flags & EVENT_INPUT)
+ FD_SET(p->fd, &in);
+ if (p->flags & EVENT_OUTPUT)
+ FD_SET(p->fd, &out);
+ if (p->flags & EVENT_EXCEPT)
+ FD_SET(p->fd, &except);
+ if (p->fd > max)
+ max = p->fd;
+ }
+ if ((res = select(max + 1, &in, &out, &except, 0)) < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ return 1;
+ }
+ if (!res)
+ continue;
+ for (p = iochans; p; p = nextp)
+ {
+ nextp = p->next;
+ if (FD_ISSET(p->fd, &in))
+ (*p->fun)(p, EVENT_INPUT);
+ if (!p->destroyed && FD_ISSET(p->fd, &in))
+ (*p->fun)(p, EVENT_OUTPUT);
+ if (!p->destroyed && FD_ISSET(p->fd, &except))
+ (*p->fun)(p, EVENT_EXCEPT);
+ if (p->destroyed)
+ {
+ IOCHAN tmp = p, pr;
+
+ if (p == iochans)
+ iochans = p->next;
+ else
+ {
+ for (pr = iochans; pr; pr = pr->next)
+ if (pr->next == p)
+ break;
+ assert(pr);
+ pr->next = p->next;
+ }
+ if (nextp == p)
+ nextp = p->next;
+ free(tmp);
+ }
+ }
+ }
+ while (iochans);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (C) 1994, Index Data I/S
+ * All rights reserved.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: eventl.h,v $
+ * Revision 1.1 1995-03-10 18:22:45 quinn
+ * The rudiments of an asynchronous server.
+ *
+ */
+
+#ifndef EVENTL_H
+#define EVENTL_H
+
+struct iochan;
+
+typedef void (*IOC_CALLBACK)(struct iochan *i, int event);
+
+typedef struct iochan
+{
+ int fd;
+ int flags;
+#define EVENT_INPUT 0x01
+#define EVENT_OUTPUT 0x02
+#define EVENT_EXCEPT 0x04
+#define EVENT_TIMEOUT 0x08
+ IOC_CALLBACK fun;
+ void *data;
+ int destroyed;
+
+ struct iochan *next;
+} *IOCHAN;
+
+#define iochan_destroy(i) (void)((i)->destroyed = 1)
+#define iochan_getfd(i)
+#define iochan_getdata(i) ((i)->data)
+#define iochan_setdata(i, d) ((i)->data = d)
+#define iochan_getflags(i) ((i)->flags)
+#define iochan_setflags(i, d) ((i)->flags = d)
+#define iochan_getfun(i) ((i)->fun)
+#define iochan_setfun(i, d) ((i)->fun = d)
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1994, Index Data I/S
+ * All rights reserved.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: statserv.c,v $
+ * Revision 1.1 1995-03-10 18:22:45 quinn
+ * The rudiments of an asynchronous server.
+ *
+ */
+
+/*
+ * Simple, static server. I wouldn't advise a static server unless you
+ * really have to, but it's great for debugging memory management. :)
+ */
+
+#include <stdio.h>
+
+#include <eventl.h>
+
+static char *me = "";
+
+/*
+ * handle incoming connect requests.
+ */
+void listener(IOCHAN h, int event)
+{
+ COMSTACK line = (COMSTACK) iochan_getdata(h);
+
+ if (event == EVENT_INPUT)
+ {
+ if (cs_listen(line, 0, 0) < 0)
+ {
+ if (cs_errno(line) == CSNODATA)
+ return;
+ fprintf(stderr, "cs_listen failed.\n");
+ exit(1);
+ }
+ iochan_setflags(h, EVENT_OUTPUT) /* set us up for accepting */
+ }
+ else if (event == EVENT_OUTPUT)
+ {
+ COMSTACK new_line;
+ IOCHAN new_chan;
+
+ if (!(new_line = cs_accept(line)))
+ {
+ fprintf(stderr, "Accept failed.\n");
+ exit(1);
+ }
+ if (!(new_chan = iochan_create(cs_fileno(initializer, init_fun,
+ EVENT_INPUT))))
+ {
+ fprintf(stderr, "Failed to create iochan\n");
+ exit(1);
+ }
+ iochan_setflags(h, EVENT_INPUT); /* reset for listening */
+ }
+ else
+ {
+ fprintf(stderr, "Bad event on listener.\n");
+ exit(1);
+ }
+}
+
+/*
+ * Set up a listening endpoint, and give it to the event-handler.
+ */
+void add_listener(char *where)
+{
+ COMSTACK l;
+ CS_TYPE type;
+ char mode[100], addr[100]
+ void *ap;
+ IOCHAN lst;
+
+ if (!where || sscanf(where, "%[^:]:%s", mode, addr) != 2)
+ {
+ fprintf(stderr, "%s: Address format: ('tcp'|'osi')':'<address>.\n",
+ me);
+ exit(1);
+ }
+ if (!strcmp(mode, "tcp"))
+ {
+ if (!(ap = tcpip_strtoaddr(where)))
+ {
+ fprintf(stderr, "Address resolution failed for TCP.\n");
+ exit(1);
+ }
+ type = tcpip_type;
+ }
+ else if (!strcmp(mode, "osi"))
+ {
+ if (!(ap = mosi_strtoaddr(where)))
+ {
+ fprintf(stderr, "Address resolution failed for TCP.\n");
+ exit(1);
+ }
+ type = mosi_type;
+ }
+ else
+ {
+ fprintf(stderr, "You must specify either 'osi:' or 'tcp:'.\n");
+ exit(1);
+ }
+ if (!(l = cs_create(type, 1)))
+ {
+ fprintf(stderr, "Failed to create listener\n");
+ exit(1);
+ }
+ if (cs_bind(l, ap, CS_SERVER) < 0)
+ {
+ fprintf(stderr, "Failed to bind.\n");
+ perror(where);
+ exit(1);
+ }
+ if (!(lst = iochan_create(cs_fileno(l), listener, EVENT_INPUT)))
+ {
+ fprintf(stderr, "Failed to create IOCHAN-type\n");
+ exit(1);
+ }
+ iochan_setdata(lst, l);
+}
+
+int main(int argc, char **argv)
+{
+ int ret, listeners = 0;
+ char *arg;
+
+ while ((ret = options("l:", argv, argc, &arg)) != -2)
+ switch (ret)
+ {
+ case 0: me = arg; break;
+ case 'l': add_listener(arg); l++; break;
+ default:
+ fprintf(stderr, "Usage: %s [-l <listener-addr>]\n", me);
+ exit(1);
+ }
+ if (!listeners)
+ {
+ fprintf(stderr, "%s: Must specify at least one listener.\n", me);
+ exit(1);
+ }
+ return event_loop();
+}