Skip to content
Snippets Groups Projects
Select Git revision
  • dbck-q-n-d-link
  • foutput-text_stat-override
  • generations
  • text-stat-sha256
  • use-nettle
  • import-nettle
  • refactor-cached_get_text
  • refactor-cached_get_text-part-2
  • add-text_store
  • introduce-generation_position
  • remove-reclamation
  • dbfile-temp-filenames
  • sstrdup
  • dbfile_open_read-check-magic
  • master default
  • adns_dist
  • liboop_dist
  • search
  • isc
  • dbdbckmultiplechoice
  • last.cvs.revision
  • 2.1.2
  • 2.1.1
  • 2.1.0
  • adns_1_0
  • liboop_0_9
  • 2.0.7
  • search_bp
  • 2.0.6
  • 2.0.5
  • isc_1_01
  • Protocol-A-10.4
  • 2.0.4
  • 2.0.3
  • 2.0.2
  • 2.0.1
  • 2.0.0
  • isc_1_00
  • isc_merge_1999_05_01
  • isc_merge_1999_04_21
40 results

prot-a-parse.c

Blame
  • prot-a-parse.c 7.32 KiB
    /*
     * $Id: prot-a-parse.c,v 0.7 1991/09/15 10:30:12 linus Exp $
     * Copyright (C) 1991  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. 
     */
    /*
     * prot-a-parse.c - parse protocol-A messages.
     *
     * BUG: Not all functions are used, I think. /ceder
     */
    
    static char *rcsid = "$Id: prot-a-parse.c,v 0.7 1991/09/15 10:30:12 linus Exp $";
    
    
    #include <setjmp.h>
    #include <string.h>
    
    #include "s-string.h"
    #include <kom-types.h>
    #include "lyskomd.h"
    #include "com.h"
    #include "connections.h"
    #include "prot-a-parse.h"
    #include "isc-parse.h"
    #include <server/smalloc.h>
    #include "minmax.h"
    #include "prot-a.h"
    #include "config.h"
    #include "log.h"
    
    long
    prot_a_parse_long(Connection *client)
    {
        String	token;
        String_size end;
        long	res;
    
        token = prot_a_get_token(client);
        res = s_strtol(token, &end, PROTOCOL_NUMBER_BASE);
        if (end != s_strlen(token))
    	longjmp(parse_env, ISC_PROTOCOL_ERR);
        
        return res;
    }
    
    void
    prot_a_parse_priv_bits(Connection *client,
    		       Priv_bits      *res)
    {
        String token;
    
        token = prot_a_get_token(client);
    
        if ( s_strlen(token) != 16 )
    	longjmp(parse_env, ISC_PROTOCOL_ERR);
        
        res->wheel = token.string[ 0 ] != '0';
        res->admin = token.string[ 1 ] != '0';
        res->statistic = token.string[ 2 ] != '0';
        res->create_pers = token.string[ 3 ] != '0';
        res->create_conf = token.string[ 4 ] != '0';
        res->change_name = token.string[ 5 ] != '0';
        res->flg7 = token.string[ 6 ] != '0';
        res->flg8 = token.string[ 7 ] != '0';
        res->flg9 = token.string[ 8 ] != '0';
        res->flg10 = token.string[ 9 ] != '0';
        res->flg11 = token.string[ 10 ] != '0';
        res->flg12 = token.string[ 11 ] != '0';
        res->flg13 = token.string[ 12 ] != '0';
        res->flg14 = token.string[ 13 ] != '0';
        res->flg15 = token.string[ 14 ] != '0';
        res->flg16 = token.string[ 15 ] != '0';
    }
    
    void
    prot_a_parse_conf_type(Connection *client,
    		Conf_type      *res)
    {
        String token;
    
        token = prot_a_get_token(client);
        
        if ( s_strlen(token) != 4 )
    	longjmp(parse_env, ISC_PROTOCOL_ERR);
      
        res->rd_prot = token.string[ 0 ] != '0';
        res->original = token.string[ 1 ] != '0';
        res->secret = token.string[ 2 ] != '0';
        res->letter_box = token.string[ 3 ] != '0';
    }
    
    /*
     * Parse a string. At most 'maxlen' characters are allowed. If the
     * client sends a longer string only the first 'maxlen+1' characters
     * are read. Any remaining characters are discarded.
     */
    /*
     * +++ This needs cleaning up. See comments in and above mux_parse_string.
     */
    void
    prot_a_parse_string(Connection  *client,
    		    String	*result,
    		    int		 maxlen)
    {
        String_size hptr;		/* Pointer to 'H' */
        String_size client_len;	/* The len the client is sending. */
        String_size truncated_len;	/* How much the server will receive. */
        String_size to_skip;
        static u_long err_cnt = 0;
    
        switch ( client->string_parse_pos )
        {
        case 0:
    	if ( (result->len != 0 || result->string != NULL) && err_cnt++ < 20 )
    	{
    	    log ("prot_a_parse_string(): result->len == %lu, "
    		 "result->string == %lu. This memory will not be free()'d.\n",
    		 (u_long)result->len, (u_long)result->string);
    	    *result = EMPTY_STRING;
    	    if ( err_cnt == 20 )
    		log("Won't log the above warning no more.");
    	}
    
    	/* Get number and discard trailing 'H' */
    	client_len = s_strtol(s_fsubstr(client->unparsed,
    					client->first_to_parse,
    					END_OF_STRING),
    			      &hptr, PROTOCOL_NUMBER_BASE);
    
    	if ( hptr == -1
    	    || client->first_to_parse + hptr
    	    >= s_strlen(client->unparsed) )
    	{
    	    longjmp(parse_env, ISC_MSG_INCOMPLETE);
    	}
    	
    	/* Check that
    	      a) there is a trailing H
    	      b) there was at least one digit before the H */
    
    	if ( client->unparsed.string[ client->first_to_parse
    					  + hptr ] != 'H'
    	    || hptr <= 0 )
    	{
    	    longjmp(parse_env, ISC_PROTOCOL_ERR);
    	}
    
    	client->first_to_parse += 1 + hptr;
    	client->string_parse_pos = 1;
    	result->len = client_len; /* +++ Transfer */
    	/* Fall through */
        case 1:
    	client_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, client_len);
    	
    	if ( client->first_to_parse + truncated_len
    	    > s_strlen(client->unparsed) )
    	{
    	    longjmp(parse_env, ISC_MSG_INCOMPLETE);
    	}
    
    	*result = EMPTY_STRING;
    
    	s_mem_crea_str(result,
    		       client->unparsed.string + client->first_to_parse,
    		       truncated_len);
    	result->len = client_len; /* Ugly! +++ */
    
    	client->first_to_parse += truncated_len;
    	client->string_parse_pos = 2;
    	/* Fall through */
        case 2:
    	/* Was the string too long? If so, skip the truncated data. */
    
    	client_len = result->len;
    	truncated_len = min(maxlen+1, client_len);
    	
    	if ( client_len > truncated_len )
    	{
    	    to_skip = min(client_len - truncated_len,
    			   client->unparsed.len - client->first_to_parse);
    	    client_len -= to_skip;
    	    client->first_to_parse += to_skip;
    	}
    
    	result->len = client_len;
    	
    	if ( client_len > truncated_len )
    	    longjmp(parse_env, ISC_MSG_INCOMPLETE);
    	/* Fall through */
        default:
    	client->string_parse_pos = 0;
        }
    }
    
    
    extern void
    prot_a_parse_misc_info(Connection *client,
    		       Misc_info      *result)
    {
        switch ( client->struct_parse_pos )
        {
        case 0:
    	result->type = prot_a_parse_long(client);
    	client->struct_parse_pos = 1;
    	/* Fall through */
        case 1:
    	switch( result->type )
    	{
    	case recpt:
    	    result->datum.recipient = prot_a_parse_long(client);
    	    break;
    
    	case cc_recpt:
    	    result->datum.cc_recipient = prot_a_parse_long(client);
    	    break;
    	    
    	case loc_no:
    	    result->datum.local_no = prot_a_parse_long(client);
    	    break;
    	    
    	case comm_to:
    	    result->datum.comment_to = prot_a_parse_long(client);
    	    break;
    	    
    	case footn_to:
    	    result->datum.footnote_to = prot_a_parse_long(client);
    	    break;
    
    	case comm_in:
    	case footn_in:
    	case rec_time:
    	case sent_by:
    	case sent_at:
    	    /* Fall through */
    	    
    #ifndef COMPILE_CHECKS
    	default:
    #endif
    	    longjmp(parse_env, ISC_PROTOCOL_ERR);
    	}
        default:
    	client->struct_parse_pos = 0;
        }
    }
    
    
    String
    prot_a_get_token(Connection *client)
    {
        String result;
        String_size old_first;
    
        old_first = client->first_to_parse;
        
        result = s_strtok(client->unparsed, &client->first_to_parse,
    		      s_fcrea_str(WHITESPACE));
    
        /* Check that there was at least one trailing blank. */
        
        if ( client->first_to_parse >= s_strlen(client->unparsed) )
        {
    	client->first_to_parse = old_first;
    	longjmp(parse_env, ISC_MSG_INCOMPLETE);
        }
    
        return result;
    }