Commit ec88921b authored by Per Cederqvist's avatar Per Cederqvist

Initial revision

parent 4a5a5ab3
#
# 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
/*
** 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;
}
/*
** 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;
}
/*
** 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;