/* ** mux.c */ static char *rcsid = "$Id: mux.c,v 0.4 1991/08/28 02:21:13 ceder Exp $"; #include #include #include #include "s-string.h" #include "lyskomd.h" #include #include "com.h" #include "connections.h" #include "isc.h" #include "mux.h" #include extern _printf( int (*sputc)(int chr), const char *fmt, va_list AP); /* ** MUX support functions */ Mux * mux_create(Mux_type type, ISCSCB *scb) { Mux *mp; mp = (Mux *) smalloc(sizeof(Mux)); mp->magic = MUX_MAGIC_ALLOC; mp->type = type; mp->scb = scb; mp->client_c = 0; mp->client_v = NULL; mp->parse.parse_pos = 0; mp->parse.parse_pos_2 = 0; mp->parse.string_parse_pos = 0; mp->parse.first_to_parse = 0; mp->parse.more_to_parse = TRUE; mp->parse.function = 0; mp->parse.string = EMPTY_STRING; mp->parse.unparsed = EMPTY_STRING; return mp; } void mux_free_parsed(Mux *mp) { s_clear(&mp->parse.string); mp->parse.parse_pos = 0; mp->parse.parse_pos_2 = 0; mp->parse.string_parse_pos = 0; } void mux_destruct(Mux *mp) { switch (mp->magic) { case MUX_MAGIC_ALLOC: break; case MUX_MAGIC_FREE: restart_kom("MUX_DESTRUCT: Trying to destruct freed Mux block\n"); default: restart_kom("MUX_DESTRUCT: Bad magic number\n"); } mp->magic = MUX_MAGIC_FREE; mux_free_parsed(mp); s_clear(&mp->parse.unparsed); sfree(mp->client_v); sfree(mp); } int mux_clients(Mux *mp) { int i; int c; switch (mp->magic) { case MUX_MAGIC_ALLOC: break; case MUX_MAGIC_FREE: restart_kom("MUX_CLIENTS: Trying to work on freed Mux block\n"); default: restart_kom("MUX_CLIENTS: Bad magic number\n"); } for (i = 0, c = 0; i < mp->client_c; i++) if (mp->client_v[i].id != -1) c++; return c; } void mux_addclient(Mux *mp, int id, Connection *cp) { int i; switch (mp->magic) { case MUX_MAGIC_ALLOC: break; case MUX_MAGIC_FREE: restart_kom("MUX_ADDCLIENT: Trying to work on freed Mux block\n"); default: restart_kom("MUX_ADDCLIENT: Bad magic number\n"); } for (i = 0; i < mp->client_c; i++) if (mp->client_v[i].id == -1) break; if (i == mp->client_c) { mp->client_c++; if (mp->client_v == NULL) mp->client_v = (Mux_client *) smalloc(sizeof(Mux_client)); else mp->client_v = (Mux_client *) srealloc(mp->client_v, sizeof(Mux_client) * (mp->client_c)); } mp->client_v[i].conn = cp; mp->client_v[i].id = id; mp->client_v[i].outmsg = isc_allocmsg(MUX_OUTMSGSIZE); } void mux_delclient(Mux *mp, int id) { int i; switch (mp->magic) { case MUX_MAGIC_ALLOC: break; case MUX_MAGIC_FREE: restart_kom("MUX_DELCLIENT: Trying to work on freed Mux block\n"); default: restart_kom("MUX_DELCLIENT: Bad magic number\n"); } for (i = 0; i < mp->client_c; i++) if (mp->client_v[i].id == id) { mp->client_v[i].id = -1; mp->client_v[i].conn = NULL; isc_freemsg(mp->client_v[i].outmsg); return; } } Mux_client * mux_getclientbyid(Mux *mp, int id) { int i; switch (mp->magic) { case MUX_MAGIC_ALLOC: break; case MUX_MAGIC_FREE: restart_kom("MUX_GETCLIENTBYID: Trying to work on freed Mux block\n"); default: restart_kom("MUX_GETCLIENTBYID: Bad magic number\n"); } for (i = 0; i < mp->client_c; i++) if (mp->client_v[i].id == id) return &mp->client_v[i]; return NULL; } Mux_client * mux_getclientbyconn(Mux *mp, Connection *cp) { int i; switch (mp->magic) { case MUX_MAGIC_ALLOC: break; case MUX_MAGIC_FREE: restart_kom("MUX_GETCLIENTBYCONN: Trying to work on freed Mux block\n"); default: restart_kom("MUX_GETCLIENTBYCONN: Bad magic number\n"); } for (i = 0; i < mp->client_c; i++) if (mp->client_v[i].conn == cp) return &mp->client_v[i]; return NULL; } /* ** MUX output functions */ int mux_write(Connection * cp, const unsigned char * buf, size_t size) { Mux * mp = cp->mux; Mux_client * mcp; size_t osize; size_t wlen; size_t clen; mcp = mux_getclientbyconn(mp, cp); if (mcp == NULL) /* BETTER ERROR HANDLING SHOULD GO HERE */ restart_kom("mux_write: STALE CLIENT ID\n"); osize = size; while (size > 0) { while ((wlen = mcp->outmsg->size - mcp->outmsg->length) == 0) mux_flush(cp); clen = size > wlen ? wlen : size; memcpy(mcp->outmsg->buffer + mcp->outmsg->length, buf, clen); mcp->outmsg->length += clen; size -= clen; buf += clen; } return osize; } int mux_putc(int chr, Connection * cp) { Mux * mp = cp->mux; Mux_client * mcp; mcp = mux_getclientbyconn(mp, cp); if (mcp == NULL) /* BETTER ERROR HANDLING SHOULD GO HERE */ restart_kom("mux_putc: STALE CLIENT ID\n"); while (mcp->outmsg->length == mcp->outmsg->size) mux_flush(cp); mcp->outmsg->buffer[mcp->outmsg->length++] = chr; return chr; } static Connection *send_cp; static int send_putc(int chr) { return mux_putc(chr, send_cp); } int mux_printf(Connection * cp, const char * format, ...) { va_list AP; int retval = -1; va_start(AP, format); send_cp = cp; retval = _printf(&send_putc, format, AP); va_end(AP); return retval; } void mux_flush(Connection * cp) { Mux * mp = cp->mux; Mux_client * mcp; mcp = mux_getclientbyconn(mp, cp); if (mcp == NULL) /* BETTER ERROR HANDLING SHOULD GO HERE */ restart_kom("mux_flush: STALE CLIENT ID\n"); if (mcp->outmsg->length == 0) return; switch (mp->type) { case MUX_TYPE_CLIENT: isc_send(mp->scb, mcp->outmsg); isc_flush(mp->scb); mcp->outmsg = isc_allocmsg(MUX_OUTMSGSIZE); break; case MUX_TYPE_MUX: isc_printf(mp->scb, "3 %d %dH", mcp->id, mcp->outmsg->length); isc_write(mp->scb, mcp->outmsg->buffer, mcp->outmsg->length); isc_printf(mp->scb, "\n"); isc_flush(mp->scb); mcp->outmsg->length = 0; break; default: restart_kom("mux_flush: ILLEGAL MUX TYPE: %d\n", mp->type); } } void mux_close(Connection * cp) { Mux * mp = cp->mux; Mux_client * mcp; mcp = mux_getclientbyconn(mp, cp); if (mcp == NULL) /* BETTER ERROR HANDLING SHOULD GO HERE */ restart_kom("mux_close: STALE CLIENT ID\n"); mux_flush(cp); switch (mp->type) { case MUX_TYPE_CLIENT: isc_close(mp->scb); mux_destruct(mp); cp->mux = NULL; break; case MUX_TYPE_MUX: isc_printf(mp->scb, "2 %d\n", mcp->id); isc_flush(mp->scb); mux_delclient(mp, mcp->id); cp->mux = NULL; break; default: restart_kom("mux_close: ILLEGAL MUX TYPE: %d\n", mp->type); } }