From 0c1ea8cc7ea3d969d18ae15c5d0f36e03a38f025 Mon Sep 17 00:00:00 2001 From: Vreixo Formoso Date: Sat, 19 Jan 2008 16:56:46 +0100 Subject: [PATCH] Add open() and close() operations to IsoFilesystem. --- demo/iso_read.c | 2 +- src/fs_image.c | 71 ++++++++++++++++++++++++------------------------- src/fs_image.h | 32 ++++------------------ src/fs_local.c | 16 +++++++++++ src/fsource.h | 47 ++++++++++++++++++++++++++++++-- 5 files changed, 102 insertions(+), 66 deletions(-) diff --git a/demo/iso_read.c b/demo/iso_read.c index 401ea0b..3a61cc8 100644 --- a/demo/iso_read.c +++ b/demo/iso_read.c @@ -157,7 +157,7 @@ int main(int argc, char **argv) printf("\nDIRECTORY TREE\n"); printf("==============\n"); - result = fs->fs.get_root((IsoFilesystem*)fs, &root); + result = fs->get_root(fs, &root); if (result < 0) { printf ("Can't get root %d\n", result); return 1; diff --git a/src/fs_image.c b/src/fs_image.c index 9a66f7d..6f9c1f6 100644 --- a/src/fs_image.c +++ b/src/fs_image.c @@ -291,7 +291,7 @@ int read_dir(ImageFileSourceData *data) } fs = data->fs; - fsdata = fs->fs.data; + fsdata = fs->data; block = data->block; ret = fsdata->src->read_block(fsdata->src, block, buffer); @@ -529,7 +529,7 @@ int ifs_read(IsoFileSource *src, void *buf, size_t count) /* EOF */ break; } - fsdata = data->fs->fs.data; + fsdata = data->fs->data; block = data->block + (data->data.offset / BLOCK_SIZE); ret = fsdata->src->read_block(fsdata->src, block, data->data.content); @@ -655,7 +655,7 @@ IsoFilesystem* ifs_get_filesystem(IsoFileSource *src) } data = src->data; - return (IsoFilesystem*) data->fs; + return data->fs; } static @@ -674,7 +674,7 @@ void ifs_free(IsoFileSource *src) if (S_ISLNK(data->info.st_mode)) { free(data->data.content); } - iso_filesystem_unref((IsoFilesystem*)data->fs); + iso_filesystem_unref(data->fs); if (data->parent != NULL) { iso_file_source_unref(data->parent); } @@ -759,11 +759,11 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, uint32_t relocated_dir = 0; - if (fs == NULL || fs->fs.data == NULL || record == NULL || src == NULL) { + if (fs == NULL || fs->data == NULL || record == NULL || src == NULL) { return ISO_NULL_POINTER; } - fsdata = (_ImageFsData*)fs->fs.data; + fsdata = (_ImageFsData*)fs->data; memset(&atts, 0, sizeof(struct stat)); @@ -1134,7 +1134,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent, /* fill data */ ifsdata->fs = fs; - iso_filesystem_ref((IsoFilesystem*)fs); + iso_filesystem_ref(fs); if (parent != NULL) { ifsdata->parent = parent; iso_file_source_ref(parent); @@ -1317,11 +1317,11 @@ int ifs_fs_open(IsoImageFilesystem *fs) { _ImageFsData *data; - if (fs == NULL || fs->fs.data == NULL) { + if (fs == NULL || fs->data == NULL) { return ISO_NULL_POINTER; } - data = (_ImageFsData*)fs->fs.data; + data = (_ImageFsData*)fs->data; if (data->open_count == 0) { /* we need to actually open the data source */ @@ -1339,11 +1339,11 @@ int ifs_fs_close(IsoImageFilesystem *fs) { _ImageFsData *data; - if (fs == NULL || fs->fs.data == NULL) { + if (fs == NULL || fs->data == NULL) { return ISO_NULL_POINTER; } - data = (_ImageFsData*)fs->fs.data; + data = (_ImageFsData*)fs->data; if (--data->open_count == 0) { /* we need to actually close the data source */ @@ -1663,15 +1663,14 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts, goto fs_cleanup; } + ifs->data = data; + ifs->refcount = 1; + ifs->get_root = ifs_get_root; + ifs->get_by_path = ifs_get_by_path; + ifs->get_id = ifs_get_id; ifs->open = ifs_fs_open; ifs->close = ifs_fs_close; - - ifs->fs.data = data; - ifs->fs.refcount = 1; - ifs->fs.get_root = ifs_get_root; - ifs->fs.get_by_path = ifs_get_by_path; - ifs->fs.free = ifs_fs_free; - ifs->fs.get_id = ifs_get_id; + ifs->free = ifs_fs_free; /* read Volume Descriptors and ensure it is a valid image */ @@ -1829,7 +1828,7 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts, return ISO_SUCCESS; fs_cleanup: ; - ifs_fs_free((IsoFilesystem*)ifs); + ifs_fs_free(ifs); free(ifs); return ret; } @@ -1863,7 +1862,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image, case S_IFREG: { /* source is a regular file */ - _ImageFsData *fsdata = data->fs->fs.data; + _ImageFsData *fsdata = data->fs->data; if (fsdata->eltorito && data->block == fsdata->catblock) { @@ -2050,11 +2049,11 @@ int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoFileSource **src) IsoFileSource *ifsrc = NULL; ImageFileSourceData *ifsdata = NULL; - if (fs == NULL || fs->fs.data == NULL || src == NULL) { + if (fs == NULL || fs->data == NULL || src == NULL) { return ISO_NULL_POINTER; } - fsdata = (_ImageFsData*)fs->fs.data; + fsdata = (_ImageFsData*)fs->data; memset(&atts, 0, sizeof(struct stat)); atts.st_mode = S_IFREG; @@ -2088,7 +2087,7 @@ int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoFileSource **src) /* fill data */ ifsdata->fs = fs; - iso_filesystem_ref((IsoFilesystem*)fs); + iso_filesystem_ref(fs); ifsdata->parent = NULL; ifsdata->info = atts; ifsdata->name = NULL; @@ -2129,10 +2128,10 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, if (ret < 0) { return ret; } - data = fs->fs.data; + data = fs->data; /* get root from filesystem */ - ret = fs->fs.get_root((IsoFilesystem*)fs, &newroot); + ret = fs->get_root(fs, &newroot); if (ret < 0) { return ret; } @@ -2151,7 +2150,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, goto import_revert; } - image->fs = (IsoFilesystem*)fs; + image->fs = fs; /* create new root, and set root attributes from source */ ret = iso_node_new_root(&image->root); @@ -2280,62 +2279,62 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, iso_file_source_unref(newroot); fs->close(fs); - iso_filesystem_unref((IsoFilesystem*)fs); + iso_filesystem_unref(fs); return ret; } const char *iso_image_fs_get_volset_id(IsoImageFilesystem *fs) { - _ImageFsData *data = (_ImageFsData*) fs->fs.data; + _ImageFsData *data = (_ImageFsData*) fs->data; return data->volset_id; } const char *iso_image_fs_get_volume_id(IsoImageFilesystem *fs) { - _ImageFsData *data = (_ImageFsData*) fs->fs.data; + _ImageFsData *data = (_ImageFsData*) fs->data; return data->volume_id; } const char *iso_image_fs_get_publisher_id(IsoImageFilesystem *fs) { - _ImageFsData *data = (_ImageFsData*) fs->fs.data; + _ImageFsData *data = (_ImageFsData*) fs->data; return data->publisher_id; } const char *iso_image_fs_get_data_preparer_id(IsoImageFilesystem *fs) { - _ImageFsData *data = (_ImageFsData*) fs->fs.data; + _ImageFsData *data = (_ImageFsData*) fs->data; return data->data_preparer_id; } const char *iso_image_fs_get_system_id(IsoImageFilesystem *fs) { - _ImageFsData *data = (_ImageFsData*) fs->fs.data; + _ImageFsData *data = (_ImageFsData*) fs->data; return data->system_id; } const char *iso_image_fs_get_application_id(IsoImageFilesystem *fs) { - _ImageFsData *data = (_ImageFsData*) fs->fs.data; + _ImageFsData *data = (_ImageFsData*) fs->data; return data->application_id; } const char *iso_image_fs_get_copyright_file_id(IsoImageFilesystem *fs) { - _ImageFsData *data = (_ImageFsData*) fs->fs.data; + _ImageFsData *data = (_ImageFsData*) fs->data; return data->copyright_file_id; } const char *iso_image_fs_get_abstract_file_id(IsoImageFilesystem *fs) { _ImageFsData *data; - data = (_ImageFsData*) fs->fs.data; + data = (_ImageFsData*) fs->data; return data->abstract_file_id; } const char *iso_image_fs_get_biblio_file_id(IsoImageFilesystem *fs) { - _ImageFsData *data = (_ImageFsData*) fs->fs.data; + _ImageFsData *data = (_ImageFsData*) fs->data; return data->biblio_file_id; } diff --git a/src/fs_image.h b/src/fs_image.h index 852230f..88bb0b1 100644 --- a/src/fs_image.h +++ b/src/fs_image.h @@ -12,36 +12,14 @@ #include "libisofs.h" #include "fsource.h" -struct libiso_msgs; -typedef struct Iso_Image_Filesystem IsoImageFilesystem; - /** - * Extends IsoFilesystem interface, to offer a way to access specific - * information of the image, such as several volume attributes, extensions - * being used, El-Torito artifacts... + * IsoFilesystem implementation to deal with ISO images, and to offer a way to + * access specific information of the image, such as several volume attributes, + * extensions being used, El-Torito artifacts... */ -struct Iso_Image_Filesystem -{ - IsoFilesystem fs; - /* - * TODO both open and close have meaning to other filesystems, in fact - * they seem useful for any kind of Filesystems, with the exception of - * the local filesystem. Thus, we should consider adding them to - * IsoFilesystem interface - */ - - /** - * Opens the filesystem for several read operations. Calling this funcion - * is not needed at all, each time that the underlying IsoDataSource need - * to be read, it is openned propertly. However, if you plan to execute - * several operations on the image, it is a good idea to open it - * previously, to prevent several open/close operations. - */ - int (*open)(IsoImageFilesystem *fs); - - int (*close)(IsoImageFilesystem *fs); -}; +struct libiso_msgs; +typedef IsoFilesystem IsoImageFilesystem; int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts, int msgid, IsoImageFilesystem **fs); diff --git a/src/fs_local.c b/src/fs_local.c index 82f30f4..e2e066f 100644 --- a/src/fs_local.c +++ b/src/fs_local.c @@ -592,6 +592,20 @@ unsigned int lfs_get_id(IsoFilesystem *fs) return ISO_LOCAL_FS_ID; } +static +int lfs_fs_open(IsoFilesystem *fs) +{ + /* open() operation is not needed */ + return ISO_SUCCESS; +} + +static +int lfs_fs_close(IsoFilesystem *fs) +{ + /* close() operation is not needed */ + return ISO_SUCCESS; +} + static void lfs_fs_free(IsoFilesystem *fs) { @@ -620,6 +634,8 @@ int iso_local_filesystem_new(IsoFilesystem **fs) lfs->get_root = lfs_get_root; lfs->get_by_path = lfs_get_by_path; lfs->get_id = lfs_get_id; + lfs->open = lfs_fs_open; + lfs->close = lfs_fs_close; lfs->free = lfs_fs_free; } *fs = lfs; diff --git a/src/fsource.h b/src/fsource.h index eca2b0a..eb63fdf 100644 --- a/src/fsource.h +++ b/src/fsource.h @@ -32,10 +32,28 @@ typedef struct Iso_Filesystem IsoFilesystem; */ extern unsigned int iso_fs_global_id; +/** + * An IsoFilesystem is a handler for a source of files, or a "filesystem". + * That is defined as a set of files that are organized in a hierarchical + * structure. + * + * A filesystem allows libisofs to access files from several sources in + * an homogeneous way, thus abstracting the underlying operations needed to + * access and read file contents. Note that this doesn't need to be tied + * to the disc filesystem used in the partition being accessed. For example, + * we have an IsoFilesystem implementation to access any mounted filesystem, + * using standard Linux functions. It is also legal, of course, to implement + * an IsoFilesystem to deal with a specific filesystem over raw partitions. + * That is what we do, for example, to access an ISO Image. + * + * Each file inside an IsoFilesystem is represented as an IsoFileSource object, + * that defines POSIX-like interface for accessing files. + */ struct Iso_Filesystem { /** + * Get the root of a filesystem. * * @return * 1 on success, < 0 on error @@ -43,6 +61,7 @@ struct Iso_Filesystem int (*get_root)(IsoFilesystem *fs, IsoFileSource **root); /** + * Retrieve a file from its absolute path inside the filesystem. * * @return * 1 success, < 0 error @@ -72,10 +91,34 @@ struct Iso_Filesystem */ unsigned int (*get_id)(IsoFilesystem *fs); + /** + * Opens the filesystem for several read operations. Calling this funcion + * is not needed at all, each time that the underlying system resource + * needs to be accessed, it is openned propertly. + * However, if you plan to execute several operations on the filesystem, + * it is a good idea to open it previously, to prevent several open/close + * operations to occur. + * + * @return 1 on success, < 0 on error + */ + int (*open)(IsoFilesystem *fs); + + /** + * Close the filesystem, thus freeing all system resources. You should + * call this function if you have previously open() it. + * Note that you can open()/close() a filesystem several times. + * + * @return 1 on success, < 0 on error + */ + int (*close)(IsoFilesystem *fs); + + /** + * Free implementation specific data. Should never be called by user. + * Use iso_filesystem_unref() instead. + */ void (*free)(IsoFilesystem *fs); - /* TODO each file will take a ref to IsoFilesystem, so maybe a 64bits - * integer is a better choose for this */ + /* internal usage, do never access them directly */ unsigned int refcount; void *data; };