diff --git a/demo/iso_cat.c b/demo/iso_cat.c index cfe7bc8..912cfb4 100644 --- a/demo/iso_cat.c +++ b/demo/iso_cat.c @@ -11,12 +11,9 @@ #include #include "libisofs.h" -#include "fsource.h" -#include "fs_image.h" -#include "messages.h" /* - * Little test program to test filesystem implementations. + * Little test program that extracts a file form a given ISO image. * Outputs file contents to stdout! */ @@ -27,11 +24,11 @@ int main(int argc, char **argv) IsoFileSource *file; struct stat info; IsoDataSource *src; - struct libiso_msgs *messenger; struct iso_read_opts opts = { 0, /* block */ 0, /* norock */ 0, /* nojoliet */ + 0, /* noiso1999 */ 0, /* preferjoliet */ 0, /* uid; */ 0, /* gid; */ @@ -44,23 +41,21 @@ int main(int argc, char **argv) return 1; } - res = libiso_msgs_new(&messenger, 0); - if (res <= 0) { - printf ("Can't create messenger\n"); + res = iso_init(); + if (res < 0) { + fprintf(stderr, "Can't init libisofs\n"); return 1; } - libiso_msgs_set_severities(messenger, LIBISO_MSGS_SEV_NEVER, - LIBISO_MSGS_SEV_ALL, "", 0); res = iso_data_source_new_from_file(argv[1], &src); if (res < 0) { - printf ("Error creating data source\n"); + fprintf(stderr, "Error creating data source\n"); return 1; } - res = iso_image_filesystem_new(src, &opts, messenger, &fs); + res = iso_image_filesystem_new(src, &opts, 1, &fs); if (res < 0) { - printf ("Error creating filesystem\n"); + fprintf(stderr, "Error creating filesystem\n"); return 1; } @@ -99,6 +94,6 @@ int main(int argc, char **argv) iso_file_source_unref(file); iso_filesystem_unref(fs); iso_data_source_unref(src); - libiso_msgs_destroy(&messenger, 0); + iso_finish(); return 0; } diff --git a/demo/iso_read.c b/demo/iso_read.c index 3a61cc8..d42e55f 100644 --- a/demo/iso_read.c +++ b/demo/iso_read.c @@ -11,7 +11,6 @@ #include #include "libisofs.h" -#include "fs_image.h" static void print_permissions(mode_t mode) diff --git a/src/fs_image.h b/src/fs_image.h index 1f69cea..c037c7c 100644 --- a/src/fs_image.h +++ b/src/fs_image.h @@ -12,70 +12,4 @@ #include "libisofs.h" #include "fsource.h" -/** - * 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 libiso_msgs; -typedef IsoFilesystem IsoImageFilesystem; - -int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts, - int msgid, IsoImageFilesystem **fs); - -/** - * Get the volset identifier for an existent image. The returned string belong - * to the IsoImageFilesystem and shouldn't be free() nor modified. - */ -const char *iso_image_fs_get_volset_id(IsoImageFilesystem *fs); - -/** - * Get the volume identifier for an existent image. The returned string belong - * to the IsoImageFilesystem and shouldn't be free() nor modified. - */ -const char *iso_image_fs_get_volume_id(IsoImageFilesystem *fs); - -/** - * Get the publisher identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - */ -const char *iso_image_fs_get_publisher_id(IsoImageFilesystem *fs); - -/** - * Get the data preparer identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - */ -const char *iso_image_fs_get_data_preparer_id(IsoImageFilesystem *fs); - -/** - * Get the system identifier for an existent image. The returned string belong - * to the IsoImageFilesystem and shouldn't be free() nor modified. - */ -const char *iso_image_fs_get_system_id(IsoImageFilesystem *fs); - -/** - * Get the application identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - */ -const char *iso_image_fs_get_application_id(IsoImageFilesystem *fs); - -/** - * Get the copyright file identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - */ -const char *iso_image_fs_get_copyright_file_id(IsoImageFilesystem *fs); - -/** - * Get the abstract file identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - */ -const char *iso_image_fs_get_abstract_file_id(IsoImageFilesystem *fs); - -/** - * Get the biblio file identifier for an existent image. The returned string - * belong to the IsoImageFilesystem and shouldn't be free() nor modified. - */ -const char *iso_image_fs_get_biblio_file_id(IsoImageFilesystem *fs); - #endif /*LIBISO_FS_IMAGE_H_*/ diff --git a/src/fsource.h b/src/fsource.h index af54377..44dda9a 100644 --- a/src/fsource.h +++ b/src/fsource.h @@ -10,506 +10,17 @@ #define LIBISO_FSOURCE_H_ /* - * Definitions for the file sources. + * Definitions for the file sources. Most functions/structures related with + * this were moved to libisofs.h. */ -/* - * Some functions here will be moved to libisofs.h when we expose Sources. - */ - -#include +#include "libisofs.h" #define ISO_LOCAL_FS_ID 1 #define ISO_IMAGE_FS_ID 2 #define ISO_ELTORITO_FS_ID 3 #define ISO_MEM_FS_ID 4 -typedef struct Iso_File_Source IsoFileSource; -typedef struct Iso_Filesystem IsoFilesystem; -typedef struct IsoFileSource_Iface IsoFileSourceIface; - -/** - * See IsoFilesystem->get_id() for info about this. - */ -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 -{ - /** - * Type of filesystem. - * "file" -> local filesystem - * "iso " -> iso image filesystem - */ - char type[4]; - - /** - * Get the root of a filesystem. - * - * @return - * 1 on success, < 0 on error - */ - int (*get_root)(IsoFilesystem *fs, IsoFileSource **root); - - /** - * Retrieve a file from its absolute path inside the filesystem. - * - * @return - * 1 success, < 0 error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_MEM_ERROR - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ - int (*get_by_path)(IsoFilesystem *fs, const char *path, - IsoFileSource **file); - - /** - * Get filesystem identifier. - * - * If the filesystem is able to generate correct values of the st_dev - * and st_ino fields for the struct stat of each file, this should - * return an unique number, greater than 0. - * - * To get a identifier for your filesystem implementation you should - * use iso_fs_global_id, incrementing it by one each time. - * - * Otherwise, if you can't ensure values in the struct stat are valid, - * this should return 0. - */ - 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); - - /* internal usage, do never access them directly */ - unsigned int refcount; - void *data; -}; - -struct IsoFileSource_Iface -{ - - /** - * Get the path, relative to the filesystem this file source - * belongs to. - * - * @return - * the path of the FileSource inside the filesystem, it should be - * freed when no more needed. - */ - char* (*get_path)(IsoFileSource *src); - - /** - * Get the name of the file, with the dir component of the path. - * - * @return - * the name of the file, it should be freed when no more needed. - */ - char* (*get_name)(IsoFileSource *src); - - /** - * Get information about the file. - * @return - * 1 success, < 0 error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_MEM_ERROR - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ - int (*lstat)(IsoFileSource *src, struct stat *info); - - /** - * Get information about the file. If the file is a symlink, the info - * returned refers to the destination. - * - * @return - * 1 success, < 0 error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_MEM_ERROR - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ - int (*stat)(IsoFileSource *src, struct stat *info); - - /** - * Check if the process has access to read file contents. Note that this - * is not necessarily related with (l)stat functions. For example, in a - * filesystem implementation to deal with an ISO image, if the user has - * read access to the image it will be able to read all files inside it, - * despite of the particular permission of each file in the RR tree, that - * are what the above functions return. - * - * @return - * 1 if process has read access, < 0 on error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_MEM_ERROR - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ - int (*access)(IsoFileSource *src); - - /** - * Opens the source. - * @return 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ALREADY_OPENNED - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_MEM_ERROR - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ - int (*open)(IsoFileSource *src); - - /** - * Close a previuously openned file - * @return 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENNED - */ - int (*close)(IsoFileSource *src); - - /** - * Attempts to read up to count bytes from the given source into - * the buffer starting at buf. - * - * The file src must be open() before calling this, and close() when no - * more needed. Not valid for dirs. On symlinks it reads the destination - * file. - * - * @return - * number of bytes read, 0 if EOF, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENNED - * ISO_WRONG_ARG_VALUE -> if count == 0 - * ISO_FILE_IS_DIR - * ISO_MEM_ERROR - * ISO_INTERRUPTED - */ - int (*read)(IsoFileSource *src, void *buf, size_t count); - - /** - * Read a directory. - * - * Each call to this function will return a new children, until we reach - * the end of file (i.e, no more children), in that case it returns 0. - * - * The dir must be open() before calling this, and close() when no more - * needed. Only valid for dirs. - * - * Note that "." and ".." children MUST NOT BE returned. - * - * @param child - * pointer to be filled with the given child. Undefined on error or OEF - * @return - * 1 on success, 0 if EOF (no more children), < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENNED - * ISO_FILE_IS_NOT_DIR - * ISO_MEM_ERROR - */ - int (*readdir)(IsoFileSource *src, IsoFileSource **child); - - /** - * Read the destination of a symlink. You don't need to open the file - * to call this. - * - * @param buf - * allocated buffer of at least bufsiz bytes. - * The dest. will be copied there, and it will be NULL-terminated - * @param bufsiz - * characters to be copied. Destination link will be truncated if - * it is larger than given size. This include the \0 character. - * @return - * 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_WRONG_ARG_VALUE -> if bufsiz <= 0 - * ISO_FILE_IS_NOT_SYMLINK - * ISO_MEM_ERROR - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * - */ - int (*readlink)(IsoFileSource *src, char *buf, size_t bufsiz); - - /** - * Get the filesystem for this source. No extra ref is added, so you - * musn't unref the IsoFilesystem. - * - * @return - * The filesystem, NULL on error - */ - IsoFilesystem* (*get_filesystem)(IsoFileSource *src); - - /** - * Free implementation specific data. Should never be called by user. - * Use iso_file_source_unref() instead. - */ - void (*free)(IsoFileSource *src); - - /* - * TODO #00004 Add a get_mime_type() function. - * This can be useful for GUI apps, to choose the icon of the file - */ -}; - -struct Iso_File_Source -{ - const IsoFileSourceIface *class; - int refcount; - void *data; -}; - -void iso_file_source_ref(IsoFileSource *src); -void iso_file_source_unref(IsoFileSource *src); - -/* - * this are just helpers to invoque methods in class - */ - -/** - * Get the path, relative to the filesystem this file source - * belongs to. - * - * @return - * the path of the FileSource inside the filesystem, it should be - * freed when no more needed. - */ -char* iso_file_source_get_path(IsoFileSource *src); - -/** - * Get the name of the file, with the dir component of the path. - * - * @return - * the name of the file, it should be freed when no more needed. - */ -char* iso_file_source_get_name(IsoFileSource *src); - -/** - * Get information about the file. - * @return - * 1 success, < 0 error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_MEM_ERROR - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ -int iso_file_source_lstat(IsoFileSource *src, struct stat *info); - -/** - * Check if the process has access to read file contents. Note that this - * is not necessarily related with (l)stat functions. For example, in a - * filesystem implementation to deal with an ISO image, if the user has - * read access to the image it will be able to read all files inside it, - * despite of the particular permission of each file in the RR tree, that - * are what the above functions return. - * - * @return - * 1 if process has read access, < 0 on error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_MEM_ERROR - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ -int iso_file_source_access(IsoFileSource *src); - -/** - * Get information about the file. If the file is a symlink, the info - * returned refers to the destination. - * - * @return - * 1 success, < 0 error - * Error codes: - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_MEM_ERROR - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ -int iso_file_source_stat(IsoFileSource *src, struct stat *info); - -/** - * Opens the source. - * @return 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ALREADY_OPENNED - * ISO_FILE_ACCESS_DENIED - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * ISO_MEM_ERROR - * ISO_FILE_ERROR - * ISO_NULL_POINTER - */ -int iso_file_source_open(IsoFileSource *src); - -/** - * Close a previuously openned file - * @return 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENNED - */ -int iso_file_source_close(IsoFileSource *src); - -/** - * Attempts to read up to count bytes from the given source into - * the buffer starting at buf. - * - * The file src must be open() before calling this, and close() when no - * more needed. Not valid for dirs. On symlinks it reads the destination - * file. - * - * @return - * number of bytes read, 0 if EOF, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENNED - * ISO_WRONG_ARG_VALUE -> if count == 0 - * ISO_FILE_IS_DIR - * ISO_MEM_ERROR - * ISO_INTERRUPTED - */ -int iso_file_source_read(IsoFileSource *src, void *buf, size_t count); - -/** - * Read a directory. - * - * Each call to this function will return a new children, until we reach - * the end of file (i.e, no more children), in that case it returns 0. - * - * The dir must be open() before calling this, and close() when no more - * needed. Only valid for dirs. - * - * Note that "." and ".." children MUST NOT BE returned. - * - * @param child - * pointer to be filled with the given child. Undefined on error or OEF - * @return - * 1 on success, 0 if EOF (no more children), < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_FILE_NOT_OPENNED - * ISO_FILE_IS_NOT_DIR - * ISO_MEM_ERROR - */ -int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child); - -/** - * Read the destination of a symlink. You don't need to open the file - * to call this. - * - * @param buf - * allocated buffer of at least bufsiz bytes. - * The dest. will be copied there, and it will be NULL-terminated - * @param bufsiz - * characters to be copied. Destination link will be truncated if - * it is larger than given size. This include the \0 character. - * @return - * 1 on success, < 0 on error - * Error codes: - * ISO_FILE_ERROR - * ISO_NULL_POINTER - * ISO_WRONG_ARG_VALUE -> if bufsiz <= 0 - * ISO_FILE_IS_NOT_SYMLINK - * ISO_MEM_ERROR - * ISO_FILE_BAD_PATH - * ISO_FILE_DOESNT_EXIST - * - */ -int iso_file_source_readlink(IsoFileSource *src, char *buf, size_t bufsiz); - -/** - * Get the filesystem for this source. No extra ref is added, so you - * musn't unref the IsoFilesystem. - * - * @return - * The filesystem, NULL on error - */ -IsoFilesystem* iso_file_source_get_filesystem(IsoFileSource *src); - -/** - * Take a ref to the given IsoFilesystem - */ -void iso_filesystem_ref(IsoFilesystem *fs); - -/** - * Drop your ref to the given IsoFilesystem, evetually freeing associated - * resources. - */ -void iso_filesystem_unref(IsoFilesystem *fs); - /** * Create a new IsoFilesystem to deal with local filesystem. * diff --git a/src/libisofs.h b/src/libisofs.h index 2580279..e90f0d4 100644 --- a/src/libisofs.h +++ b/src/libisofs.h @@ -401,6 +401,317 @@ struct iso_read_image_features uint32_t size; }; +typedef struct iso_file_source IsoFileSource; +typedef struct iso_filesystem IsoFilesystem; +typedef struct IsoFileSource_Iface IsoFileSourceIface; + +/** + * 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... + */ +typedef IsoFilesystem IsoImageFilesystem; + +/** + * See IsoFilesystem->get_id() for info about this. + */ +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 +{ + /** + * Type of filesystem. + * "file" -> local filesystem + * "iso " -> iso image filesystem + */ + char type[4]; + + /** + * Get the root of a filesystem. + * + * @return + * 1 on success, < 0 on error + */ + int (*get_root)(IsoFilesystem *fs, IsoFileSource **root); + + /** + * Retrieve a file from its absolute path inside the filesystem. + * + * @return + * 1 success, < 0 error + * Error codes: + * ISO_FILE_ACCESS_DENIED + * ISO_FILE_BAD_PATH + * ISO_FILE_DOESNT_EXIST + * ISO_MEM_ERROR + * ISO_FILE_ERROR + * ISO_NULL_POINTER + */ + int (*get_by_path)(IsoFilesystem *fs, const char *path, + IsoFileSource **file); + + /** + * Get filesystem identifier. + * + * If the filesystem is able to generate correct values of the st_dev + * and st_ino fields for the struct stat of each file, this should + * return an unique number, greater than 0. + * + * To get a identifier for your filesystem implementation you should + * use iso_fs_global_id, incrementing it by one each time. + * + * Otherwise, if you can't ensure values in the struct stat are valid, + * this should return 0. + */ + 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); + + /* internal usage, do never access them directly */ + unsigned int refcount; + void *data; +}; + +/** + * Interface definition for an IsoFileSource. Defines the POSIX-like function + * to access files and abstract underlying source. + */ +struct IsoFileSource_Iface +{ + /** + * Get the path, relative to the filesystem this file source belongs to. + * + * @return + * the path of the FileSource inside the filesystem, it should be + * freed when no more needed. + */ + char* (*get_path)(IsoFileSource *src); + + /** + * Get the name of the file, with the dir component of the path. + * + * @return + * the name of the file, it should be freed when no more needed. + */ + char* (*get_name)(IsoFileSource *src); + + /** + * Get information about the file. It is equivalent to lstat(2). + * + * @return + * 1 success, < 0 error + * Error codes: + * ISO_FILE_ACCESS_DENIED + * ISO_FILE_BAD_PATH + * ISO_FILE_DOESNT_EXIST + * ISO_MEM_ERROR + * ISO_FILE_ERROR + * ISO_NULL_POINTER + */ + int (*lstat)(IsoFileSource *src, struct stat *info); + + /** + * Get information about the file. If the file is a symlink, the info + * returned refers to the destination. It is equivalent to stat(2). + * + * @return + * 1 success, < 0 error + * Error codes: + * ISO_FILE_ACCESS_DENIED + * ISO_FILE_BAD_PATH + * ISO_FILE_DOESNT_EXIST + * ISO_MEM_ERROR + * ISO_FILE_ERROR + * ISO_NULL_POINTER + */ + int (*stat)(IsoFileSource *src, struct stat *info); + + /** + * Check if the process has access to read file contents. Note that this + * is not necessarily related with (l)stat functions. For example, in a + * filesystem implementation to deal with an ISO image, if the user has + * read access to the image it will be able to read all files inside it, + * despite of the particular permission of each file in the RR tree, that + * are what the above functions return. + * + * @return + * 1 if process has read access, < 0 on error + * Error codes: + * ISO_FILE_ACCESS_DENIED + * ISO_FILE_BAD_PATH + * ISO_FILE_DOESNT_EXIST + * ISO_MEM_ERROR + * ISO_FILE_ERROR + * ISO_NULL_POINTER + */ + int (*access)(IsoFileSource *src); + + /** + * Opens the source. + * @return 1 on success, < 0 on error + * Error codes: + * ISO_FILE_ALREADY_OPENNED + * ISO_FILE_ACCESS_DENIED + * ISO_FILE_BAD_PATH + * ISO_FILE_DOESNT_EXIST + * ISO_MEM_ERROR + * ISO_FILE_ERROR + * ISO_NULL_POINTER + */ + int (*open)(IsoFileSource *src); + + /** + * Close a previuously openned file + * @return 1 on success, < 0 on error + * Error codes: + * ISO_FILE_ERROR + * ISO_NULL_POINTER + * ISO_FILE_NOT_OPENNED + */ + int (*close)(IsoFileSource *src); + + /** + * Attempts to read up to count bytes from the given source into + * the buffer starting at buf. + * + * The file src must be open() before calling this, and close() when no + * more needed. Not valid for dirs. On symlinks it reads the destination + * file. + * + * @return + * number of bytes read, 0 if EOF, < 0 on error + * Error codes: + * ISO_FILE_ERROR + * ISO_NULL_POINTER + * ISO_FILE_NOT_OPENNED + * ISO_WRONG_ARG_VALUE -> if count == 0 + * ISO_FILE_IS_DIR + * ISO_MEM_ERROR + * ISO_INTERRUPTED + */ + int (*read)(IsoFileSource *src, void *buf, size_t count); + + /** + * Read a directory. + * + * Each call to this function will return a new children, until we reach + * the end of file (i.e, no more children), in that case it returns 0. + * + * The dir must be open() before calling this, and close() when no more + * needed. Only valid for dirs. + * + * Note that "." and ".." children MUST NOT BE returned. + * + * @param child + * pointer to be filled with the given child. Undefined on error or OEF + * @return + * 1 on success, 0 if EOF (no more children), < 0 on error + * Error codes: + * ISO_FILE_ERROR + * ISO_NULL_POINTER + * ISO_FILE_NOT_OPENNED + * ISO_FILE_IS_NOT_DIR + * ISO_MEM_ERROR + */ + int (*readdir)(IsoFileSource *src, IsoFileSource **child); + + /** + * Read the destination of a symlink. You don't need to open the file + * to call this. + * + * @param buf + * allocated buffer of at least bufsiz bytes. + * The dest. will be copied there, and it will be NULL-terminated + * @param bufsiz + * characters to be copied. Destination link will be truncated if + * it is larger than given size. This include the \0 character. + * @return + * 1 on success, < 0 on error + * Error codes: + * ISO_FILE_ERROR + * ISO_NULL_POINTER + * ISO_WRONG_ARG_VALUE -> if bufsiz <= 0 + * ISO_FILE_IS_NOT_SYMLINK + * ISO_MEM_ERROR + * ISO_FILE_BAD_PATH + * ISO_FILE_DOESNT_EXIST + * + */ + int (*readlink)(IsoFileSource *src, char *buf, size_t bufsiz); + + /** + * Get the filesystem for this source. No extra ref is added, so you + * musn't unref the IsoFilesystem. + * + * @return + * The filesystem, NULL on error + */ + IsoFilesystem* (*get_filesystem)(IsoFileSource *src); + + /** + * Free implementation specific data. Should never be called by user. + * Use iso_file_source_unref() instead. + */ + void (*free)(IsoFileSource *src); + + /* + * TODO #00004 Add a get_mime_type() function. + * This can be useful for GUI apps, to choose the icon of the file + */ +}; + +/** + * An IsoFile Source is a POSIX abstraction of a file. + */ +struct iso_file_source +{ + const IsoFileSourceIface *class; + int refcount; + void *data; +}; + /** * Initialize libisofs. You must call this before any usage of the library. * @return 1 on success, < 0 on error @@ -1388,4 +1699,272 @@ int iso_obtain_msgs(char *minimum_severity, int *error_code, */ void *iso_get_messenger(); +/** + * Take a ref to the given IsoFileSource. + */ +void iso_file_source_ref(IsoFileSource *src); + +/** + * Drop your ref to the given IsoFileSource, eventually freeing the associated + * system resources. + */ +void iso_file_source_unref(IsoFileSource *src); + +/* + * this are just helpers to invoque methods in class + */ + +/** + * Get the path, relative to the filesystem this file source + * belongs to. + * + * @return + * the path of the FileSource inside the filesystem, it should be + * freed when no more needed. + */ +char* iso_file_source_get_path(IsoFileSource *src); + +/** + * Get the name of the file, with the dir component of the path. + * + * @return + * the name of the file, it should be freed when no more needed. + */ +char* iso_file_source_get_name(IsoFileSource *src); + +/** + * Get information about the file. + * @return + * 1 success, < 0 error + * Error codes: + * ISO_FILE_ACCESS_DENIED + * ISO_FILE_BAD_PATH + * ISO_FILE_DOESNT_EXIST + * ISO_MEM_ERROR + * ISO_FILE_ERROR + * ISO_NULL_POINTER + */ +int iso_file_source_lstat(IsoFileSource *src, struct stat *info); + +/** + * Check if the process has access to read file contents. Note that this + * is not necessarily related with (l)stat functions. For example, in a + * filesystem implementation to deal with an ISO image, if the user has + * read access to the image it will be able to read all files inside it, + * despite of the particular permission of each file in the RR tree, that + * are what the above functions return. + * + * @return + * 1 if process has read access, < 0 on error + * Error codes: + * ISO_FILE_ACCESS_DENIED + * ISO_FILE_BAD_PATH + * ISO_FILE_DOESNT_EXIST + * ISO_MEM_ERROR + * ISO_FILE_ERROR + * ISO_NULL_POINTER + */ +int iso_file_source_access(IsoFileSource *src); + +/** + * Get information about the file. If the file is a symlink, the info + * returned refers to the destination. + * + * @return + * 1 success, < 0 error + * Error codes: + * ISO_FILE_ACCESS_DENIED + * ISO_FILE_BAD_PATH + * ISO_FILE_DOESNT_EXIST + * ISO_MEM_ERROR + * ISO_FILE_ERROR + * ISO_NULL_POINTER + */ +int iso_file_source_stat(IsoFileSource *src, struct stat *info); + +/** + * Opens the source. + * @return 1 on success, < 0 on error + * Error codes: + * ISO_FILE_ALREADY_OPENNED + * ISO_FILE_ACCESS_DENIED + * ISO_FILE_BAD_PATH + * ISO_FILE_DOESNT_EXIST + * ISO_MEM_ERROR + * ISO_FILE_ERROR + * ISO_NULL_POINTER + */ +int iso_file_source_open(IsoFileSource *src); + +/** + * Close a previuously openned file + * @return 1 on success, < 0 on error + * Error codes: + * ISO_FILE_ERROR + * ISO_NULL_POINTER + * ISO_FILE_NOT_OPENNED + */ +int iso_file_source_close(IsoFileSource *src); + +/** + * Attempts to read up to count bytes from the given source into + * the buffer starting at buf. + * + * The file src must be open() before calling this, and close() when no + * more needed. Not valid for dirs. On symlinks it reads the destination + * file. + * + * @return + * number of bytes read, 0 if EOF, < 0 on error + * Error codes: + * ISO_FILE_ERROR + * ISO_NULL_POINTER + * ISO_FILE_NOT_OPENNED + * ISO_WRONG_ARG_VALUE -> if count == 0 + * ISO_FILE_IS_DIR + * ISO_MEM_ERROR + * ISO_INTERRUPTED + */ +int iso_file_source_read(IsoFileSource *src, void *buf, size_t count); + +/** + * Read a directory. + * + * Each call to this function will return a new children, until we reach + * the end of file (i.e, no more children), in that case it returns 0. + * + * The dir must be open() before calling this, and close() when no more + * needed. Only valid for dirs. + * + * Note that "." and ".." children MUST NOT BE returned. + * + * @param child + * pointer to be filled with the given child. Undefined on error or OEF + * @return + * 1 on success, 0 if EOF (no more children), < 0 on error + * Error codes: + * ISO_FILE_ERROR + * ISO_NULL_POINTER + * ISO_FILE_NOT_OPENNED + * ISO_FILE_IS_NOT_DIR + * ISO_MEM_ERROR + */ +int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child); + +/** + * Read the destination of a symlink. You don't need to open the file + * to call this. + * + * @param buf + * allocated buffer of at least bufsiz bytes. + * The dest. will be copied there, and it will be NULL-terminated + * @param bufsiz + * characters to be copied. Destination link will be truncated if + * it is larger than given size. This include the \0 character. + * @return + * 1 on success, < 0 on error + * Error codes: + * ISO_FILE_ERROR + * ISO_NULL_POINTER + * ISO_WRONG_ARG_VALUE -> if bufsiz <= 0 + * ISO_FILE_IS_NOT_SYMLINK + * ISO_MEM_ERROR + * ISO_FILE_BAD_PATH + * ISO_FILE_DOESNT_EXIST + * + */ +int iso_file_source_readlink(IsoFileSource *src, char *buf, size_t bufsiz); + +/** + * Get the filesystem for this source. No extra ref is added, so you + * musn't unref the IsoFilesystem. + * + * @return + * The filesystem, NULL on error + */ +IsoFilesystem* iso_file_source_get_filesystem(IsoFileSource *src); + +/** + * Take a ref to the given IsoFilesystem + */ +void iso_filesystem_ref(IsoFilesystem *fs); + +/** + * Drop your ref to the given IsoFilesystem, evetually freeing associated + * resources. + */ +void iso_filesystem_unref(IsoFilesystem *fs); + +/** + * Create a new IsoFilesystem to access a existent ISO image. + * + * @param src + * Data source to access data. + * @param opts + * Image read options + * @param msgid + * TODO + * @param fs + * Will be filled with a pointer to the filesystem that can be used + * to access image contents. + * @param + * 1 on success, < 0 on error + */ +int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts, + int msgid, IsoImageFilesystem **fs); + +/** + * Get the volset identifier for an existent image. The returned string belong + * to the IsoImageFilesystem and shouldn't be free() nor modified. + */ +const char *iso_image_fs_get_volset_id(IsoImageFilesystem *fs); + +/** + * Get the volume identifier for an existent image. The returned string belong + * to the IsoImageFilesystem and shouldn't be free() nor modified. + */ +const char *iso_image_fs_get_volume_id(IsoImageFilesystem *fs); + +/** + * Get the publisher identifier for an existent image. The returned string + * belong to the IsoImageFilesystem and shouldn't be free() nor modified. + */ +const char *iso_image_fs_get_publisher_id(IsoImageFilesystem *fs); + +/** + * Get the data preparer identifier for an existent image. The returned string + * belong to the IsoImageFilesystem and shouldn't be free() nor modified. + */ +const char *iso_image_fs_get_data_preparer_id(IsoImageFilesystem *fs); + +/** + * Get the system identifier for an existent image. The returned string belong + * to the IsoImageFilesystem and shouldn't be free() nor modified. + */ +const char *iso_image_fs_get_system_id(IsoImageFilesystem *fs); + +/** + * Get the application identifier for an existent image. The returned string + * belong to the IsoImageFilesystem and shouldn't be free() nor modified. + */ +const char *iso_image_fs_get_application_id(IsoImageFilesystem *fs); + +/** + * Get the copyright file identifier for an existent image. The returned string + * belong to the IsoImageFilesystem and shouldn't be free() nor modified. + */ +const char *iso_image_fs_get_copyright_file_id(IsoImageFilesystem *fs); + +/** + * Get the abstract file identifier for an existent image. The returned string + * belong to the IsoImageFilesystem and shouldn't be free() nor modified. + */ +const char *iso_image_fs_get_abstract_file_id(IsoImageFilesystem *fs); + +/** + * Get the biblio file identifier for an existent image. The returned string + * belong to the IsoImageFilesystem and shouldn't be free() nor modified. + */ +const char *iso_image_fs_get_biblio_file_id(IsoImageFilesystem *fs); + #endif /*LIBISO_LIBISOFS_H_*/