diff --git a/lib/dbfdb.c b/lib/dbfdb.c index 63416bbb..dcdb642d 100644 --- a/lib/dbfdb.c +++ b/lib/dbfdb.c @@ -142,6 +142,9 @@ int mbsedb_CloseFDB(struct _fdbarea *fdb_area) +/* + * Lock Files DataBase + */ int mbsedb_LockFDB(struct _fdbarea *fdb_area, int Timeout) { int rc, Tries = 0; @@ -176,6 +179,9 @@ int mbsedb_LockFDB(struct _fdbarea *fdb_area, int Timeout) +/* + * Unlock Files DataBase + */ int mbsedb_UnlockFDB(struct _fdbarea *fdb_area) { struct flock fl; @@ -196,6 +202,154 @@ int mbsedb_UnlockFDB(struct _fdbarea *fdb_area) } + +int mbsedb_InsertFDB(struct _fdbarea *fdb_area, struct FILE_record frec, int AddAlpha) +{ + char *temp, *temp2; + int i, Insert, Done = FALSE, Found = FALSE, rc; + FILE *fp; + + Syslog('f', "InsertFDB %ld %s", fdb_area->area, frec.LName); + if (mbsedb_LockFDB(fdb_area, 30) == FALSE) + return FALSE; + + fseek(fdb_area->fp, 0, SEEK_END); + if (ftell(fdb_area->fp) == fdbhdr.hdrsize) { + /* + * No records yet, simply append this first record. + */ + Syslog('f', "append first record"); + fwrite(&frec, sizeof(frec), 1, fdb_area->fp); + mbsedb_UnlockFDB(fdb_area); + return TRUE; + } + + /* + * There are files, search the insert point. + */ + temp = calloc(PATH_MAX, sizeof(char)); + temp2 = calloc(PATH_MAX, sizeof(char)); + sprintf(temp, "%s/fdb/file%ld.temp", getenv("MBSE_ROOT"), fdb_area->area); + fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET); + Insert = 0; + do { + if (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) != 1) + Done = TRUE; + if (!Done) { + if (strcmp(frec.LName, fdb.LName) == 0) { + Found = TRUE; + Insert++; + } else if (strcmp(frec.LName, fdb.LName) < 0) + Found = TRUE; + else + Insert++; + } + } while ((!Found) && (!Done)); + + if (Found) { + if ((fp = fopen(temp, "a+")) == NULL) { + WriteError("$Can't create %s", temp); + mbsedb_UnlockFDB(fdb_area); + free(temp); + return FALSE; + } + fwrite(&fdbhdr, sizeof(fdbhdr), 1, fp); + + fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET); + /* + * Copy entries untill the insert point. + */ + for (i = 0; i < Insert; i++) { + fread(&fdb, fdbhdr.hdrsize, 1, fdb_area->fp); + /* + * If we see a magic that is the new magic, remove + * the old one. + */ + if (strlen(frec.Magic) && (strcmp(fdb.Magic, frec.Magic) == 0)) { + Syslog('f', "InsertFDB: remove magic from %s (%s)", fdb.Name, fdb.LName); + memset(&fdb.Magic, 0, sizeof(fdb.Magic)); + } + + /* + * Check if we are importing a file with the same + * name, if so, don't copy the original database + * record. The file is also overwritten. + */ + if (strcmp(fdb.LName, frec.LName) != 0) + fwrite(&fdb, fdbhdr.recsize, 1, fp); + } + + if (AddAlpha) { + /* + * Insert new entry + */ + fwrite(&frec, fdbhdr.recsize, 1, fp); + } + + /* + * Append the rest of the entries + */ + while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) { + /* + * If we see a magic that is the new magic, remove + * the old one. + */ + if (strlen(frec.Magic) && (strcmp(fdb.Magic, frec.Magic) == 0)) { + Syslog('f', "InsertFDB: remove magic from %s (%s)", fdb.Name, fdb.LName); + memset(&fdb.Magic, 0, sizeof(fdb.Magic)); + } + + /* + * Check if we are importing a file with the same + * name, if so, don't copy the original database + * record. The file is also overwritten. + */ + if (strcmp(fdb.LName, frec.LName) != 0) + fwrite(&fdb, fdbhdr.recsize, 1, fp); + } + + if (! AddAlpha) { + /* + * Append + */ + fwrite(&frec, fdbhdr.recsize, 1, fp); + } + + /* + * Now the trick, some might be waiting for a lock on the original file, + * we will give that a new name on disk. Then we move the temp in place. + * Finaly remove the old (still locked) original file. + */ + sprintf(temp2, "%s/fdb/file%ld.data", getenv("MBSE_ROOT"), fdb_area->area); + sprintf(temp, "%s/fdb/file%ld.xxxx", getenv("MBSE_ROOT"), fdb_area->area); + rc = rename(temp2, temp); + Syslog('f', "rename %s %s rc=%d", temp2, temp, rc); + sprintf(temp, "%s/fdb/file%ld.temp", getenv("MBSE_ROOT"), fdb_area->area); + rc = rename(temp, temp2); + Syslog('f', "rename %s %s rc=%d", temp, temp2, rc); + sprintf(temp, "%s/fdb/file%ld.xxxx", getenv("MBSE_ROOT"), fdb_area->area); + rc = unlink(temp); + Syslog('f', "unlink %s rc=%d", temp, rc); + + fdb_area->fp = fp; + fdb_area->locked = 0; + } else { + /* + * Append new entry + */ + fseek(fdb_area->fp, 0, SEEK_END); + fwrite(&frec, fdbhdr.recsize, 1, fdb_area->fp); + } + + free(temp); + free(temp2); + + Syslog('f', "success"); + return TRUE; +} + + + // mbsedb_SearchFileFDB // mbsedb_UpdateFileFDB // mbsedb_InsertFileFDB diff --git a/lib/mbsedb.h b/lib/mbsedb.h index 3f29e5d0..ef8b0fa2 100644 --- a/lib/mbsedb.h +++ b/lib/mbsedb.h @@ -148,6 +148,7 @@ struct _fdbarea *mbsedb_OpenFDB(long, int); int mbsedb_CloseFDB(struct _fdbarea *); int mbsedb_LockFDB(struct _fdbarea *, int); int mbsedb_UnlockFDB(struct _fdbarea *); +int mbsedb_InsertFDB(struct _fdbarea *, struct FILE_record, int); #endif