Skip to content
Snippets Groups Projects
Select Git revision
  • dcb4eb362862873928e3546cd10424ed833bc32d
  • master default
  • wip-slh-dsa-sha2-128s
  • master-updates
  • release-3.10-fixes
  • getopt-prototype
  • fix-bcrypt-warning
  • refactor-hmac
  • wip-use-alignas
  • trim-sha3-context
  • fix-gitlab-ci
  • check-fat-emulate
  • delete-digest_func-size
  • slh-dsa-shake-128f-nettle
  • slh-dsa-shake-128s-nettle
  • slh-dsa-shake-128s
  • delete-openpgp
  • ppc64-sha512
  • delete-md5-compat
  • cleanup-hmac-tests
  • ppc64-sha256
  • nettle_3.10.2_release_20250626
  • nettle_3.10.1_release_20241230
  • nettle_3.10_release_20240616
  • nettle_3.10rc2
  • nettle_3.10rc1
  • nettle_3.9.1_release_20230601
  • nettle_3.9_release_20230514
  • nettle_3.8.1_release_20220727
  • nettle_3.8_release_20220602
  • nettle_3.7.3_release_20210606
  • nettle_3.7.2_release_20210321
  • nettle_3.7.1_release_20210217
  • nettle_3.7_release_20210104
  • nettle_3.7rc1
  • nettle_3.6_release_20200429
  • nettle_3.6rc3
  • nettle_3.6rc2
  • nettle_3.6rc1
  • nettle_3.5.1_release_20190627
  • nettle_3.5_release_20190626
41 results

testutils.c

