ram-output.c 23.2 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"
53
#include "eintr.h"
Per Cederqvist's avatar
Per Cederqvist committed
54

55
/* Forward declarations. */
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
static void foutput_aux_item_list(struct dbfile *, const Aux_item_list *);
static void foutput_conf_type (struct dbfile *, Conf_type);
static void foutput_mark(struct dbfile *, Mark);
static void foutput_mark_list(struct dbfile *, const Mark_list);
static void foutput_member(struct dbfile *, Member);
static void foutput_member_list(struct dbfile *, Member_list);
static void foutput_membership_list(struct dbfile *, Membership_list);
static void foutput_misc_info(struct dbfile *, Misc_info);
static void foutput_personal_flags(struct dbfile *, Personal_flags);
static void foutput_priv_bits(struct dbfile *, Priv_bits);
static void foutput_string(struct dbfile *, String);
static void foutput_text_list(struct dbfile *, const Local_to_global *);
static void foutput_time(struct dbfile *, time_t);
static void foutput_ulong(unsigned long, struct dbfile *);
static void foutput_space(struct dbfile *fp);
static void foutput_bool(struct dbfile *fp, int val);
static void foutput_array_start(struct dbfile *fp);
static void foutput_array_end(struct dbfile *fp);
static void foutput_array_nodata(struct dbfile *fp);
75

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

