Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
static imgtoolerr_t os9_lookup_path(imgtool_image *img, const char *path,
	creation_policy_t create, struct os9_fileinfo *file_info,
	UINT32 *parent_lsn, UINT32 *dirent_lsn, UINT32 *dirent_index)
{
	imgtoolerr_t err = IMGTOOLERR_SUCCESS;
	struct os9_fileinfo dir_info;
	UINT32 index, current_lsn, dir_size;
	UINT32 entry_index = 0;
	UINT32 free_entry_index = 0xffffffff;
	UINT32 entry_lsn = 0;
	UINT32 allocated_lsn = 0;
	UINT8 entry[32];
	UINT8 block[64];
	char *filename;
	const os9_diskinfo *disk_info;

	disk_info = os9_get_diskinfo(img);
	current_lsn = disk_info->root_dir_lsn;

	if (parent_lsn)
		*parent_lsn = 0;

	/* we have to transverse each path element */
	while(*path)
	{
		if (parent_lsn)
			*parent_lsn = current_lsn;

		/* decode the directory header of this directory */
		err = os9_decode_file_header(img, current_lsn, &dir_info);
		if (err)
			goto done;
		dir_size = dir_info.file_size;

		/* sanity check directory */
		if (!dir_info.directory)
		{
			err = (current_lsn == disk_info->root_dir_lsn) ? IMGTOOLERR_CORRUPTIMAGE : IMGTOOLERR_INVALIDPATH;
			goto done;
		}

		/* walk the directory */
		for (index = 0; index < dir_size; index += 32)
		{
			entry_index = index;
			entry_lsn = os9_lookup_lsn(img, &dir_info, &entry_index);

			err = os9_read_lsn(img, entry_lsn, entry_index, entry, sizeof(entry));
			if (err)
				goto done;

			/* remember first free entry found */
			if( free_entry_index == 0xffffffff )
			{
				if( entry[0] == 0 )
					free_entry_index = index;
			}

			if (os9_interpret_dirent(entry, &filename, &current_lsn, NULL))
			{
				if (!strcmp(path, filename))
					break;
			}

		}

		/* at the end of the file? */
		if (index >= dir_size)
		{
			/* if we're not creating, or we are creating but we have not fully
			 * transversed the directory, error out */
			if (!create || path[strlen(path) + 1])
			{
				err = IMGTOOLERR_PATHNOTFOUND;
				goto done;
			}

			/* allocate a new LSN */
			err = os9_allocate_lsn(img, &allocated_lsn);
			if (err)
				goto done;

			/* write the file */
			memset(block, 0, sizeof(block));
			place_integer_be(block, 0, 1, 0x1B | ((create == CREATE_DIR) ? 0x80 : 0x00));
			err = os9_write_lsn(img, allocated_lsn, 0, block, sizeof(block));
			if (err)
				goto done;

			if( free_entry_index == 0xffffffff )
			{
				/* expand the directory to hold the new entry */
				err = os9_set_file_size(img, &dir_info, dir_size + 32);
				if (err)
					goto done;
			}
			else
				/* use first unused entry in directory */
				dir_size = free_entry_index;

			/* now prepare the directory entry */
			memset(entry, 0, sizeof(entry));
			place_string(entry, 0, 28, path);
			place_integer_be(entry, 29, 3, allocated_lsn);

			/* now write the directory entry */
			entry_index = dir_size;
			entry_lsn = os9_lookup_lsn(img, &dir_info, &entry_index);
			err = os9_write_lsn(img, entry_lsn, entry_index, entry, 32);
			if (err)
				goto done;

			/* directory entry append complete; no need to hold this lsn */
			current_lsn = allocated_lsn;
			allocated_lsn = 0;
		}
		path += strlen(path) + 1;
	}

	if (file_info)
	{
		err = os9_decode_file_header(img, current_lsn, file_info);
		if (err)
			goto done;
	}

	if (dirent_lsn)
		*dirent_lsn = entry_lsn;
	if (dirent_index)
		*dirent_index = entry_index;

done:
	if (allocated_lsn != 0)
		os9_deallocate_lsn(img, allocated_lsn);
	return err;
}