AmendHub

Download:

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);