Commit 04999393 authored by Per Cederqvist's avatar Per Cederqvist

The mux protocol is no longer supported.

parent 8466f94d
/*
* $Id: mux-parse.c,v 0.21 1998/12/26 22:40:45 byers Exp $
* Copyright (C) 1991, 1993, 1994, 1995, 1996 Lysator Academic Computer Association.
*
* This file is part of the LysKOM server.
*
* LysKOM is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* LysKOM is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with LysKOM; see the file COPYING. If not, write to
* Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
* or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
* MA 02139, USA.
*
* Please mail bug reports to bug-lyskom@lysator.liu.se.
*/
/*
** mux-parse.c Handle the MUX protocol
* This is a hack. Clean this mess up with lacgen.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
static const char *
rcsid = "$Id: mux-parse.c,v 0.21 1998/12/26 22:40:45 byers Exp $";
#include "rcs.h"
USE(rcsid);
#include <stdio.h>
#include <setjmp.h>
#include <sys/types.h>
#include <time.h>
#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif
#include <sys/socket.h>
#include "s-string.h"
#include "kom-types.h"
#include "com.h"
#include "async.h"
#include "connections.h"
#include "isc-interface.h"
#include "kom-config.h"
#include "log.h"
#include "minmax.h"
#include "mux.h"
#include "mux-parse.h"
jmp_buf mux_parse_env;
static String
mux_get_token(Mux *mux)
{
String result;
String_size old_first;
old_first = mux->parse.first_to_parse;
result = s_strtok(mux->parse.unparsed, &mux->parse.first_to_parse,
s_fcrea_str(WHITESPACE));
/* Check that there was at least one trailing blank. */
if ( mux->parse.first_to_parse >= s_strlen(mux->parse.unparsed) )
{
mux->parse.first_to_parse = old_first;
longjmp(mux_parse_env, MUX_MSG_INCOMPLETE);
}
return result;
}
static long
mux_parse_long(Mux *mux)
{
String token;
String_size end;
long res;
token = mux_get_token(mux);
res = s_strtol(token, &end, PROTOCOL_NUMBER_BASE);
if (end != s_strlen(token))
longjmp(mux_parse_env, MUX_PROTOCOL_ERR);
return res;
}
/*
* Parse a string. At most 'maxlen' characters are allowed. If the
* mux sends a longer string only the first 'maxlen+1' characters
* are read. Any remaining characters are discarded.
*
* longjmp if not enough characters are available or if there
* is an error. Result is used to save state in that case.
* +++ Result should not be used to save state.
*/
static void
mux_parse_string(Mux *mux,
String *result,
int maxlen)
{
String_size hptr; /* Pointer to 'H' */
String_size mux_len; /* The len the mux is sending. */
String_size truncated_len; /* How much the server will receive. */
String_size to_skip;
static u_long err_cnt = 0;
switch ( mux->parse.string_parse_pos )
{
case 0:
if ( ( result->len != 0 || result->string != NULL) && err_cnt++ < 20 )
{
log ("%s == %lu, result->string == %lu. %s.\n",
"mux_parse_string(): result->len",
(u_long)result->len, (u_long)result->string,
"This memory will not be free()'d");
*result = EMPTY_STRING;
if ( err_cnt == 20 )
log("Won't log the above warning no more.");
}
/* Get number and discard trailing 'H' */
mux_len = s_strtol(s_fsubstr(mux->parse.unparsed,
mux->parse.first_to_parse,
END_OF_STRING),
&hptr, PROTOCOL_NUMBER_BASE);
if ( hptr == -1
|| mux->parse.first_to_parse + hptr
>= s_strlen(mux->parse.unparsed) )
{
longjmp(mux_parse_env, MUX_MSG_INCOMPLETE);
}
if (mux_len < 0)
{
log("Insane string length from mux. Logging out mux.\n");
longjmp(mux_parse_env, MUX_LOGOUT);
}
/* Check that
a) there is a trailing H
b) there was at least one digit before the H */
/* +++ Use s-string.c to extract the char. */
/* +++ Fix prot_a_parse_string also. */
if ( mux->parse.unparsed.string[ mux->parse.first_to_parse
+ hptr ] != 'H'
|| hptr <= 0 )
{
longjmp(mux_parse_env, MUX_PROTOCOL_ERR);
}
mux->parse.first_to_parse += 1 + hptr;
mux->parse.string_parse_pos = 1;
result->len = mux_len; /* +++ Transfer mux_len. */
/* Fall through */
case 1:
mux_len = result->len;
/* Check that the entire string is transmitted. */
/* (Don't care about the trailing part that will be skipped if the
* string is longer than maxlen) */
truncated_len = min(maxlen + 1, mux_len);
if ( mux->parse.first_to_parse + truncated_len
> s_strlen(mux->parse.unparsed) )
{
longjmp(mux_parse_env, MUX_MSG_INCOMPLETE);
}
*result = EMPTY_STRING;
s_mem_crea_str(result,
mux->parse.unparsed.string + mux->parse.first_to_parse,
truncated_len);
mux->parse.first_to_parse += truncated_len;
mux->parse.string_parse_pos = 2;
result->len = mux_len; /* Can't transfer the local mux_len across
* call boundary. +++ There should be room
* for mux_len in the per-connection
* protocol data.
*/
/* Fall through */
case 2:
/* Was the string too long? If so, skip the truncated data. */
mux_len = result->len; /* +++ shouldn't modify ->len */
truncated_len = min(maxlen+1, mux_len);
if ( mux_len > truncated_len )
{
to_skip = min(mux_len - truncated_len,
mux->parse.unparsed.len - mux->parse.first_to_parse);
/* From now on, mux_len is length of result + numer of
chars to skip. Clean up this! +++
*/
mux_len -= to_skip;
mux->parse.first_to_parse += to_skip;
}
result->len = mux_len;
if ( mux_len > truncated_len )
{
/* +++ mux_len is transferred in result->len. */
longjmp(mux_parse_env, MUX_MSG_INCOMPLETE);
}
/* Fall through */
default:
mux->parse.string_parse_pos = 0;
}
}
static Bool
mux_is_legal_fnc(int fnc)
{
switch(fnc)
{
case 0:
case 1:
case 2:
case 3:
return TRUE;
default:
return FALSE;
}
}
static void
mux_parse_client_message(Mux *mux)
{
switch(mux->parse.parse_pos_2)
{
case 0:
mux->parse.num = mux_parse_long(mux);
mux->parse.parse_pos_2 = 1;
/* Fall through */
case 1:
mux_parse_string(mux, &mux->parse.string, 10000);
/* Fall through */
default:
mux->parse.parse_pos_2 = 0;
}
}
void
mux_parse_packet(Mux *mux)
{
switch(mux->parse.parse_pos)
{
case 0: /* Get fnc_no */
mux->parse.function = mux_parse_long(mux);
if ( !mux_is_legal_fnc(mux->parse.function) )
longjmp(mux_parse_env, MUX_PROTOCOL_ERR);
mux->parse.parse_pos = 1;
/* Fall through */
case 1:
/* Call the function that parses the arguments for this call. */
switch(mux->parse.function)
{
case 0:
break;
case 2:
mux->parse.num = mux_parse_long(mux);
break;
case 1:
case 3:
mux_parse_client_message(mux);
break;
}
/* Fall through */
default:
mux->parse.parse_pos = 0;
}
}
/*
* $Id: mux-parse.h,v 0.8 1995/01/01 20:17:23 ceder Exp $
* Copyright (C) 1991, 1992, 1993, 1994, 1995 Lysator Academic Computer Association.
*
* This file is part of the LysKOM server.
*
* LysKOM is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* LysKOM is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with LysKOM; see the file COPYING. If not, write to
* Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
* or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
* MA 02139, USA.
*
* Please mail bug reports to bug-lyskom@lysator.liu.se.
*/
/*
* $Id: mux-parse.h,v 0.8 1995/01/01 20:17:23 ceder Exp $
*
** mux-parse.c Handle the MUX protocol
* This is a hack.
*/
extern jmp_buf mux_parse_env;
#define MUX_PROTOCOL_ERR 1
#define MUX_MSG_INCOMPLETE 2
#define MUX_LOGOUT 3
extern void
mux_parse_packet(Mux *mux);
/*
* $Id: mux.c,v 0.21 1998/12/26 22:40:46 byers Exp $
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Lysator Academic Computer Association.
*
* This file is part of the LysKOM server.
*
* LysKOM is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* LysKOM is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with LysKOM; see the file COPYING. If not, write to
* Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
* or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
* MA 02139, USA.
*
* Please mail bug reports to bug-lyskom@lysator.liu.se.
*/
/*
** mux.c
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
static const char *
rcsid = "$Id: mux.c,v 0.21 1998/12/26 22:40:46 byers Exp $";
#include "rcs.h"
USE(rcsid);
#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#include <setjmp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include "isc-interface.h"
#include "s-string.h"
#include "misc-types.h"
#include "kom-types.h"
#include "com.h"
#include "async.h"
#include "connections.h"
#include "mux.h"
#include "server/smalloc.h"
#include "lyskomd.h"
#ifdef HAVE_STDARG_H
extern int UCB_printf( int (*sputc)(int chr), const char *fmt, va_list AP);
#endif
/*
** MUX support functions
*/
Mux *
mux_create(Mux_type type, IscSession *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");