Newer
Older
{
adjust_text_list(tlist);
mark_conference_as_changed(cc);
modifications++;
log("Repaired: text_list adjusted.\n");
}
else
error++;
}
return error;
}
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
locate_membership(Conf_no conf_no,
Person * pers_p)
{
Membership * confp;
int i;
for(confp = pers_p->conferences.confs, i = pers_p->conferences.no_of_confs;
i > 0; i--, confp++)
{
if ( confp->conf_no == conf_no )
{
return confp;
}
}
return NULL;
}
static int
check_member(Conf_no cc,
Member *memb)
{
Person *pp;
int error=0;
pp = cached_get_person_stat(memb->member);
if ( pp == NULL )
{
log("Person %lu, supposedly a member in conf %lu, is nonexistent.\n",
(unsigned long)memb->member, (unsigned long)cc);
error++;
}
else
{
if ( locate_membership(cc, pp) == NULL )
{
log("Person %lu is not a member in conf %lu.\n",
(unsigned long)memb->member,
(unsigned long)cc);
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
error++;
}
}
return error;
}
static int
check_member_list(Conf_no cc,
const Member_list *mlist)
{
int errors=0;
int i;
for (i = 0; i < mlist->no_of_members; i++)
errors += check_member(cc, &mlist->members[i]);
return errors;
}
static int
check_confs(void)
{
Conf_no cc = 0;
Person *pstat=NULL;
Conference *cstat=NULL;
long errors = 0;
Conf_no number_of_confs = 0;
while ( (cc = traverse_conference(cc)) != 0 )
{
number_of_confs++;
cstat = cached_get_conf_stat (cc);
if ( cstat == NULL )
{
log("Conference %lu nonexistent.\n", (unsigned long)cc);
errors++;
}
else
{
if (cstat->type.letter_box)
{
pstat = cached_get_person_stat(cc);
if (pstat == NULL)
{
log("Mailbox %lu has no person.\n", (unsigned long)cc);
errors++;
}
}
else /* not letter_box */
{
/* Remember that the creator might no longer exist. */
if ( person_scratchpad[ cstat->creator ] != NULL )
++person_scratchpad[ cstat->creator ]->created_confs;
}
errors += (check_texts_in_conf(cc, &cstat->texts)
+ check_member_list(cc, &cstat->members));
}
}
if ( vflag )
log("Total of %lu conferences.\n", (unsigned long)number_of_confs);
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
return errors;
}
static void
init_person_scratch(void)
{
Pers_no pno = 0;
while( (pno = traverse_person(pno)) != 0 )
{
person_scratchpad[pno] = alloc_person_scratchpad();
}
}
static long
post_check_persons(void)
{
long errors = 0;
Pers_no pers_no = 0;
Person *pstat;
while ( (pers_no = traverse_person(pers_no)) != 0 )
{
if ( (pstat = cached_get_person_stat(pers_no)) == NULL )
{
log("%s(): can't cached_get_person_stat(%d).\n",
"INTERNAL DBCK ERROR: post_check_persons", pers_no);
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
}
}
return errors;
}
/*
* Returns 0 if the database seems to be correct.
*/
static long
check_data_base(void)
{
long errors;
init_person_scratch();
errors = check_texts() + check_persons() + check_confs();
return errors + post_check_persons();
}
static void
init_data_base(char *dbase_dir)
sprintf(datafilename, "%s/%s", dbase_dir, param.datafile_name);
sprintf(backupfilename, "%s/%s", dbase_dir, param.backupfile_name);
sprintf(textfilename, "%s/%s", dbase_dir, param.textfile_name);
sprintf(textbackupfilename, "%s/%s", dbase_dir, param.textbackupfile_name);
if ( vflag )
{
log("Database = %s\n", datafilename);
log("Backup = %s\n", backupfilename);
log("Text = %s\n", textfilename);
log("Textback = %s\n", textbackupfilename);
}
if ( init_cache() == FAILURE )
restart_kom("Can't find database.\n");
}
garb_text_file(void)
{
Text_no tno = 0;
String text;
log("Renaming %s to %s\n", textfilename, textbackupfilename);
log("Writing texts to (new) %s\n", textfilename);
fflush(stdout);
fflush(stderr);
cache_open_new_text_file();
while ( (tno = traverse_text(tno)) != 0 )
{
text = cached_get_text(tno);
cached_flush_text(tno, text);
free_tmp();
}
log("Writing datafile with new indexes.\n");
fflush(stdout);
fflush(stderr);
cache_sync();
log("Ready.");
}
print_statistics(void)
{
Text_stat *ts;
Text_no t;
int *hist;
int i;
hist = calloc(param.text_len, sizeof(int));
if (hist == NULL)
{
perror("dbck: print_statistics(): can't calloc()");
return;
}
for (t=0; (t=traverse_text(t)) != 0;)
{
ts = cached_get_text_stat(t);
if (ts == NULL)
{
log("print_statistics(): Can't get text_stat.\n");
return;
}
hist[ts->no_of_chars]++;
}
log("Length Frequency\n");
for(i=0; i<param.text_len; i++)
if(hist[i] != 0)
log("%8d %d\n", i, hist[i]);
}
/* Stop "no previous prototype" warning from gcc 2.0 */
int main(int, char**);
int
main (int argc,
char **argv)
{
int i;
int errors;
char *default_config_file;
char *config_file;
BUGDECL;
for (i = 1; i < argc && argv[i][0] == '-'; i++)
{
switch (argv[i][1])
{
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
case 'd':
buglevel++;
break;
#endif
case 'i': /* Running interactively. */
iflag++; /* Will ask user and try to repair. */
break;
case 'r': /* Repair simple errors wihtout asking. */
rflag++;
break;
case 'v': /* Verbose: report more than errors. */
vflag++;
break;
case 'g': /* Garbage collect: compress text-file. */
gflag++;
break;
case 's': /* Statistics: text length et c. */
sflag++;
break;
case 'c': /* Consider an unset change_name an error. */
unset_change_name_is_error = 1;
break;
restart_kom("usage: %s %s [config_file]\n",
argv[0], "[-d ...] [-i] [-r] [-v] [-g] [-s] [-c]");
/* Read in the configuration file. */
default_config_file = smalloc(strlen(DEFAULT_DBASE_DIR) +
strlen(CONFIG_FILE) + 2);
sprintf(default_config_file, "%s/%s", DEFAULT_DBASE_DIR, CONFIG_FILE);
if (i < argc)
config_file = argv[i++];
else
config_file = default_config_file;
read_configuration(config_file);
sfree(default_config_file);
if (i != argc)
restart_kom("usage: %s %s [config_file]\n",
argv[0], "[-d ...] [-i] [-r] [-v] [-g] [-s] [-c]");
s_set_storage_management(smalloc, srealloc, sfree);
init_data_base(param.dbase_dir);
if (truncated_texts == TRUE)
modifications++;
if ( iflag )
log("Total of %d error%s remains.\n", errors, errors == 1 ? "" : "s");
else if ( vflag && errors > 0 )
log("%d error%s found.\n", errors, errors == 1 ? "" : "s");
if ( modifications > 0 )
{
log("%d modification%s made. Syncing...\n",
modifications, modifications == 1 ? "" : "s");
fflush(stdout);
fflush(stderr);
cache_sync();
log("ready.\n");
}
if ( sflag )
print_statistics();
if ( modifications == 0 && errors == 0 )
{
log("No errors found. Compressing textfile.\n");
fflush(stdout);
fflush(stderr);
garb_text_file();
log("ready.\n");
}
else
log("Compression not done since errors was found.\n");