diff --git a/src/libraries/libisc-new/demo/mux.c b/src/libraries/libisc-new/demo/mux.c new file mode 100644 index 0000000000000000000000000000000000000000..a06df4fd3c48321d483eb98c65a98c1c26eca1e8 --- /dev/null +++ b/src/libraries/libisc-new/demo/mux.c @@ -0,0 +1,261 @@ +/* +** libmux.c A set of functions to implement a multiplexing +** protocol above the ISC library +** +** Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the +** Lysator Academic Computer Association. +** +** history: +** 920210 pen initial coding +*/ + +#include <stdio.h> +#include <isc.h> +#include "mux.h" + + +#define MAXSESSIONS 20 + + +typedef struct mux_session +{ + IscSession *scb; + int id; +} MuxSession; + + +typedef struct mux_control +{ + IscSession *scb[MAXSESSIONS]; +} MuxControl; + + + + +static int +mux_session_write_fn(IscHandlerList *hl, + IscSession *scb, + IscMessage *msg) +{ + /* Here, SCB is a pointer to a MUX simulated session */ + MuxSession *msp = scb->udg; + + isc_printf(msp->scb, "MSG #%d %d:", msp->id, msg->length); + isc_write(msp->scb, msg->buffer, msg->length); + isc_flush(msp->scb); + + return msg->length; +} + + +static int +mux_session_close_fn(IscHandlerList *hl, + IscSession *scb) +{ + return 0; +} + + +static void +mux_session_destroy_fn(IscHandlerList *hl, + IscSession *scb) +{ + MuxSession *msp; + MuxControl *mcp; + + + msp = scb->udg; + + /* Remove this MUX session from the MUX controller */ + mcp = msp->scb->udg; + mcp->scb[msp->id] = NULL; + + free(msp); +} + + + +static IscSessionFuns isc_session_funs = +{ + NULL, + &mux_session_write_fn, + &mux_session_close_fn, + NULL, + NULL, + &mux_session_destroy_fn, + NULL +}; + + + + +/* +** Allocate storage for a MUX control structure +*/ +MuxControl * +mux_newcontrol(void) +{ + MuxControl *mcp; + int i; + + + mcp = malloc(sizeof(MuxControl)); + if (!mcp) + return NULL; + + for (i = 0; i < MAXSESSIONS; i++) + mcp->scb[i] = NULL; + + return mcp; +} + + + + +/* +** Create a new MUX session on a MUX control session +*/ +IscSession * +mux_newsession(IscSession *scb) +{ + MuxSession *msp; + MuxControl *mcp; + int i; + + + mcp = scb->udg; + + for (i = 0; i < MAXSESSIONS; i++) + if (mcp->scb[i] == NULL) + { + msp = malloc(sizeof(MuxSession)); + if (!msp) + return NULL; + + mcp->scb[i] = isc_create(scb->cfg, &mux_session_funs); + + msp->id = i; + msp->scb = scb; + mcp->scb[i]->udg = msp; + + return scb; + } + + return NULL; +} + + + + +int +mux_control_close_fn(IscHandlerList *hl, + IscSession *scb) +{ + MuxControl *mcp; + int i; + + mcp = scb->udg; + for (i = 0; i < MAXSESSIONS; i++) + if (mcp->scb[i]) + { + isc_close(mcp->scb[i]); + mcp->scb[i] = NULL; + } + + if (!hl) + return 0; + else + return (*hl->hcb->close)(hl->old.close, scb); +} + + + +void +mux_control_destroy_fn(IscSession *scb) +{ + mux_control_close_fn(scb); + + free(mcp); +} + + +IscEvent * +mux_control_parse_fn(IscSession *scb, + IscMesssage *msg) +{ + MuxControl *mcp; + IscEvent *ep; + IscMessage *nmsg; + int id; + + +/* Here we handle the MUX-to-MUX protocol */ + + mcp = scb->udg; + ep = isc_newevent(); + + while (parse_msg(msg, &ep->event, &id, &nmsg)) + switch (ep->event) + { + case ISC_EVENT_LOGIN: + ep->session = mux_newsession(scb); + return ep; + + case ISC_EVENT_LOGOUT: + isc_close(mcp->scb[id]); + mcp->scb[id] = NULL; + break; + + case ISC_EVENT_MESSAGE: + isc_pushqueue(mcp->scb[id]->rd_msg_q, nmsg); + break; + + default: + /* Do something, perhaps */ + } + + return NULL; +} + + +/* +** Callback function to accept new sessions +*/ +IscSession * +mux_control_accept_fn(IscSession *scb, + IscMessage *msg) +{ + IscSession *nscb; + + nscb = isc_tcp_accept_fn(scb, msg); + + nscb->fun->close = &mux_control_close_fn; + nscb->fun->destroy = &mux_control_destroy_fn; + nscb->fun->parse = &mux_control_parse_fn; + + nscb->udg = mux_newcontrol(); + + return nscb; +} + + + +/* +** Establish a TCP/IP port to listen at for new MUX connections +*/ +IscSession * +mux_listentcp(IscMaster *mcb, + const char *address, + const char *service) +{ + IscSession *scb; + + + scb = isc_listentcp(mcb, address, service); + if (!scb) + return NULL + + scb->fun->accept = &mux_control_accept_fn; + + return scb; +}