Commit febece4e authored by Per Cederqvist's avatar Per Cederqvist

Initial revision

parent 07e2e306
This package implements a library of functions that is intendend
to help creating client-server packages using TCP/IP or other
file descriptor based links.
Have a look at EXAMPLE.c for a example of how it can be used.
/Peter Eriksson (pen@lysator.liu.se)
* Anvnd ett IscMessage som sendbuffert
* Kolla upp s att inte tecken i sendbuf[] snds frn isc_flush() verkligen
har gjorts (manuellt). Vi vill inte ha en-teckens-paket..
* Ta bort isc_setlogfn() et al - ska styras via IscMasterConfig-structen.
* IscHandlerCache: Direkta funktionspekare ocks.
* Man-sidorna
* Root-Makefile
INCDIRS=-I$(HOME)/include
LIBDIRS=-L$(HOME)/lib
SOURCES=tcp.c udp.c
CFLAGS= -g $(LIBDIRS) $(INCDIRS)
CC=gcc
tcp: tcp.c $(HOME)/include/isc.h $(HOME)/lib/libisc.a
gcc $(CFLAGS) -o tcp tcp.c -lisc -lansi
udp: udp.c $(HOME)/include/isc.h $(HOME)/lib/libisc.a
gcc $(CFLAGS) -o udp udp.c -lisc -lansi
clean:
rm -f *~ *.o a.out core tcp udp \#*\#
depend:
gmkdep $(INCDIRS) $(SOURCES)
# DO NOT DELETE THIS LINE -- mkdep uses it.
/*
** udp.c A small ISC subsystem demo program
**
** Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the
** Lysator Academic Computer Association.
**
** history:
** 910306 pen initial coding
** 920211 pen code cleaned up
*/
#include <stdio.h>
#include <errno.h>
/*
** Could do a "#define ISC_UDGTYPE foobar" to change the type of
** the (IscSession) 'udg' member pointer type from "void *" to "foobar *".
*/
#include <isc.h>
extern void abort(void);
static IscConfig cfg =
{
1005,
{
1001,
{ -1, -1, -1, -1, -1 }
},
{
1001
}
};
#define TIMEOUT 30000 /* 30 seconds */
Perror(char *msg)
{
perror(msg);
exit(1);
}
void
main(int argc, char *argv[])
{
IscMaster * mcb; /* ISC master control block */
IscSession * scb; /* ISC session control block */
IscSession * tty; /* ISC session control block */
IscEvent * ecb; /* ISC event control block */
if (argc < 2)
exit(1);
puts("Beginning operation...");
/*
** Initialize the ISC subsystem, create a Master Control Block
*/
if ((mcb = isc_initialize(&cfg)) == NULL)
Perror("isc_initialize");
puts("ISC initialized.");
if (argc > 2)
{
/* Client connection */
/*
** Establish a TCP session to a remote service (IRC)
*/
if ((scb = isc_openudp(mcb, argv[1], argv[2])) == NULL)
Perror("isc_openudp");
if ((tty = isc_openfd(mcb, 0)) == NULL)
Perror("isc_openfd(tty)");
puts("Connection initiated.");
}
else
{
/*
** Enable remote connection attempts at port "argv[1]"
*/
if (isc_listenudp(mcb, NULL, argv[1]) == 0)
Perror("isc_listenudp");
puts("Listening port installed.");
}
puts("entering main event loop...");
/*
** Handle all events
*/
while (ecb = isc_getnextevent(mcb, TIMEOUT))
{
switch (ecb->event)
{
case ISC_EVENT_CONNECTED:
puts("Server connection established.");
break;
case ISC_EVENT_REJECTED:
puts("Server connection rejected.");
isc_destroy(mcb, scb);
exit(0);
case ISC_EVENT_ERROR: /* ISC subsystem error */
fprintf(stderr, "ISC-ERROR: errno = %d", errno);
if (ecb->msg)
fprintf(stderr, " (%s)", ecb->msg->buffer);
putc('\n', stderr);
/*
** Should probably do something more sensible than
** just finishing off the session
*/
if (ecb->session)
isc_destroy(mcb, ecb->session);
break;
case ISC_EVENT_TIMEOUT: /* Timeout limit reached */
puts("*** Timeout ***");
break;
case ISC_EVENT_LOGIN: /* New client requesting connection */
{
/*
** THIS SHOULD NORMALLY NEVER HAPPEN FOR UDP SESSIONS
*/
char laddr[256];
char lserv[256];
char raddr[256];
char rserv[256];
fetch_address(ecb->session->info.tcp.raddr,
raddr,
sizeof(raddr)-1,
rserv,
sizeof(rserv)-1);
fetch_address(ecb->session->info.tcp.laddr,
laddr,
sizeof(laddr)-1,
lserv,
sizeof(lserv)-1);
printf("New session #%d on %s/%s connecting from: %s/%s\n",
ecb->session,
laddr, lserv,
raddr, rserv);
/*
** Here we could assign the 'ecb->session->udg' member some
** arbitrary value to be used later by our own routines
*/
}
break;
case ISC_EVENT_LOGOUT: /* Client closed connection */
if (ecb->session == scb)
{
printf("Server disconnecting\n");
exit(0);
}
else
printf("Client #%d disconnecting\n", ecb->session);
/*
** Deallocate the storage reserved for the session
*/
isc_destroy(mcb, ecb->session);
break;
case ISC_EVENT_MESSAGE: /* Message from client or server */
if (ecb->session == scb)
printf("Message from server: '%s'\n", ecb->msg->buffer);
else if (ecb->session == tty)
isc_send(scb, isc_copymsg(ecb->msg));
else
{
IscMessage *msg;
char raddr[256];
char rserv[256];
fetch_address(ecb->msg->address,
raddr,
sizeof(raddr)-1,
rserv,
sizeof(rserv)-1);
printf("Message from client #%d (%s/%s):\n%s",
ecb->session,
raddr, rserv,
ecb->msg->buffer);
fflush(stdout);
/*
** Reply with some text to the client
*/
msg = isc_mkstrmsg("Ok, got it via UDP\n\r");
isc_sendto(ecb->session,
ecb->msg->address,
msg);
isc_flush(ecb->session);
}
break;
default: /* NOTREACHED - OR SHOULDN'T BE ATLEAST :-) */
Perror("NOTREACHED");
}
/*
** Finished with the event, lets get rid of it
*/
isc_dispose(ecb);
}
/* NOTREACHED - I THINK ... */
Perror("SHUTDOWN");
}
const char *strerror(int num)
{
static char foo[256];
sprintf(foo, "Error #%d", num);
return foo;
}
fetch_address(IscAddress *ia,
char *host,
int hlen,
char *port,
int plen)
{
char *cp;
cp = isc_gethostname(ia, host, hlen);
if (!cp)
isc_getipnum(ia, host, hlen);
cp = isc_getservice(ia, port, plen, ISC_TYPE_TCP);
if (!cp)
sprintf(port, "%d", isc_getportnum(ia));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment