ram-output.c 22.7 KB
Newer Older
Linus Tolke Y's avatar
Linus Tolke Y committed
1
/*
2 3
 * $Id: ram-output.c,v 0.45 2003/08/23 16:38:14 ceder Exp $
 * Copyright (C) 1991, 1993-1999, 2001-2003  Lysator Academic Computer Association.
Linus Tolke Y's avatar
Linus Tolke Y committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * 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.
 *
Per Cederqvist's avatar
Per Cederqvist committed
23
 * Please report bugs at http://bugzilla.lysator.liu.se/. 
Linus Tolke Y's avatar
Linus Tolke Y committed
24
 */
Per Cederqvist's avatar
Per Cederqvist committed
25 26 27 28 29 30 31 32 33 34 35
/*
 * 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.)
 */

David Byers's avatar
David Byers committed
36 37 38 39 40

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

Per Cederqvist's avatar
Per Cederqvist committed
41
#include <stdio.h>
42
#include "timewrap.h"
Per Cederqvist's avatar
Per Cederqvist committed
43
#include <sys/types.h>
Per Cederqvist's avatar
Per Cederqvist committed
44

45
#include "s-string.h"
Per Cederqvist's avatar
Per Cederqvist committed
46
#include "kom-types.h"
47
#include "ram-io.h"
Per Cederqvist's avatar
Per Cederqvist committed
48
#include "ram-output.h"
Per Cederqvist's avatar
Per Cederqvist committed
49
#include "lyskomd.h"
Per Cederqvist's avatar
Per Cederqvist committed
50
#include "log.h"
51
#include "local-to-global.h"
52
#include "server-time.h"
Per Cederqvist's avatar
Per Cederqvist committed
53

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
/* 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 *);
69 70 71 72 73
static void foutput_space(FILE *fp);
static void foutput_bool(FILE *fp, int val);
static void foutput_array_start(FILE *fp);
static void foutput_array_end(FILE *fp);
static void foutput_array_nodata(FILE *fp);
74 75


76 77
static int output_format = 2;

78 79 80 81 82 83 84 85
void
foutput_header(FILE* fp, const char *state, int include_timestamp)
{
    fprintf(fp, "%s:%05d\n", state, output_format); /* DIRTY-FLAG and VERSION*/
    if (include_timestamp)
	fprintf(fp, "%020lu\n", (unsigned long)current_time.tv_sec);
}

Per Cederqvist's avatar
Per Cederqvist committed
86
void
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
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;
    }   
}

102 103
static void
foutput_info_0(FILE *fp, Info *info)
104 105 106 107 108 109 110 111 112
{
    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);
}

113 114
static void
foutput_info_2(FILE *fp, Info *info)
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
{
    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;
    }
}


145
static void
146
foutput_person_0 (FILE *fp,
147
                  const Person *person)
148 149 150 151 152
{
    foutput_string (fp, person->username);
    foutput_priv_bits (fp, person->privileges);
    foutput_personal_flags (fp, person->flags);

153
    foutput_text_list (fp, &person->created_texts);
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
    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);
}

173
static void
174 175
foutput_person_2(FILE *fp,
		 const Person *person)
Per Cederqvist's avatar
Per Cederqvist committed
176 177 178 179 180
{
    foutput_string (fp, person->username);
    foutput_priv_bits (fp, person->privileges);
    foutput_personal_flags (fp, person->flags);

181
    foutput_space(fp);
182
    l2g_write (fp, &person->created_texts);
Per Cederqvist's avatar
Per Cederqvist committed
183 184 185 186 187 188
    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",
Per Cederqvist's avatar
Per Cederqvist committed
189 190
	     (unsigned long) person -> user_area,
	     (unsigned long) person -> total_time_present, /* This is not a time,
Per Cederqvist's avatar
Per Cederqvist committed
191 192
						     * but a number of seconds.
						     */
Per Cederqvist's avatar
Per Cederqvist committed
193 194 195 196 197 198 199
	     (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);
Per Cederqvist's avatar
Per Cederqvist committed
200 201
}

202
extern void
203
foutput_person (FILE *fp,
204
                const Person *person)
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
{
    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;
    }
}


222
static void
223 224
foutput_conference_2(FILE *fp,
		     const Conference *conf_c)
