Commit ea505862 authored by David Byers's avatar David Byers
Browse files

Removed file (again).

parent e6dca4a9
/*
* $Id: mux-parse.c,v 0.23 1999/05/12 13:25:17 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.23 1999/05/12 13:25:17 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 )
{
kom_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 )
kom_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)
{
kom_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;
}
}
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