From 7b241176fbb6312f998dd9239663537bf94c08bb Mon Sep 17 00:00:00 2001 From: Vreixo Formoso Date: Sat, 15 Dec 2007 13:13:49 +0100 Subject: [PATCH] Init implementation of IsoFileSrc. Ecma119Image, defined for first time in this commit, is the context for image written. It keeps the low level objects needed during image written. IsoFileSrc is the low level object that takes care about the info needed to write file contents to image. It takes care about reading from Stream in 2K block chunks. To prevent the same file be written twice to image, we keep in Ecma119Image a search tree, indexed by the triple key (fs, device, inode) that uniquelly identifies a source. --- Makefile.am | 5 +- src/ecma119.h | 23 +++++++ src/filesrc.c | 101 ++++++++++++++++++++++++++++ src/filesrc.h | 160 ++++++++++++++++++++++----------------------- src/image_writer.h | 35 ++++++++++ src/stream.c | 11 ++-- 6 files changed, 247 insertions(+), 88 deletions(-) create mode 100644 src/ecma119.h create mode 100644 src/filesrc.c create mode 100644 src/image_writer.h diff --git a/Makefile.am b/Makefile.am index 6b8684c..c17cb9f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -28,7 +28,10 @@ src_libisofs_la_SOURCES = \ src/stream.h \ src/stream.c \ src/util.h \ - src/util.c + src/util.c \ + src/filesrc.h \ + src/filesrc.c \ + src/ecma119.h libinclude_HEADERS = \ src/libisofs.h diff --git a/src/ecma119.h b/src/ecma119.h new file mode 100644 index 0000000..7a97447 --- /dev/null +++ b/src/ecma119.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2007 Vreixo Formoso + * + * This file is part of the libisofs project; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See COPYING file for details. + */ + +#ifndef LIBISO_ECMA119_H_ +#define LIBISO_ECMA119_H_ + +typedef struct ecma119_image Ecma119Image; + +struct ecma119_image { + + unsigned int iso_level:2; + + /* tree of files sources */ + void *file_srcs; + int file_count; +}; + +#endif /*LIBISO_ECMA119_H_*/ diff --git a/src/filesrc.c b/src/filesrc.c new file mode 100644 index 0000000..6219781 --- /dev/null +++ b/src/filesrc.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2007 Vreixo Formoso + * + * This file is part of the libisofs project; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See COPYING file for details. + */ + +#include "filesrc.h" +#include "error.h" +#include "node.h" + +#include +#include + +static +int comp_iso_file_src(const void *n1, const void *n2) +{ + const IsoFileSrc *f1, *f2; + f1 = (const IsoFileSrc *)n1; + f2 = (const IsoFileSrc *)n2; + + if (f1->fs_id < f2->fs_id) { + return -1; + } else if (f1->fs_id > f2->fs_id) { + return 1; + } else { + /* files belong to the same fs */ + if (f1->dev_id > f2->dev_id) { + return -1; + } else if (f1->dev_id < f2->dev_id) { + return 1; + } else { + /* files belong to same device in same fs */ + return f1->ino_id - f2->ino_id; + } + } +} + +int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src) +{ + int res; + IsoStream *stream; + IsoFileSrc *fsrc; + unsigned int fs_id; + dev_t dev_id; + ino_t ino_id; + off_t size; + + if (img == NULL || file == NULL || src == NULL) { + return ISO_NULL_POINTER; + } + + stream = file->stream; + res = stream->get_id(stream, &fs_id, &dev_id, &ino_id); + if (res < 0) { + return res; + } else if (res == 0) { + // TODO this corresponds to Stream that cannot provide a valid id + // Not implemented for now + return ISO_ERROR; + } else { + IsoFileSrc *inserted; + + size = stream->get_size(stream); + if (size == (off_t)-1) { + return ISO_FILE_ERROR; + } + + fsrc = malloc(sizeof(IsoFileSrc)); + if (fsrc == NULL) { + return ISO_MEM_ERROR; + } + + /* fill key and other atts */ + fsrc->fs_id = fs_id; + fsrc->dev_id = dev_id; + fsrc->ino_id = ino_id; + fsrc->prev_img = file->msblock ? 1 : 0; + fsrc->block = file->msblock; + fsrc->size = size; + fsrc->sort_weight = file->sort_weight; + fsrc->stream = file->stream; + + /* insert the filesrc in the tree */ + inserted = tsearch(fsrc, img->file_srcs, comp_iso_file_src); + if (inserted == NULL) { + free(fsrc); + return ISO_MEM_ERROR; + } else if (inserted == fsrc) { + /* the file was inserted */ + img->file_count++; + } else { + /* the file was already on the tree */ + free(fsrc); + } + *src = inserted; + } + return ISO_SUCCESS; +} + diff --git a/src/filesrc.h b/src/filesrc.h index de67a8a..63e541e 100644 --- a/src/filesrc.h +++ b/src/filesrc.h @@ -8,93 +8,87 @@ #ifndef LIBISO_FILESRC_H_ #define LIBISO_FILESRC_H_ -/* - * FIXME definitions here shouldn't be used for now!!! +#include "libisofs.h" +#include "stream.h" +#include "ecma119.h" + +#include + +typedef struct Iso_File_Src IsoFileSrc; + +struct Iso_File_Src { + + /* key */ + unsigned int fs_id; + dev_t dev_id; + ino_t ino_id; + + unsigned int prev_img:1; /**< if the file comes from a previous image */ + off_t size; /**< size of this file */ + uint32_t block; /**< Block where this file will be written on image */ + int sort_weight; + IsoStream *stream; +}; + +/** + * Create a new IsoFileSrc to get data from a specific IsoFile. * + * The IsoFileSrc will be cached in a tree to prevent the same file for + * being written several times to image. If you call again this function + * with a node that refers to the same source file, the previously + * created one will be returned. No new IsoFileSrc is created in that case. + * + * @param img + * The image where this file is to be written + * @param file + * The IsoNode we want to write + * @param src + * Will be filled with a pointer to the IsoFileSrc + * @return + * 1 on success, < 0 on error */ +int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src); +// TODO not implemented +int iso_file_src_open(IsoFileSrc *file); -/* - * Definitions of streams. +// TODO not implemented +int iso_file_src_close(IsoFileSrc *file); + +/** + * TODO define propertly this comment + * TODO not implemented + * + * Read a block (2048 bytes) from the IsoFileSrc. + * + * This function should always read the full 2048 bytes, blocking if + * needed. When it reaches EOF, the buf is filled with 0's, if needed. + * Note that the EOF is not reported in that call, but in the next call. + * I.e., when the EOF is reported you can be sure that the function + * has not written anything to the buffer. If the file size is a multiple + * of block size, i.e N*2048, the read_block reports the EOF just when + * reading the N+1 block. + * + * Note that EOF refers to the original size as reported by get_size. + * If the underlying source size has changed, this function should take + * care of this, truncating the file, or filling the buffer with 0s. I.e. + * this function return 0 (EOF) only when get_size() bytes have been + * readed. + * + * On an I/O error, or a file smaller than the expected size, this + * function returns a [specific error code], and the buffer is filled + * with 0s. Subsequent calls will still return an error code and fill + * buffer with 0's, until EOF (as defined above) is reached, and then + * the function will return 0. + * + * Note that if the current size is larger than expected, you don't get + * any error on reading. + * + * @param buf + * Buffer where data fill be copied, with at least 2048 bytes. + * @return + * 1 sucess, 0 EOF, < 0 error (buf is filled with 0's) */ - -/* - * Some functions here will be moved to libisofs.h when we expose - * Streams. - */ - -//typedef struct Iso_Stream IsoStream; -// -//struct Iso_Stream -//{ -// /** -// * Opens the stream. -// * -// * @return -// * 1 on success, < 0 on error, 2 file is smaller than expect, -// * 3 file is larger than expected (2 and 3 are not errors, they're -// * handled by read_block, see there. Moreover, IsooStream -// * implementations doesn't need to check that) -// */ -// int (*open)(IsoStream *stream); -// -// /** -// * Close the Stream. -// * @return 1 on success, < 0 on error -// */ -// int (*close)(IsoStream *stream); -// -// /** -// * Get the size (in bytes) of the stream. This function must return -// * always the same size, even if the underlying source file has changed. -// */ -// off_t (*get_size)(IsoStream *stream); -// -// /** -// * Read a block (2048 bytes) from the stream. -// * -// * This function should always read the full 2048 bytes, blocking if -// * needed. When it reaches EOF, the buf is filled with 0's, if needed. -// * Note that the EOF is not reported in that call, but in the next call. -// * I.e., when the EOF is reported you can be sure that the function -// * has not written anything to the buffer. If the file size is a multiple -// * of block size, i.e N*2048, the read_block reports the EOF just when -// * reading the N+1 block. -// * -// * Note that EOF refers to the original size as reported by get_size. -// * If the underlying source size has changed, this function should take -// * care of this, truncating the file, or filling the buffer with 0s. I.e. -// * this function return 0 (EOF) only when get_size() bytes have been -// * readed. -// * -// * On an I/O error, or a file smaller than the expected size, this -// * function returns a [specific error code], and the buffer is filled -// * with 0s. Subsequent calls will still return an error code and fill -// * buffer with 0's, until EOF (as defined above) is reached, and then -// * the function will return 0. -// * -// * Note that if the current size is larger than expected, you don't get -// * any error on reading. -// * -// * @param buf -// * Buffer where data fill be copied, with at least 2048 bytes. -// * @return -// * 1 sucess, 0 EOF, < 0 error (buf is filled with 0's) -// */ -// int (*read_block)(IsoStream *stream, void *buf); -// -// /** -// * Whether this Stram can be read several times, with the same results. -// * For example, a regular file is repeatable, you can read it as many -// * times as you want. However, a pipe isn't. -// * -// * This function doesn't take into account if the file has been modified -// * between the two reads. -// */ -// int (*is_repeatable)(IsoStream *stream); -// -// int refcount; -// void *data; -//} +int iso_file_src_read_block(IsoFileSrc *file, void *buf); #endif /*LIBISO_FILESRC_H_*/ diff --git a/src/image_writer.h b/src/image_writer.h new file mode 100644 index 0000000..4e6ee8b --- /dev/null +++ b/src/image_writer.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2007 Vreixo Formoso + * + * This file is part of the libisofs project; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See COPYING file for details. + */ +#ifndef LIBISO_IMAGE_WRITER_H_ +#define LIBISO_IMAGE_WRITER_H_ + +struct Iso_Writer_State +{ + +}; + +struct Iso_Image_Writer +{ + + //init() + + //compute_dir_structure() + + //write_vol_desc + + // + + + //free + + void *data; + Ecma119Image *image; + +}; + +#endif /*LIBISO_IMAGE_WRITER_H_*/ diff --git a/src/stream.c b/src/stream.c index d03278e..61d57ca 100644 --- a/src/stream.c +++ b/src/stream.c @@ -104,14 +104,17 @@ int fsrc_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, } src = (IsoFileSource*)stream->data; + fs = src->get_filesystem(src); + + *fs_id = fs->get_id(fs); + if (fs_id == 0) { + return 0; + } + result = src->stat(src, &info); if (result < 0) { return result; } - - fs = src->get_filesystem(src); - - *fs_id = fs->get_id(fs); *dev_id = info.st_dev; *ino_id = info.st_ino; return ISO_SUCCESS;