225 226 227
{
    foutput_string(fp, conf_c->name);
    foutput_member_list(fp, conf_c->members);
228
    foutput_space(fp);
229
    l2g_write(fp, &conf_c->texts);
230 231 232 233
    foutput_conf_type(fp, conf_c->type);

    foutput_time(fp, conf_c -> creation_time );
    foutput_time(fp, conf_c -> last_written );
Per Cederqvist's avatar
Per Cederqvist committed
234

235 236 237 238 239 240 241 242
    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);
243
    foutput_ulong((unsigned long) conf_c->keep_commented, fp);
244 245 246 247
    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);
}
Per Cederqvist's avatar
Per Cederqvist committed
248

249
static void
250
foutput_conference_1 (FILE *fp,
Per Cederqvist's avatar
Per Cederqvist committed
251 252 253 254
		    Conference *conf_c)
{
    foutput_string(fp, conf_c->name);
    foutput_member_list(fp, conf_c->members);
255
    foutput_text_list(fp, &conf_c->texts);
Per Cederqvist's avatar
Per Cederqvist committed
256 257 258 259 260 261
    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",
Per Cederqvist's avatar
Per Cederqvist committed
262 263 264 265 266 267 268
	     (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);
Per Cederqvist's avatar
Per Cederqvist committed
269 270
}

271
static void
272
foutput_conference_0 (FILE *fp,
273
                      Conference *conf_c)
274 275 276
{
    foutput_string(fp, conf_c->name);
    foutput_member_list(fp, conf_c->members);
277
    foutput_text_list(fp, &conf_c->texts);
278
    foutput_conf_type(fp, conf_c->type);
279 280 281 282 283 284 285 286 287 288 289 290 291 292

    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);
}

293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
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;
    }
}


Per Cederqvist's avatar
Per Cederqvist committed
314

315
static void
316 317
foutput_text_stat_0(FILE *fp,
                    Text_stat *t_stat)
Per Cederqvist's avatar
Per Cederqvist committed
318 319 320 321 322
{
    int i;

    foutput_time(fp, t_stat->creation_time);
    
Per Cederqvist's avatar
Per Cederqvist committed
323 324 325 326 327 328
    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);
Per Cederqvist's avatar
Per Cederqvist committed
329 330 331

    if ( t_stat->misc_items != NULL && t_stat->no_of_misc > 0 )
    {
332
	foutput_array_start(fp);
Per Cederqvist's avatar
Per Cederqvist committed
333 334
	for ( i = 0; i < t_stat->no_of_misc; i++ )
	    foutput_misc_info(fp, t_stat->misc_items[ i ]);
335
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
336 337
    }
    else
338
	foutput_array_nodata(fp);
339 340
}

341
static void
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
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 )
    {
358
	foutput_array_start(fp);
359 360
	for ( i = 0; i < t_stat->no_of_misc; i++ )
	    foutput_misc_info(fp, t_stat->misc_items[ i ]);
361
	foutput_array_end(fp);
362 363
    }
    else
364
	foutput_array_nodata(fp);
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390

    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;
    }
}



391
static void
392 393 394
foutput_aux_flags(FILE *fp,
                  Aux_item_flags f)
{
395 396 397 398 399 400 401 402 403
    foutput_space(fp);
    foutput_bool(fp, f.deleted);
    foutput_bool(fp, f.inherit);
    foutput_bool(fp, f.secret);
    foutput_bool(fp, f.hide_creator);
    foutput_bool(fp, f.dont_garb);
    foutput_bool(fp, f.reserved3);
    foutput_bool(fp, f.reserved4);
    foutput_bool(fp, f.reserved5);
404 405
}

David Byers's avatar
David Byers committed
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
static void
foutput_aux_item_link(FILE *fp,
                      Aux_item_link *link)
{
    foutput_ulong((unsigned long) link->target_type, fp);
    foutput_ulong((unsigned long) link->target_item, fp);
    switch (link->target_type)
    {
    case CONF_OBJECT_TYPE:
        foutput_ulong((unsigned long) link->target_object.conf, fp);
        break;
    case TEXT_OBJECT_TYPE:
        foutput_ulong((unsigned long) link->target_object.text, fp);
        break;
    default:
421
	;
David Byers's avatar
David Byers committed
422 423 424
    }
}

