static imgtoolerr_t os9_diskimage_readfile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *destf) { imgtoolerr_t err; imgtool_image *img = imgtool_partition_image(partition); const os9_diskinfo *disk_info; struct os9_fileinfo file_info; UINT8 buffer[256]; int i, j; UINT32 file_size; UINT32 used_size; disk_info = os9_get_diskinfo(img); err = os9_lookup_path(img, filename, CREATE_NONE, &file_info, NULL, NULL, NULL); if (err) return err; if (file_info.directory) return IMGTOOLERR_FILENOTFOUND; file_size = file_info.file_size; for (i = 0; file_info.sector_map[i].count > 0; i++) { for (j = 0; j < file_info.sector_map[i].count; j++) { used_size = MIN(file_size, disk_info->sector_size); err = os9_read_lsn(img, file_info.sector_map[i].lsn + j, 0, buffer, used_size); if (err) return err; stream_write(destf, buffer, used_size); file_size -= used_size; } } return IMGTOOLERR_SUCCESS; }
static imgtoolerr_t os9_diskimage_createdir(imgtool_partition *partition, const char *path) { imgtoolerr_t err; imgtool_image *image = imgtool_partition_image(partition); struct os9_fileinfo file_info; UINT8 dir_data[64]; UINT32 parent_lsn; err = os9_lookup_path(image, path, CREATE_DIR, &file_info, &parent_lsn, NULL, NULL); if (err) goto done; err = os9_set_file_size(image, &file_info, 64); if (err) goto done; /* create intial directories */ memset(dir_data, 0, sizeof(dir_data)); place_string(dir_data, 0, 32, ".."); place_integer_be(dir_data, 29, 3, parent_lsn); place_string(dir_data, 32, 32, "."); place_integer_be(dir_data, 61, 3, file_info.lsn); err = os9_write_lsn(image, file_info.sector_map[0].lsn, 0, dir_data, sizeof(dir_data)); if (err) goto done; done: return err; }
static imgtoolerr_t os9_diskimage_writefile(imgtool_partition *partition, const char *path, const char *fork, imgtool_stream *sourcef, option_resolution *opts) { imgtoolerr_t err; imgtool_image *image = imgtool_partition_image(partition); struct os9_fileinfo file_info; size_t write_size; void *buf = NULL; int i = -1; UINT32 lsn = 0; UINT32 count = 0; UINT32 sz; const os9_diskinfo *disk_info; disk_info = os9_get_diskinfo(image); buf = malloc(disk_info->sector_size); if (!buf) { err = IMGTOOLERR_OUTOFMEMORY; goto done; } err = os9_lookup_path(image, path, CREATE_FILE, &file_info, NULL, NULL, NULL); if (err) goto done; sz = (UINT32) stream_size(sourcef); err = os9_set_file_size(image, &file_info, sz); if (err) goto done; while(sz > 0) { write_size = (size_t) MIN(sz, (UINT64) disk_info->sector_size); stream_read(sourcef, buf, write_size); while(count == 0) { i++; lsn = file_info.sector_map[i].lsn; count = file_info.sector_map[i].count; } err = os9_write_lsn(image, lsn, 0, buf, write_size); if (err) goto done; lsn++; count--; sz -= write_size; } done: if (buf) free(buf); return err; }
static imgtoolerr_t os9_diskimage_beginenum(imgtool_directory *enumeration, const char *path) { imgtoolerr_t err = IMGTOOLERR_SUCCESS; struct os9_direnum *os9enum; imgtool_image *image; image = imgtool_directory_image(enumeration); os9enum = os9_get_dirinfo(enumeration); err = os9_lookup_path(image, path, CREATE_NONE, &os9enum->dir_info, NULL, NULL, NULL); if (err) goto done; /* this had better be a directory */ if (!os9enum->dir_info.directory) { err = IMGTOOLERR_CORRUPTIMAGE; goto done; } done: return err; }
static imgtoolerr_t os9_diskimage_delete(imgtool_partition *partition, const char *path, unsigned int delete_directory) { imgtoolerr_t err; imgtool_image *image = imgtool_partition_image(partition); //const os9_diskinfo *disk_info; struct os9_fileinfo file_info; UINT32 dirent_lsn, dirent_index; UINT32 entry_lsn, entry_index; UINT32 i, j, lsn; UINT8 b; //disk_info = os9_get_diskinfo(image); err = os9_lookup_path(image, path, CREATE_NONE, &file_info, NULL, &dirent_lsn, &dirent_index); if (err) return err; if (file_info.directory != delete_directory) return IMGTOOLERR_FILENOTFOUND; /* make sure that if we are deleting a directory, it is empty */ if (delete_directory) { for (i = 64; i < file_info.file_size; i += 32) { entry_index = i; entry_lsn = os9_lookup_lsn(image, &file_info, &entry_index); err = os9_read_lsn(image, entry_lsn, entry_index, &b, 1); if (err) return err; /* this had better be a deleted file, if not we can't delete */ if (b != 0) return IMGTOOLERR_DIRNOTEMPTY; } } /* zero out the file entry */ b = '\0'; err = os9_write_lsn(image, dirent_lsn, dirent_index, &b, 1); if (err) return err; /* get the link count */ err = os9_read_lsn(image, file_info.lsn, 8, &b, 1); if (err) return err; if (b > 0) b--; if (b > 0) { /* link count is greater than zero */ err = os9_write_lsn(image, file_info.lsn, 8, &b, 1); if (err) return err; } else { /* no more links; outright delete the file */ err = os9_deallocate_lsn(image, file_info.lsn); if (err) return err; for (i = 0; (i < ARRAY_LENGTH(file_info.sector_map)) && file_info.sector_map[i].count; i++) { lsn = file_info.sector_map[i].lsn; for (j = 0; j < file_info.sector_map[i].count; j++) { err = os9_deallocate_lsn(image, lsn + j); if (err) return err; } } } return IMGTOOLERR_SUCCESS; }