/** * Get the next block header from the savefile */ static errr next_blockheader(ang_file *f, struct blockheader *b) { byte savefile_head[SAVEFILE_HEAD_SIZE]; size_t len; len = file_read(f, (char *)savefile_head, SAVEFILE_HEAD_SIZE); if (len == 0) /* no more blocks */ return 1; if (len != SAVEFILE_HEAD_SIZE || savefile_head[15] != 0) { return -1; } #define RECONSTRUCT_U32B(from) \ ((u32b) savefile_head[from]) | \ ((u32b) savefile_head[from+1] << 8) | \ ((u32b) savefile_head[from+2] << 16) | \ ((u32b) savefile_head[from+3] << 24); my_strcpy(b->name, (char *)&savefile_head, sizeof b->name); b->version = RECONSTRUCT_U32B(16); b->size = RECONSTRUCT_U32B(20); /* Pad to 4 bytes */ if (b->size % 4) b->size += 4 - (b->size % 4); return 0; }
static bool try_load(ang_file *f) { byte savefile_head[SAVEFILE_HEAD_SIZE]; u32b block_version, block_size; char *block_name; while (TRUE) { size_t i; int (*loader)(void) = NULL; /* Load in the next header */ size_t size = file_read(f, (char *)savefile_head, SAVEFILE_HEAD_SIZE); if (!size) break; if (size != SAVEFILE_HEAD_SIZE || savefile_head[15] != 0) { note("Savefile is corrupted -- block header mangled."); return FALSE; } #define RECONSTRUCT_U32B(from) \ ((u32b) savefile_head[from]) | \ ((u32b) savefile_head[from+1] << 8) | \ ((u32b) savefile_head[from+2] << 16) | \ ((u32b) savefile_head[from+3] << 24); block_name = (char *) savefile_head; block_version = RECONSTRUCT_U32B(16); block_size = RECONSTRUCT_U32B(20); /* pad to 4 bytes */ if (block_size % 4) block_size += 4 - (block_size % 4); /* Find the right loader */ for (i = 0; i < N_ELEMENTS(loaders); i++) { if (streq(block_name, loaders[i].name) && block_version == loaders[i].version) { loader = loaders[i].load; } } if (!loader) { /* No loader found */ note("Savefile too old. Try importing it into an older Angband first."); return FALSE; } /* Allocate space for the buffer */ buffer = mem_alloc(block_size); buffer_pos = 0; buffer_check = 0; buffer_size = file_read(f, (char *) buffer, block_size); if (buffer_size != block_size) { note("Savefile is corrupted -- not enough bytes."); mem_free(buffer); return FALSE; } /* Try loading */ if (loader() != 0) { note("Savefile is corrupted."); mem_free(buffer); return FALSE; } mem_free(buffer); } /* Still alive */ if (p_ptr->chp >= 0) { /* Reset cause of death */ my_strcpy(p_ptr->died_from, "(alive and well)", sizeof(p_ptr->died_from)); } return TRUE; }