Added extra option to mbfile check

This commit is contained in:
Michiel Broek 2004-05-04 14:31:25 +00:00
parent 5bec0065cf
commit 75b991af56
7 changed files with 271 additions and 176 deletions

View File

@ -45,6 +45,8 @@ v0.51.4 11-Apr-2004
logfile. logfile.
Mbfile check will abort if a header of a files database is Mbfile check will abort if a header of a files database is
corrupt. corrupt.
Mbfile check will now accept an area number to just check one
single area.
mbnntp: mbnntp:
New program, news server to read echomail with a news client. New program, news server to read echomail with a news client.

View File

@ -47,16 +47,19 @@ struct _fdbarea *mbsedb_OpenFDB(long Area, int Timeout)
char *temp; char *temp;
struct _fdbarea *fdb_area = NULL; struct _fdbarea *fdb_area = NULL;
int Tries = 0; int Tries = 0;
FILE *fp;
Syslog('f', "OpenFDB area %ld, timeout %d", Area, Timeout); Syslog('f', "OpenFDB area %ld, timeout %d", Area, Timeout);
temp = calloc(PATH_MAX, sizeof(char)); temp = calloc(PATH_MAX, sizeof(char));
fdb_area = malloc(sizeof(struct _fdbarea)); /* Will be freed by CloseFDB */
sprintf(temp, "%s/fdb/file%ld.data", getenv("MBSE_ROOT"), Area); sprintf(temp, "%s/fdb/file%ld.data", getenv("MBSE_ROOT"), Area);
/* /*
* Open the file database, if it's locked, just wait. * Open the file database, if it's locked, just wait.
*/ */
while (((fdb_area->fp = fopen(temp, "r+")) == NULL) && ((errno == EACCES) || (errno == EAGAIN))) { while (((fp = fopen(temp, "r+")) == NULL) && ((errno == EACCES) || (errno == EAGAIN))) {
if (++Tries >= (Timeout * 4)) { if (++Tries >= (Timeout * 4)) {
WriteError("Can't open file area %ld, timeout", Area); WriteError("Can't open file area %ld, timeout", Area);
free(temp); free(temp);
@ -65,12 +68,12 @@ struct _fdbarea *mbsedb_OpenFDB(long Area, int Timeout)
msleep(250); msleep(250);
Syslog('f', "Open file area %ld, try %d", Area, Tries); Syslog('f', "Open file area %ld, try %d", Area, Tries);
} }
if (fdb_area->fp == NULL) { if (fp == NULL) {
WriteError("$Can't open %s", temp); WriteError("$Can't open %s", temp);
free(temp); free(temp);
return NULL; return NULL;
} }
fread(&fdbhdr, sizeof(fdbhdr), 1, fdb_area->fp); fread(&fdbhdr, sizeof(fdbhdr), 1, fp);
/* /*
* Fix attributes if needed * Fix attributes if needed
@ -84,17 +87,18 @@ struct _fdbarea *mbsedb_OpenFDB(long Area, int Timeout)
return NULL; return NULL;
} }
fseek(fdb_area->fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
if ((ftell(fdb_area->fp) - fdbhdr.hdrsize) % fdbhdr.recsize) { if ((ftell(fp) - fdbhdr.hdrsize) % fdbhdr.recsize) {
WriteError("Files database area %ld is corrupt, unalligned records", Area); WriteError("Files database area %ld is corrupt, unalligned records", Area);
fclose(fdb_area->fp); fclose(fp);
return NULL; return NULL;
} }
/* /*
* Point to the first record * Point to the first record
*/ */
fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET); fseek(fp, fdbhdr.hdrsize, SEEK_SET);
fdb_area->fp = fp;
fdb_area->locked = 0; fdb_area->locked = 0;
fdb_area->area = Area; fdb_area->area = Area;
Syslog('f', "OpenFDB success"); Syslog('f', "OpenFDB success");
@ -116,6 +120,8 @@ int mbsedb_CloseFDB(struct _fdbarea *fdb_area)
mbsedb_UnlockFDB(fdb_area); mbsedb_UnlockFDB(fdb_area);
} }
fclose(fdb_area->fp); fclose(fdb_area->fp);
free(fdb_area);
return TRUE; return TRUE;
} }

