ram-output.c 24.3 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
    {
    case 0:
    case 1:
        foutput_info_0(fp, info);
        break;
    case 2:
118
    case 3:
119 120 121
        foutput_info_2(fp, info);
        break;
    default:
122
        restart_kom("unknown database format: %d", fp->format);
123 124 125 126 127
        break;
    }
}


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

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

    foutput_time(fp, person->last_login);

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

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

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

    foutput_time(fp, person->last_login);

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

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


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

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

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

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

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

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

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

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

277
void foutput_conference(struct dbfile *fp,
278 279
                        Conference *conf_c)
{
280
    switch(fp->format)
281 282 283 284 285 286 287 288
    {
    case 0:
        foutput_conference_0(fp, conf_c);
        break;
    case 1:
        foutput_conference_1(fp, conf_c);
        break;
    case 2:
289
    case 3:
290 291 292
        foutput_conference_2(fp, conf_c);
        break;
    default:
293
        restart_kom("unknown database format: %d", fp->format);
294 295 296 297 298
        break;
    }
}


Per Cederqvist's avatar
Per Cederqvist committed
299

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

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

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

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

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

355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
static void
foutput_text_stat_3(struct dbfile *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->generation, fp);
    foutput_ulong((unsigned long) t_stat->reclamation, 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 )
    {
	foutput_array_start(fp);
	for ( i = 0; i < t_stat->no_of_misc; i++ )
	    foutput_misc_info(fp, t_stat->misc_items[ i ]);
	foutput_array_end(fp);
    }
    else
	foutput_array_nodata(fp);

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

386
void
387
foutput_text_stat(struct dbfile *fp,
388 389
                  Text_stat *t_stat)
{
390
    switch (fp->format)
391 392 393 394 395 396 397 398
    {
    case 0:
    case 1:
        foutput_text_stat_0(fp, t_stat);
        break;
    case 2:
        foutput_text_stat_2(fp, t_stat);
        break;
399 400 401
    case 3:
        foutput_text_stat_3(fp, t_stat);
        break;
402
    default:
403
        restart_kom("unknown database format: %d\n", fp->format);
404 405 406 407 408 409
        break;
    }
}



410
static void
411
foutput_aux_flags(struct dbfile *fp,
412 413
                  Aux_item_flags f)
{
414 415 416 417 418 419 420 421 422
    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);
423 424
}

David Byers's avatar
David Byers committed
425
static void
426
foutput_aux_item_link(struct dbfile *fp,
David Byers's avatar
David Byers committed
427 428 429 430 431 432 433 434 435 436 437 438 439
                      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:
440
	;
David Byers's avatar
David Byers committed
441 442 443
    }
}

444
static void
445
foutput_aux_item(struct dbfile *fp,
446 447 448 449 450 451 452 453 454
                 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
455
    foutput_aux_item_link(fp, &a_item->linked_item);
456 457
}

458
static void
459
foutput_aux_item_list(struct dbfile *fp,
460
		      const Aux_item_list *aux)
461 462 463 464 465 466
{
    int i;

    foutput_ulong((unsigned long) aux->length, fp);
    if (aux->items && aux->length > 0)
    {
467
        foutput_array_start(fp);
468 469
        for (i = 0; i < aux->length; i++)
            foutput_aux_item(fp, &aux->items[i]);
470
        foutput_array_end(fp);
471 472
    }
    else
473
        foutput_array_nodata(fp);
474 475 476
}
		      

477
static void
478
foutput_membership_type(struct dbfile *fp,
479 480
                        Membership_type type)
{
481 482 483 484 485 486 487 488 489
    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);
490 491
}

492
static void
493
foutput_read_ranges_0(struct dbfile *fp,
494 495 496 497 498 499 500 501 502 503
		      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)
504
	fprintf(fp->fp, " 0 0 *");
505 506 507 508 509 510 511 512 513 514
    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)
	{
515
	    fprintf(fp->fp, " %lu", begin->last_read);
516 517 518
	    begin++;
	}
	else