84
static void
85
foutput_info_0(struct dbfile *fp, Info *info)
86
{
87
    fprintf(fp->fp, " %lu %lu %lu %lu %lu",
88 89 90 91 92 93 94
	    (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);
}

95
static void
96
foutput_info_2(struct dbfile *fp, Info *info)
97
{
98
    fprintf(fp->fp, " %lu %lu %lu %lu %lu %lu",
99 100 101 102 103 104 105 106 107 108
	    (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);
}


109
void foutput_info(struct dbfile *fp, Info *info)
110
{
111
    switch(fp->format)
112 113 114 115 116 117 118 119 120
    {
    case 0:
    case 1:
        foutput_info_0(fp, info);
        break;
    case 2:
        foutput_info_2(fp, info);
        break;
    default:
121
        restart_kom("unknown database format: %d", fp->format);
122 123 124 125 126
        break;
    }
}


127
static void
128
foutput_person_0 (struct dbfile *fp,
129
                  const Person *person)
130 131 132 133 134
{
    foutput_string (fp, person->username);
    foutput_priv_bits (fp, person->privileges);
    foutput_personal_flags (fp, person->flags);

135
    foutput_text_list (fp, &person->created_texts);
136 137 138 139 140
    foutput_mark_list (fp, person->marks);
    foutput_membership_list (fp, person->conferences);

    foutput_time(fp, person->last_login);

141
    fprintf (fp->fp, " %lu %lu %lu %lu %lu %lu %lu %lu %lu",
142 143 144 145 146 147 148 149 150 151 152 153 154
	     (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);
}

155
static void
156
foutput_person_2(struct dbfile *fp,
157
		 const Person *person)
Per Cederqvist's avatar
Per Cederqvist committed
158 159 160 161 162
{
    foutput_string (fp, person->username);
    foutput_priv_bits (fp, person->privileges);
    foutput_personal_flags (fp, person->flags);

163
    foutput_space(fp);
164
    l2g_write (fp, &person->created_texts);
Per Cederqvist's avatar
Per Cederqvist committed
165 166 167 168 169
    foutput_mark_list (fp, person->marks);
    foutput_membership_list (fp, person->conferences);

    foutput_time(fp, person->last_login);

170
    fprintf (fp->fp, " %lu %lu %lu %lu %lu %lu %lu %lu %lu",
Per Cederqvist's avatar
Per Cederqvist committed
171 172
	     (unsigned long) person -> user_area,
	     (unsigned long) person -> total_time_present, /* This is not a time,
Per Cederqvist's avatar
Per Cederqvist committed
173 174
						     * but a number of seconds.
						     */
Per Cederqvist's avatar
Per Cederqvist committed
175 176 177 178 179 180 181
	     (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
182 183
}

184
extern void
185
foutput_person (struct dbfile *fp,
186
                const Person *person)
187
{
188
    switch(fp->format)
189 190 191 192 193 194 195 196 197
    {
    case 0:
    case 1:
        foutput_person_0(fp, person);
        break;
    case 2:
        foutput_person_2(fp, person);
        break;
    default:
198
        restart_kom("unknown database format: %d", fp->format);
199 200 201 202 203
        break;
    }
}


204
static void
205
foutput_conference_2(struct dbfile *fp,
206
		     const Conference *conf_c)
207 208 209
{
    foutput_string(fp, conf_c->name);
    foutput_member_list(fp, conf_c->members);
210
    foutput_space(fp);
211
    l2g_write(fp, &conf_c->texts);
212 213 214 215
    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
216

217
    fprintf (fp->fp, " %lu %lu %lu %lu %lu %lu %lu",
218 219 220 221 222 223 224
	     (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);
225
    foutput_ulong((unsigned long) conf_c->keep_commented, fp);
226 227 228 229
    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
230

231
static void
232
foutput_conference_1 (struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
233 234 235 236
		    Conference *conf_c)
{
    foutput_string(fp, conf_c->name);
    foutput_member_list(fp, conf_c->members);
237
    foutput_text_list(fp, &conf_c->texts);
Per Cederqvist's avatar
Per Cederqvist committed
238 239 240 241 242
    foutput_conf_type(fp, conf_c->type);

    foutput_time(fp, conf_c -> creation_time );
    foutput_time(fp, conf_c -> last_written );

243
    fprintf (fp->fp, " %lu %lu %lu %lu %lu %lu %lu",
Per Cederqvist's avatar
Per Cederqvist committed
244 245 246 247 248 249 250
	     (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
251 252
}

253
static void
254
foutput_conference_0 (struct dbfile *fp,
255
                      Conference *conf_c)
256 257 258
{
    foutput_string(fp, conf_c->name);
    foutput_member_list(fp, conf_c->members);
259
    foutput_text_list(fp, &conf_c->texts);
260
    foutput_conf_type(fp, conf_c->type);
261 262 263 264

    foutput_time(fp, conf_c -> creation_time );
    foutput_time(fp, conf_c -> last_written );

265
    fprintf (fp->fp, " %lu %lu %lu %lu %lu %lu %lu",
266 267 268 269 270 271 272 273 274
	     (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);
}

275
void foutput_conference(struct dbfile *fp,
276 277
                        Conference *conf_c)
{
278
    switch(fp->format)
279 280 281 282 283 284 285 286 287 288 289
    {
    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:
290
        restart_kom("unknown database format: %d", fp->format);
291 292 293 294 295
        break;
    }
}


Per Cederqvist's avatar
Per Cederqvist committed
296

297
static void
298
foutput_text_stat_0(struct dbfile *fp,
299
                    Text_stat *t_stat)
Per Cederqvist's avatar
Per Cederqvist committed
300 301 302 303 304
{
    int i;

    foutput_time(fp, t_stat->creation_time);
    
Per Cederqvist's avatar
Per Cederqvist committed
305 306 307 308 309 310
    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
311 312 313

    if ( t_stat->misc_items != NULL && t_stat->no_of_misc > 0 )
    {
314
	foutput_array_start(fp);
Per Cederqvist's avatar
Per Cederqvist committed
315 316
	for ( i = 0; i < t_stat->no_of_misc; i++ )
	    foutput_misc_info(fp, t_stat->misc_items[ i ]);
317
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
318 319
    }
    else
320
	foutput_array_nodata(fp);
321 322
}

323
static void
324
foutput_text_stat_2(struct dbfile *fp,
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
                    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 )
    {
340
	foutput_array_start(fp);
341 342
	for ( i = 0; i < t_stat->no_of_misc; i++ )
	    foutput_misc_info(fp, t_stat->misc_items[ i ]);
343
	foutput_array_end(fp);
344 345
    }
    else
346
	foutput_array_nodata(fp);
347 348 349 350 351 352

    foutput_ulong((unsigned long) t_stat->highest_aux, fp);
    foutput_aux_item_list(fp, &t_stat->aux_item_list);
}

void
353
foutput_text_stat(struct dbfile *fp,
354 355
                  Text_stat *t_stat)
{
356
    switch (fp->format)
357 358 359 360 361 362 363 364 365
    {
    case 0:
    case 1:
        foutput_text_stat_0(fp, t_stat);
        break;
    case 2:
        foutput_text_stat_2(fp, t_stat);
        break;
    default:
366
        restart_kom("unknown database format: %d\n", fp->format);
367 368 369 370 371 372
        break;
    }
}



373
static void
374
foutput_aux_flags(struct dbfile *fp,
375 376
                  Aux_item_flags f)
{
377 378 379 380 381 382 383 384 385
    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);
386 387
}

David Byers's avatar
David Byers committed
388
static void
389
foutput_aux_item_link(struct dbfile *fp,
David Byers's avatar
David Byers committed
390 391 392 393 394 395 396 397 398 399 400 401 402
                      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:
403
	;
David Byers's avatar
David Byers committed
404 405 406
    }
}

407
static void
408
foutput_aux_item(struct dbfile *fp,
409 410 411 412 413 414 415 416 417
                 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
418
    foutput_aux_item_link(fp, &a_item->linked_item);
419 420
}

421
static void
422
foutput_aux_item_list(struct dbfile *fp,
423
		      const Aux_item_list *aux)
424 425 426 427 428 429
{
    int i;

    foutput_ulong((unsigned long) aux->length, fp);
    if (aux->items && aux->length > 0)
    {
430
        foutput_array_start(fp);
431 432
        for (i = 0; i < aux->length; i++)
            foutput_aux_item(fp, &aux->items[i]);
433
        foutput_array_end(fp);
434 435
    }
    else
436
        foutput_array_nodata(fp);
437 438 439
}
		      

440
static void
441
foutput_membership_type(struct dbfile *fp,
442 443
                        Membership_type type)
{
444 445 446 447 448 449 450 451 452
    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);
453 454
}

455
static void
456
foutput_read_ranges_0(struct dbfile *fp,
457 458 459 460 461 462 463 464 465 466
		      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)
467
	fprintf(fp->fp, " 0 0 *");
468 469 470 471 472 473 474 475 476 477
    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)
	{
478
	    fprintf(fp->fp, " %lu", begin->last_read);
479 480 481
	    begin++;
	}
	else
482
	    fprintf(fp->fp, " 0");
483 484

	if (begin == end)
485
	    fprintf(fp->fp, " 0 *");
486 487 488 489 490 491 492 493
	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;

494
	    fprintf(fp->fp, " %lu {", no_of_read);
495 496 497 498 499 500
	    
	    for (ptr = begin; ptr < end; ++ptr)
	    {
		Local_text_no lno;

		for (lno = ptr->first_read; lno <= ptr->last_read; lno++)
501
		    fprintf(fp->fp, " %lu", (unsigned long)lno);
502 503
	    }
	    
504
	    fprintf(fp->fp, " }");
505 506 507 508
	}
    }
}

509
static void
510
foutput_membership_0(struct dbfile *fp,
511 512 513 514
		   Membership *mship)
{
    foutput_time(fp, mship->last_time_read );
    
515
    fprintf(fp->fp, " %lu %lu",
516
	    (unsigned long)mship->conf_no,
517 518
	    (unsigned long)mship->priority);
    foutput_read_ranges_0(fp, mship);
519 520 521
}

static void
522
foutput_membership_2(struct dbfile *fp,
523 524 525 526
                     Membership *mship)
{
    foutput_time(fp, mship->last_time_read );
    
527
    fprintf(fp->fp, " %lu %lu",
528
	    (unsigned long)mship->conf_no,
529 530
	    (unsigned long)mship->priority);
    foutput_read_ranges_0(fp, mship);
531
    fprintf(fp->fp, " %lu", (unsigned long)mship->added_by);
532 533 534 535 536
    foutput_time(fp, mship->added_at);
    foutput_membership_type(fp, mship->type);
}


537
extern void
538
foutput_membership(struct dbfile *fp,
539 540
                   Membership *mship)
{
541
    switch (fp->format)
542 543
    {
    case 0:
544
    case 1:
545 546 547 548 549 550
        foutput_membership_0(fp, mship);
        break;
    case 2:
        foutput_membership_2(fp, mship);
        break;
    default:
551
        restart_kom("unknown database format: %d", fp->format);
552 553 554 555
        break;
    }
}

Per Cederqvist's avatar
Per Cederqvist committed
556 557


558
static void
559
foutput_string(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
560 561
	       String str)
{
Per Cederqvist's avatar
Per Cederqvist committed
562
    foutput_ulong((unsigned long)str.len, fp);
563
    putc('H', fp->fp);
Per Cederqvist's avatar
Per Cederqvist committed
564 565

    if (str.len)
566
	fwrite(str.string, str.len, 1, fp->fp);
Per Cederqvist's avatar
Per Cederqvist committed
567 568
}

569
static void
570
foutput_priv_bits(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
571 572
		  Priv_bits bits)
{
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
    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
590 591
}

592
static void
593
foutput_personal_flags(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
594 595
		       Personal_flags flags)
{
596 597 598 599 600 601 602 603 604
    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
605 606 607
}	


608
static void
609
foutput_text_list(struct dbfile *fp,
610
		  const Local_to_global *text_list)
Per Cederqvist's avatar
Per Cederqvist committed
611
{
612 613
    Local_text_no first;
    Local_text_no end;
Per Cederqvist's avatar
Per Cederqvist committed
614

615 616
    first = l2g_next_key(text_list, 0);
    end = l2g_first_appendable_key(text_list);
617 618 619

    if (first == 0)
	first = end;
620 621 622
    
    foutput_ulong((unsigned long)first, fp);
    foutput_ulong((unsigned long)(end - first), fp);
Per Cederqvist's avatar
Per Cederqvist committed
623

624
    if (first < end)
Per Cederqvist's avatar
Per Cederqvist committed
625
    {
626
	foutput_array_start(fp);
627
	while (first < end)
628
	    foutput_ulong((unsigned long)l2g_lookup(text_list, first++), fp);
629
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
630 631
    }
    else
632
	foutput_array_nodata(fp);
Per Cederqvist's avatar
Per Cederqvist committed
633 634 635
}


636
static void
637
foutput_mark_list(struct dbfile *fp,
638
		  const Mark_list mark_list)
Per Cederqvist's avatar
Per Cederqvist committed
639 640 641
{
    int i;

642
    fprintf(fp->fp, " %lu", (unsigned long)mark_list.no_of_marks);
Per Cederqvist's avatar
Per Cederqvist committed
643 644 645

    if ( mark_list.marks != NULL && mark_list.no_of_marks > 0 )
    {
646
	fprintf(fp->fp, " {");
Per Cederqvist's avatar
Per Cederqvist committed
647 648
	for ( i = 0; i < mark_list.no_of_marks; i++ )
	    foutput_mark(fp, mark_list.marks[ i ]);
649
	fprintf(fp->fp, " }");
Per Cederqvist's avatar
Per Cederqvist committed
650 651
    }
    else
652
	fprintf(fp->fp, " *");
Per Cederqvist's avatar
Per Cederqvist committed
653 654 655 656
    
}


657
static void
658
foutput_mark(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
659 660
	     Mark mark)
{
661
    fprintf(fp->fp, " %lu %lu", (unsigned long)mark.text_no, (unsigned long)mark.mark_type);
Per Cederqvist's avatar
Per Cederqvist committed
662 663
}

664
static void
665
foutput_membership_list_0 (struct dbfile		* fp,
666
                           Membership_list  mlist)
Per Cederqvist's avatar
Per Cederqvist committed
667 668 669
{
    int i;
    
670
    fprintf(fp->fp, " %lu", (unsigned long)mlist.no_of_confs);
Per Cederqvist's avatar
Per Cederqvist committed
671 672 673

    if ( mlist.confs != NULL && mlist.no_of_confs > 0 )
    {
674
	foutput_array_start(fp);
Per Cederqvist's avatar
Per Cederqvist committed
675
	for ( i = 0; i < mlist.no_of_confs; i++)
676
	    foutput_membership_0(fp, mlist.confs + i);
677
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
678 679
    }
    else
680
	foutput_array_nodata(fp);
Per Cederqvist's avatar
Per Cederqvist committed
681 682
}

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

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

702
static void
703
foutput_membership_list(struct dbfile        * fp,
704 705
                        Membership_list mlist)
{
706
    switch (fp->format)
707 708
    {
    case 0:
709
    case 1:
710 711 712 713 714 715
        foutput_membership_list_0(fp, mlist);
        break;
    case 2:
        foutput_membership_list_2(fp, mlist);
        break;
    default:
716
        restart_kom("unknown database format: %d", fp->format);
717 718 719 720
        break;
    }    
}

721
static void
722
foutput_time(struct dbfile *fp,
723
	     time_t clk)
Per Cederqvist's avatar
Per Cederqvist committed
724
{
725
    foutput_ulong((unsigned long) clk, fp);
Per Cederqvist's avatar
Per Cederqvist committed
726 727 728
}


729
static void
730
foutput_member_list(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
731 732 733 734
		    Member_list m_list)
{
    int i;

735
    fprintf(fp->fp, " %lu", (unsigned long)m_list.no_of_members);
Per Cederqvist's avatar
Per Cederqvist committed
736 737
    if ( m_list.members != NULL && m_list.no_of_members > 0 )
    {
738
	foutput_array_start(fp);
Per Cederqvist's avatar
Per Cederqvist committed
739 740
	for ( i = 0; i < m_list.no_of_members; i++ )
	    foutput_member(fp, m_list.members[ i ]);
741
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
742 743
    }
    else
744
	foutput_array_nodata(fp);
Per Cederqvist's avatar
Per Cederqvist committed
745 746 747
}


748
static void
749
foutput_member_0(struct dbfile *fp,
750 751
                 Member member)
{
752
    fprintf(fp->fp, " %lu", (unsigned long)member.member);
753 754 755
}

static void
756
foutput_member_2(struct dbfile *fp,
757 758
                 Member member)
{
759
    fprintf(fp->fp, " %lu %lu",
760 761 762 763 764 765
            (unsigned long)member.member,
            (unsigned long)member.added_by);
    foutput_time(fp, member.added_at);
    foutput_membership_type(fp, member.type);
}

766
static void
767
foutput_member(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
768 769
	       Member member)
{
770
    switch (fp->format)
771 772 773 774 775 776 777 778 779
    {
    case 0:
    case 1:
        foutput_member_0(fp, member);
        break;
    case 2:
        foutput_member_2(fp, member);
        break;
    default:
780
        restart_kom("unknown database format: %d", fp->format);
781 782
        break;
    }
Per Cederqvist's avatar
Per Cederqvist committed
783 784
}

785
static void
786
foutput_conf_type_1(struct dbfile *fp,
787
                    Conf_type type)
Per Cederqvist's avatar
Per Cederqvist committed
788
{
789 790 791 792 793 794 795 796 797
    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
798 799
}

800
static void
801
foutput_conf_type_0(struct dbfile *fp,
802
                    Conf_type type)
803
{
804 805 806 807 808
    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);
809 810
}

811
static void
812
foutput_conf_type (struct dbfile *fp,
813 814
                   Conf_type type)
{
815
    switch (fp->format)
816 817 818 819 820 821 822 823 824
    {
    case 0:
        foutput_conf_type_0(fp, type);
        break;
    case 1:
    case 2:
        foutput_conf_type_1(fp, type);
        break;
    default:
825
        restart_kom("unknown database format: %d", fp->format);
826 827 828 829
        break;
    }
}

Per Cederqvist's avatar
Per Cederqvist committed
830

831
static void
832
foutput_misc_info(struct dbfile *fp, 
Per Cederqvist's avatar
Per Cederqvist committed
833 834
		  Misc_info misc)
{
Per Cederqvist's avatar
Per Cederqvist committed
835
    foutput_ulong((unsigned long)misc.type, fp);
Per Cederqvist's avatar
Per Cederqvist committed
836 837 838 839 840
    
    switch(misc.type)
    {
    case recpt:
    case cc_recpt:
841
    case bcc_recpt:
842
	foutput_ulong((unsigned long)misc.datum.recipient, fp);
843
	break;
844

Per Cederqvist's avatar
Per Cederqvist committed
845
    case loc_no:
Per Cederqvist's avatar
Per Cederqvist committed
846
	foutput_ulong((unsigned long)misc.datum.local_no, fp);
Per Cederqvist's avatar
Per Cederqvist committed
847 848 849 850 851 852 853 854 855 856
	break;
	
    case rec_time:
	foutput_time(fp, misc.datum.received_at);
	break;
	
    case comm_to:
    case comm_in:
    case footn_to:
    case footn_in:
857
	foutput_ulong((unsigned long)misc.datum.text_link, fp);
Per Cederqvist's avatar
Per Cederqvist committed
858 859 860
	break;
	
    case sent_by:
Per Cederqvist's avatar
Per Cederqvist committed
861
	foutput_ulong((unsigned long)misc.datum.sender, fp);
Per Cederqvist's avatar
Per Cederqvist committed
862 863 864 865 866 867 868 869 870
	break;
	
    case sent_at:
	foutput_time(fp, misc.datum.sent_at);
	break;

#ifndef COMPILE_CHECKS
    default:
#endif
871 872
    case unknown_info:
	restart_kom("prot_a_output_misc_info: Illegal misc\n");
Per Cederqvist's avatar
Per Cederqvist committed
873 874 875 876 877 878 879 880 881
    }
}


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

882
static void
Per Cederqvist's avatar
Per Cederqvist committed
883
foutput_ulong (unsigned long l,
884
	       struct dbfile *fp)
Per Cederqvist's avatar
Per Cederqvist committed
885
{
886
    static char   buf[sizeof(unsigned long) * 3 + 1];
Per Cederqvist's avatar
Per Cederqvist committed
887 888
    char         *cp;

889
    foutput_space(fp);
Per Cederqvist's avatar
Per Cederqvist committed
890
    if (l < 10)
891
	putc("0123456789"[l], fp->fp);
892 893 894 895 896 897
    else
    {
	cp = buf + sizeof(buf);
	while (l > 0)
	{
	    *--cp = (l % 10) + '0';
Per Cederqvist's avatar
Per Cederqvist committed
898 899
	    l /= 10;
	}
900
	fwrite(cp, buf + sizeof(buf) - cp, 1, fp->fp);
Per Cederqvist's avatar
Per Cederqvist committed
901 902
    }
}
903 904

void
905
foutput_atsign(struct dbfile *fp)
906
{
907
    putc('@', fp->fp);