jcs
/subtext
/amendments
/113
db: Try to recover databases on open failure
jcs made amendment 113 over 2 years ago
--- db.c Mon May 23 14:32:28 2022
+++ db.c Wed Jun 1 13:08:50 2022
@@ -142,9 +142,17 @@ db_init(Str255 path, short vrefnum, struct bile *bile)
if (bile == NULL) {
bile = bile_open(path, vrefnum);
- if (bile == NULL)
- panic("Failed to open DB file %s: %d", PtoCstr(path),
- bile_error(NULL));
+ if (bile == NULL) {
+ if (ask("Attempt recovery with backup map?")) {
+ bile = bile_open_recover_map(path, vrefnum);
+ if (bile == NULL)
+ panic("Failed to recover DB file %s: %d",
+ PtoCstr(path), bile_error(NULL));
+ } else {
+ panic("Failed to open DB file %s: %d", PtoCstr(path),
+ bile_error(NULL));
+ }
+ }
}
/* we got this far, store it as the last-accessed file */
@@ -316,7 +324,7 @@ db_cache_boards(struct db *tdb)
tdb->nboards = bile_count_by_type(tdb->bile, DB_BOARD_RTYPE);
if (!tdb->nboards)
return;
- tdb->boards = xmallocarray(tdb->nboards, sizeof(struct board));
+ tdb->boards = xcalloc(tdb->nboards, sizeof(struct board));
for (n = 0; n < tdb->nboards; n++) {
obj = bile_get_nth_of_type(tdb->bile, n, DB_BOARD_RTYPE);
@@ -326,7 +334,8 @@ db_cache_boards(struct db *tdb)
size = bile_read_alloc(tdb->bile, DB_BOARD_RTYPE, obj->id,
&data);
bile_unmarshall_object(tdb->bile, board_object_fields,
- nboard_object_fields, data, size, (char *)(&tdb->boards[n]));
+ nboard_object_fields, data, size, (char *)(&tdb->boards[n]),
+ true);
free(data);
snprintf((char *)board_filename, sizeof(board_filename),
@@ -335,13 +344,23 @@ db_cache_boards(struct db *tdb)
tdb->boards[n].bile = bile_open(board_filename, tdb->bile->vrefnum);
if (tdb->boards[n].bile != NULL)
continue;
-
- if (ask("Failed to open board bile %s (error %d), recreate it?",
- PtoCstr(board_filename), bile_error(NULL)) == false)
- exit(0);
-
- CtoPstr(board_filename);
- tdb->boards[n].bile = db_board_create(tdb, &tdb->boards[n]);
+
+ if (ask("Attempt recovery with backup map?")) {
+ tdb->boards[n].bile = bile_open_recover_map(board_filename,
+ tdb->bile->vrefnum);
+ if (tdb->boards[n].bile == NULL)
+ panic("Failed to recover board file %s: %d",
+ PtoCstr(board_filename), bile_error(NULL));
+ } else {
+ if (ask("Failed to open board bile %s (error %d), recreate it?",
+ PtoCstr(board_filename), bile_error(NULL)) == false)
+ exit(0);
+ CtoPstr(board_filename);
+ tdb->boards[n].bile = db_board_create(tdb, &tdb->boards[n]);
+ if (tdb->boards[n].bile == NULL)
+ panic("Failed to create board file %s: %d",
+ PtoCstr(board_filename), bile_error(NULL));
+ }
}
}