Blame
  • dbck-cache.c 16.08 KiB
    /*
     * $Id: dbck-cache.c,v 0.9 1992/02/26 18:45:15 ceder 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. 
     */
    /*
     * This module contains some very simple simulations of the routines in
     * cache.c.
     *
     * Extracted from ram-cache.c and rewritten by ceder.
     *
     * New database format with texts in their own file by Inge Wallin.
     *   Also save time as a time_t instead of a struct tm.
     */
    
    static char *rcsid = "$Id: dbck-cache.c,v 0.9 1992/02/26 18:45:15 ceder Exp $";
    
    
    /*
     * All functions that can fail sets kom_errno to a suitable value
     * if they fail.
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/file.h>
    #include <unistd.h>
    #include <errno.h>
    
    #include <kom-errno.h>
    #include <kom-types.h>
    #include "s-collat-tabs.h"
    #include <server/smalloc.h>
    #include "cache.h"
    #include <debug.h>
    #include "lyskomd.h"
    #include <parser.h>
    #include "ram-parse.h"
    #include "log.h"
    #include "ram-output.h"
    #include "com.h"
    #include "connections.h"
    #include "send-async.h"
    #include "memory.h"
    #include "dbck-cache.h"
    
    #ifdef TIME_SYNC
    #  include <sys/resource.h>
    #endif
        
    #define EXPORT
    
    #include "tmp-limits.h"
    
    Person		* pers_arr[ MAX_CONF ];
    Conference 	* conf_arr[ MAX_CONF ];
    Conf_type	  conf_type_arr[ MAX_CONF ];
    String		  name_list [ MAX_CONF ]; /* "cache" list */
    			        	  /* Global var auto init to NULL */
    int		  next_free_num = 1;
    
    Text_stat 	* text_arr[ MAX_TEXT ];
    int next_text_num = 1;
    
    /* Defined in ramkomd.c */
    extern char datafilename[];
    extern char backupfilename[];
    extern char textfilename[];
    
    
    static FILE          *text_file = NULL;
    static FILE	     *new_text_file = NULL; /* Used when garbage collecting. */
    
    BUGDECL;
    
    
    /* Macros */
    
    #define TRACE2(format, arg) if ( buglevel > 2 ) printf(format, arg)
    #define TRACE1(format) if ( buglevel > 2 ) printf(format)
    #define TRACESTR(str)  if ( buglevel > 2 ) s_puts(str)
    #define INRANGE(str, num, retval) if ( num == 0 || num >= next_free_num ) \
    {			\
        return retval;	\
        printf("%s: conf_no %d out of range 1 ... %d ", str, num, next_free_num); \
        fflush(stdout);	\
        fflush(stderr);	\
        abort();		\
    }
    
    #define TEXT_RANGE(str, num, retval) if ( num == 0 || num >= next_text_num ) \
    {	\
        return retval;\
        printf("Text_no out of range 1 ... %d ", next_text_num); \
        printf(str);	\
        fflush(stdout);	\
        fflush(stderr);	\
        abort(); 		\
    }
    
    
    extern Conf_type
    cached_get_conf_type (Conf_no conf_no)
    {
        return conf_arr [ conf_no ]->type;
    }
    
    
    
    #define IMPL(retval) if (1) { fflush(stderr); fflush(stdout); abort(); }
    
    
    /*
     * Various function calls to tell the cache that something is changed.
     */
    
    void
    mark_person_as_changed(Pers_no	pers_no)
    {
        TRACE2("Person %d is changed\n", pers_no);
        return;    
    }
    
    
    void
    mark_conference_as_changed(Conf_no	conf_no)
    {
        TRACE2("Conf.  %d is changed\n", conf_no);
        return;
    }
    
    void
    mark_text_as_changed( Text_no text_no )
    {
        TRACE2("Text %d is changed.\n", text_no);
        TEXT_RANGE("mark_text_as_changed\n", text_no, (void)0);
    }    
    
    
    /*
     * Person-related calls
     */
    
    
    extern Success
    cached_create_person( Pers_no person )
    {
        TRACE2("Person %d is being created.\n", person);
        INRANGE("cached_create_person\n", person, FAILURE);
    
        if ( pers_arr[ person ] != NULL )
        {
    	TRACE1("pers_arr not NULL");
    	fflush(stdout);
    	fflush(stderr);
    	abort();
        }
        
        pers_arr[ person ] = alloc_person();
        return OK;
    }
    
    
    extern Person *
    cached_get_person_stat( Pers_no	person )
    {
        INRANGE("cached_get_person_stat\n", person, NULL);
        TRACE2("cached_get_person_stat %d\n", person);
        kom_errno = KOM_UNDEF_PERS;
        
        return pers_arr[ person ];
    }
    
    
    
    /*
     * Conference-related calls
     */
    extern Conf_no	/* Also cache the name */
    cached_create_conf (String  name)
    {
        Conference * conf_c;
        Conf_no	 conf_no;
    
        TRACE1("cached_create_conf( ");
        TRACESTR(name);
        TRACE1(" )\n");
    
        if ( next_free_num >= MAX_CONF )
        {
    	kom_errno = KOM_INDEX_OUT_OF_RANGE;
    	return 0;
        }
        
        conf_no = next_free_num++;
        conf_c  = alloc_conference();
    
        conf_c->name = EMPTY_STRING;
        s_strcpy(&conf_c->name, name);
    
        TRACE2(" number %d\n", conf_no);
    
        conf_arr[ conf_no ] = conf_c;
        pers_arr[ conf_no ] = NULL;
        
        return conf_no;
    }
    
    extern Success
    cached_delete_conf( Conf_no	conf )
    {
        INRANGE("cached_delete_conf()", conf, FAILURE);
        if ( conf_arr[ conf ] == NULL )
        {
    	kom_errno = KOM_UNDEF_CONF;
    	return FAILURE;
        }
        free_conference(conf_arr[ conf ]);
        conf_arr[ conf ] = NULL;
        return OK;
    }
    
    Success
    cached_delete_person(Pers_no pers)
    {
        INRANGE("cached_delete_person()", pers, FAILURE);
        if ( pers_arr[ pers ] == NULL )
        {
    	kom_errno = KOM_UNDEF_PERS;
    	return FAILURE;
        }
    
        pers_arr[ pers ] = NULL;
        return OK;
    }
    
    Success
    cached_delete_text(Text_no text)
    {
        TEXT_RANGE("cached_delete_text()", text, FAILURE);
        if ( text_arr[ text ] == NULL )
        {
    	kom_errno = KOM_NO_SUCH_TEXT;
    	return FAILURE;
        }
        free_text_stat(text_arr[ text ]);
        text_arr[ text ] = NULL;
        return OK;
        
    }
    
    
    extern Conference *
    cached_get_conf_stat(	Conf_no		conf_no )
    {
        INRANGE("cached_get_conf_stat\n", conf_no, NULL);
        TRACE2("cached_get_conf_stat %d\n", conf_no);
        kom_errno = KOM_UNDEF_CONF;
        
        return conf_arr[ conf_no ];
    }
    
    /*
     * Return TRUE if conf_no exists.
     */
    Bool
    cached_conf_exists(Conf_no conf_no)
    {
        return conf_arr[ conf_no ] != NULL ? TRUE : FALSE;
    }
    
        
    /*
     * Calls to handle texts
     */
    
    extern String
    cached_get_text( Text_no text )
    {
        String  the_string;
    
        TEXT_RANGE("cached_get_text\n", text, EMPTY_STRING);
        TRACE2("cached_get_text %d\n", text);
    
        if ( text_arr[ text ] == NULL )
    	return EMPTY_STRING;
        else
        {
    	the_string.string = tmp_alloc( text_arr[text]->no_of_chars );
    	the_string.len = text_arr[text]->no_of_chars;
    	fseek(text_file, text_arr[ text ]->file_pos, SEEK_SET);
    	if ( fread(the_string.string, sizeof(char), the_string.len, text_file)
    	    != the_string.len )
    	{
    	    log("WARNING: cached_get_text: "
    		"couldn't read enough characters of text %d\n",
    		text);
    	}
    		    
    	return the_string;
        }
    }
    
    extern Text_stat *	/* NULL on error */
    cached_get_text_stat(	Text_no		text )
    {
        kom_errno = KOM_NO_SUCH_TEXT;
        TEXT_RANGE("cached_get_text_stat\n", text, NULL);
        TRACE2("cached_get_text_stat %d\n", text);
        
        return text_arr[ text ];
    }
    
    
    
    /*
     * The text is set up with an empty misc-field. The misc field is
     * later initialized by create_text.
     */
    
    #if 0
    extern Text_no
    cached_create_text( String message)
    {
        Text_no tno;
    
        tno = next_text_num++;
    
        TRACE2("cached_create_text (len=%d)\n", message.len);
    
        if ( tno >= MAX_TEXT )
        {
    	kom_errno = KOM_INDEX_OUT_OF_RANGE;
    	next_text_num = MAX_TEXT;
    	
    	return 0;
        }
            
        text_arr[ tno ] = alloc_text_stat();
        text_arr[ tno ]->no_of_misc = 0;
        text_arr[ tno ]->misc_items = NULL;
        text_arr[ tno ]->no_of_marks = 0;
        text_arr[ tno ]->no_of_lines = 0;
        text_arr[ tno ]->no_of_chars = 0;
        fseek(text_file, 0, SEEK_END);
        text_arr[ tno ]->file_pos = ftell(text_file);
    
        if ( fwrite(message.string, sizeof(char), message.len, text_file)
    	!= message.len ) {
    	log("WARNING: cached_create_text: Couldn't write the text %d\n",
    	    tno);
        }
    
        fflush(text_file);
        
        TRACE2("cached_create_text -> %d\n", tno);
        
        return tno;
    }
    #endif
    
    void
    cached_flush_text(Text_no text_no,
    		  String message)
    {
        if ( text_no >= next_text_num )
        {
    	log("cached_flush_text(%lu, string): only text %lu exists.",
    	    (u_long) text_no, (u_long) next_text_num);
    	return;
        }
            
        fseek(new_text_file, 0, SEEK_END);
        text_arr[ text_no ]->file_pos = ftell(new_text_file);
    
        if ( fwrite(message.string, sizeof(char), message.len, new_text_file)
    	!= message.len )
        {
    	log("WARNING: cached_flush_text: Couldn't write the text %d\n",
    	    text_no);
        }
    
        fflush(new_text_file);
    }
    
    Text_no
    traverse_text(Text_no seed)
    {
        seed++;
        
        while ( seed < next_text_num && text_arr[ seed ] == NULL )
    	seed++;
    
        return (seed == next_text_num) ? 0 : seed ;
    }
    
    Pers_no
    traverse_person(Pers_no seed)
    {
        seed++;
        
        while ( seed < next_free_num && pers_arr[ seed ] == NULL )
    	seed++;
    
        return (seed == next_free_num) ? 0 : seed ;
    }
    
    Conf_no
    traverse_conference(Conf_no seed)
    {
        seed++;
        
        while ( seed < next_free_num && conf_arr[ seed ] == NULL )
    	seed++;
    
        return (seed == next_free_num) ? 0 : seed ;
    }
    
    extern Garb_nice
    cached_get_garb_nice (Conf_no conf_no)
    {
        return conf_arr [ conf_no ]->nice;
    }
    
    extern Local_text_no
    cached_get_highest_local_no (Conf_no conf_no)
    {
        return ( conf_arr [ conf_no ]->texts.first_local_no
    	    - 1 + conf_arr [ conf_no ]->texts.no_of_texts );
    }
    
    /* Lock a person struct in memory. Increase a referenc count. */
    void
    cached_lock_person(Pers_no pers_no)
    {}
    
    /* Decrease reference count. If zero, unlock person. */
    void
    cached_unlock_person(Pers_no pers_no)
    {}
    
    /* Lock a conf struct in memory. Increase a referenc count. */
    void
    cached_lock_conf(Conf_no conf_no)
    {}
    
    /* Decrease reference count. If zero, unlock conf. */
    void
    cached_unlock_conf(Conf_no conf_no)
    {}
    
    
    
    
    static Bool
    is_clean(const char *fn)
    {
        FILE *fp;
    
        if ( (fp = fopen(fn, "rb")) == NULL )
    	return FALSE;
    
        if ( getc(fp) == 'C' && getc(fp) == 'L' && getc(fp) == 'E'
    	&& getc(fp) == 'A' && getc(fp) == 'N' )
        {
    	fclose(fp);
    	return TRUE;
        }
        else
        {
    	fclose(fp);
    	return FALSE;
        }
    }
    
    #ifdef TIME_SYNC
    static long
    timerdiff(struct timeval a,
    	   struct timeval b)
    {
        return a.tv_sec - b.tv_sec;
    }
    #endif
    
    extern void			/* Write out everything. */
    cache_sync(void)
    {
        FILE *fp;
        int i;
    
    #ifdef TIME_SYNC
        struct rusage start, after_confs, after_persons, after_text_stats,
        	after_text_masses;
        time_t st, ac, ap, ats, atm;
        void getrusage(int who, struct rusage *rusage);
    #endif
        
    #ifdef TIME_SYNC
        getrusage(0, &start);
        time(&st);
    #endif
    
        if ( is_clean(datafilename) )
        {
    	if ( rename(datafilename, backupfilename) != 0 )
    	    log("WARNING: cache_sync: can't backup.\n");
        }
        else
    	log("cache_sync: datafile not clean. No backup taken.\n");
        
        if ( (fp=fopen(datafilename, "w") ) == NULL )
        {
    	log("WARNING: cache_sync: can't open file to save in.\n");
    	return;
        }
    
        fprintf(fp, "DIRTY\n");		 /* DIRTY-FLAG */
    
        fprintf(fp, "%d\n", next_free_num);	  /* NEXT_FREE_NUM */
    
        for ( i = 1; i < next_free_num; i++ ) /* CONFS */
        {
    	if ( conf_arr[ i ] == NULL )
    	    fprintf(fp, "@");
    	else
    	{
    	    fprintf(fp, "+ ");
    	    foutput_conference(fp, conf_arr[ i ]);
    	}
    	putc('\n', fp);
        }
    #ifdef TIME_SYNC
        getrusage(0, &after_confs);
        time(&ac);
    #endif
    
        for ( i = 1; i < next_free_num; i++ ) /* PERSONS */
        {
    	if ( pers_arr[ i ] == NULL )
    	    fprintf(fp, "@");
    	else
    	{
    	    fprintf(fp, "+ %dH", PASSWD_LEN);
    	    fwrite(pers_arr[ i ]->pwd, PASSWD_LEN, 1, fp);
    	    foutput_person(fp, pers_arr[ i ]);
    	}
    	putc('\n', fp);
        }
    #ifdef TIME_SYNC
        getrusage(0, &after_persons);
        time(&ap);
    #endif
    
        fprintf(fp, "%d\n", next_text_num);	/* NEXT_TEXT_NUM */
    
        for ( i = 1; i < next_text_num; i++ ) /* TEXT_STATS */
        {
    	if ( text_arr[ i ] == NULL )
    	    fprintf(fp, "@");
    	else
    	{
    	    fprintf(fp, "+ ");
    	    foutput_text_stat(fp, text_arr[ i ]);
    	}
    	putc('\n', fp);
        }
    
    #ifdef TIME_SYNC
        getrusage(0, &after_text_stats);
        time(&ats);
    
        getrusage(0, &after_text_masses);
        time(&atm);
    #endif
    
        rewind(fp);
        fprintf(fp, "CLEAN");
        fclose(fp);
    
    #ifdef TIME_SYNC
        log("Sync ready.\n"
        	"User: %4ld sec (%4ld conf, %4ld pers, %4ld stat, %4ld text)\n"
        	"Sys:  %4ld sec (%4ld conf, %4ld pers, %4ld stat, %4ld text)\n"
    	"Real: %4ld sec (%4ld conf, %4ld pers, %4ld stat, %4ld text)\n"
    	"Page faults: %4ld. Swapped: %4ld. Outblocked: %4ld.\n",
    	
    	timerdiff(after_text_masses.ru_utime, start.ru_utime),
    	timerdiff(after_confs.ru_utime, start.ru_utime),
    	timerdiff(after_persons.ru_utime, after_confs.ru_utime),
    	timerdiff(after_text_stats.ru_utime, after_persons.ru_utime),
    	timerdiff(after_text_masses.ru_utime, after_text_stats.ru_utime),
    	
    	timerdiff(after_text_masses.ru_stime, start.ru_stime),
    	timerdiff(after_confs.ru_stime, start.ru_stime),
    	timerdiff(after_persons.ru_stime, after_confs.ru_stime),
    	timerdiff(after_text_stats.ru_stime, after_persons.ru_stime),
    	timerdiff(after_text_masses.ru_stime, after_text_stats.ru_stime),
    
    	(u_long)difftime(atm, st),
    	(u_long)difftime(ac, st),
    	(u_long)difftime(ap, ac),
    	(u_long)difftime(ats, ap),
    	(u_long)difftime(atm, ats),
    
    	after_text_masses.ru_majflt - start.ru_majflt,
    	after_text_masses.ru_nswap - start.ru_nswap,
    	after_text_masses.ru_oublock - start.ru_oublock);
    #endif    
    }
    
    void
    cache_open_new_text_file(void)
    {
        if ( ( new_text_file = fopen(textfilename, "w")) == NULL )
        {
    	log("Can't open file to save new texts. Goodbye.\n");
    	exit(1);
        }
    }
    
    extern Success
    init_cache(void)
    {
        FILE *fp = NULL;
        int i;
        extern int vflag;		/* from dbck.c */
    
        new_text_file = NULL;
        
        if ( (text_file = fopen(textfilename, "rb")) == NULL )
        {
    	perror(textfilename);
    	restart_kom("ERROR: init_cache: can't open text file %s.\n",
    		    textfilename);
        }
    
        if ( is_clean(datafilename) )
        {
    	if ( (fp = fopen(datafilename, "rb")) == NULL )
    	{
    	    log("WARNING: init_cache: can't open datafile.\n");
    	    return FAILURE;
    	}
    	log("MSG: init_cache: using datafile.\n");
        }
        else if ( is_clean(backupfilename) )
        {
    	if ( (fp = fopen(backupfilename, "rb")) == NULL )
    	{
    	    log("WARNING: init_cache: can't open backupfile.\n");
    	    return FAILURE;
    	}
    	log("MSG: init_cache: using backup file.\n");
        }
        else
        {
    	log("WARNING: init_cache: can't find old data base.\n");
    	return FAILURE;
        }
            
        fseek(fp, 6, SEEK_SET);	/* skip clean/dirty flag. */
    
        next_free_num = fparse_long(fp);	  /* NEXT_FREE_NUM */
    
        if ( vflag )
    	log("Reading %d conferences, starting at pos %d.\n",
    	    next_free_num-1, ftell(fp));
    
        for ( i = 1; i < next_free_num; i++ ) /* CONFS */
        {
    	fskipwhite(fp);
    	switch(getc(fp))
    	{
    	case '@':
    	    conf_arr[ i ] = NULL;
    	    break;
    
    	case '+':
    	    conf_arr[ i ] = alloc_conference();
    	    if ( fparse_conference(fp, conf_arr[ i ]) != OK )
    		restart_kom("init_cache(): fparse_conference failed. "
    			    "i == %d\n", i);
    
    	    name_list[i] = EMPTY_STRING;
    	    s_strcpy(&name_list[i], conf_arr[ i ]->name);
    	    
    	    break;
    	}
        }
    
        if ( vflag )
    	log("Reading %d persons, starting at pos %d.\n",
    	    next_free_num-1, ftell(fp));
    
        for ( i = 1; i < next_free_num; i++ ) /* PERSONS */
        {
    	fskipwhite(fp);
    	switch(getc(fp))
    	{
    	case '@':
    	    pers_arr[ i ] = NULL;
    	    break;
    
    	case '+':
    	    pers_arr[ i ] = alloc_person();
    	    if ( fparse_person(fp, pers_arr[ i ]) != OK )
    		restart_kom("init_cache: fparse_person failed. i == %d\n", i);
    	    
    	    break;
    	}
        }
    
        next_text_num = fparse_long(fp);	/* NEXT_TEXT_NUM */
    
        if ( vflag )
    	log("Reading %d texts, starting at pos %d.\n",
    	    next_text_num-1, ftell(fp));
    
        for ( i = 1; i < next_text_num; i++ ) /* TEXT_STATS */
        {
    	fskipwhite(fp);
    	switch(getc(fp))
    	{
    	case '@':
    	    text_arr[ i ] = NULL;
    	    break;
    
    	case '+':
    	    text_arr[ i ] = alloc_text_stat();
    	    if ( fparse_text_stat(fp, text_arr[ i ]) != OK )
    		restart_kom("init_cache(): fparse_text_stat failed. i == %d\n",
    			    i);
    	    break;
    	}
        }
    
        log("Read %d confs/persons and %d texts, eof at %d\n",
    	next_free_num-1, next_text_num-1, ftell(fp));
    
        fclose(fp);
    
        return OK;
    }