425
static void
426 427 428 429 430 431 432 433 434 435
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);
David Byers's avatar
David Byers committed
436
    foutput_aux_item_link(fp, &a_item->linked_item);
437 438
}

439
static void
440
foutput_aux_item_list(FILE *fp,
441
		      const Aux_item_list *aux)
442 443 444 445 446 447
{
    int i;

    foutput_ulong((unsigned long) aux->length, fp);
    if (aux->items && aux->length > 0)
    {
448
        foutput_array_start(fp);
449 450
        for (i = 0; i < aux->length; i++)
            foutput_aux_item(fp, &aux->items[i]);
451
        foutput_array_end(fp);
452 453
    }
    else
454
        foutput_array_nodata(fp);
455 456 457
}
		      

458
static void
459 460 461
foutput_membership_type(FILE *fp,
                        Membership_type type)
{
462 463 464 465 466 467 468 469 470
    foutput_space(fp);
    foutput_bool(fp, type.invitation);
    foutput_bool(fp, type.passive);
    foutput_bool(fp, type.secret);
    foutput_bool(fp, type.passive_message_invert);
    foutput_bool(fp, type.reserved2);
    foutput_bool(fp, type.reserved3);
    foutput_bool(fp, type.reserved4);
    foutput_bool(fp, type.reserved5);
471 472
}

473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
static void
foutput_read_ranges_0(FILE *fp,
		      Membership *mship)
{
    if (mship->read_ranges == NULL && mship->no_of_read_ranges != 0 )
    {
	kom_log("foutput_read_ranges_0(): no_of_read_ranges forced to 0"
		" in a membership in %lu.\n", (unsigned long)mship->conf_no);
	mship->no_of_read_ranges = 0;
    }

    if (mship->no_of_read_ranges == 0)
	fprintf(fp, " 0 0 *");
    else
    {
	struct read_range *begin;
	struct read_range *end;

	begin = &mship->read_ranges[0];
	end = begin + mship->no_of_read_ranges;

	if (begin->first_read == 1)
	{
	    fprintf(fp, " %lu", begin->last_read);
	    begin++;
	}
	else
	    fprintf(fp, " 0");

	if (begin == end)
	    fprintf(fp, " 0 *");
	else
	{
	    unsigned long no_of_read = 0;
	    const struct read_range *ptr;

	    for (ptr = begin; ptr < end; ++ptr)
		no_of_read += ptr->last_read - ptr->first_read + 1;

	    fprintf(fp, " %lu {", no_of_read);
	    
	    for (ptr = begin; ptr < end; ++ptr)
	    {
		Local_text_no lno;

		for (lno = ptr->first_read; lno <= ptr->last_read; lno++)
		    fprintf(fp, " %lu", (unsigned long)lno);
	    }
	    
	    fprintf(fp, " }");
	}
    }
}

527 528 529 530 531 532
static void
foutput_membership_0(FILE *fp,
		   Membership *mship)
{
    foutput_time(fp, mship->last_time_read );
    
533
    fprintf(fp, " %lu %lu",
534
	    (unsigned long)mship->conf_no,
535 536
	    (unsigned long)mship->priority);
    foutput_read_ranges_0(fp, mship);
537 538 539 540 541 542 543 544
}

static void
foutput_membership_2(FILE *fp,
                     Membership *mship)
{
    foutput_time(fp, mship->last_time_read );
    
545
    fprintf(fp, " %lu %lu",
546
	    (unsigned long)mship->conf_no,
547 548
	    (unsigned long)mship->priority);
    foutput_read_ranges_0(fp, mship);
549 550 551 552 553 554
    fprintf(fp, " %lu", (unsigned long)mship->added_by);
    foutput_time(fp, mship->added_at);
    foutput_membership_type(fp, mship->type);
}


555
extern void
556 557 558 559 560 561
foutput_membership(FILE *fp,
                   Membership *mship)
{
    switch (output_format)
    {
    case 0:
562
    case 1:
563 564 565 566 567 568 569 570 571 572 573
        foutput_membership_0(fp, mship);
        break;
    case 2:
        foutput_membership_2(fp, mship);
        break;
    default:
        restart_kom("unknown database format: %d", output_format);
        break;
    }
}

