/* loc.c: Interface to dbm index of object locations. */ #include <stdio.h> #include <sys/types.h> #include <sys/file.h> #include <sys/stat.h> #include <ndbm.h> #include <fcntl.h> #include "log.h" #ifdef S_IRUSR #define READ_WRITE (S_IRUSR | S_IWUSR) #define READ_WRITE_EXECUTE (S_IRUSR | S_IWUSR | S_IXUSR) #else #define READ_WRITE 0600 #define READ_WRITE_EXECUTE 0700 #endif static DBM *dbp; struct hbuf { off_t offset; int size; }; void loc_open(char *name, int new) { if (new) dbp = dbm_open(name, O_TRUNC | O_RDWR | O_CREAT, READ_WRITE); else dbp = dbm_open(name, O_RDWR, READ_WRITE); if (!dbp) fail_to_start("Cannot open dbm database file."); } void loc_close(void) { dbm_close(dbp); } void loc_sync(void) { /* Only way to do this with ndbm is close and re-open. */ dbm_close(dbp); dbp = dbm_open("binary/index", O_RDWR | O_CREAT, READ_WRITE); if (!dbp) panic("Cannot reopen dbm database file."); } int loc_retrieve(char *name, off_t *offset, int *size) { datum key, dat; struct hbuf hbuf; /* Get the key from the database. */ key.dptr = name; key.dsize = strlen(name) + 1; dat = dbm_fetch(dbp, key); if (!dat.dptr) return 0; /* Translate the result into offset and size. */ memcpy(&hbuf, dat.dptr, sizeof(hbuf)); *offset = hbuf.offset; *size = hbuf.size; return 1; } int loc_store(char *name, off_t offset, int size) { datum key, dat; struct hbuf hbuf; /* Set up key and data structures. */ key.dptr = name; key.dsize = strlen(name) + 1; hbuf.offset = offset; hbuf.size = size; dat.dptr = (char *) &hbuf; dat.dsize = sizeof(hbuf); if (dbm_store(dbp, key, dat, DBM_REPLACE)) { write_log("ERROR: Failed to store key %s.", name); return 0; } return 1; } int loc_remove(char *name) { datum key; /* Remove the key from the database. */ key.dptr = name; key.dsize = strlen(name) + 1; if (dbm_delete(dbp, key)) { write_log("ERROR: Failed to delete key %s.", name); return 0; } return 1; } char *loc_first(void) { datum key; key = dbm_firstkey(dbp); return key.dptr; } char *loc_next(void) { datum key; key = dbm_nextkey(dbp); return key.dptr; }