Select Git revision
Per Cederqvist authored
tcp.c 4.50 KiB
/*
** 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));
}