Skip to content
Snippets Groups Projects
Select Git revision
21 results Searching

XML.pmod

Blame
  • ram-output.c 21.44 KiB
    /*
     * $Id: ram-output.c,v 0.29 1999/04/05 16:19:26 ceder 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. 
     */
    /*
     * ram-output.c  -  write objects to disk.
     *
     * This is a hack. It shouldn't be used except for debugging and as a
     * temporary substitute for what Willf|r is (or should:-) be doing.
     *
     * Written by ceder 1990-07-13. Rewritten 1990-08-31.
     * Some functions rewritten for speed by Inge Wallin.
     * (It worked - now saving is twice as fast.)
     */
    
    
    #ifdef HAVE_CONFIG_H
    #  include <config.h>
    #endif
    
    static const char *
    rcsid = "$Id: ram-output.c,v 0.29 1999/04/05 16:19:26 ceder Exp $";
    #include "rcs.h"
    USE(rcsid);
    
    #include <stdio.h>
    #include <time.h>
    #ifdef HAVE_STDARG_H
    #  include <stdarg.h>
    #endif
    #include <sys/types.h>
    
    #include "s-string.h"
    #include "kom-types.h"
    #include "ram-output.h"
    #include "lyskomd.h"
    #include "log.h"
    #include "local-to-global.h"
    
    /* Forward declarations. */
    static void foutput_aux_item_list(FILE *, const Aux_item_list *);
    static void foutput_conf_type (FILE *, Conf_type);
    static void foutput_mark(FILE *, Mark);
    static void foutput_mark_list(FILE *, const Mark_list);
    static void foutput_member(FILE *, Member);
    static void foutput_member_list(FILE *, Member_list);
    static void foutput_membership_list(FILE *, Membership_list);
    static void foutput_misc_info(FILE *, Misc_info);
    static void foutput_personal_flags(FILE *, Personal_flags);
    static void foutput_priv_bits(FILE *, Priv_bits);
    static void foutput_string(FILE *, String);
    static void foutput_text_list(FILE *, const Local_to_global *);
    static void foutput_time(FILE *, time_t);
    static void foutput_ulong(unsigned long, FILE *);
    
    
    static int output_format = 2;
    
    void
    set_output_format(int fmt)
    {
        output_format = fmt;
        switch (fmt)
        {
        case 0:
        case 1:
        case 2:
            break;
        default:
            restart_kom("unknown output format selected: %d\n", fmt);
            break;
        }   
    }
    
    static void
    foutput_info_0(FILE *fp, Info *info)
    {
        fprintf(fp, " %lu %lu %lu %lu %lu",
    	    (unsigned long)info->conf_pres_conf,
    	    (unsigned long)info->pers_pres_conf,
    	    (unsigned long)info->motd_conf,
    	    (unsigned long)info->kom_news_conf,
    	    (unsigned long)info->motd_of_lyskom);
    }
    
    static void
    foutput_info_2(FILE *fp, Info *info)
    {
        fprintf(fp, " %lu %lu %lu %lu %lu %lu",
    	    (unsigned long)info->conf_pres_conf,
    	    (unsigned long)info->pers_pres_conf,
    	    (unsigned long)info->motd_conf,
    	    (unsigned long)info->kom_news_conf,
    	    (unsigned long)info->motd_of_lyskom,
                (unsigned long)info->highest_aux_no);
        foutput_aux_item_list(fp, &info->aux_item_list);
    }
    
    
    void foutput_info(FILE *fp, Info *info)
    {
        switch(output_format)
        {
        case 0:
        case 1:
            foutput_info_0(fp, info);
            break;
        case 2:
            foutput_info_2(fp, info);
            break;
        default:
            restart_kom("unknown database format: %d", output_format);
            break;
        }
    }
    
    
    static void
    foutput_person_0 (FILE *fp,
                      const Person *person)
    {
        foutput_string (fp, person->username);
        foutput_priv_bits (fp, person->privileges);
        foutput_personal_flags (fp, person->flags);
    
        foutput_text_list (fp, &person->created_texts);
        foutput_mark_list (fp, person->marks);
        foutput_membership_list (fp, person->conferences);
    
        foutput_time(fp, person->last_login);
    
        fprintf (fp, " %lu %lu %lu %lu %lu %lu %lu %lu %lu",
    	     (unsigned long) person -> user_area,
    	     (unsigned long) person -> total_time_present, /* This is not a time,
    						     * but a number of seconds.
    						     */
    	     (unsigned long) person -> sessions,
    	     (unsigned long) person -> created_lines,
    	     (unsigned long) person -> created_bytes,
    	     (unsigned long) person -> read_texts,
    	     (unsigned long) person -> no_of_text_fetches,
    	     (unsigned long) person -> created_persons,
    	     (unsigned long) person -> created_confs);
    }
    
    static void
    foutput_person_2(FILE *fp,
    		 const Person *person)
    {
        foutput_string (fp, person->username);
        foutput_priv_bits (fp, person->privileges);
        foutput_personal_flags (fp, person->flags);
    
        l2g_write (fp, &person->created_texts);
        foutput_mark_list (fp, person->marks);
        foutput_membership_list (fp, person->conferences);
    
        foutput_time(fp, person->last_login);
    
        fprintf (fp, " %lu %lu %lu %lu %lu %lu %lu %lu %lu",
    	     (unsigned long) person -> user_area,
    	     (unsigned long) person -> total_time_present, /* This is not a time,
    						     * but a number of seconds.
    						     */
    	     (unsigned long) person -> sessions,
    	     (unsigned long) person -> created_lines,
    	     (unsigned long) person -> created_bytes,
    	     (unsigned long) person -> read_texts,
    	     (unsigned long) person -> no_of_text_fetches,
    	     (unsigned long) person -> created_persons,
    	     (unsigned long) person -> created_confs);
    }
    
    extern void
    foutput_person (FILE *fp,
                    const Person *person)
    {
        switch(output_format)
        {
        case 0:
        case 1:
            foutput_person_0(fp, person);
            break;
        case 2:
            foutput_person_2(fp, person);
            break;
        default:
            restart_kom("unknown database format: %d", output_format);
            break;
        }
    }
    
    
    static void
    foutput_conference_2(FILE *fp,
    		     const Conference *conf_c)
    {
        foutput_string(fp, conf_c->name);
        foutput_member_list(fp, conf_c->members);
        l2g_write(fp, &conf_c->texts);
        foutput_conf_type(fp, conf_c->type);
    
        foutput_time(fp, conf_c -> creation_time );
        foutput_time(fp, conf_c -> last_written );
    
        fprintf (fp, " %lu %lu %lu %lu %lu %lu %lu",
    	     (unsigned long) conf_c -> creator,
    	     (unsigned long) conf_c -> presentation,
    	     (unsigned long) conf_c -> supervisor,
    	     (unsigned long) conf_c -> permitted_submitters,
    	     (unsigned long) conf_c -> super_conf,
    	     (unsigned long) conf_c -> msg_of_day,
    	     (unsigned long) conf_c -> nice);
        foutput_ulong((unsigned long) conf_c->keep_commented, fp);
        foutput_ulong((unsigned long) conf_c->expire, fp);
        foutput_ulong((unsigned long) conf_c->highest_aux, fp);
        foutput_aux_item_list(fp, &conf_c->aux_item_list);
    }
    
    static void
    foutput_conference_1 (FILE *fp,
    		    Conference *conf_c)
    {
        foutput_string(fp, conf_c->name);
        foutput_member_list(fp, conf_c->members);
        foutput_text_list(fp, &conf_c->texts);
        foutput_conf_type(fp, conf_c->type);
    
        foutput_time(fp, conf_c -> creation_time );
        foutput_time(fp, conf_c -> last_written );
    
        fprintf (fp, " %lu %lu %lu %lu %lu %lu %lu",
    	     (unsigned long) conf_c -> creator,
    	     (unsigned long) conf_c -> presentation,
    	     (unsigned long) conf_c -> supervisor,
    	     (unsigned long) conf_c -> permitted_submitters,
    	     (unsigned long) conf_c -> super_conf,
    	     (unsigned long) conf_c -> msg_of_day,
    	     (unsigned long) conf_c -> nice);
    }
    
    static void
    foutput_conference_0 (FILE *fp,
                          Conference *conf_c)
    {
        foutput_string(fp, conf_c->name);
        foutput_member_list(fp, conf_c->members);
        foutput_text_list(fp, &conf_c->texts);
        foutput_conf_type(fp, conf_c->type);
    
        foutput_time(fp, conf_c -> creation_time );
        foutput_time(fp, conf_c -> last_written );
    
        fprintf (fp, " %lu %lu %lu %lu %lu %lu %lu",
    	     (unsigned long) conf_c -> creator,
    	     (unsigned long) conf_c -> presentation,
    	     (unsigned long) conf_c -> supervisor,
    	     (unsigned long) conf_c -> permitted_submitters,
    	     (unsigned long) conf_c -> super_conf,
    	     (unsigned long) conf_c -> msg_of_day,
    	     (unsigned long) conf_c -> nice);
    }
    
    void foutput_conference(FILE *fp,
                            Conference *conf_c)
    {
        switch(output_format)
        {
        case 0:
            foutput_conference_0(fp, conf_c);
            break;
        case 1:
            foutput_conference_1(fp, conf_c);
            break;
        case 2:
            foutput_conference_2(fp, conf_c);
            break;
        default:
            restart_kom("unknown database format: %d", output_format);
            break;
        }
    }
    
    
    
    static void
    foutput_text_stat_0(FILE *fp,
                        Text_stat *t_stat)
    {
        int i;
    
        foutput_time(fp, t_stat->creation_time);
        
        foutput_ulong((unsigned long) t_stat->author, fp);
        foutput_ulong((unsigned long) t_stat->file_pos, fp);
        foutput_ulong((unsigned long) t_stat->no_of_lines, fp);
        foutput_ulong((unsigned long) t_stat->no_of_chars, fp);
        foutput_ulong((unsigned long) t_stat->no_of_marks, fp);
        foutput_ulong((unsigned long) t_stat->no_of_misc, fp);
    
        if ( t_stat->misc_items != NULL && t_stat->no_of_misc > 0 )
        {
    	fputs(" {", fp);
    	for ( i = 0; i < t_stat->no_of_misc; i++ )
    	    foutput_misc_info(fp, t_stat->misc_items[ i ]);
    	fputs(" }", fp);
        }
        else
    	fputs(" *", fp);
    }
    
    static void
    foutput_text_stat_2(FILE *fp,
                        Text_stat *t_stat)
    {
        int i;
    
        foutput_time(fp, t_stat->creation_time);
        
        foutput_ulong((unsigned long) t_stat->author, fp);
        foutput_ulong((unsigned long) t_stat->file_pos, fp);
        foutput_ulong((unsigned long) t_stat->no_of_lines, fp);
        foutput_ulong((unsigned long) t_stat->no_of_chars, fp);
        foutput_ulong((unsigned long) t_stat->no_of_marks, fp);
        foutput_ulong((unsigned long) t_stat->no_of_misc, fp);
    
        if ( t_stat->misc_items != NULL && t_stat->no_of_misc > 0 )
        {
    	fputs(" {", fp);
    	for ( i = 0; i < t_stat->no_of_misc; i++ )
    	    foutput_misc_info(fp, t_stat->misc_items[ i ]);
    	fputs(" }", fp);
        }
        else
    	fputs(" *", fp);
    
        foutput_ulong((unsigned long) t_stat->highest_aux, fp);
        foutput_aux_item_list(fp, &t_stat->aux_item_list);
    }
    
    void
    foutput_text_stat(FILE *fp,
                      Text_stat *t_stat)
    {
        switch (output_format)
        {
        case 0:
        case 1:
            foutput_text_stat_0(fp, t_stat);
            break;
        case 2:
            foutput_text_stat_2(fp, t_stat);
            break;
        default:
            restart_kom("unknown database format: %d\n", output_format);
            break;
        }
    }
    
    
    
    static void
    foutput_aux_flags(FILE *fp,
                      Aux_item_flags f)
    {
        putc(' ', fp);
        putc(f.deleted + '0', fp);
        putc(f.inherit + '0', fp);
        putc(f.secret + '0', fp);
        putc(f.hide_creator + '0', fp);
        putc(f.dont_garb + '0', fp);
        putc(f.reserved3 + '0', fp);
        putc(f.reserved4 + '0', fp);
        putc(f.reserved5 + '0', fp);
    }
    
    static void
    foutput_aux_item(FILE *fp,
                     Aux_item *a_item)
    {
        foutput_ulong((unsigned long) a_item->aux_no, fp);
        foutput_ulong((unsigned long) a_item->tag, fp);
        foutput_ulong((unsigned long) a_item->creator, fp);
        foutput_time(fp, a_item->sent_at);
        foutput_aux_flags(fp, a_item->flags);
        foutput_ulong((unsigned long) a_item->inherit_limit, fp);
        foutput_string(fp, a_item->data);
    }
    
    static void
    foutput_aux_item_list(FILE *fp,
    		      const Aux_item_list *aux)
    {
        int i;
    
        foutput_ulong((unsigned long) aux->length, fp);
        if (aux->items && aux->length > 0)
        {
            fputs(" {", fp);
            for (i = 0; i < aux->length; i++)
                foutput_aux_item(fp, &aux->items[i]);
            fputs(" }", fp);
        }
        else
            fputs(" *", fp);
    }
    		      
    
    static void
    foutput_membership_type(FILE *fp,
                            Membership_type type)
    {
        putc(' ', fp);
        putc(type.invitation + '0', fp);
        putc(type.passive    + '0', fp);
        putc(type.secret     + '0', fp);
        putc(type.reserved1  + '0', fp);
        putc(type.reserved2  + '0', fp);
        putc(type.reserved3  + '0', fp);
        putc(type.reserved4  + '0', fp);
        putc(type.reserved5  + '0', fp);
    }
    
    static void
    foutput_membership_0(FILE *fp,
    		   Membership *mship)
    {
        int i;
        
        foutput_time(fp, mship->last_time_read );
        
        if ( mship->read_texts == NULL && mship->no_of_read != 0 )
        {
    	log("%s(): no_of_read forced to 0 in a membership in %lu.\n",
    	    "foutput_membership", (unsigned long)mship->conf_no);
    	mship->no_of_read = 0;
        }
        
        fprintf(fp, " %lu %lu %lu %lu",
    	    (unsigned long)mship->conf_no,
    	    (unsigned long)mship->priority,
    	    (unsigned long)mship->last_text_read,
    	    (unsigned long)mship->no_of_read);
        
        if ( mship->read_texts != NULL && mship->no_of_read > 0)
        {
    	fprintf(fp, " {");
    	for ( i = 0; i < mship->no_of_read; i++)
    	    fprintf(fp, " %lu", (unsigned long)mship->read_texts[ i ]);
    	
    	fprintf(fp, " }");
        }
        else
    	fprintf(fp, " *");
    }
    
    static void
    foutput_membership_2(FILE *fp,
                         Membership *mship)
    {
        int i;
        
        foutput_time(fp, mship->last_time_read );
        
        if ( mship->read_texts == NULL && mship->no_of_read != 0 )
        {
    	log("%s(): no_of_read forced to 0 in a membership in %lu.\n",
    	    "foutput_membership", (unsigned long)mship->conf_no);
    	mship->no_of_read = 0;
        }
        
        fprintf(fp, " %lu %lu %lu %lu",
    	    (unsigned long)mship->conf_no,
    	    (unsigned long)mship->priority,
    	    (unsigned long)mship->last_text_read,
    	    (unsigned long)mship->no_of_read);
        
        if ( mship->read_texts != NULL && mship->no_of_read > 0)
        {
    	fprintf(fp, " {");
    	for ( i = 0; i < mship->no_of_read; i++)
    	    fprintf(fp, " %lu", (unsigned long)mship->read_texts[ i ]);
    	
    	fprintf(fp, " }");
        }
        else
    	fprintf(fp, " *");
        fprintf(fp, " %lu", (unsigned long)mship->added_by);
        foutput_time(fp, mship->added_at);
        foutput_membership_type(fp, mship->type);
    }
    
    
    extern void
    foutput_membership(FILE *fp,
                       Membership *mship)
    {
        switch (output_format)
        {
        case 0:
            foutput_membership_0(fp, mship);
            break;
        case 1:
        case 2:
            foutput_membership_2(fp, mship);
            break;
        default:
            restart_kom("unknown database format: %d", output_format);
            break;
        }
    }
    
    
    
    static void
    foutput_string(FILE *fp,
    	       String str)
    {
        foutput_ulong((unsigned long)str.len, fp);
        putc('H', fp);
    
        if (str.len)
    	fwrite(str.string, str.len, 1, fp);
    }
    
    static void
    foutput_priv_bits(FILE *fp,
    		  Priv_bits bits)
    {
        putc(' ', fp);
        putc(bits.wheel + '0', fp);
        putc(bits.admin + '0', fp);
        putc(bits.statistic + '0', fp);
        putc(bits.create_pers + '0', fp);
        putc(bits.create_conf + '0', fp);
        putc(bits.change_name + '0', fp);
        putc(bits.extern_gw + '0', fp);
        putc(bits.flg8 + '0', fp);
        putc(bits.flg9 + '0', fp);
        putc(bits.flg10 + '0', fp);
        putc(bits.flg11 + '0', fp);
        putc(bits.flg12 + '0', fp);
        putc(bits.flg13 + '0', fp);
        putc(bits.flg14 + '0', fp);
        putc(bits.flg15 + '0', fp);
        putc(bits.flg16 + '0', fp);
    }
    
    static void
    foutput_personal_flags(FILE *fp,
    		       Personal_flags flags)
    {
        putc(' ', fp);
        putc(flags.unread_is_secret + '0', fp);
        putc(flags.flg2 + '0', fp);
        putc(flags.flg3 + '0', fp);
        putc(flags.flg4 + '0', fp);
        putc(flags.flg5 + '0', fp);
        putc(flags.flg6 + '0', fp);
        putc(flags.flg7 + '0', fp);
        putc(flags.flg8 + '0', fp);
    }	
    
    
    static void
    foutput_text_list(FILE *fp,
    		  const Local_to_global *text_list)
    {
        Local_text_no first;
        Local_text_no end;
    
        first = l2g_next_key(text_list, 0);
        end = l2g_first_appendable_key(text_list);
    
        if (first == 0)
    	first = end;
        
        foutput_ulong((unsigned long)first, fp);
        foutput_ulong((unsigned long)(end - first), fp);
    
        if (first < end)
        {
    	fputs(" {", fp);
    	while (first < end)
    	    foutput_ulong((unsigned long)l2g_lookup(text_list, first), fp);
    	fputs(" }", fp);
        }
        else
    	fprintf(fp, " *");
    }
    
    
    void
    foutput_mark_list(FILE *fp,
    		  const Mark_list mark_list)
    {
        int i;
    
        fprintf(fp, " %lu", (unsigned long)mark_list.no_of_marks);
    
        if ( mark_list.marks != NULL && mark_list.no_of_marks > 0 )
        {
    	fprintf(fp, " {");
    	for ( i = 0; i < mark_list.no_of_marks; i++ )
    	    foutput_mark(fp, mark_list.marks[ i ]);
    	fprintf(fp, " }");
        }
        else
    	fprintf(fp, " *");
        
    }
    
    
    static void
    foutput_mark(FILE *fp,
    	     Mark mark)
    {
        fprintf(fp, " %lu %lu", (unsigned long)mark.text_no, (unsigned long)mark.mark_type);
    }
    
    static void
    foutput_membership_list_0 (FILE		* fp,
                               Membership_list  mlist)
    {
        int i;
        
        fprintf(fp, " %lu", (unsigned long)mlist.no_of_confs);
    
        if ( mlist.confs != NULL && mlist.no_of_confs > 0 )
        {
    	fprintf(fp, " {");
    	for ( i = 0; i < mlist.no_of_confs; i++)
    	    foutput_membership_0(fp, mlist.confs + i);
    	fprintf(fp, " }");
        }
        else
    	fprintf(fp, " *");
    }
    
    static void
    foutput_membership_list_2 (FILE		* fp,
                               Membership_list  mlist)
    {
        int i;
        
        fprintf(fp, " %lu", (unsigned long)mlist.no_of_confs);
    
        if ( mlist.confs != NULL && mlist.no_of_confs > 0 )
        {
    	fprintf(fp, " {");
    	for ( i = 0; i < mlist.no_of_confs; i++)
    	    foutput_membership_2(fp, mlist.confs + i);
    	fprintf(fp, " }");
        }
        else
    	fprintf(fp, " *");
    }
    
    static void
    foutput_membership_list(FILE        * fp,
                            Membership_list mlist)
    {
        switch (output_format)
        {
        case 0:
            foutput_membership_list_0(fp, mlist);
            break;
        case 1:
        case 2:
            foutput_membership_list_2(fp, mlist);
            break;
        default:
            restart_kom("unknown database format: %d", output_format);
            break;
        }    
    }
    
    static void
    foutput_time(FILE *fp,
    	     time_t clk)
    {
        foutput_ulong((unsigned long) clk, fp);
    }
    
    
    static void
    foutput_member_list(FILE *fp,
    		    Member_list m_list)
    {
        int i;
    
        fprintf(fp, " %lu", (unsigned long)m_list.no_of_members);
        if ( m_list.members != NULL && m_list.no_of_members > 0 )
        {
    	fprintf(fp, " {");
    	for ( i = 0; i < m_list.no_of_members; i++ )
    	    foutput_member(fp, m_list.members[ i ]);
    	fprintf(fp, " }");
        }
        else
    	fprintf(fp, " *");
    }
    
    
    static void
    foutput_member_0(FILE *fp,
                     Member member)
    {
        fprintf(fp, " %lu", (unsigned long)member.member);
    }
    
    static void
    foutput_member_2(FILE *fp,
                     Member member)
    {
        fprintf(fp, " %lu %lu",
                (unsigned long)member.member,
                (unsigned long)member.added_by);
        foutput_time(fp, member.added_at);
        foutput_membership_type(fp, member.type);
    }
    
    static void
    foutput_member(FILE *fp,
    	       Member member)
    {
        switch (output_format)
        {
        case 0:
        case 1:
            foutput_member_0(fp, member);
            break;
        case 2:
            foutput_member_2(fp, member);
            break;
        default:
            restart_kom("unknown database format: %d", output_format);
            break;
        }
    }
    
    static void
    foutput_conf_type_1(FILE *fp,
                        Conf_type type)
    {
        putc(' ', fp);
        putc(type.rd_prot + '0', fp);
        putc(type.original + '0', fp);
        putc(type.secret + '0', fp);
        putc(type.letter_box + '0', fp);
        putc(type.allow_anon + '0', fp);
        putc(type.forbid_secret + '0', fp);
        putc(type.reserved2 + '0', fp);
        putc(type.reserved3 + '0', fp);
    }
    
    static void
    foutput_conf_type_0(FILE *fp,
                        Conf_type type)
    {
        putc(' ', fp);
        putc(type.rd_prot + '0', fp);
        putc(type.original + '0', fp);
        putc(type.secret + '0', fp);
        putc(type.letter_box + '0', fp);
    }
    
    static void
    foutput_conf_type (FILE *fp,
                       Conf_type type)
    {
        switch (output_format)
        {
        case 0:
            foutput_conf_type_0(fp, type);
            break;
        case 1:
        case 2:
            foutput_conf_type_1(fp, type);
            break;
        default:
            restart_kom("unknown database format: %d", output_format);
            break;
        }
    }
    
    
    static void
    foutput_misc_info(FILE *fp, 
    		  Misc_info misc)
    {
        foutput_ulong((unsigned long)misc.type, fp);
        
        switch(misc.type)
        {
        case recpt:
    	foutput_ulong((unsigned long)misc.datum.recipient, fp);
    	break;
    	
        case cc_recpt:
    	foutput_ulong((unsigned long)misc.datum.cc_recipient, fp);
    	break;
    	
        case bcc_recpt:
    	foutput_ulong((unsigned long)misc.datum.bcc_recipient, fp);
    	break;
    	
        case loc_no:
    	foutput_ulong((unsigned long)misc.datum.local_no, fp);
    	break;
    	
        case rec_time:
    	foutput_time(fp, misc.datum.received_at);
    	break;
    	
        case comm_to:
    	foutput_ulong((unsigned long)misc.datum.comment_to, fp);
    	break;
    	
        case comm_in:
    	foutput_ulong((unsigned long)misc.datum.commented_in, fp);
    	break;
    	
        case footn_to:
    	foutput_ulong((unsigned long)misc.datum.footnote_to, fp);
    	break;
    	
        case footn_in:
    	foutput_ulong((unsigned long)misc.datum.footnoted_in, fp);
    	break;
    	
        case sent_by:
    	foutput_ulong((unsigned long)misc.datum.sender, fp);
    	break;
    	
        case sent_at:
    	foutput_time(fp, misc.datum.sent_at);
    	break;
    
    #ifndef COMPILE_CHECKS
        default:
    	restart_kom("prot_a_output_misc_info: Illegal misc\n");
    #endif
        }
    }
    
    
    /* 
     * Output the unsigned long L in the fastest way possible to the file
     * FP. Ok, it's ugly, but it's fast (or is it?).
     */
    
    static void
    foutput_ulong (unsigned long l,
    	       FILE *fp)
    {
        static char   buf[sizeof(unsigned long) * 3 + 1];
        char         *cp;
    
        putc(' ', fp);
        if (l < 10)
    	putc("0123456789"[l], fp);
        else
        {
    	cp = buf + sizeof(buf);
    	while (l > 0)
    	{
    	    *--cp = (l % 10) + '0';
    	    l /= 10;
    	}
    	fwrite(cp, buf + sizeof(buf) - cp, 1, fp);
        }
    }