Commit 997161ef authored by Per Cederqvist's avatar Per Cederqvist

Initial revision

parent febece4e
/*
** tcp.c A small ISC TCP/IP subsystem demo program
**
** Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the
** Lysator Academic Computer Association.
**
** history:
** 910306 pen initial coding
** 920211 pen 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,
{ NULL, NULL, NULL },
NULL
}
};
#define TIMEOUT 30000 /* 30 seconds */
Perror(char *msg)
{
perror(msg);
exit(1);
}
void
main(void)
{
IscMaster * mcb; /* ISC master control block */
IscSession * scb; /* ISC session control block */
IscEvent * ecb; /* ISC event control block */
puts("Beginning operation...");
/*
** Initialize the ISC subsystem, create a Master Control Block
*/
if ((mcb = isc_initialize(&cfg)) == NULL)
Perror("isc_initialize");
puts("ISC initialized, connecting to remote service...");
/*
** Establish a TCP session to a remote service (IRC)
*/
if ((scb = isc_opentcp(mcb, "obel5.ida.liu.se", "2000")) == NULL)
Perror("isc_opentcp");
puts("Connection initiated, enabling listening ports...");
/*
** Enable remote connection attempts at port #20000 and #20001
*/
if (isc_listentcp(mcb, "localhost", "20000") == NULL)
Perror("isc_listentcp-20000");
if (isc_listentcp(mcb, NULL, "20001") == NULL)
Perror("isc_listentcp-20001");
puts("Listening ports installed, 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);
scb = NULL;
break;
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 */
{
char laddr[256];
char lserv[256];
char raddr[256];
char rserv[256];
strcpy(raddr, "<unknown>");
strcpy(rserv, "<unknown>");
strcpy(laddr, "<unknown>");
strcpy(lserv, "<unknown>");
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");
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
{
printf("Message from client #%d: '%s'\n",
ecb->session,
ecb->msg->buffer);
/*
** Reply with some text to the client
*/
isc_write(ecb->session, "OK, got it\n\r", 12);
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));
}
/*
** intern.h Definitions and prototypes used internally
**
** Copyright (c) 1991 Peter Eriksson and Per Cederqvist of the
** Lysator Academic Computer Association.
**
** history:
** 910305 pen initial coding
*/
#ifndef __ISC_INTERNALS_H__
#define __ISC_INTERNALS_H__
/* isc_log.c */
extern void
isc_log(const char *format, ...);
/* isc_abort.c */
extern void
isc_abort(const char *message);
/* isc_alloc.c */
extern void *
isc_malloc(size_t length);
extern void *
isc_realloc(void *buf, size_t length);
extern void
isc_free(void *buf);
extern char *
isc_strdup(const char *str);
/* isc_queue.c */
extern IscMsgQueue *
isc_newqueue(void);
extern int
isc_pollqueue(IscMsgQueue *queue);
extern void
isc_killqueue(IscMsgQueue *queue);
extern void
isc_pushqueue(IscMsgQueue *queue, IscMessage *msg);
extern IscMessage *
isc_topqueue(IscMsgQueue *queue);
extern int
isc_sizequeue(IscMsgQueue *queue);
extern IscMessage *
isc_popqueue(IscMsgQueue *queue);
extern IscMessage *
isc_default_read_fn(IscHandlerList *hl, IscSession *scb);
extern int
isc_default_write_fn(IscHandlerList *hl, IscSession *scb, IscMessage *msg);
extern int
isc_default_close_fn(IscHandlerList *hl, IscSession *scb);
extern IscAddress *
isc_mkipaddress(struct sockaddr *addr);
extern void
isc_oflush(IscSession * scb);
/*
** Setup a set of functions to handle memory allocation
*/
extern void
isc_setallocfn(void * (*mallocfn)(size_t size),
void * (*reallocfn)(void * buf, size_t size),
void (*freefn)(void * buf));
/*
** Setup a function to handle fatal abort requests
*/
extern void
isc_setabortfn(void (*abortfn)(const char * msg));
#define ISC_XNEW(var) (var = isc_malloc(sizeof(*var)))
#define ISC_SCALLFUN1(SCB, NAME, ARG) \
(*SCB->fun.NAME->hcb->NAME)(SCB->fun.NAME, ARG)
#define ISC_SCALLFUN2(SCB, NAME, A1, A2) \
(*SCB->fun.NAME->hcb->NAME)(SCB->fun.NAME, A1, A2)
#define ISC_SCALLFUN3(SCB, NAME, A1, A2, A3) \
(*SCB->fun.NAME->hcb->NAME)(SCB->fun.NAME, A1, A2, A3)
#endif
This diff is collapsed.
/*
** isc_abort.c Route to handle fatal errors
**
** Copyright (c) 1991 Peter Eriksson and Per Cederqvist of the
** Lysator Academic Computer Association.
**
** history:
** 910305 pen moved into separate file
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include "isc.h"
#include "intern.h"
/*
** External function declarations
*/
extern int fprintf(FILE *, char *, ...);
#if defined(__sun__) && !defined(__stdlib_h)
extern void abort(void);
#endif
static void (*isc_abortfn)(const char *msg) = (void (*)(const char *))NULL;
void
isc_setabortfn(void (*abortfn)(const char *msg))
{
isc_abortfn = abortfn;
}
void
isc_abort(const char *message)
{
if (isc_abortfn)
(*isc_abortfn)(message);
else
{
fprintf(stderr, "\n\r*** ISC SUBSYSTEM FATAL ERROR: %s\n\r", message);
abort();
}
}
/*
** isc_alloc.c ISC storage allocation routines
**
** Copyright (c) 1991 Peter Eriksson and Per Cederqvist of the
** Lysator Academic Computer Association.
**
** history:
** 910305 pen moved into separate file
*/
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "isc.h"
#include "intern.h"
/*
** Some magic numbers
*/
#define ISC_MAGIC_ALLOC 0x12F54ACE
#define ISC_MAGIC_FREE 0xEE47A37F
/*
** External declarations
*/
#if defined(__sun__) && !defined(__stdlib_h)
extern void *malloc(size_t);
extern void *calloc(int, size_t);
extern void *realloc(void *, size_t);
extern void free(void *);
#endif
/*
** Pointers to functions to handle storage allocation
*/
static void * (*isc_mallocfn)(size_t size) =
(void * (*)(size_t)) NULL;
static void * (*isc_reallocfn)(void *bufp, size_t size) =
(void * (*)(void *, size_t)) NULL;
static void (*isc_freefn)(void *bufp) =
(void (*)(void *)) NULL;
/*
** Define functions to handle storage allocation
*/
void
isc_setallocfn(void * (*mallocfn)(size_t size),
void * (*reallocfn)(void *buf, size_t size),
void (*freefn)(void *buf))
{
isc_mallocfn = mallocfn;
isc_reallocfn = reallocfn;
isc_freefn = freefn;
}
void *
isc_malloc(size_t size)
{
unsigned int * buf;
if (isc_mallocfn)
buf = (unsigned int *) (*isc_mallocfn)(size + sizeof(unsigned int));
else
{
buf = (unsigned int *) malloc(size + sizeof(unsigned int));
if (!buf)
isc_abort("isc_malloc");
}
*buf++ = ISC_MAGIC_ALLOC;
return (void *) buf;
}
void *
isc_realloc(void *oldbuf, size_t size)
{
unsigned int *buf;
if (!oldbuf)
return isc_malloc(size);
buf = (unsigned int *) oldbuf;
switch (*--buf)
{
case ISC_MAGIC_ALLOC:
break;
case ISC_MAGIC_FREE:
isc_abort("isc_realloc");
default:
isc_abort("isc_realloc");
}
*buf = ISC_MAGIC_FREE;
if (isc_reallocfn)
buf = (unsigned int *) (*isc_reallocfn)((void *) buf,
size + sizeof(unsigned int));
else
{
buf = (void *) realloc((void *) buf, size + sizeof(unsigned int));
if (!buf)
isc_abort("isc_realloc");
}
*buf++ = ISC_MAGIC_ALLOC;
return (void *) buf;
}
void
isc_free(void *buf)
{
unsigned int *ibuf;
if (!buf)
isc_abort("isc_free");
ibuf = (unsigned int *) buf;
switch (*--ibuf)
{
case ISC_MAGIC_ALLOC:
break;
case ISC_MAGIC_FREE:
isc_abort("isc_free");
default:
isc_abort("isc_free");
}
*ibuf = ISC_MAGIC_FREE;
if (isc_freefn)
{
(*isc_freefn)((void *) ibuf);
return;
}
else
free((void *) ibuf);
}
/*
** Safe (hopefully) string duplicator
*/
char *
isc_strdup(const char *str)
{
char *newstr;
newstr = isc_malloc(strlen(str)+1);
strcpy(newstr, str);
return newstr;
}
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