Commit 2f9330d4 authored by David Byers's avatar David Byers
Browse files

New database format

parent b1c02d51
Fri Feb 23 12:41:46 1996 David Byers <byers@lysator.liu.se>
* dbck.c, simple-cache.c: Added support for remove records. THIS
SUPPORT HAS NOT BEEN TESTED AT ALL SO DON'T USE IT!
Fri Dec 15 12:48:54 1995 David Byers <byers@lysator.liu.se>
* dbck.c, simple-cache.c: #C and #T records in database for
next-free-num and next-text-num.
Sun Nov 12 16:34:34 1995 David Byers <byers@lysator.liu.se>
* dbck.c: Option -o to select output db format
* dbck-cache.c: Read/write version 0 and version 1 files
* simple-cache.c: Saves and reads version one files
* text.c: anarchy bit checked for anonymous texts
Wed Nov 8 21:59:22 1995 Per Cederqvist (ceder@lysator.liu.se)
* Release 1.8.0.
......
/*
* $Id: dbck-cache.c,v 0.22 1995/11/02 21:48:37 ceder Exp $
* $Id: dbck-cache.c,v 0.23 1996/02/23 16:00:12 byers Exp $
* Copyright (C) 1991, 1992, 1993, 1994, 1995 Lysator Academic Computer Association.
*
* This file is part of the LysKOM server.
......@@ -32,7 +32,7 @@
* Also save time as a time_t instead of a struct tm.
*/
static char *rcsid = "$Id: dbck-cache.c,v 0.22 1995/11/02 21:48:37 ceder Exp $";
static char *rcsid = "$Id: dbck-cache.c,v 0.23 1996/02/23 16:00:12 byers Exp $";
#include "rcs.h"
USE(rcsid);
......@@ -91,6 +91,18 @@ int next_free_num = 1;
Text_stat * text_arr[ MAX_TEXT ];
int next_text_num = 1;
Info kom_info =
{
#include "version.incl"
, /* version */
1, /* conf_pres_conf */
2, /* pers_pres_conf */
3, /* motd_conf */
4, /* kom_news_conf */
0 /* motd_of_lyskom */
};
/* Defined in ramkomd.c */
static FILE *text_file = NULL;
......@@ -485,6 +497,27 @@ cached_unlock_conf(Conf_no conf_no)
{}
static long
get_version(const char *fn)
{
FILE *fp;
char c;
long version;
if ( (fp = fopen(fn, "rb")) == NULL)
return -1;
fseek(fp, 5, SEEK_SET);
if ( (c = getc(fp)) == '\n')
{
fclose(fp);
return 0;
}
version = fparse_long(fp);
fclose(fp);
return version;
}
static Bool
......@@ -522,6 +555,7 @@ cache_sync(void)
{
FILE *fp;
int i;
extern long oformat;
#ifdef TIME_SYNC
struct rusage start, after_confs, after_persons, after_text_stats,
......@@ -549,17 +583,30 @@ cache_sync(void)
return;
}
fprintf(fp, "DIRTY\n"); /* DIRTY-FLAG */
if (oformat == 0)
fprintf(fp, "DIRTY\n"); /* DIRTY-FLAG */
else
fprintf(fp, "DIRTY:%05ld\n", oformat);
fprintf(fp, "%d\n", next_free_num); /* NEXT_FREE_NUM */
if (oformat == 0)
fprintf(fp, "%d\n", next_free_num); /* NEXT_FREE_NUM */
else
{
fprintf(fp, "#C %d\n", next_free_num);
fprintf(fp, "#T %d\n", next_text_num);
}
for ( i = 1; i < next_free_num; i++ ) /* CONFS */
{
if ( conf_arr[ i ] == NULL )
if ( conf_arr[ i ] == NULL && oformat == 0)
fprintf(fp, "@");
else
{
fprintf(fp, "+ ");
if (oformat == 0)
fprintf(fp, "+ ");
else
fprintf(fp, "C %d ", i);
foutput_conference(fp, conf_arr[ i ]);
}
putc('\n', fp);
......@@ -568,38 +615,53 @@ cache_sync(void)
getrusage(0, &after_confs);
time(&ac);
#endif
for ( i = 1; i < next_free_num; i++ ) /* PERSONS */
{
if ( pers_arr[ i ] == NULL )
fprintf(fp, "@");
if ( pers_arr[ i ] == NULL)
{
if (oformat == 0)
fprintf(fp, "@\n");
}
else
{
fprintf(fp, "+ %dH", PASSWD_LEN);
if (oformat == 0)
fprintf(fp, "+ %dH", PASSWD_LEN);
else
fprintf(fp, "P %d %dH", i, PASSWD_LEN);
fwrite(pers_arr[ i ]->pwd, PASSWD_LEN, 1, fp);
foutput_person(fp, pers_arr[ i ]);
putc('\n', fp);
}
putc('\n', fp);
}
#ifdef TIME_SYNC
getrusage(0, &after_persons);
time(&ap);
#endif
fprintf(fp, "%d\n", next_text_num); /* NEXT_TEXT_NUM */
if (oformat == 0)
fprintf(fp, "%d\n", next_text_num); /* NEXT_TEXT_NUM */
for ( i = 1; i < next_text_num; i++ ) /* TEXT_STATS */
{
if ( text_arr[ i ] == NULL )
if ( text_arr[ i ] == NULL && oformat == 0)
fprintf(fp, "@");
else
{
fprintf(fp, "+ ");
if (oformat == 0)
fprintf(fp, "+ ");
else
fprintf(fp, "T %d ", i);
foutput_text_stat(fp, text_arr[ i ]);
}
putc('\n', fp);
}
if (oformat != 0)
{
putc('$', fp);
putc('\n', fp);
}
#ifdef TIME_SYNC
getrusage(0, &after_text_stats);
time(&ats);
......@@ -660,7 +722,18 @@ init_cache(void)
int i;
extern int vflag; /* from dbck.c */
extern Bool truncated_texts; /* from dbck.c */
long num;
long data_file_version;
char done, read_text_num, read_conf_num;
for (i = 0; i < MAX_CONF; i++)
conf_arr[i] = NULL;
for (i = 0; i < MAX_CONF; i++)
pers_arr[i] = NULL;
for (i = 0; i < MAX_TEXT; i++)
text_arr[i] = NULL;
new_text_file = NULL;
if ( (text_file = fopen(param.textfile_name, "rb")) == NULL )
......@@ -672,6 +745,7 @@ init_cache(void)
if ( is_clean(param.datafile_name) )
{
data_file_version = get_version(param.datafile_name);
if ( (fp = fopen(param.datafile_name, "rb")) == NULL )
{
log("WARNING: init_cache: can't open datafile.\n");
......@@ -681,6 +755,7 @@ init_cache(void)
}
else if ( is_clean(param.backupfile_name) )
{
data_file_version = get_version(param.backupfile_name);
if ( (fp = fopen(param.backupfile_name, "rb")) == NULL )
{
log("WARNING: init_cache: can't open backupfile.\n");
......@@ -693,34 +768,167 @@ init_cache(void)
log("WARNING: init_cache: can't find old data base.\n");
return FAILURE;
}
fseek(fp, 6, SEEK_SET); /* skip clean/dirty flag. */
next_free_num = fparse_long(fp); /* NEXT_FREE_NUM */
if (data_file_version == 0)
fseek(fp, 6, SEEK_SET); /* skip clean/dirty flag. */
else
fseek(fp, 12, SEEK_SET);
if (data_file_version == 0)
{
next_free_num = fparse_long(fp); /* NEXT_FREE_NUM */
read_conf_num = 1;
}
if ( vflag )
log("Data file version is '%c'\n", data_file_version);
if ( vflag && data_file_version == 0)
log("Reading %d conferences, starting at pos %d.\n",
next_free_num-1, ftell(fp));
for ( i = 1; i < next_free_num; i++ ) /* CONFS */
done = 0;
for ( i = 1;
!done && (i < next_free_num || data_file_version != 0);
i++ ) /* CONFS */
{
num = i;
fskipwhite(fp);
switch(getc(fp))
{
case '@':
conf_arr[ i ] = NULL;
if (data_file_version != 0)
restart_kom("init_cache(): empty record in new datafile.\n");
conf_arr[ num ] = NULL;
break;
case 'I':
if (data_file_version == 0)
restart_kom("init_cache(): new type record in old file\n");
kom_info.conf_pres_conf = fparse_long(fp);
kom_info.pers_pres_conf = fparse_long(fp);
kom_info.motd_conf = fparse_long(fp);
kom_info.kom_news_conf = fparse_long(fp);
kom_info.motd_of_lyskom = fparse_long(fp);
break;
case 'C':
if (data_file_version == 0)
restart_kom("init_cache(): new type record in old file\n");
num = fparse_long(fp);
if (conf_arr[num])
free_conference(conf_arr[num]);
conf_arr[num] = alloc_conference();
if (fparse_conference(fp, conf_arr[num]) != OK)
restart_kom("init_cache(): %s. i == %d\n",
"fparse_conference failed", i);
name_list[num] = EMPTY_STRING;
s_strcpy(&name_list[num], conf_arr[ num ]->name);
break;
case 'P':
if (data_file_version == 0)
restart_kom("init_cache(): new type record in old file\n");
num = fparse_long(fp);
if (pers_arr[num])
free_person(pers_arr[num]);
pers_arr[num] = alloc_person();
if ( fparse_person(fp, pers_arr[ num ]) != OK )
restart_kom("init_cache: fparse_person failed. i == %d\n",
i);
break;
case 'T':
if (data_file_version == 0)
restart_kom("init_cache(): new type record in old file\n");
num = fparse_long(fp);
if (text_arr[num])
free_text_stat(text_arr[num]);
text_arr[ num ] = alloc_text_stat();
if ( fparse_text_stat(fp, text_arr[ num ]) != OK )
{
/* Simply ignore the following texts. The cause of this
error might be that the file has been truncated (maybe
due to an overfull disk). */
log("init_cache(): fparse_text_stat failed for text %d.\n%s",
i, "All remaining texts are lost.\n");
next_text_num = i;
read_text_num = 1;
truncated_texts = TRUE;
done = 1;
}
break;
case '+':
if (data_file_version != 0)
restart_kom("init_cache(): %s\n",
"Old type record found in new type file");
conf_arr[ i ] = alloc_conference();
if ( fparse_conference(fp, conf_arr[ i ]) != OK )
restart_kom("init_cache(): %s. i == %d\n",
"fparse_conference failed", i);
name_list[i] = EMPTY_STRING;
s_strcpy(&name_list[i], conf_arr[ i ]->name);
break;
case '#':
if (data_file_version == 0)
restart_kom("init_cache(): %s\n",
"New type record found in old datafile");
switch (fgetc(fp))
{
case 'C':
next_free_num = fparse_long(fp);
read_conf_num = 1;
break;
case 'T':
next_text_num = fparse_long(fp);
read_text_num = 1;
break;
default:
restart_kom("init_cache(): %s\n",
"Bad number specification");
}
break;
case '-':
if (data_file_version == 0)
restart_kom("init_cache(): %s\n",
"New type record found in old datafile");
fskipwhite(fp);
switch(fgetc(fp))
{
case 'C':
num = fparse_long(fp);
if (conf_arr[num])
free_conference(conf_arr[num]);
conf_arr[num] = NULL;
break;
case 'P':
num = fparse_long(fp);
if (pers_arr[num])
free_person(pers_arr[num]);
pers_arr[num] = NULL;
break;
case 'T':
num = fparse_long(fp);
if (text_arr[num])
free_text_stat(text_arr[num]);
text_arr[num] = NULL;
break;
}
break;
case '$':
done = 1;
break;
default:
restart_kom("init_cache(): bad conf format at %d\n", i);
}
}
......@@ -728,60 +936,65 @@ init_cache(void)
log("Reading %d persons, starting at pos %d.\n",
next_free_num-1, ftell(fp));
for ( i = 1; i < next_free_num; i++ ) /* PERSONS */
if (data_file_version == 0)
{
fskipwhite(fp);
switch(getc(fp))
for ( i = 1; i < next_free_num; i++ ) /* PERSONS */
{
case '@':
pers_arr[ i ] = NULL;
break;
case '+':
pers_arr[ i ] = alloc_person();
if ( fparse_person(fp, pers_arr[ i ]) != OK )
restart_kom("init_cache: fparse_person failed. i == %d\n", i);
break;
fskipwhite(fp);
switch(getc(fp))
{
case '@':
pers_arr[ i ] = NULL;
break;
case '+':
pers_arr[ i ] = alloc_person();
if ( fparse_person(fp, pers_arr[ i ]) != OK )
restart_kom("init_cache: fparse_person failed. i == %d\n",
i);
break;
}
}
}
next_text_num = fparse_long(fp); /* NEXT_TEXT_NUM */
next_text_num = fparse_long(fp); /* NEXT_TEXT_NUM */
read_text_num = 1;
if ( vflag )
log("Reading %d texts, starting at pos %d.\n",
next_text_num-1, ftell(fp));
if ( vflag )
log("Reading %d texts, starting at pos %d.\n",
next_text_num-1, ftell(fp));
for ( i = 1; i < next_text_num; i++ ) /* TEXT_STATS */
{
fskipwhite(fp);
switch(getc(fp))
for ( i = 1; i < next_text_num; i++ ) /* TEXT_STATS */
{
case '@':
text_arr[ i ] = NULL;
break;
case '+':
text_arr[ i ] = alloc_text_stat();
if ( fparse_text_stat(fp, text_arr[ i ]) != OK )
fskipwhite(fp);
switch(getc(fp))
{
/* Simply ignore the following texts. The cause of this
error might be that the file has been truncated (maybe
due to an overfull disk). */
log("init_cache(): fparse_text_stat failed for text %d.\n%s",
i, "All remaining texts are lost.\n");
next_text_num = i;
truncated_texts = TRUE;
case '@':
text_arr[ i ] = NULL;
break;
case '+':
text_arr[ i ] = alloc_text_stat();
if ( fparse_text_stat(fp, text_arr[ i ]) != OK )
{
/* Simply ignore the following texts. The cause of this
error might be that the file has been truncated (maybe
due to an overfull disk). */
log("init_cache(): fparse_text_stat failed for text %d.\n%s",
i, "All remaining texts are lost.\n");
next_text_num = i;
truncated_texts = TRUE;
}
break;
}
break;
}
}
} /* if (datafile_version == 0) */
log("Read %d confs/persons and %d texts, eof at %d\n",
next_free_num-1, next_text_num-1, ftell(fp));
if (read_text_num == 0 || read_conf_num == 0)
restart_kom("init_cache(): Failed to read next_conf or text num.\n");
fclose(fp);
return OK;
......
/*
* $Id: simple-cache.c,v 0.52 1995/11/02 21:49:05 ceder Exp $
* $Id: simple-cache.c,v 0.53 1996/02/23 16:00:29 byers Exp $
* Copyright (C) 1991, 1992, 1993, 1994, 1995 Lysator Academic Computer Association.
*
* This file is part of the LysKOM server.
......@@ -33,7 +33,7 @@
* New save algorithm by ceder.
*/
static char *rcsid = "$Id: simple-cache.c,v 0.52 1995/11/02 21:49:05 ceder Exp $";
static char *rcsid = "$Id: simple-cache.c,v 0.53 1996/02/23 16:00:29 byers Exp $";
#include "rcs.h"
USE(rcsid);
......@@ -76,6 +76,7 @@ USE(rcsid);
#include "send-async.h"
#include "param.h"
#include "config.h"
#include "admin.h"
/*
* Possible improvements: +++
......@@ -206,6 +207,8 @@ static void log_access(Log_type t,
#define TRACE1(format) if ( buglevel > 2 ) printf(format)
#define TRACESTR(str) if ( buglevel > 2 ) s_puts(str)
#define TIMESTAMP_FORMAT "%y %m %d %H %M %S"
static Person *
read_person(FILE *fp,
......@@ -213,9 +216,11 @@ read_person(FILE *fp,
long size)
{
Person *p;
long dummy;
p = alloc_person();
fseek(fp, pos+1, SEEK_SET); /* Skip '+' */
dummy = fparse_long(fp);
if ( fparse_person(fp, p) != OK )
{
free_person(p);
......@@ -233,9 +238,11 @@ read_conference(FILE *fp,
long size)
{
Conference *c;
long dummy;
c = alloc_conference();
fseek(fp, pos+1, SEEK_SET); /* Skip '+' */
dummy = fparse_long(fp);
if ( fparse_conference(fp, c) != OK )
{
free_conference(c);
......@@ -252,9 +259,11 @@ read_text_stat(FILE *fp,
long size)
{
Text_stat *t;
long dummy;
t = alloc_text_stat();
fseek(fp, pos+1, SEEK_SET); /* Skip '+' */
dummy = fparse_long(fp);
if ( fparse_text_stat(fp, t) != OK )
{
free_text_stat(t);
......@@ -1343,11 +1352,34 @@ is_clean(const char *fn)
}
static long
get_version(const char *fn)
{
FILE *fp;
char c;
long version;
if ( (fp = fopen(fn, "rb")) == NULL)
return -1;
fseek(fp, 5, SEEK_SET);
if ( (c = getc(fp)) == '\n')
{
fclose(fp);
return 0;
}
version = fparse_long(fp);
fclose(fp);
return version;
}
static void
pre_sync(void)
{
long i;
Cache_node *node;
time_t now;
async_sync_db();
......@@ -1478,9 +1510,19 @@ pre_sync(void)
return;
}
fprintf(file_b, "DIRTY\n"); /* DIRTY-FLAG */
fprintf(file_b, "DIRTY:%05ld\n", 1L); /* DIRTY-FLAG and VERSION*/
now = time(NULL);
fprintf(file_b, "#C %d\n", highest_conf_no);
fprintf(file_b, "#T %ld\n", highest_text_no);
fprintf(file_b, "I %d %d %d %d %ld\n",
kom_info.conf_pres_conf,
kom_info.pers_pres_conf,
kom_info.motd_conf,
kom_info.kom_news_conf,
kom_info.motd_of_lyskom);
fprintf(file_b, "%d\n", highest_conf_no); /* NEXT_FREE_NUM */
sync_state = sync_save_conf;
sync_next = 1;
}
......@@ -1489,7 +1531,8 @@ static void
copy_file(FILE *from,
FILE *to,
long from_pos,
long len)
long len,
long no)