519
	    fprintf(fp->fp, " 0");
520 521

	if (begin == end)
522
	    fprintf(fp->fp, " 0 *");
523 524 525 526 527 528 529 530
	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;

531
	    fprintf(fp->fp, " %lu {", no_of_read);
532 533 534 535 536 537
	    
	    for (ptr = begin; ptr < end; ++ptr)
	    {
		Local_text_no lno;

		for (lno = ptr->first_read; lno <= ptr->last_read; lno++)
538
		    fprintf(fp->fp, " %lu", (unsigned long)lno);
539 540
	    }
	    
541
	    fprintf(fp->fp, " }");
542 543 544 545
	}
    }
}

546
static void
547
foutput_membership_0(struct dbfile *fp,
548 549 550 551
		   Membership *mship)
{
    foutput_time(fp, mship->last_time_read );
    
552
    fprintf(fp->fp, " %lu %lu",
553
	    (unsigned long)mship->conf_no,
554 555
	    (unsigned long)mship->priority);
    foutput_read_ranges_0(fp, mship);
556 557 558
}

static void
559
foutput_membership_2(struct dbfile *fp,
560 561 562 563
                     Membership *mship)
{
    foutput_time(fp, mship->last_time_read );
    
564
    fprintf(fp->fp, " %lu %lu",
565
	    (unsigned long)mship->conf_no,
566 567
	    (unsigned long)mship->priority);
    foutput_read_ranges_0(fp, mship);
568
    fprintf(fp->fp, " %lu", (unsigned long)mship->added_by);
569 570 571 572 573
    foutput_time(fp, mship->added_at);
    foutput_membership_type(fp, mship->type);
}


574
extern void
575
foutput_membership(struct dbfile *fp,
576 577
                   Membership *mship)
{
578
    switch (fp->format)
579 580
    {
    case 0:
581
    case 1:
582 583 584
        foutput_membership_0(fp, mship);
        break;
    case 2:
585
    case 3:
586 587 588
        foutput_membership_2(fp, mship);
        break;
    default:
589
        restart_kom("unknown database format: %d", fp->format);
590 591 592 593
        break;
    }
}

Per Cederqvist's avatar
Per Cederqvist committed
594 595


596
static void
597
foutput_string(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
598 599
	       String str)
{
Per Cederqvist's avatar
Per Cederqvist committed
600
    foutput_ulong((unsigned long)str.len, fp);
601
    putc('H', fp->fp);
Per Cederqvist's avatar
Per Cederqvist committed
602 603

    if (str.len)
604
	fwrite(str.string, str.len, 1, fp->fp);
Per Cederqvist's avatar
Per Cederqvist committed
605 606
}

607
static void
608
foutput_priv_bits(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
609 610
		  Priv_bits bits)
{
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
    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
628 629
}

630
static void
631
foutput_personal_flags(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
632 633
		       Personal_flags flags)
{
634 635 636 637 638 639 640 641 642
    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
643 644 645
}	


646
static void
647
foutput_text_list(struct dbfile *fp,
648
		  const Local_to_global *text_list)
Per Cederqvist's avatar
Per Cederqvist committed
649
{
650 651
    Local_text_no first;
    Local_text_no end;
Per Cederqvist's avatar
Per Cederqvist committed
652

653 654
    first = l2g_next_key(text_list, 0);
    end = l2g_first_appendable_key(text_list);
655 656 657

    if (first == 0)
	first = end;
658 659 660
    
    foutput_ulong((unsigned long)first, fp);
    foutput_ulong((unsigned long)(end - first), fp);
Per Cederqvist's avatar
Per Cederqvist committed
661

662
    if (first < end)
Per Cederqvist's avatar
Per Cederqvist committed
663
    {
664
	foutput_array_start(fp);
665
	while (first < end)
666
	    foutput_ulong((unsigned long)l2g_lookup(text_list, first++), fp);
667
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
668 669
    }
    else
670
	foutput_array_nodata(fp);
Per Cederqvist's avatar
Per Cederqvist committed
671 672 673
}


