Select Git revision
js_html.pike
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);
}
}