diff --git a/ChangeLog b/ChangeLog index 52b164ee..75a5e348 100644 --- a/ChangeLog +++ b/ChangeLog @@ -45,6 +45,8 @@ v0.51.4 11-Apr-2004 logfile. Mbfile check will abort if a header of a files database is corrupt. + Mbfile check will now accept an area number to just check one + single area. mbnntp: New program, news server to read echomail with a news client. diff --git a/lib/dbfdb.c b/lib/dbfdb.c index bad85496..889b5214 100644 --- a/lib/dbfdb.c +++ b/lib/dbfdb.c @@ -47,16 +47,19 @@ struct _fdbarea *mbsedb_OpenFDB(long Area, int Timeout) char *temp; struct _fdbarea *fdb_area = NULL; int Tries = 0; + FILE *fp; Syslog('f', "OpenFDB area %ld, timeout %d", Area, Timeout); 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); /* * 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)) { WriteError("Can't open file area %ld, timeout", Area); free(temp); @@ -65,12 +68,12 @@ struct _fdbarea *mbsedb_OpenFDB(long Area, int Timeout) msleep(250); Syslog('f', "Open file area %ld, try %d", Area, Tries); } - if (fdb_area->fp == NULL) { + if (fp == NULL) { WriteError("$Can't open %s", temp); free(temp); return NULL; } - fread(&fdbhdr, sizeof(fdbhdr), 1, fdb_area->fp); + fread(&fdbhdr, sizeof(fdbhdr), 1, fp); /* * Fix attributes if needed @@ -84,17 +87,18 @@ struct _fdbarea *mbsedb_OpenFDB(long Area, int Timeout) return NULL; } - fseek(fdb_area->fp, 0, SEEK_END); - if ((ftell(fdb_area->fp) - fdbhdr.hdrsize) % fdbhdr.recsize) { + fseek(fp, 0, SEEK_END); + if ((ftell(fp) - fdbhdr.hdrsize) % fdbhdr.recsize) { WriteError("Files database area %ld is corrupt, unalligned records", Area); - fclose(fdb_area->fp); + fclose(fp); return NULL; } /* * 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->area = Area; Syslog('f', "OpenFDB success"); @@ -116,6 +120,8 @@ int mbsedb_CloseFDB(struct _fdbarea *fdb_area) mbsedb_UnlockFDB(fdb_area); } fclose(fdb_area->fp); + + free(fdb_area); return TRUE; } diff --git a/mbfido/mbfcheck.c b/mbfido/mbfcheck.c index 899c676d..83c6d372 100644 --- a/mbfido/mbfcheck.c +++ b/mbfido/mbfcheck.c @@ -41,6 +41,12 @@ extern int do_quiet; /* Suppress screen output */ 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 @@ -57,31 +63,28 @@ extern int do_pack; /* Pack filebase */ * Remarks: Maybe if the crc check fails, and the date and time are * ok, the file is damaged and must be made unavailable. */ -void Check(void) +void Check(long AreaNr) { FILE *pAreas, *pFile; - int i, j, iAreas, iAreasNew = 0, Fix, inArea, iTotal = 0, iErrors = 0, rc; - char *sAreas, *fAreas, *newdir, *temp, *mname, *tname; + char *sAreas, *fAreas, *newdir, *temp, *mname; + long i, iAreas; DIR *dp; struct dirent *de; - int Found, Update; - char fn[PATH_MAX]; - struct stat stb; - struct passwd *pw; - struct group *gr; - struct FILEIndex idx; + int Found; + struct FILEIndex idx; sAreas = calloc(PATH_MAX, sizeof(char)); fAreas = calloc(PATH_MAX, sizeof(char)); - newdir = calloc(PATH_MAX, sizeof(char)); temp = calloc(PATH_MAX, sizeof(char)); mname = calloc(PATH_MAX, sizeof(char)); - + newdir = calloc(PATH_MAX, sizeof(char)); + if (!do_quiet) { colour(3, 0); printf("Checking file database...\n"); } + iAreasNew = iTotal = iErrors = 0; sprintf(sAreas, "%s/etc/fareas.data", getenv("MBSE_ROOT")); if ((pAreas = fopen (sAreas, "r")) == NULL) { @@ -93,87 +96,200 @@ void Check(void) fseek(pAreas, 0, SEEK_END); iAreas = (ftell(pAreas) - areahdr.hdrsize) / areahdr.recsize; - for (i = 1; i <= iAreas; i++) { - - fseek(pAreas, ((i-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET); + 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); + } - IsDoing("Check area %d", i); + } else { + /* + * Do all areas + */ + for (i = 1; i <= iAreas; i++) { - if (!do_quiet) { - printf("\r%4d => %-44s \b\b\b\b", i, area.Name); - fflush(stdout); - } + fseek(pAreas, ((i-1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET); + fread(&area, areahdr.recsize, 1, pAreas); - /* - * Check if download directory exists, - * if not, create the directory. - */ - if (access(area.Path, R_OK) == -1) { - Syslog('!', "No dir: %s", area.Path); - sprintf(newdir, "%s/foobar", area.Path); - mkdirs(newdir, 0775); - } + if (area.Available) { + CheckArea(i); - if (stat(area.Path, &stb) == 0) { - /* - * Very extended directory check - */ - Fix = FALSE; - if ((stb.st_mode & S_IRUSR) == 0) { - Fix = TRUE; - WriteError("No owner read access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff); - } - if ((stb.st_mode & S_IWUSR) == 0) { - Fix = TRUE; - WriteError("No owner write access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff); - } - if ((stb.st_mode & S_IRGRP) == 0) { - Fix = TRUE; - WriteError("No group read access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff); - } - if ((stb.st_mode & S_IWGRP) == 0) { - Fix = TRUE; - WriteError("No group write access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff); - } - if ((stb.st_mode & S_IROTH) == 0) { - Fix = TRUE; - WriteError("No others read access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff); - } - if (Fix) { - iErrors++; - if (chmod(area.Path, 0775)) - WriteError("Could not set mode to 0775"); - else - Syslog('+', "Corrected directory mode to 0775"); - } - Fix = FALSE; - pw = getpwuid(stb.st_uid); - if (strcmp(pw->pw_name, (char *)"mbse")) { - WriteError("Directory %s not owned by user mbse", area.Path); - Fix = TRUE; - } - gr = getgrgid(stb.st_gid); - if (strcmp(gr->gr_name, (char *)"bbs")) { - WriteError("Directory %s not owned by group bbs", area.Path); - Fix = TRUE; - } - if (Fix) { - iErrors++; - pw = getpwnam((char *)"mbse"); - gr = getgrnam((char *)"bbs"); - if (chown(area.Path, pw->pw_gid, gr->gr_gid)) - WriteError("Could not set owner to mbse.bbs"); - else - Syslog('+', "Corrected directory owner to mbse.bbs"); - } } else { - WriteError("Can't stat %s", area.Path); - } - sprintf(fAreas, "%s/fdb/file%d.data", getenv("MBSE_ROOT"), i); + 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) { + 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); + } + + /* + * Check if download directory exists, + * if not, create the directory. + */ + if (access(area.Path, R_OK) == -1) { + Syslog('!', "No dir: %s", area.Path); + sprintf(newdir, "%s/foobar", area.Path); + mkdirs(newdir, 0775); + } + + if (stat(area.Path, &stb) == 0) { + /* + * Very extended directory check + */ + Fix = FALSE; + if ((stb.st_mode & S_IRUSR) == 0) { + Fix = TRUE; + WriteError("No owner read access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff); + } + if ((stb.st_mode & S_IWUSR) == 0) { + Fix = TRUE; + WriteError("No owner write access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff); + } + if ((stb.st_mode & S_IRGRP) == 0) { + Fix = TRUE; + WriteError("No group read access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff); + } + if ((stb.st_mode & S_IWGRP) == 0) { + Fix = TRUE; + WriteError("No group write access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff); + } + if ((stb.st_mode & S_IROTH) == 0) { + Fix = TRUE; + WriteError("No others read access in %s, mode is %04o", area.Path, stb.st_mode & 0x1ff); + } + if (Fix) { + iErrors++; + if (chmod(area.Path, 0775)) + WriteError("Could not set mode to 0775"); + else + Syslog('+', "Corrected directory mode to 0775"); + } + Fix = FALSE; + pw = getpwuid(stb.st_uid); + if (strcmp(pw->pw_name, (char *)"mbse")) { + WriteError("Directory %s not owned by user mbse", area.Path); + Fix = TRUE; + } + gr = getgrgid(stb.st_gid); + if (strcmp(gr->gr_name, (char *)"bbs")) { + WriteError("Directory %s not owned by group bbs", area.Path); + Fix = TRUE; + } + if (Fix) { + iErrors++; + pw = getpwnam((char *)"mbse"); + gr = getgrnam((char *)"bbs"); + if (chown(area.Path, pw->pw_gid, gr->gr_gid)) + WriteError("Could not set owner to mbse.bbs"); + else + Syslog('+', "Corrected directory owner to mbse.bbs"); + } + } else { + WriteError("Can't stat %s", area.Path); + } + + sprintf(fAreas, "%s/fdb/file%ld.data", getenv("MBSE_ROOT"), Area); /* * Open the file database, if it doesn't exist, @@ -217,7 +333,7 @@ void Check(void) sprintf(mname, "%s/%s", area.Path, fdb.Name); 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) { fdb.Deleted = TRUE; do_pack = TRUE; @@ -353,19 +469,19 @@ void Check(void) 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); iErrors++; Update = TRUE; } 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); iErrors++; Update = TRUE; } 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); iErrors++; Update = TRUE; @@ -379,7 +495,7 @@ void Check(void) if (strlen(fdb.Magic)) { rc = magic_check(fdb.Magic, fdb.Name); 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)); fseek(pFile, - fdbhdr.recsize, SEEK_CUR); fwrite(&fdb, fdbhdr.recsize, 1, pFile); @@ -388,7 +504,7 @@ void Check(void) } } 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. @@ -410,7 +526,7 @@ void Check(void) * Record has been found before, so this must be * 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++; fdb.Double = TRUE; do_pack = TRUE; @@ -447,81 +563,11 @@ void Check(void) fclose(pFile); chmod(fAreas, 0660); 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); - - Syslog('+', "Check Areas [%5d] Files [%5d] Errors [%5d]", iAreasNew, iTotal, iErrors); + free(newdir); + free(temp); + free(mname); } - diff --git a/mbfido/mbfcheck.h b/mbfido/mbfcheck.h index 92bb5113..5aa30b92 100644 --- a/mbfido/mbfcheck.h +++ b/mbfido/mbfcheck.h @@ -3,6 +3,6 @@ #ifndef _MBFCHECK_H_ #define _MBFCHECK_H -void Check(void); /* Check file database */ +void Check(long); /* Check file database */ #endif diff --git a/mbfido/mbfile.c b/mbfido/mbfile.c index 944547f0..42ae14a7 100644 --- a/mbfido/mbfile.c +++ b/mbfido/mbfile.c @@ -204,6 +204,14 @@ int main(int argc, char **argv) do_pack = TRUE; } else if (!strncasecmp(argv[i], "c", 1)) { 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)) { do_kill = TRUE; } else if (!strncasecmp(argv[i], "t", 1)) { @@ -261,8 +269,9 @@ int main(int argc, char **argv) if (do_sort) SortFileBase(Area); - if (do_check) - Check(); + if (do_check) { + Check(Area); + } if (do_rearc) { ReArc(Area, FileName); diff --git a/mbfido/mbflist.c b/mbfido/mbflist.c index 943d2441..26f18078 100644 --- a/mbfido/mbflist.c +++ b/mbfido/mbflist.c @@ -42,10 +42,15 @@ extern int do_quiet; /* Suppress screen output */ void ListFileAreas(int Area) { - FILE *pAreas, *pFile, *pTic; + FILE *pAreas, *pTic; int i, iAreas, fcount, tcount = 0, iTotal = 0, columns = 80; long fsize, tsize = 0; 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. @@ -103,6 +108,12 @@ void ListFileAreas(int Area) 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. */ @@ -119,6 +130,7 @@ void ListFileAreas(int Area) } else { fread(&fdbhdr, sizeof(fdbhdr), 1, pFile); } +#endif fcount = 0; fsize = 0L; @@ -132,7 +144,11 @@ void ListFileAreas(int Area) 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) { +#endif sprintf(flags, "---"); if (fdb.Deleted) flags[0] = 'D'; @@ -155,7 +171,11 @@ void ListFileAreas(int Area) printf("-"); printf("\n"); printf("%d file%s, %ld Kbytes\n", fcount, (fcount == 1) ? "":"s", fsize); +#ifdef USE_EXPERIMENT + mbsedb_CloseFDB(fdb_area); +#else fclose(pFile); +#endif } else { WriteError("Area %d is not available", Area); @@ -184,6 +204,9 @@ void ListFileAreas(int Area) 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. */ @@ -200,10 +223,15 @@ void ListFileAreas(int Area) } else { fread(&fdbhdr, sizeof(fdbhdr), 1, pFile); } +#endif fcount = 0; fsize = 0L; +#ifdef USE_EXPERIMENT + while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) { +#else while (fread(&fdb, fdbhdr.recsize, 1, pFile) == 1) { +#endif fcount++; 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); iTotal++; +#ifdef USE_EXPERIMENT + mbsedb_CloseFDB(fdb_area); +#else fclose(pFile); +#endif } } diff --git a/mbfido/mbfutil.c b/mbfido/mbfutil.c index 6777b142..31ad99f5 100644 --- a/mbfido/mbfutil.c +++ b/mbfido/mbfutil.c @@ -113,7 +113,7 @@ void Help(void) printf(" Commands are:\n\n"); colour(CYAN, BLACK); printf(" a adopt [desc] Adopt file to area\n"); - printf(" c check Check filebase\n"); + printf(" c check [area] Check filebase\n"); printf(" d delete \"\" Mark file(s) in area for deletion\n"); printf(" im import Import files in current dir to area\n"); printf(" in index Create filerequest index\n");