674
static void
675
foutput_mark_list(struct dbfile *fp,
676
		  const Mark_list mark_list)
Per Cederqvist's avatar
Per Cederqvist committed
677 678 679
{
    int i;

680
    fprintf(fp->fp, " %lu", (unsigned long)mark_list.no_of_marks);
Per Cederqvist's avatar
Per Cederqvist committed
681 682 683

    if ( mark_list.marks != NULL && mark_list.no_of_marks > 0 )
    {
684
	fprintf(fp->fp, " {");
Per Cederqvist's avatar
Per Cederqvist committed
685 686
	for ( i = 0; i < mark_list.no_of_marks; i++ )
	    foutput_mark(fp, mark_list.marks[ i ]);
687
	fprintf(fp->fp, " }");
Per Cederqvist's avatar
Per Cederqvist committed
688 689
    }
    else
690
	fprintf(fp->fp, " *");
Per Cederqvist's avatar
Per Cederqvist committed
691 692 693 694
    
}


695
static void
696
foutput_mark(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
697 698
	     Mark mark)
{
699
    fprintf(fp->fp, " %lu %lu", (unsigned long)mark.text_no, (unsigned long)mark.mark_type);
Per Cederqvist's avatar
Per Cederqvist committed
700 701
}

702
static void
703
foutput_membership_list_0 (struct dbfile		* fp,
704
                           Membership_list  mlist)
Per Cederqvist's avatar
Per Cederqvist committed
705 706 707
{
    int i;
    
708
    fprintf(fp->fp, " %lu", (unsigned long)mlist.no_of_confs);
Per Cederqvist's avatar
Per Cederqvist committed
709 710 711

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

721
static void
722
foutput_membership_list_2 (struct dbfile		* fp,
723
                           Membership_list  mlist)
Per Cederqvist's avatar
Per Cederqvist committed
724 725 726
{
    int i;
    
727
    fprintf(fp->fp, " %lu", (unsigned long)mlist.no_of_confs);
728 729

    if ( mlist.confs != NULL && mlist.no_of_confs > 0 )
Per Cederqvist's avatar
Per Cederqvist committed
730
    {
731
	foutput_array_start(fp);
732 733
	for ( i = 0; i < mlist.no_of_confs; i++)
	    foutput_membership_2(fp, mlist.confs + i);
734
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
735 736
    }
    else
737
	foutput_array_nodata(fp);
Per Cederqvist's avatar
Per Cederqvist committed
738 739
}

740
static void
741
foutput_membership_list(struct dbfile        * fp,
742 743
                        Membership_list mlist)
{
744
    switch (fp->format)
745 746
    {
    case 0:
747
    case 1:
748 749 750
        foutput_membership_list_0(fp, mlist);
        break;
    case 2:
751
    case 3:
752 753 754
        foutput_membership_list_2(fp, mlist);
        break;
    default:
755
        restart_kom("unknown database format: %d", fp->format);
756 757 758 759
        break;
    }    
}

760
static void
761
foutput_time(struct dbfile *fp,
762
	     time_t clk)
Per Cederqvist's avatar
Per Cederqvist committed
763
{
764
    foutput_ulong((unsigned long) clk, fp);
Per Cederqvist's avatar
Per Cederqvist committed
765 766 767
}


768
static void
769
foutput_member_list(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
770 771 772 773
		    Member_list m_list)
{
    int i;

774
    fprintf(fp->fp, " %lu", (unsigned long)m_list.no_of_members);
Per Cederqvist's avatar
Per Cederqvist committed
775 776
    if ( m_list.members != NULL && m_list.no_of_members > 0 )
    {
777
	foutput_array_start(fp);
Per Cederqvist's avatar
Per Cederqvist committed
778 779
	for ( i = 0; i < m_list.no_of_members; i++ )
	    foutput_member(fp, m_list.members[ i ]);
780
	foutput_array_end(fp);
Per Cederqvist's avatar
Per Cederqvist committed
781 782
    }
    else
783
	foutput_array_nodata(fp);
Per Cederqvist's avatar
Per Cederqvist committed
784 785 786
}


787
static void
788
foutput_member_0(struct dbfile *fp,
789 790
                 Member member)
{
791
    fprintf(fp->fp, " %lu", (unsigned long)member.member);
792 793 794
}

static void
795
foutput_member_2(struct dbfile *fp,
796 797
                 Member member)
{
798
    fprintf(fp->fp, " %lu %lu",
799 800 801 802 803 804
            (unsigned long)member.member,
            (unsigned long)member.added_by);
    foutput_time(fp, member.added_at);
    foutput_membership_type(fp, member.type);
}

805
static void
806
foutput_member(struct dbfile *fp,
Per Cederqvist's avatar
Per Cederqvist committed
807 808
	       Member member)
{
809
    switch (fp->format)
810 811 812 813 814 815
    {
    case 0:
    case 1:
        foutput_member_0(fp, member);
        break;
    case 2:
816
    case 3:
817 818 819
        foutput_member_2(fp, member);
        break;
    default:
820
        restart_kom("unknown database format: %d", fp->format);
821 822
        break;
    }
Per Cederqvist's avatar
Per Cederqvist committed
823 824
}

825
static void
826
foutput_conf_type_1(struct dbfile *fp,
827
                    Conf_type type)
Per Cederqvist's avatar
Per Cederqvist committed
828
{
829 830 831 832 833 834 835 836 837
    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
838 839
}

840
static void
841
foutput_conf_type_0(struct dbfile *fp,
842
                    Conf_type type)
843
{
844 845 846 847 848
    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);
849 850
}

