jcs
/amend
/amendments
/48
bile: Version 2 :/
Increased header size with some padding for future work, now includes
both map pointers in the header
jcs made amendment 48 over 2 years ago
--- bile.c Tue Jan 18 16:50:07 2022
+++ bile.c Wed Jan 19 16:22:46 2022
@@ -47,7 +47,7 @@ bile_create(const Str255 filename, short vrefnum, cons
{
struct bile *bile = NULL;
size_t len;
- char *magic;
+ char *tmp;
short fh;
_bile_error = 0;
@@ -69,9 +69,9 @@ bile_create(const Str255 filename, short vrefnum, cons
/* write magic */
len = BILE_MAGIC_LEN;
- magic = xstrdup(BILE_MAGIC);
- _bile_error = FSWrite(bile->frefnum, &len, magic);
- free(magic);
+ tmp = xstrdup(BILE_MAGIC);
+ _bile_error = FSWrite(bile->frefnum, &len, tmp);
+ free(tmp);
if (_bile_error)
goto create_bail;
@@ -81,6 +81,20 @@ bile_create(const Str255 filename, short vrefnum, cons
if (_bile_error)
goto create_bail;
+ len = sizeof(bile->old_map_ptr);
+ _bile_error = FSWrite(bile->frefnum, &len, &bile->old_map_ptr);
+ if (_bile_error)
+ goto create_bail;
+
+ /* padding */
+ len = BILE_HEADER_LEN - BILE_MAGIC_LEN - BILE_OBJECT_SIZE -
+ BILE_OBJECT_SIZE;
+ tmp = xmalloczero(len);
+ _bile_error = FSWrite(bile->frefnum, &len, tmp);
+ if (_bile_error)
+ goto create_bail;
+ free(tmp);
+
GetFPos(fh, &bile->file_size);
if (bile->file_size != BILE_HEADER_LEN)
@@ -101,9 +115,9 @@ bile_open(const Str255 filename, short vrefnum)
{
struct bile *bile = NULL;
struct bile_object map_obj;
- size_t file_size, map_size, size;
- short fh;
char magic[BILE_MAGIC_LEN + 1];
+ size_t file_size, map_size, size;
+ short fh, old_map_tried = 0;
_bile_error = 0;
@@ -118,6 +132,12 @@ bile_open(const Str255 filename, short vrefnum)
GetFPos(fh, &file_size);
SetFPos(fh, fsFromStart, 0);
+ bile = xmalloczero(sizeof(struct bile));
+ bile->vrefnum = vrefnum;
+ bile->frefnum = fh;
+ memcpy(bile->filename, filename, sizeof(bile->filename));
+ bile->file_size = file_size;
+
/* verify magic */
size = BILE_MAGIC_LEN;
_bile_error = FSRead(fh, &size, &magic);
@@ -125,54 +145,80 @@ bile_open(const Str255 filename, short vrefnum)
goto open_bail;
if (strncmp(magic, BILE_MAGIC, BILE_MAGIC_LEN) != 0) {
- _bile_error = -1;
+ if (strncmp(magic, BILE1_MAGIC, BILE1_MAGIC_LEN) == 0)
+ _bile_error = BILE_ERR_NEED_UPGRADE_1;
+ else
+ _bile_error = -1;
goto open_bail;
}
-
- bile = xmalloczero(sizeof(struct bile));
- bile->vrefnum = vrefnum;
- bile->frefnum = fh;
- memcpy(bile->filename, filename, sizeof(bile->filename));
- bile->file_size = file_size;
-
+
/* load map pointer */
size = sizeof(bile->map_ptr);
_bile_error = FSRead(bile->frefnum, &size, &bile->map_ptr);
if (_bile_error)
goto open_bail;
+
+ /* old map pointer */
+ size = sizeof(bile->old_map_ptr);
+ _bile_error = FSRead(bile->frefnum, &size, &bile->old_map_ptr);
+ if (_bile_error)
+ goto open_bail;
- if (bile->map_ptr.pos + bile->map_ptr.size > file_size)
- panic("bile_open: map points to %lu + %lu, but file is only %lu",
- bile->map_ptr.pos, bile->map_ptr.size, file_size);
- if (bile->map_ptr.size % BILE_OBJECT_SIZE != 0)
- panic("bile_open: map pointer size is not a multiple of object "
- "size (%lu): %lu", BILE_OBJECT_SIZE, bile->map_ptr.size);
+retry_map_check:
+ if (bile->map_ptr.pos + bile->map_ptr.size > file_size) {
+ if (old_map_tried)
+ panic("bile_open: map points to %lu + %lu, but file is only %lu",
+ bile->map_ptr.pos, bile->map_ptr.size, file_size);
+ goto load_old_map;
+ }
+ if (bile->map_ptr.size % BILE_OBJECT_SIZE != 0) {
+ if (old_map_tried)
+ panic("bile_open: map pointer size is not a multiple of object "
+ "size (%lu): %lu", BILE_OBJECT_SIZE, bile->map_ptr.size);
+ goto load_old_map;
+ }
if (bile->map_ptr.size) {
/* read and verify map object header map_ptr points to */
_bile_error = SetFPos(bile->frefnum, fsFromStart,
bile->map_ptr.pos);
- if (_bile_error)
- goto open_bail;
+ if (_bile_error) {
+ if (old_map_tried)
+ goto open_bail;
+ goto load_old_map;
+ }
size = sizeof(struct bile_object);
_bile_error = FSRead(bile->frefnum, &size, &map_obj);
- if (_bile_error)
- goto open_bail;
+ if (_bile_error) {
+ if (old_map_tried)
+ goto open_bail;
+ goto load_old_map;
+ }
- if (map_obj.pos != bile->map_ptr.pos)
- panic("bile_open: map pointer points to %lu but object there "
- "has position %lu", bile->map_ptr.pos, map_obj.pos);
- if (map_obj.size != bile->map_ptr.size)
- panic("bile_open: map is supposed to have size %lu but object "
- "pointed to has size %lu", bile->map_ptr.size, map_obj.size);
-
+ if (map_obj.pos != bile->map_ptr.pos) {
+ if (old_map_tried)
+ panic("bile_open: map pointer points to %lu but object "
+ "there has position %lu", bile->map_ptr.pos, map_obj.pos);
+ goto load_old_map;
+ }
+ if (map_obj.size != bile->map_ptr.size) {
+ if (old_map_tried)
+ panic("bile_open: map is supposed to have size %lu but "
+ "object pointed to has size %lu", bile->map_ptr.size,
+ map_obj.size);
+ goto load_old_map;
+ }
+
/* read entire map */
size = map_obj.size;
bile->map = xmalloczero(size);
_bile_error = FSRead(bile->frefnum, &size, bile->map);
- if (_bile_error)
- goto open_bail;
+ if (_bile_error) {
+ if (old_map_tried)
+ goto open_bail;
+ goto load_old_map;
+ }
bile->nobjects = map_obj.size / BILE_OBJECT_SIZE;
}
@@ -183,6 +229,14 @@ open_bail:
if (bile != NULL)
free(bile);
return NULL;
+
+load_old_map:
+ if (bile->old_map_ptr.pos == 0)
+ goto open_bail;
+ _bile_error = 0;
+ old_map_tried = 1;
+ bile->map_ptr = bile->old_map_ptr;
+ goto retry_map_check;
}
void
@@ -460,8 +514,8 @@ bile_write(struct bile *bile, const OSType type, const
new_obj = bile_alloc(bile, type, id, len);
- bile_xwriteat(bile, new_obj->pos, new_obj, BILE_OBJECT_SIZE);
- if (bile->last_error)
+ wrote = bile_xwriteat(bile, new_obj->pos, new_obj, BILE_OBJECT_SIZE);
+ if (wrote != BILE_OBJECT_SIZE || bile->last_error)
return 0;
wrote = bile_xwriteat(bile, new_obj->pos + BILE_OBJECT_SIZE, data, len);
if (wrote != len || bile->last_error)
@@ -479,14 +533,14 @@ bile_write(struct bile *bile, const OSType type, const
void
-bile_fsck(struct bile *bile)
+bile_verify(struct bile *bile)
{
struct bile_object o;
size_t n;
char data;
if (bile == NULL)
- panic("bile_fsck: bogus bile");
+ panic("bile_verify: bogus bile");
_bile_error = bile->last_error = 0;
@@ -631,6 +685,9 @@ bile_write_map(struct bile *bile)
free(bile->map);
bile->nobjects = new_nobjects;
bile->map = new_map;
+ bile->old_map_ptr.pos = bile->map_ptr.pos;
+ bile->old_map_ptr.size = bile->map_ptr.size;
+ bile->old_map_ptr.id = bile->map_ptr.id;
bile->map_ptr.pos = new_map_obj->pos;
bile->map_ptr.size = new_map_obj->size;
bile->map_ptr.id = new_map_obj->id;
@@ -640,8 +697,13 @@ bile_write_map(struct bile *bile)
sizeof(bile->map_ptr));
if (bile->last_error)
return -1;
+ bile_xwriteat(bile, BILE_MAGIC_LEN + sizeof(bile->map_ptr),
+ &bile->old_map_ptr, sizeof(bile->old_map_ptr));
+ if (bile->last_error)
+ return -1;
- PBFlushFile(&pb, false);
+ if ((ret = PBFlushFile(&pb, false)) != noErr)
+ panic("PBFlushFIle failed: %d", ret);
return 0;
}
--- bile.h Mon Jan 10 21:07:52 2022
+++ bile.h Wed Jan 19 15:19:18 2022
@@ -28,6 +28,12 @@
* [ pointer size - long ]
* [ pointer type (_BL>) - long ]
* [ pointer id - long ]
+ * [ previous map pointer object ]
+ * [ pointer position - long ]
+ * [ pointer size - long ]
+ * [ pointer type (_BL>) - long ]
+ * [ pointer id - long ]
+ * [ padding for future use ]
* [ object[0] start (map points to this as its position) ]
* [ object[0] position - long ]
* [ object[0] size - long ]
@@ -42,7 +48,7 @@
* [ map id - long ]
* [ map contents ]
*/
-#define BILE_MAGIC "BILE1"
+#define BILE_MAGIC "BILE2"
#define BILE_MAGIC_LEN 5
#define BILE_TYPE_MAP '_BLM'
#define BILE_TYPE_MAPPTR '_BL>'
@@ -54,11 +60,21 @@ struct bile_object {
OSType type;
unsigned long id;
};
-#define BILE_OBJECT_SIZE (sizeof(struct bile_object))
-#define BILE_HEADER_LEN (BILE_MAGIC_LEN + BILE_OBJECT_SIZE)
+#define BILE_OBJECT_SIZE (sizeof(struct bile_object))
+#define BILE_HEADER_LEN 256
+#ifndef BILE1_MAGIC
+#define BILE1_MAGIC "BILE1"
+#endif
+#ifndef BILE1_MAGIC_LEN
+#define BILE1_MAGIC_LEN 5
+#endif
+
+#define BILE_ERR_NEED_UPGRADE_1 -4000
+
struct bile {
struct bile_object map_ptr;
+ struct bile_object old_map_ptr;
short vrefnum, frefnum, last_error;
Str255 filename;
size_t file_size;
@@ -94,6 +110,6 @@ size_t bile_read_alloc(struct bile *bile,
size_t bile_write(struct bile *bile, OSType type,
const unsigned long id, const void *data,
const size_t len);
-void bile_fsck(struct bile *bile);
+void bile_verify(struct bile *bile);
#endif
--- repo.c Tue Jan 11 20:55:19 2022
+++ repo.c Wed Jan 19 17:27:55 2022
@@ -55,12 +55,16 @@ repo_open(AppFile *file)
bile = bile_open(reply.fName, reply.vRefNum);
if (bile == NULL) {
- warn("Opening repo %s failed: %d", PtoCstr(reply.fName),
- bile_error(NULL));
+ if (bile_error(NULL) == BILE_ERR_NEED_UPGRADE_1)
+ warn("File %s is a version 1 repo and must be upgraded",
+ PtoCstr(reply.fName));
+ else
+ warn("Opening repo %s failed: %d", PtoCstr(reply.fName),
+ bile_error(NULL));
return NULL;
}
- bile_fsck(bile);
+ bile_verify(bile);
return repo_init(bile, 0);
}
@@ -1034,7 +1038,7 @@ repo_migrate(struct repo *repo, short is_new)
if (bile_write(repo->bile, REPO_VERS_RTYPE, 1, &ver, 1) != 1)
panic("Failed writing new version: %d", bile_error(repo->bile));
- bile_fsck(repo->bile);
+ bile_verify(repo->bile);
progress("Copying templates...");
@@ -1071,7 +1075,7 @@ repo_migrate(struct repo *repo, short is_new)
}
progress("Doing a full check of the new repo...");
- bile_fsck(repo->bile);
+ bile_verify(repo->bile);
progress(NULL);