Per Cederqvist's avatar
Per Cederqvist committed
574 575


576
static void
Per Cederqvist's avatar
Per Cederqvist committed
577 578 579
foutput_string(FILE *fp,
	       String str)
{
Per Cederqvist's avatar
Per Cederqvist committed
580
    foutput_ulong((unsigned long)str.len, fp);
Per Cederqvist's avatar
Per Cederqvist committed
581 582 583 584 585 586
    putc('H', fp);

    if (str.len)
	fwrite(str.string, str.len, 1, fp);
}

587
static void
Per Cederqvist's avatar
Per Cederqvist committed
588 589 590
foutput_priv_bits(FILE *fp,
		  Priv_bits bits)
{
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
    foutput_space(fp);
    foutput_bool(fp, bits.wheel);
    foutput_bool(fp, bits.admin);
    foutput_bool(fp, bits.statistic);
    foutput_bool(fp, bits.create_pers);
    foutput_bool(fp, bits.create_conf);
    foutput_bool(fp, bits.change_name);
    foutput_bool(fp, bits.flg7);
    foutput_bool(fp, bits.flg8);
    foutput_bool(fp, bits.flg9);
    foutput_bool(fp, bits.flg10);
    foutput_bool(fp, bits.flg11);
    foutput_bool(fp, bits.flg12);
    foutput_bool(fp, bits.flg13);
    foutput_bool(fp, bits.flg14);
    foutput_bool(fp, bits.flg15);
    foutput_bool(fp, bits.flg16);
Per Cederqvist's avatar
Per Cederqvist committed
608 609
}

610
static void
Per Cederqvist's avatar
Per Cederqvist committed
611 612 613
foutput_personal_flags(FILE *fp,
		       Personal_flags flags)
{
614 615 616 617 618 619 620 621 622
    foutput_space(fp);
    foutput_bool(fp, flags.unread_is_secret);
    foutput_bool(fp, flags.flg2);
    foutput_bool(fp, flags.flg3);
    foutput_bool(fp, flags.flg4);
    foutput_bool(fp, flags.flg5);
    foutput_bool(fp, flags.flg6);
    foutput_bool(fp, flags.flg7);
    foutput_bool(fp, flags.flg8);
Per Cederqvist's avatar
Per Cederqvist committed
623 624 625
}	


626
static void
Per Cederqvist's avatar
Per Cederqvist committed
627
foutput_text_list(FILE *fp,
628
		  const Local_to_global *text_list)
Per Cederqvist's avatar
Per Cederqvist committed
629
{
630 631
    Local_text_no first;
    Local_text_no end;
Per Cederqvist's avatar
Per Cederqvist committed
632

633 634
    first = l2g_next_key(text_list, 0);
    end = l2g_first_appendable_key(text_list);
635 636 637

    if (first == 0)
	first = end;
638 639 640
    
    foutput_ulong((unsigned long)first, fp);
    foutput_ulong((unsigned long)(end - first), fp);
Per Cederqvist's avatar
Per Cederqvist committed
641

642
    if (first < end)
Per Cederqvist's avatar
Per Cederqvist committed
643
    {
644
	foutput_array_start(fp);
645
	while (first < end)
646
	    foutput_ulong((unsigned long)l2g_lookup(text_list, first++), fp);
647
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
648 649
    }
    else
650
	foutput_array_nodata(fp);
Per Cederqvist's avatar
Per Cederqvist committed
651 652 653
}


654
static void
Per Cederqvist's avatar
Per Cederqvist committed
655
foutput_mark_list(FILE *fp,
656
		  const Mark_list mark_list)
Per Cederqvist's avatar
Per Cederqvist committed
657 658 659
{
    int i;

Per Cederqvist's avatar
Per Cederqvist committed
660
    fprintf(fp, " %lu", (unsigned long)mark_list.no_of_marks);
Per Cederqvist's avatar
Per Cederqvist committed
661 662 663 664 665 666 667 668 669 670 671 672 673 674

    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, " *");
    
}


675
static void
Per Cederqvist's avatar
Per Cederqvist committed
676 677 678
foutput_mark(FILE *fp,
	     Mark mark)
{
Per Cederqvist's avatar
Per Cederqvist committed
679
    fprintf(fp, " %lu %lu", (unsigned long)mark.text_no, (unsigned long)mark.mark_type);
Per Cederqvist's avatar
Per Cederqvist committed
680 681
}