851
static void
852
foutput_conf_type (struct dbfile *fp,
853 854
                   Conf_type type)
{
855
    switch (fp->format)
856 857 858 859 860 861
    {
    case 0:
        foutput_conf_type_0(fp, type);
        break;
    case 1:
    case 2:
862
    case 3:
863 864 865
        foutput_conf_type_1(fp, type);
        break;
    default:
866
        restart_kom("unknown database format: %d", fp->format);
867 868 869 870
        break;
    }
}

Per Cederqvist's avatar
Per Cederqvist committed
871

872
static void
873
foutput_misc_info(struct dbfile *fp, 
Per Cederqvist's avatar
Per Cederqvist committed
874 875
		  Misc_info misc)
{
Per Cederqvist's avatar
Per Cederqvist committed
876
    foutput_ulong((unsigned long)misc.type, fp);
Per Cederqvist's avatar
Per Cederqvist committed
877 878 879 880 881
    
    switch(misc.type)
    {
    case recpt:
    case cc_recpt:
882
    case bcc_recpt:
883
	foutput_ulong((unsigned long)misc.datum.recipient, fp);
884
	break;
885

Per Cederqvist's avatar
Per Cederqvist committed
886
    case loc_no:
Per Cederqvist's avatar
Per Cederqvist committed
887
	foutput_ulong((unsigned long)misc.datum.local_no, fp);
Per Cederqvist's avatar
Per Cederqvist committed
888 889 890 891 892 893 894 895 896 897
	break;
	
    case rec_time:
	foutput_time(fp, misc.datum.received_at);
	break;
	
    case comm_to:
    case comm_in:
    case footn_to:
    case footn_in:
898
	foutput_ulong((unsigned long)misc.datum.text_link, fp);
Per Cederqvist's avatar
Per Cederqvist committed
899 900 901
	break;
	
    case sent_by:
Per Cederqvist's avatar
Per Cederqvist committed
902
	foutput_ulong((unsigned long)misc.datum.sender, fp);
Per Cederqvist's avatar
Per Cederqvist committed
903 904 905 906 907 908 909