View File

@ -41,6 +41,12 @@ extern int do_quiet; /* Suppress screen output */
extern int do_pack; /* Pack filebase */ extern int do_pack; /* Pack filebase */
int iErrors = 0;
int iTotal = 0;
int iAreasNew = 0;
void CheckArea(long); /* Check a single area */
/* /*
* Check file database integrity, all files in the file database must * Check file database integrity, all files in the file database must
@ -57,31 +63,28 @@ extern int do_pack; /* Pack filebase */
* Remarks: Maybe if the crc check fails, and the date and time are * Remarks: Maybe if the crc check fails, and the date and time are
* ok, the file is damaged and must be made unavailable. * ok, the file is damaged and must be made unavailable.
*/ */
void Check(void) void Check(long AreaNr)
{ {
FILE *pAreas, *pFile; FILE *pAreas, *pFile;
int i, j, iAreas, iAreasNew = 0, Fix, inArea, iTotal = 0, iErrors = 0, rc; char *sAreas, *fAreas, *newdir, *temp, *mname;
char *sAreas, *fAreas, *newdir, *temp, *mname, *tname; long i, iAreas;
DIR *dp; DIR *dp;
struct dirent *de; struct dirent *de;
int Found, Update; int Found;
char fn[PATH_MAX];
struct stat stb;
struct passwd *pw;
struct group *gr;
struct FILEIndex idx; struct FILEIndex idx;
sAreas = calloc(PATH_MAX, sizeof(char)); sAreas = calloc(PATH_MAX, sizeof(char));
fAreas = calloc(PATH_MAX, sizeof(char)); fAreas = calloc(PATH_MAX, sizeof(char));
newdir = calloc(PATH_MAX, sizeof(char));
temp = calloc(PATH_MAX, sizeof(char)); temp = calloc(PATH_MAX, sizeof(char));
mname = calloc(PATH_MAX, sizeof(char)); mname = calloc(PATH_MAX, sizeof(char));
newdir = calloc(PATH_MAX, sizeof(char));
if (!do_quiet) { if (!do_quiet) {
colour(3, 0); colour(3, 0);
printf("Checking file database...\n"); printf("Checking file database...\n");
} }
iAreasNew = iTotal = iErrors = 0;
sprintf(sAreas, "%s/etc/fareas.data", getenv("MBSE_ROOT")); sprintf(sAreas, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
if ((pAreas = fopen (sAreas, "r")) == NULL) { if ((pAreas = fopen (sAreas, "r")) == NULL) {
@ -93,17 +96,130 @@ void Check(void)
fseek(pAreas, 0, SEEK_END); fseek(pAreas, 0, SEEK_END);
iAreas = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize; iAreas = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize;
if (AreaNr) {
fseek(pAreas, ((AreaNr-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&area, areahdr.recsize, 1, pAreas);
if (area.Available) {
Syslog('+', "Checking file area %ld", AreaNr);
CheckArea(AreaNr);
}
} else {
/*
* Do all areas
*/
for (i = 1; i <= iAreas; i++) { for (i = 1; i <= iAreas; i++) {
fseek(pAreas, ((i-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET); fseek(pAreas, ((i-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET);
fread(&area, areahdr.recsize, 1, pAreas); fread(&area, areahdr.recsize, 1, pAreas);
if (area.Available) { if (area.Available) {
CheckArea(i);
IsDoing("Check area %d", i); } else {
if (strlen(area.Name) == 0) {
sprintf(fAreas, "%s/fdb/file%ld.data", getenv("MBSE_ROOT"), i);
if (unlink(fAreas) == 0) {
Syslog('+', "Removed obsolete %s", fAreas);
}
}
} /* if area.Available */
}
fclose(pAreas);
}
if (! AreaNr) {
/*
* Only if we check all areas, check magic filenames.
*/
if (!do_quiet) {
printf("\rChecking magic alias names ... \r");
fflush(stdout);
}
if (!strlen(CFG.req_magic)) {
WriteError("No magic filename path configured");
} else {
if ((dp = opendir(CFG.req_magic)) == NULL) {
WriteError("$Can't open directory %s", CFG.req_magic);
} else {
while ((de = readdir(dp))) {
if (de->d_name[0] != '.') {
sprintf(temp, "%s/%s", CFG.req_magic, de->d_name);
if (file_exist(temp, X_OK) == 0) {
Syslog('f', "%s is executable", temp);
} else if (file_exist(temp, R_OK) == 0) {
if ((pFile = fopen(temp, "r"))) {
fgets(mname, PATH_MAX -1, pFile);
fclose(pFile);
Striplf(mname);
sprintf(newdir, "%s/etc/request.index", getenv("MBSE_ROOT"));
Found = FALSE;
if ((pFile = fopen(newdir, "r"))) {
while (fread(&idx, sizeof(idx), 1, pFile)) {
if ((strcmp(idx.Name, mname) == 0) || (strcmp(idx.LName, mname) == 0)) {
Found = TRUE;
break;
}
}
fclose(pFile);
}
if (!Found) {
Syslog('+', "Error: magic alias %s (%s) is invalid, removed", de->d_name, mname);
iErrors++;
unlink(temp);
}
}
} else {
Syslog('f', "%s cannot be", temp);
}
}
}
closedir(dp);
}
}
}
if (!do_quiet) { if (!do_quiet) {
printf("\r%4d => %-44s \b\b\b\b", i, area.Name); printf("\r \r");
fflush(stdout);
}
free(mname);
free(temp);
free(newdir);
free(sAreas);
free(fAreas);
Syslog('+', "Check Areas [%5d] Files [%5d] Errors [%5d]", iAreasNew, iTotal, iErrors);
}
void CheckArea(long Area)
{
FILE *pFile;
int j, Fix, inArea, rc;
char *fAreas, *newdir, *temp, *mname, *tname;
DIR *dp;
struct dirent *de;
int Found, Update;
char fn[PATH_MAX];
struct stat stb;
struct passwd *pw;
struct group *gr;
fAreas = calloc(PATH_MAX, sizeof(char));
newdir = calloc(PATH_MAX, sizeof(char));
temp = calloc(PATH_MAX, sizeof(char));
mname = calloc(PATH_MAX, sizeof(char));
IsDoing("Check area %ld", Area);
if (!do_quiet) {
printf("\r%4ld => %-44s \b\b\b\b", Area, area.Name);
fflush(stdout); fflush(stdout);
} }
@ -173,7 +289,7 @@ void Check(void)
WriteError("Can't stat %s", area.Path); WriteError("Can't stat %s", area.Path);
} }
sprintf(fAreas, "%s/fdb/file%d.data", getenv("MBSE_ROOT"), i); sprintf(fAreas, "%s/fdb/file%ld.data", getenv("MBSE_ROOT"), Area);
/* /*
* Open the file database, if it doesn't exist, * Open the file database, if it doesn't exist,
@ -217,7 +333,7 @@ void Check(void)
sprintf(mname, "%s/%s", area.Path, fdb.Name); sprintf(mname, "%s/%s", area.Path, fdb.Name);
if (file_exist(newdir, R_OK) && file_exist(mname, R_OK)) { if (file_exist(newdir, R_OK) && file_exist(mname, R_OK)) {
Syslog('+', "File %s area %d not on disk.", newdir, i); Syslog('+', "File %s area %ld not on disk.", newdir, Area);
if (!fdb.NoKill) { if (!fdb.NoKill) {
fdb.Deleted = TRUE; fdb.Deleted = TRUE;
do_pack = TRUE; do_pack = TRUE;
@ -353,19 +469,19 @@ void Check(void)
if (file_time(newdir) != fdb.FileDate) { if (file_time(newdir) != fdb.FileDate) {
Syslog('!', "Date mismatch area %d file %s", i, fdb.LName); Syslog('!', "Date mismatch area %ld file %s", Area, fdb.LName);
fdb.FileDate = file_time(newdir); fdb.FileDate = file_time(newdir);
iErrors++; iErrors++;
Update = TRUE; Update = TRUE;
} }
if (file_size(newdir) != fdb.Size) { if (file_size(newdir) != fdb.Size) {
Syslog('!', "Size mismatch area %d file %s", i, fdb.LName); Syslog('!', "Size mismatch area %ld file %s", Area, fdb.LName);
fdb.Size = file_size(newdir); fdb.Size = file_size(newdir);
iErrors++; iErrors++;
Update = TRUE; Update = TRUE;
} }
if (file_crc(newdir, CFG.slow_util && do_quiet) != fdb.Crc32) { if (file_crc(newdir, CFG.slow_util && do_quiet) != fdb.Crc32) {
Syslog('!', "CRC error area %d, file %s", i, fdb.LName); Syslog('!', "CRC error area %ld, file %s", Area, fdb.LName);
fdb.Crc32 = file_crc(newdir, CFG.slow_util && do_quiet); fdb.Crc32 = file_crc(newdir, CFG.slow_util && do_quiet);
iErrors++; iErrors++;
Update = TRUE; Update = TRUE;
@ -379,7 +495,7 @@ void Check(void)
if (strlen(fdb.Magic)) { if (strlen(fdb.Magic)) {
rc = magic_check(fdb.Magic, fdb.Name); rc = magic_check(fdb.Magic, fdb.Name);
if (rc == -1) { if (rc == -1) {
Syslog('+', "Area %d magic alias %s file %s is invalid", i, fdb.Magic, fdb.Name); Syslog('+', "Area %ld magic alias %s file %s is invalid", Area, fdb.Magic, fdb.Name);
memset(&fdb.Magic, 0, sizeof(fdb.Magic)); memset(&fdb.Magic, 0, sizeof(fdb.Magic));
fseek(pFile, - fdbhdr.recsize, SEEK_CUR); fseek(pFile, - fdbhdr.recsize, SEEK_CUR);
fwrite(&fdb, fdbhdr.recsize, 1, pFile); fwrite(&fdb, fdbhdr.recsize, 1, pFile);
@ -388,7 +504,7 @@ void Check(void)
} }
} }
if (inArea == 0) if (inArea == 0)
Syslog('+', "Warning: area %d (%s) is empty", i, area.Name); Syslog('+', "Warning: area %ld (%s) is empty", Area, area.Name);
/* /*
* Check files in the directory against the database. * Check files in the directory against the database.
@ -410,7 +526,7 @@ void Check(void)
* Record has been found before, so this must be * Record has been found before, so this must be
* a double record. * a double record.
*/ */
Syslog('!', "Double file record area %d file %s", i, fdb.LName); Syslog('!', "Double file record area %ld file %s", Area, fdb.LName);
iErrors++; iErrors++;
fdb.Double = TRUE; fdb.Double = TRUE;
do_pack = TRUE; do_pack = TRUE;
@ -448,80 +564,10 @@ void Check(void)
chmod(fAreas, 0660); chmod(fAreas, 0660);
iAreasNew++; iAreasNew++;
} else {
if (strlen(area.Name) == 0) {
sprintf(fAreas, "%s/fdb/file%d.data", getenv("MBSE_ROOT"), i);
if (unlink(fAreas) == 0) {
Syslog('+', "Removed obsolete %s", fAreas);
}
}
} /* if area.Available */
}
fclose(pAreas);
if (!do_quiet) {
printf("\rChecking magic alias names ... \r");
fflush(stdout);
}
if (!strlen(CFG.req_magic)) {
WriteError("No magic filename path configured");
} else {
if ((dp = opendir(CFG.req_magic)) == NULL) {
WriteError("$Can't open directory %s", CFG.req_magic);
} else {
while ((de = readdir(dp))) {
if (de->d_name[0] != '.') {
sprintf(temp, "%s/%s", CFG.req_magic, de->d_name);
if (file_exist(temp, X_OK) == 0) {
Syslog('f', "%s is executable", temp);
} else if (file_exist(temp, R_OK) == 0) {
if ((pFile = fopen(temp, "r"))) {
fgets(mname, PATH_MAX -1, pFile);
fclose(pFile);
Striplf(mname);
sprintf(newdir, "%s/etc/request.index", getenv("MBSE_ROOT"));
Found = FALSE;
if ((pFile = fopen(newdir, "r"))) {
while (fread(&idx, sizeof(idx), 1, pFile)) {
if ((strcmp(idx.Name, mname) == 0) || (strcmp(idx.LName, mname) == 0)) {
Found = TRUE;
break;
}
}
fclose(pFile);
}
if (!Found) {
Syslog('+', "Error: magic alias %s (%s) is invalid, removed", de->d_name, mname);
iErrors++;
unlink(temp);
}
}
} else {
Syslog('f', "%s cannot be", temp);
}
}
}
closedir(dp);
}
}
if (!do_quiet) {
printf("\r \r");
fflush(stdout);
}
free(mname);
free(temp);
free(newdir);
free(sAreas);
free(fAreas); free(fAreas);
free(newdir);
Syslog('+', "Check Areas [%5d] Files [%5d] Errors [%5d]", iAreasNew, iTotal, iErrors); free(temp);
free(mname);
} }

View File

@ -3,6 +3,6 @@
#ifndef _MBFCHECK_H_ #ifndef _MBFCHECK_H_
#define _MBFCHECK_H #define _MBFCHECK_H
void Check(void); /* Check file database */ void Check(long); /* Check file database */
#endif #endif

View File

@ -204,6 +204,14 @@ int main(int argc, char **argv)
do_pack = TRUE; do_pack = TRUE;
} else if (!strncasecmp(argv[i], "c", 1)) { } else if (!strncasecmp(argv[i], "c", 1)) {
do_check = TRUE; do_check = TRUE;
if (argc > (i + 1)) {
Area = atoi(argv[i+1]);
if (Area) {
i++;
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
}
}
} else if (!strncasecmp(argv[i], "k", 1)) { } else if (!strncasecmp(argv[i], "k", 1)) {
do_kill = TRUE; do_kill = TRUE;
} else if (!strncasecmp(argv[i], "t", 1)) { } else if (!strncasecmp(argv[i], "t", 1)) {
@ -261,8 +269,9 @@ int main(int argc, char **argv)
if (do_sort) if (do_sort)
SortFileBase(Area); SortFileBase(Area);
if (do_check) if (do_check) {
Check(); Check(Area);
}
if (do_rearc) { if (do_rearc) {
ReArc(Area, FileName); ReArc(Area, FileName);

View File

@ -42,10 +42,15 @@ extern int do_quiet; /* Suppress screen output */
void ListFileAreas(int Area) void ListFileAreas(int Area)
{ {
FILE *pAreas, *pFile, *pTic; FILE *pAreas, *pTic;
int i, iAreas, fcount, tcount = 0, iTotal = 0, columns = 80; int i, iAreas, fcount, tcount = 0, iTotal = 0, columns = 80;
long fsize, tsize = 0; long fsize, tsize = 0;
char *sAreas, *fAreas, *sTic, flags[6], *ticarea; char *sAreas, *fAreas, *sTic, flags[6], *ticarea;
#ifdef USE_EXPERIMENT
struct _fdbarea *fdb_area = NULL;
#else
FILE *pFile;
#endif
/* /*
* If nothing to display allowed, return at once. * If nothing to display allowed, return at once.
@ -103,6 +108,12 @@ void ListFileAreas(int Area)
if (area.Available) { if (area.Available) {
#ifdef USE_EXPERIMENT
/*
* Open the file database.
*/
fdb_area = mbsedb_OpenFDB(Area, 30);
#else
/* /*
* Open the file database, create new one if it doesn't exist. * Open the file database, create new one if it doesn't exist.
*/ */
@ -119,6 +130,7 @@ void ListFileAreas(int Area)
} else { } else {
fread(&fdbhdr, sizeof(fdbhdr), 1, pFile); fread(&fdbhdr, sizeof(fdbhdr), 1, pFile);
} }
#endif
fcount = 0; fcount = 0;
fsize = 0L; fsize = 0L;
@ -132,7 +144,11 @@ void ListFileAreas(int Area)
colour(LIGHTGRAY, BLACK); colour(LIGHTGRAY, BLACK);
#ifdef USE_EXPERIMENT
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
#else
while (fread(&fdb, fdbhdr.recsize, 1, pFile) == 1) { while (fread(&fdb, fdbhdr.recsize, 1, pFile) == 1) {
#endif
sprintf(flags, "---"); sprintf(flags, "---");
if (fdb.Deleted) if (fdb.Deleted)
flags[0] = 'D'; flags[0] = 'D';
@ -155,7 +171,11 @@ void ListFileAreas(int Area)
printf("-"); printf("-");
printf("\n"); printf("\n");
printf("%d file%s, %ld Kbytes\n", fcount, (fcount == 1) ? "":"s", fsize); printf("%d file%s, %ld Kbytes\n", fcount, (fcount == 1) ? "":"s", fsize);
#ifdef USE_EXPERIMENT
mbsedb_CloseFDB(fdb_area);
#else
fclose(pFile); fclose(pFile);
#endif
} else { } else {
WriteError("Area %d is not available", Area); WriteError("Area %d is not available", Area);
@ -184,6 +204,9 @@ void ListFileAreas(int Area)
if (area.Available) { if (area.Available) {
#ifdef USE_EXPERIMENT
fdb_area = mbsedb_OpenFDB(i, 30);
#else
/* /*
* Open the file database, create new one if it doesn't exist. * Open the file database, create new one if it doesn't exist.
*/ */
@ -200,10 +223,15 @@ void ListFileAreas(int Area)
} else { } else {
fread(&fdbhdr, sizeof(fdbhdr), 1, pFile); fread(&fdbhdr, sizeof(fdbhdr), 1, pFile);
} }
#endif
fcount = 0; fcount = 0;
fsize = 0L; fsize = 0L;
#ifdef USE_EXPERIMENT
while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
#else
while (fread(&fdb, fdbhdr.recsize, 1, pFile) == 1) { while (fread(&fdb, fdbhdr.recsize, 1, pFile) == 1) {
#endif
fcount++; fcount++;
fsize = fsize + fdb.Size; fsize = fsize + fdb.Size;
} }
@ -213,7 +241,11 @@ void ListFileAreas(int Area)
printf("%5d %5d %5ld %-12s %s\n", i, fcount, fsize, area.BbsGroup, area.Name); printf("%5d %5d %5ld %-12s %s\n", i, fcount, fsize, area.BbsGroup, area.Name);
iTotal++; iTotal++;
#ifdef USE_EXPERIMENT
mbsedb_CloseFDB(fdb_area);
#else
fclose(pFile); fclose(pFile);
#endif
} }
} }

View File

@ -113,7 +113,7 @@ void Help(void)
printf(" Commands are:\n\n"); printf(" Commands are:\n\n");
colour(CYAN, BLACK); colour(CYAN, BLACK);
printf(" a adopt <area> <file> [desc] Adopt file to area\n"); printf(" a adopt <area> <file> [desc] Adopt file to area\n");
printf(" c check Check filebase\n"); printf(" c check [area] Check filebase\n");
printf(" d delete <area> \"<filemask>\" Mark file(s) in area for deletion\n"); printf(" d delete <area> \"<filemask>\" Mark file(s) in area for deletion\n");
printf(" im import <area> Import files in current dir to area\n"); printf(" im import <area> Import files in current dir to area\n");
printf(" in index Create filerequest index\n"); printf(" in index Create filerequest index\n");