682 683 684
static void
foutput_membership_list_0 (FILE		* fp,
                           Membership_list  mlist)
Per Cederqvist's avatar
Per Cederqvist committed
685 686 687
{
    int i;
    
Per Cederqvist's avatar
Per Cederqvist committed
688
    fprintf(fp, " %lu", (unsigned long)mlist.no_of_confs);
Per Cederqvist's avatar
Per Cederqvist committed
689 690 691

    if ( mlist.confs != NULL && mlist.no_of_confs > 0 )
    {
692
	foutput_array_start(fp);
Per Cederqvist's avatar
Per Cederqvist committed
693
	for ( i = 0; i < mlist.no_of_confs; i++)
694
	    foutput_membership_0(fp, mlist.confs + i);
695
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
696 697
    }
    else
698
	foutput_array_nodata(fp);
Per Cederqvist's avatar
Per Cederqvist committed
699 700
}

701 702 703
static void
foutput_membership_list_2 (FILE		* fp,
                           Membership_list  mlist)
Per Cederqvist's avatar
Per Cederqvist committed
704 705 706
{
    int i;
    
707 708 709
    fprintf(fp, " %lu", (unsigned long)mlist.no_of_confs);

    if ( mlist.confs != NULL && mlist.no_of_confs > 0 )
Per Cederqvist's avatar
Per Cederqvist committed
710
    {
711
	foutput_array_start(fp);
712 713
	for ( i = 0; i < mlist.no_of_confs; i++)
	    foutput_membership_2(fp, mlist.confs + i);
714
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
715 716
    }
    else
717
	foutput_array_nodata(fp);
Per Cederqvist's avatar
Per Cederqvist committed
718 719
}

720
static void
721 722 723 724 725 726
foutput_membership_list(FILE        * fp,
                        Membership_list mlist)
{
    switch (output_format)
    {
    case 0:
727
    case 1:
728 729 730 731 732 733 734 735 736 737 738
        foutput_membership_list_0(fp, mlist);
        break;
    case 2:
        foutput_membership_list_2(fp, mlist);
        break;
    default:
        restart_kom("unknown database format: %d", output_format);
        break;
    }    
}

739
static void
Per Cederqvist's avatar
Per Cederqvist committed
740
foutput_time(FILE *fp,
741
	     time_t clk)
Per Cederqvist's avatar
Per Cederqvist committed
742
{
743
    foutput_ulong((unsigned long) clk, fp);
Per Cederqvist's avatar
Per Cederqvist committed
744 745 746
}


747
static void
Per Cederqvist's avatar
Per Cederqvist committed
748 749 750 751 752
foutput_member_list(FILE *fp,
		    Member_list m_list)
{
    int i;

Per Cederqvist's avatar
Per Cederqvist committed
753
    fprintf(fp, " %lu", (unsigned long)m_list.no_of_members);
Per Cederqvist's avatar
Per Cederqvist committed
754 755
    if ( m_list.members != NULL && m_list.no_of_members > 0 )
    {
756
	foutput_array_start(fp);
Per Cederqvist's avatar
Per Cederqvist committed
757 758
	for ( i = 0; i < m_list.no_of_members; i++ )
	    foutput_member(fp, m_list.members[ i ]);
759
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
760 761
    }
    else
762
	foutput_array_nodata(fp);
Per Cederqvist's avatar
Per Cederqvist committed
763 764 765
}


766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
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);
}

784
static void
Per Cederqvist's avatar
Per Cederqvist committed
785 786 787
foutput_member(FILE *fp,
	       Member member)
{
788 789 790 791 792 793 794 795 796 797 798 799 800
    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;
    }
Per Cederqvist's avatar
Per Cederqvist committed
801 802
}

803
static void
804 805
foutput_conf_type_1(FILE *fp,
                    Conf_type type)
Per Cederqvist's avatar
Per Cederqvist committed
806
{
807 808 809 810 811 812 813 814 815
    foutput_space(fp);
    foutput_bool(fp, type.rd_prot);
    foutput_bool(fp, type.original);
    foutput_bool(fp, type.secret);
    foutput_bool(fp, type.letter_box);
    foutput_bool(fp, type.allow_anon);
    foutput_bool(fp, type.forbid_secret);
    foutput_bool(fp, type.reserved2);
    foutput_bool(fp, type.reserved3);
Per Cederqvist's avatar
Per Cederqvist committed
816 817
}

