From ec88921b39b86ed5a20c38d0bc74ea8a765baca0 Mon Sep 17 00:00:00 2001
From: Per Cederqvist <ceder@lysator.liu.se>
Date: Wed, 15 Apr 1992 18:56:09 +0000
Subject: [PATCH] Initial revision

---
 src/libraries/libisc-new/src/Makefile      | 150 +++++++++
 src/libraries/libisc-new/src/isc_handler.c | 112 +++++++
 src/libraries/libisc-new/src/isc_socket.c  | 250 ++++++++++++++
 src/libraries/libisc-new/src/isc_tcp.c     | 349 ++++++++++++++++++++
 src/libraries/libisc-new/src/isc_udp.c     | 360 +++++++++++++++++++++
 5 files changed, 1221 insertions(+)
 create mode 100644 src/libraries/libisc-new/src/Makefile
 create mode 100644 src/libraries/libisc-new/src/isc_handler.c
 create mode 100644 src/libraries/libisc-new/src/isc_socket.c
 create mode 100644 src/libraries/libisc-new/src/isc_tcp.c
 create mode 100644 src/libraries/libisc-new/src/isc_udp.c

diff --git a/src/libraries/libisc-new/src/Makefile b/src/libraries/libisc-new/src/Makefile
new file mode 100644
index 000000000..a9db699b6
--- /dev/null
+++ b/src/libraries/libisc-new/src/Makefile
@@ -0,0 +1,150 @@
+#
+# Makefile for libisc
+#
+# Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the
+#                    Lysator Academic Computer Association.
+#
+INSTROOT=/usr/local
+#
+LIBDIR=$(INSTROOT)/lib
+INCDIR=$(INSTROOT)/include
+#
+INCLUDES=-I$(HOME)/include -I/usr/local/include
+CC=gcc
+CFLAGS=-g -O -I. -pipe -Wall -ansi $(INCLUDES)
+#
+SOURCES=isc_event.c isc_session.c isc_abort.c isc_alloc.c isc_master.c\
+        isc_output.c isc_queue.c isc_message.c isc_handler.c\
+        isc_stdout.c isc_socket.c isc_tcp.c isc_udp.c printf.c
+OBJECTS=isc_event.o isc_session.o isc_abort.o isc_alloc.o isc_master.o\
+        isc_output.o isc_queue.o isc_message.o isc_handler.o\
+        isc_stdout.o isc_socket.o isc_tcp.o isc_udp.o printf.o
+
+
+all: 		libisc.a
+
+install:	$(LIBDIR)/libisc.a $(INCDIR)/isc.h
+
+$(LIBDIR)/libisc.a: libisc.a
+	cp libisc.a $(LIBDIR)
+	ranlib $(LIBDIR)/libisc.a
+
+$(INCDIR)/isc.h:    isc.h
+	cp isc.h $(INCDIR)
+
+tags:
+	etags -t *.[hc]
+
+depend:
+	gmkdep $(INCLUDES) $(SOURCES)
+
+
+clean:
+	rm -f *~ *.o libisc.a core \#*\#
+
+
+libisc.a: 	$(OBJECTS)
+	touch libisc.a
+	rm -f libisc.a
+	ar q libisc.a $(OBJECTS)
+	ranlib libisc.a
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+isc_event.o : isc_event.c /usr/include/stdio.h \
+  /usr/gnu/lib/gcc-include/stdarg.h /usr/local/include/stdlib.h \
+  /usr/include/time.h /usr/include/sys/stdtypes.h /usr/include/sys/types.h \
+  /usr/include/sys/sysmacros.h /usr/include/sys/time.h /usr/include/errno.h \
+  /usr/include/sys/errno.h /home/kolix2/elev/d89/d89peter/include/stddef.h \
+  /usr/include/string.h isc.h /usr/include/sys/socket.h intern.h 
+isc_session.o : isc_session.c /usr/include/sys/types.h \
+  /usr/include/sys/stdtypes.h /usr/include/sys/sysmacros.h \
+  /usr/include/errno.h /usr/include/sys/errno.h /usr/local/include/stdlib.h \
+  /home/kolix2/elev/d89/d89peter/include/stddef.h /usr/include/string.h \
+  /usr/include/fcntl.h /usr/include/sys/fcntlcom.h /usr/include/sys/stat.h \
+  isc.h /usr/include/time.h /usr/gnu/lib/gcc-include/stdarg.h \
+  /usr/include/sys/socket.h intern.h 
+isc_abort.o : isc_abort.c /usr/include/stdio.h /usr/local/include/stdlib.h \
+  /home/kolix2/elev/d89/d89peter/include/stddef.h /usr/include/sys/stdtypes.h \
+  isc.h /usr/include/time.h /usr/gnu/lib/gcc-include/stdarg.h \
+  /usr/include/sys/types.h /usr/include/sys/sysmacros.h \
+  /usr/include/sys/socket.h intern.h 
+isc_alloc.o : isc_alloc.c /usr/local/include/stdlib.h \
+  /home/kolix2/elev/d89/d89peter/include/stddef.h /usr/include/sys/stdtypes.h \
+  /usr/include/string.h isc.h /usr/include/time.h \
+  /usr/gnu/lib/gcc-include/stdarg.h /usr/include/sys/types.h \
+  /usr/include/sys/sysmacros.h /usr/include/sys/socket.h intern.h 
+isc_master.o : isc_master.c /usr/include/errno.h /usr/include/sys/errno.h \
+  /usr/local/include/stdlib.h /home/kolix2/elev/d89/d89peter/include/stddef.h \
+  /usr/include/sys/stdtypes.h /usr/include/sys/file.h \
+  /usr/include/sys/types.h /usr/include/sys/sysmacros.h \
+  /usr/include/sys/fcntlcom.h /usr/include/sys/stat.h isc.h \
+  /usr/include/time.h /usr/gnu/lib/gcc-include/stdarg.h \
+  /usr/include/sys/socket.h intern.h 
+isc_output.o : isc_output.c /usr/local/include/stdlib.h \
+  /home/kolix2/elev/d89/d89peter/include/stddef.h /usr/include/sys/stdtypes.h \
+  /usr/include/errno.h /usr/include/sys/errno.h /usr/include/string.h \
+  /usr/include/sys/file.h /usr/include/sys/types.h \
+  /usr/include/sys/sysmacros.h /usr/include/sys/fcntlcom.h \
+  /usr/include/sys/stat.h isc.h /usr/include/time.h \
+  /usr/gnu/lib/gcc-include/stdarg.h /usr/include/sys/socket.h intern.h 
+isc_queue.o : isc_queue.c /usr/local/include/stdlib.h \
+  /home/kolix2/elev/d89/d89peter/include/stddef.h /usr/include/sys/stdtypes.h \
+  isc.h /usr/include/time.h /usr/gnu/lib/gcc-include/stdarg.h \
+  /usr/include/sys/types.h /usr/include/sys/sysmacros.h \
+  /usr/include/sys/socket.h intern.h 
+isc_message.o : isc_message.c /usr/local/include/stdlib.h \
+  /home/kolix2/elev/d89/d89peter/include/stddef.h /usr/include/sys/stdtypes.h \
+  /usr/include/string.h isc.h /usr/include/time.h \
+  /usr/gnu/lib/gcc-include/stdarg.h /usr/include/sys/types.h \
+  /usr/include/sys/sysmacros.h /usr/include/sys/socket.h intern.h 
+isc_stdout.o : isc_stdout.c /usr/gnu/lib/gcc-include/stdarg.h \
+  /usr/include/string.h /usr/include/sys/stdtypes.h isc.h /usr/include/time.h \
+  /usr/include/sys/types.h /usr/include/sys/sysmacros.h \
+  /usr/include/sys/socket.h 
+isc_socket.o : isc_socket.c /usr/include/stdio.h \
+  /usr/gnu/lib/gcc-include/stdarg.h /usr/local/include/stdlib.h \
+  /usr/include/time.h /usr/include/sys/stdtypes.h /usr/include/sys/types.h \
+  /usr/include/sys/sysmacros.h /usr/include/sys/time.h \
+  /usr/include/netinet/in.h /usr/include/sys/socket.h \
+  /usr/local/include/arpa/inet.h /usr/include/sys/file.h \
+  /usr/include/sys/fcntlcom.h /usr/include/sys/stat.h \
+  /usr/include/sys/ioctl.h /usr/gnu/lib/gcc-include/sys/ttychars.h \
+  /usr/include/sys/ttydev.h /usr/gnu/lib/gcc-include/sys/ttold.h \
+  /usr/gnu/lib/gcc-include/sys/ioccom.h /usr/gnu/lib/gcc-include/sys/ttycom.h \
+  /usr/gnu/lib/gcc-include/sys/filio.h /usr/gnu/lib/gcc-include/sys/sockio.h \
+  /usr/include/errno.h /usr/include/sys/errno.h /usr/local/include/netdb.h \
+  /home/kolix2/elev/d89/d89peter/include/stddef.h /usr/include/string.h \
+  /usr/include/fcntl.h isc.h intern.h 
+isc_tcp.o : isc_tcp.c /usr/include/errno.h /usr/include/sys/errno.h \
+  /usr/local/include/stdlib.h /home/kolix2/elev/d89/d89peter/include/stddef.h \
+  /usr/include/sys/stdtypes.h /usr/include/ctype.h /usr/include/sys/types.h \
+  /usr/include/sys/sysmacros.h /usr/include/sys/socket.h \
+  /usr/include/netinet/in.h /usr/local/include/arpa/inet.h \
+  /usr/include/sys/file.h /usr/include/sys/fcntlcom.h /usr/include/sys/stat.h \
+  /usr/include/sys/ioctl.h /usr/gnu/lib/gcc-include/sys/ttychars.h \
+  /usr/include/sys/ttydev.h /usr/gnu/lib/gcc-include/sys/ttold.h \
+  /usr/gnu/lib/gcc-include/sys/ioccom.h /usr/gnu/lib/gcc-include/sys/ttycom.h \
+  /usr/gnu/lib/gcc-include/sys/filio.h /usr/gnu/lib/gcc-include/sys/sockio.h \
+  /usr/local/include/netdb.h /usr/include/string.h /usr/include/fcntl.h isc.h \
+  /usr/include/time.h /usr/gnu/lib/gcc-include/stdarg.h intern.h 
+isc_udp.o : isc_udp.c /usr/include/sys/types.h /usr/include/sys/stdtypes.h \
+  /usr/include/sys/sysmacros.h /usr/include/errno.h /usr/include/sys/errno.h \
+  /usr/local/include/stdlib.h /home/kolix2/elev/d89/d89peter/include/stddef.h \
+  /usr/include/ctype.h /usr/include/netinet/in.h /usr/include/sys/socket.h \
+  /usr/local/include/arpa/inet.h /usr/include/sys/file.h \
+  /usr/include/sys/fcntlcom.h /usr/include/sys/stat.h \
+  /usr/include/sys/ioctl.h /usr/gnu/lib/gcc-include/sys/ttychars.h \
+  /usr/include/sys/ttydev.h /usr/gnu/lib/gcc-include/sys/ttold.h \
+  /usr/gnu/lib/gcc-include/sys/ioccom.h /usr/gnu/lib/gcc-include/sys/ttycom.h \
+  /usr/gnu/lib/gcc-include/sys/filio.h /usr/gnu/lib/gcc-include/sys/sockio.h \
+  /usr/local/include/netdb.h /usr/include/string.h /usr/include/fcntl.h isc.h \
+  /usr/include/time.h /usr/gnu/lib/gcc-include/stdarg.h intern.h 
+printf.o : printf.c /usr/include/sys/types.h /usr/include/sys/stdtypes.h \
+  /usr/include/sys/sysmacros.h /usr/gnu/lib/gcc-include/varargs.h \
+  /usr/gnu/lib/gcc-include/va-sparc.h /usr/include/stdio.h \
+  /usr/include/ctype.h /usr/include/string.h /usr/local/include/stdlib.h \
+  /usr/include/math.h /usr/include/floatingpoint.h /usr/include/sys/ieeefp.h 
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/src/libraries/libisc-new/src/isc_handler.c b/src/libraries/libisc-new/src/isc_handler.c
new file mode 100644
index 000000000..c0a18671a
--- /dev/null
+++ b/src/libraries/libisc-new/src/isc_handler.c
@@ -0,0 +1,112 @@
+/*
+** isc_handler.c                 Routines to handle IscSession handlers
+**
+** Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the
+**                    Lysator Academic Computer Association.
+**
+** history:
+** 920211 pen      initial coding
+*/
+
+#include <stdio.h>
+
+#include "isc.h"
+#include "intern.h"
+
+
+
+IscHandler *
+isc_copyhandler(IscHandler *hcb)
+{
+  IscHandler *nhcb;
+
+
+  ISC_XNEW(nhcb);
+  *nhcb = *hcb;
+
+  return nhcb;
+}
+
+
+
+IscHandler *
+isc_newhandler(void)
+{
+  IscHandler *hcb;
+
+
+  ISC_XNEW(hcb);
+  
+  hcb->read = NULL;
+  hcb->write = NULL;
+  hcb->close = NULL;
+  hcb->poll = NULL;
+  hcb->accept = NULL;
+  hcb->destroy = NULL;
+  hcb->parse = NULL;
+  
+  return hcb;
+}
+
+
+
+void
+isc_freehandler(IscHandler *hcb)
+{
+  isc_free(hcb);
+}
+
+
+
+void
+isc_pushhandler(IscSession *scb, IscHandler *hcb)
+{
+  IscHandlerList *ihl;
+
+  
+  ISC_XNEW(ihl);
+  ihl->hcb = hcb;
+  ihl->old = scb->fun;
+  ihl->next = scb->handlers;
+  
+  scb->handlers = ihl;
+
+  if (hcb->read)
+    scb->fun.read = ihl;
+  if (hcb->write)
+    scb->fun.write = ihl;
+  if (hcb->close)
+    scb->fun.close = ihl;
+  if (hcb->poll)
+    scb->fun.poll = ihl;
+  if (hcb->accept)
+    scb->fun.accept = ihl;
+  if (hcb->destroy)
+    scb->fun.destroy = ihl;
+  if (hcb->parse)
+    scb->fun.parse = ihl;
+}
+
+
+IscHandler *
+isc_pophandler(IscSession *scb)
+{
+  IscHandlerList *ip;
+  IscHandler *hcb;
+
+  
+  if (scb->handlers == NULL)
+    return NULL;
+
+  ip = scb->handlers;
+  scb->handlers = ip->next;
+  scb->fun = ip->old;
+  hcb = ip->hcb;
+    
+  isc_free(ip);
+  
+  return hcb;
+}
+
+
+
diff --git a/src/libraries/libisc-new/src/isc_socket.c b/src/libraries/libisc-new/src/isc_socket.c
new file mode 100644
index 000000000..680541da4
--- /dev/null
+++ b/src/libraries/libisc-new/src/isc_socket.c
@@ -0,0 +1,250 @@
+/*
+** isc_socket.c                               Socket specified code
+**
+** Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the
+**                    Lysator Academic Computer Association.
+**
+** history:
+**   920210 pen     initial coding
+*/
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stddef.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/file.h>
+
+#include "isc.h"
+#include "intern.h"
+
+
+
+/*
+ * External function declarations.
+ */
+extern void *bzero(void *buf, unsigned length);
+extern void *memcpy(void *, const void *, int);
+extern int getsockname(int fd, struct sockaddr *, int *);
+extern int getpeername(int fd, struct sockaddr *, int *);
+extern time_t time(time_t *buf);
+extern int select(int setsize,
+		  fd_set *rs, fd_set *rw, fd_set *es,
+		  struct timeval *wait);
+extern int accept(int fd, struct sockaddr *sock, int *len);
+
+
+
+#if defined(__GNUC__) && defined(__sparc__)
+/*
+** inet_ntoa() is buggy on SPARCs running SunOS 4.1.1, so
+** we use our own
+*/
+#ifdef inet_ntoa
+#undef inet_ntoa
+#endif
+
+static char *inet_ntoa(ad)
+    struct in_addr ad;
+{
+  u_long s_ad;
+  int a, b, c, d;
+  static char addr[20];
+  
+  s_ad = ad.s_addr;
+  d = s_ad % 256;
+  s_ad /= 256;
+  c = s_ad % 256;
+  s_ad /= 256;
+  b = s_ad % 256;
+  a = s_ad / 256;
+  sprintf(addr, "%d.%d.%d.%d", a, b, c, d);
+  
+  return addr;
+}
+#endif
+
+
+
+IscAddress *
+isc_mkipaddress(struct sockaddr *addr)
+{
+  IscAddress *ia;
+
+
+  ISC_XNEW(ia);
+  memcpy(&ia->ip.saddr, addr, sizeof(ia->ip.saddr));
+
+  return ia;
+}
+
+
+
+
+IscAddress *
+isc_getladdress(IscSession *scb)
+{
+  struct sockaddr addr;
+  int len;
+
+
+  if (scb->type != ISC_TYPE_TCP &&
+      scb->type != ISC_TYPE_UDP)
+    return NULL;
+  
+  len = sizeof(addr);
+  if (getsockname(scb->fd, &addr, &len) < 0)
+    return NULL;
+
+  return isc_mkipaddress(&addr);
+}
+
+
+
+IscAddress *
+isc_getraddress(IscSession *scb)
+{
+  struct sockaddr addr;
+  int len;
+
+
+  if (scb->type != ISC_TYPE_TCP &&
+      scb->type != ISC_TYPE_UDP)
+    return NULL;
+  
+  len = sizeof(addr);
+  if (getpeername(scb->fd, &addr, &len) < 0)
+    return NULL;
+
+  return isc_mkipaddress(&addr);
+}
+
+
+void
+isc_freeaddress(IscAddress *addr)
+{
+  isc_free(addr);
+}
+
+
+IscAddress *
+isc_copyaddress(IscAddress *addr)
+{
+  IscAddress *new_addr;
+
+  ISC_XNEW(new_addr);
+  *new_addr = *addr;
+
+  return new_addr;
+}
+
+
+
+char *isc_getipnum(IscAddress *ia, char *buf, int len)
+{
+  static char hostname[256];
+  struct sockaddr_in *addr;
+  
+
+  if (!buf)
+  {
+    buf = hostname;
+    len = sizeof(hostname)-1;
+  }
+  
+  addr = (struct sockaddr_in *) &ia->ip.saddr;
+  
+  strncpy(buf, inet_ntoa(addr->sin_addr), len);
+  buf[len] = '\0';
+
+  return buf;
+}
+
+
+
+char *isc_gethostname(IscAddress *ia, char *buf, int len)
+{
+  static char hostname[256];
+  struct sockaddr_in *addr;
+  struct hostent *hp;
+  
+
+  if (!buf)
+  {
+    buf = hostname;
+    len = sizeof(hostname)-1;
+  }
+  
+  addr = (struct sockaddr_in *) &ia->ip.saddr;
+  
+  hp = gethostbyaddr(&addr->sin_addr,sizeof(struct in_addr),AF_INET);
+  if (!hp)
+    return NULL;
+  
+  strncpy(buf, hp->h_name, len);
+  buf[len] = '\0';
+  
+  return buf;
+}
+
+
+
+int isc_getportnum(IscAddress *ia)
+{
+  struct sockaddr_in *addr;
+
+  
+  addr = (struct sockaddr_in *) &ia->ip.saddr;
+
+  return ntohs(addr->sin_port);
+}
+
+
+char *isc_getservice(IscAddress *ia,
+		     char *buf,
+		     int len,
+		     IscSessionType type)
+{
+  static char servbuf[256];
+  struct sockaddr_in *addr;
+  struct servent *sp;
+  
+  if (!buf)
+  {
+    buf = servbuf;
+    len = sizeof(servbuf)-1;
+  }
+  
+  addr = (struct sockaddr_in *) &ia->ip.saddr;
+  
+  switch (type)
+  {
+    case ISC_TYPE_TCP:
+      sp = getservbyport(ntohs(addr->sin_port), "tcp");
+      break;
+      
+    case ISC_TYPE_UDP:
+      sp = getservbyport(ntohs(addr->sin_port), "udp");
+      break;
+    
+    default:
+      return NULL;
+  }
+
+  if (!sp)
+    return NULL;
+  
+  strncpy(buf, sp->s_name, len);
+  return buf;
+}
diff --git a/src/libraries/libisc-new/src/isc_tcp.c b/src/libraries/libisc-new/src/isc_tcp.c
new file mode 100644
index 000000000..3a436cf11
--- /dev/null
+++ b/src/libraries/libisc-new/src/isc_tcp.c
@@ -0,0 +1,349 @@
+/*
+** isc_tcp.c                          Routines to handle TCP ISC sessions
+**
+** Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the
+**                    Lysator Academic Computer Association.
+**
+** history:
+** 920209 pen      code extracted from isc_session.c
+*/
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include "isc.h"
+#include "intern.h"
+
+
+
+/*
+** External function declarations
+*/
+extern void *memset(void *, int, int);
+extern void *memcpy(void *, const void *, int);
+extern int socket(int, int, int);
+extern int setsockopt(int, int, int, char *, int);
+extern int listen(int, int);
+extern int connect(int, struct sockaddr *, int);
+extern int bind(int, struct sockaddr *, int);
+extern int close(int);
+extern int atoi(const char *str);
+extern time_t sleep(time_t);
+extern int accept(int fd, struct sockaddr *sock, int *len);
+
+
+
+IscSession *
+isc_tcp_accept_fn(IscHandlerList *hl,
+		  IscSession *scb,
+		  IscMessage *msg)
+{
+  IscSession *new_scb;
+  int fd;
+  
+
+  if ((fd = accept(scb->fd,
+		   (struct sockaddr *) NULL,
+		   (int *) NULL)) < 0)
+    return NULL;
+  
+  new_scb = isc_createtcp(scb->cfg, fd);
+  if (!new_scb)
+  {
+    close(fd);
+    return NULL;
+  }
+  
+  /* Fill in the session info structure */
+  new_scb->fd    = fd;
+  new_scb->state = ISC_STATE_RUNNING;
+  new_scb->mode  = O_RDWR;
+  new_scb->info.tcp.raddr = isc_getraddress(new_scb);
+  new_scb->info.tcp.laddr = isc_getladdress(new_scb);
+  
+  return new_scb;
+}
+
+
+
+
+
+void
+isc_tcp_destroy_fn(IscHandlerList *hl,
+		   IscSession *scb)
+{
+  if (scb->info.tcp.raddr)
+  {
+    isc_freeaddress(scb->info.tcp.raddr);
+    scb->info.tcp.raddr = NULL;
+  }
+  
+  if (scb->info.tcp.laddr)
+  {
+    isc_freeaddress(scb->info.tcp.laddr);
+    scb->info.tcp.laddr = NULL;
+  }
+}
+
+
+
+/*
+** TCP I/O functions structure
+*/
+static IscHandler isc_tcp_funs =
+{
+  &isc_default_read_fn,
+  &isc_default_write_fn,
+  &isc_default_close_fn,
+  NULL,
+  &isc_tcp_accept_fn,
+  &isc_tcp_destroy_fn,
+  NULL
+};
+
+
+
+/*
+** Create a TCP Session Address
+*/
+IscAddress *
+isc_mktcpaddress(const char *address,
+		 const char *service)
+{
+  struct sockaddr_in addr;
+  struct hostent *hp;
+  struct servent *sp;
+
+
+  memset(&addr, 0, sizeof(addr));
+  
+  /* Any local address? */
+  if (address == NULL)
+  {
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = htonl(INADDR_ANY);
+  }
+  else if (isdigit(address[0]))
+  {
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = inet_addr(address);
+    if (addr.sin_addr.s_addr == -1)
+      return NULL;
+  }
+  else if ((hp = gethostbyname(address)) == NULL)
+    return NULL;
+  else
+  {
+    addr.sin_family = hp->h_addrtype;
+    memcpy(&addr.sin_addr, hp->h_addr, sizeof(addr.sin_addr));
+  }
+  
+  if (isdigit(service[0]))
+    addr.sin_port = htons(atoi(service));
+  else if ((sp = getservbyname(service, "tcp")) == NULL)
+    return NULL;
+  else
+    addr.sin_port = sp->s_port;
+
+  return isc_mkipaddress((struct sockaddr *)&addr);
+}
+
+
+		  
+/*
+** Create a TCP session
+*/
+IscSession *
+isc_createtcp(IscSessionConfig *cfg, int fd)
+{
+  IscSession *scb;
+  int res;
+  
+
+  if (fd == -1)
+    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+      return NULL;
+  
+  /* Set non blocking write mode */
+  if ((res = fcntl(fd, F_GETFL, 0)) == -1)
+  {
+    close(fd);
+    return NULL;
+  }
+    
+  if (fcntl(fd, F_SETFL, res | FNDELAY) == -1)
+  {
+    close(fd);
+    return NULL;
+  }
+  
+  setsockopt(fd, SOL_SOCKET, SO_DONTLINGER, 0, 0); 
+  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 0, 0);
+  
+  scb = isc_create(cfg, &isc_tcp_funs);
+  if (!scb)
+    return NULL;
+
+  scb->type = ISC_TYPE_TCP;
+  scb->fd = fd;
+  
+  scb->info.tcp.raddr = NULL;
+  scb->info.tcp.laddr = NULL;
+    
+  return scb;
+}
+
+
+
+/*
+** Bind a TCP session to a local port and address
+*/
+int
+isc_bindtcp(IscSession *scb,
+	    const char *address,
+	    const char *service)
+{
+  IscAddress *ia;
+
+
+  if (scb->type != ISC_TYPE_TCP)
+    return -1;
+  
+  ia = isc_mktcpaddress(address, service);
+			
+  if (!ia)
+    return -1;
+  
+  if (bind(scb->fd, &ia->ip.saddr, sizeof(ia->ip.saddr)) < 0)
+    return -1;
+
+  scb->info.tcp.laddr = ia;
+    
+  return 0;
+}
+
+
+  
+/*
+** Connect a TCP session to a remove service.
+*/
+int
+isc_connecttcp(IscSession *scb,
+	       const char *address,
+	       const char *service)
+{
+  IscAddress *ia;
+  int res;
+
+  
+  if (scb->type != ISC_TYPE_TCP)
+    return -1;
+  
+  /* Local connection? */
+  if (address == NULL)
+    address = "localhost";
+
+  ia = isc_mktcpaddress(address, service);
+
+  if (!ia)
+    return -1;
+  
+  res = connect(scb->fd, &ia->ip.saddr, sizeof(ia->ip.saddr));
+  if (res < 0 && errno != EINPROGRESS)
+    return -1;
+
+  scb->state = (res < 0 ? ISC_STATE_CONNECTING : ISC_STATE_RUNNING);
+  
+  scb->info.tcp.raddr = ia;
+  if (scb->info.tcp.laddr == NULL)
+    scb->info.tcp.laddr = isc_getladdress(scb);
+  
+  return 0;
+}
+
+
+
+/*
+** Establish a session with a remote TCP service, then insert it
+** into a master control structure-
+*/
+IscSession *
+isc_opentcp(IscMaster *mcb,
+	    const char *address,
+	    const char *service)
+{
+  IscSession *scb;
+
+  
+  scb = isc_createtcp(&mcb->scfg, -1);
+  if (!scb)
+    return NULL;
+
+  if (isc_connecttcp(scb, address, service) < 0)
+  {
+    isc_destroy(NULL, scb);
+    return NULL;
+  }
+
+  (void) isc_insert(mcb, scb);
+
+  return scb;
+}
+
+
+
+/*
+** Establish a port to listen at for new TCP connections
+*/
+IscSession *
+isc_listentcp(IscMaster  *mcb,
+	      const char *address,
+	      const char *service)
+{
+  IscSession *scb;
+  int retries;
+  int errcode;
+  
+
+  scb = isc_createtcp(&mcb->scfg, -1);
+  if (!scb)
+    return NULL;
+
+  errno = 0;
+  for (retries = 0; retries < scb->cfg->max.openretries; sleep(1), retries++)
+    if (isc_bindtcp(scb, address, service) >= 0 || errno != EADDRINUSE)
+      break;
+
+  if (retries >= scb->cfg->max.openretries || errno != 0)
+  {
+    errcode = errno;
+    isc_destroy(NULL, scb);
+    errno = errcode;
+    return NULL;
+  }
+
+  if (listen(scb->fd, scb->cfg->max.backlog) < 0)
+  {
+    errcode = errno;
+    isc_destroy(NULL, scb);
+    errno = errcode;
+    return NULL;
+  }
+
+  scb->state = ISC_STATE_LISTENING;
+
+  (void) isc_insert(mcb, scb);
+  
+  return scb;
+}
diff --git a/src/libraries/libisc-new/src/isc_udp.c b/src/libraries/libisc-new/src/isc_udp.c
new file mode 100644
index 000000000..01a42ac4f
--- /dev/null
+++ b/src/libraries/libisc-new/src/isc_udp.c
@@ -0,0 +1,360 @@
+/*
+** isc_udp.c                          Routines to handle UDP ISC sessions
+**
+** Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the
+**                    Lysator Academic Computer Association.
+**
+** history:
+** 920209 pen      code extracted from isc_session.c
+*/
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include "isc.h"
+#include "intern.h"
+
+
+
+extern void *memset(void *, int, int);
+extern void *memcpy(void *, const void *, int);
+extern int socket(int, int, int);
+extern int setsockopt(int, int, int, char *, int);
+extern int connect(int, struct sockaddr *, int);
+extern int bind(int, struct sockaddr *, int);
+extern int close(int);
+extern int atoi(const char *str);
+extern int recvfrom(int fd, char *buf, int len, int flags,
+		    struct sockaddr *from, int *flen);
+extern int sendto(int fd, char *buf, int len, int flags,
+		  struct sockaddr *from, int flen);
+extern int sprintf(char *, const char *, ...);
+
+
+
+/*
+** Receive an UDP message and put it into an IscMessage
+*/
+IscMessage *isc_udp_read_fn(IscHandlerList *hl,
+			    IscSession *scb)
+{
+  IscMessage *msg;
+  struct sockaddr addr;
+  int len;
+  int status;
+  
+  
+  msg = isc_allocmsg(scb->cfg->max.msgsize);
+  
+  len = sizeof(addr);
+  
+  status = recvfrom(scb->fd, msg->buffer, msg->size,
+		    0,
+		    &addr, &len);
+  if (status < 0)
+  {
+    isc_freemsg(msg);
+    return NULL;
+  }
+
+  msg->length = status;
+  msg->buffer[msg->length] = '\0';
+  msg->address = isc_mkipaddress(&addr);
+  
+  return msg;
+}
+
+
+
+/*
+** Transmit an UDP message to a remote service
+*/
+int isc_udp_write_fn(IscHandlerList *hl,
+		     IscSession *scb,
+		     IscMessage *msg)
+{
+  /* No target and no default target? Then fail. */
+  if (!msg->address && !scb->info.udp.raddr)
+  {
+    errno = ENOTCONN;
+    return -1;
+  }
+
+  /* Not target specified? Use default target */
+  if (!msg->address)
+    return ISC_HCALLFUN2(hl, write, scb, msg);
+
+  return sendto(scb->fd, msg->buffer, msg->length,
+		0,
+		&msg->address->ip.saddr,
+		sizeof(msg->address->ip.saddr));
+}
+
+
+
+void
+isc_udp_destroy_fn(IscHandlerList *hl,
+		   IscSession *scb)
+{
+  if (scb->info.udp.raddr)
+  {
+    isc_freeaddress(scb->info.udp.raddr);
+    scb->info.udp.raddr = NULL;
+  }
+  
+  if (scb->info.udp.laddr)
+  {
+    isc_freeaddress(scb->info.udp.laddr);
+    scb->info.udp.laddr = NULL;
+  }
+}
+
+
+
+/*
+** Create an UDP Session Address
+*/
+IscAddress *
+isc_mkudpaddress(const char *address,
+		 const char *service)
+{
+  struct sockaddr_in addr;
+  struct hostent *hp;
+  struct servent *sp;
+
+
+  memset(&addr, 0, sizeof(addr));
+  
+  /* Any local address? */
+  if (address == NULL)
+  {
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = htonl(INADDR_ANY);
+  }
+  else if (strcmp(address, "*") == 0)
+  {
+    /* Broadcast address */
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
+  }
+  else if (isdigit(address[0]))
+  {
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = inet_addr(address);
+    if (addr.sin_addr.s_addr == -1)
+      return NULL;
+  }
+  else if ((hp = gethostbyname(address)) == NULL)
+    return NULL;
+  else
+  {
+    addr.sin_family = hp->h_addrtype;
+    memcpy(&addr.sin_addr, hp->h_addr, sizeof(addr.sin_addr));
+  }
+  
+  if (isdigit(service[0]))
+    addr.sin_port = htons(atoi(service));
+  else if ((sp = getservbyname(service, "udp")) == NULL)
+    return NULL;
+  else
+    addr.sin_port = sp->s_port;
+
+  return isc_mkipaddress((struct sockaddr *) &addr);
+}
+
+
+		  
+static IscHandler isc_udp_funs =
+{
+  &isc_udp_read_fn,
+  &isc_udp_write_fn,
+  &isc_default_close_fn,
+  NULL,
+  NULL,
+  &isc_udp_destroy_fn,
+  NULL
+};
+
+
+
+/*
+** Create an UDP session
+*/
+IscSession *
+isc_createudp(IscSessionConfig *cfg)
+{
+  IscSession *scb;
+  int fd, res;
+  
+  
+  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+    return NULL;
+  
+  /* Set non blocking write mode */
+  if ((res = fcntl(fd, F_GETFL, 0)) == -1)
+  {
+    close(fd);
+    return NULL;
+  }
+    
+  if (fcntl(fd, F_SETFL, res | FNDELAY) == -1)
+  {
+    close(fd);
+    return NULL;
+  }
+  
+  setsockopt(fd, SOL_SOCKET, SO_DONTLINGER, 0, 0); 
+  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 0, 0);
+  
+  scb = isc_create(cfg, &isc_udp_funs);
+  if (!scb)
+    return NULL;
+
+  scb->type = ISC_TYPE_UDP;
+  scb->fd = fd;
+
+  scb->info.udp.raddr = NULL;
+  scb->info.udp.laddr = NULL;
+
+  return scb;
+}
+
+
+	      
+
+
+
+/*
+** Bind an UDP session to a local port and address
+*/
+int
+isc_bindudp(IscSession *scb,
+	    const char *address,
+	    const char *service)
+{
+  IscAddress *ia;
+
+
+  if (scb->type != ISC_TYPE_UDP)
+    return -1;
+  
+  ia = isc_mkudpaddress(address, service);
+			
+  if (!ia)
+    return -1;
+  
+  if (bind(scb->fd, &ia->ip.saddr, sizeof(ia->ip.saddr)) < 0)
+    return -1;
+
+  scb->state = ISC_STATE_RUNNING;
+  scb->info.udp.laddr = ia;
+
+  return 0;
+}
+
+
+  
+/*
+** Connect an UDP session to a remove service.
+*/
+int
+isc_connectudp(IscSession *scb,
+	       const char *address,
+	       const char *service)
+{
+  IscAddress *ia;
+  int res;
+
+  
+  if (scb->type != ISC_TYPE_UDP)
+    return -1;
+
+  if (address == NULL)
+    address = "localhost";
+  
+  ia = isc_mkudpaddress(address, service);
+
+  if (!ia)
+    return -1;
+  
+  res = connect(scb->fd, &ia->ip.saddr, sizeof(ia->ip.saddr));
+  if (res < 0 && errno != EINPROGRESS)
+    return -1;
+
+  scb->state = (res < 0 ? ISC_STATE_CONNECTING : ISC_STATE_RUNNING);
+  
+  scb->info.udp.raddr = ia;
+  if (scb->info.udp.laddr == NULL)
+    scb->info.udp.laddr = isc_getladdress(scb);
+  
+  return 0;
+}
+
+
+
+/*
+** Establish a session with a remote UDP service, then insert it
+** into a master control structure-
+*/
+IscSession *
+isc_openudp(IscMaster *mcb,
+	    const char *address,
+	    const char *service)
+{
+  IscSession *scb;
+
+  
+  scb = isc_createudp(&mcb->scfg);
+  if (!scb)
+    return NULL;
+
+  if (isc_connectudp(scb, address, service) < 0)
+  {
+    isc_destroy(NULL, scb);
+    return NULL;
+  }
+
+  (void) isc_insert(mcb, scb);
+
+  return scb;
+}
+
+
+
+/*
+** Create an UDP session, prepare it for incoming messages
+** and insert it into the master structure
+*/
+IscSession *
+isc_listenudp(IscMaster *mcb,
+	      const char *address,
+	      const char *service)
+{
+  IscSession *scb;
+
+
+  scb = isc_createudp(&mcb->scfg);
+  if (!scb)
+    return NULL;
+
+  if (isc_bindudp(scb, address, service) < 0)
+  {
+    isc_destroy(NULL, scb);
+    return NULL;
+  }
+  
+  (void) isc_insert(mcb, scb);
+  
+  return scb;
+}
-- 
GitLab