818
static void
819
foutput_conf_type_0(FILE *fp,
820
                    Conf_type type)
821
{
822 823 824 825 826
    foutput_space(fp);
    foutput_bool(fp, type.rd_prot);
    foutput_bool(fp, type.original);
    foutput_bool(fp, type.secret);
    foutput_bool(fp, type.letter_box);
827 828
}

829
static void
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847
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;
    }
}

Per Cederqvist's avatar
Per Cederqvist committed
848

849
static void
Per Cederqvist's avatar
Per Cederqvist committed
850 851 852
foutput_misc_info(FILE *fp, 
		  Misc_info misc)
{
Per Cederqvist's avatar
Per Cederqvist committed
853
    foutput_ulong((unsigned long)misc.type, fp);
Per Cederqvist's avatar
Per Cederqvist committed
854 855 856 857 858
    
    switch(misc.type)
    {
    case recpt:
    case cc_recpt:
859
    case bcc_recpt:
860
	foutput_ulong((unsigned long)misc.datum.recipient, fp);
861
	break;
862

Per Cederqvist's avatar
Per Cederqvist committed
863
    case loc_no:
Per Cederqvist's avatar
Per Cederqvist committed
864
	foutput_ulong((unsigned long)misc.datum.local_no, fp);
Per Cederqvist's avatar
Per Cederqvist committed
865 866 867 868 869 870 871 872 873 874
	break;
	
    case rec_time:
	foutput_time(fp, misc.datum.received_at);
	break;
	
    case comm_to:
    case comm_in:
    case footn_to:
    case footn_in:
875
	foutput_ulong((unsigned long)misc.datum.text_link, fp);
Per Cederqvist's avatar
Per Cederqvist committed
876 877 878
	break;
	
    case sent_by:
Per Cederqvist's avatar
Per Cederqvist committed
879
	foutput_ulong((unsigned long)misc.datum.sender, fp);
Per Cederqvist's avatar
Per Cederqvist committed
880 881 882 883 884 885 886 887 888
	break;
	
    case sent_at:
	foutput_time(fp, misc.datum.sent_at);
	break;

#ifndef COMPILE_CHECKS
    default:
#endif
889 890
    case unknown_info:
	restart_kom("prot_a_output_misc_info: Illegal misc\n");
Per Cederqvist's avatar
Per Cederqvist committed
891 892 893 894 895 896 897 898 899
    }
}


/* 
 * 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?).
 */

900
static void
Per Cederqvist's avatar
Per Cederqvist committed
901
foutput_ulong (unsigned long l,
Per Cederqvist's avatar
Per Cederqvist committed
902 903
	       FILE *fp)
{
904
    static char   buf[sizeof(unsigned long) * 3 + 1];
Per Cederqvist's avatar
Per Cederqvist committed
905 906
    char         *cp;

907
    foutput_space(fp);
Per Cederqvist's avatar
Per Cederqvist committed
908 909
    if (l < 10)
	putc("0123456789"[l], fp);
910 911 912 913 914 915
    else
    {
	cp = buf + sizeof(buf);
	while (l > 0)
	{
	    *--cp = (l % 10) + '0';
Per Cederqvist's avatar
Per Cederqvist committed
916 917
	    l /= 10;
	}
918
	fwrite(cp, buf + sizeof(buf) - cp, 1, fp);
Per Cederqvist's avatar
Per Cederqvist committed
919 920
    }
}
921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962

void
foutput_atsign(FILE *fp)
{
    putc('@', fp);
}

void
foutput_newline(FILE *fp)
{
    putc('\n', fp);
}

void
foutput_space(FILE *fp)
{
    putc(' ', fp);
}

void
foutput_array_start(FILE *fp)
{
    fputs(" {", fp);
}

void
foutput_array_end(FILE *fp)
{
    fputs(" }", fp);
}

void
foutput_array_nodata(FILE *fp)
{
    fputs(" *", fp);
}

void
foutput_bool(FILE *fp, int val)
{
    putc(val + '0', fp);
}