From 9be5b241e2c70500f8b87ab037c39fdee8ac4ec2 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Fri, 18 Jun 2010 22:03:41 +0200 Subject: [PATCH] New API call iso_node_set_hidden(), new IsoHideNodeFlag value LIBISO_HIDE_BUT_WRITE. --- libisofs/ecma119_tree.c | 161 +++++++++++++++++++++++++++------------- libisofs/eltorito.c | 12 +++ libisofs/libisofs.h | 56 +++++++++++--- 3 files changed, 166 insertions(+), 63 deletions(-) diff --git a/libisofs/ecma119_tree.c b/libisofs/ecma119_tree.c index 7d49c60..eb1fb17 100644 --- a/libisofs/ecma119_tree.c +++ b/libisofs/ecma119_tree.c @@ -150,15 +150,11 @@ int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node) return ISO_SUCCESS; } -/** - * Create a new ECMA-119 node representing a regular file from a iso file - * node. - */ + static -int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node) +int create_file_src(Ecma119Image *img, IsoFile *iso, IsoFileSrc **src) { int ret; - IsoFileSrc *src; off_t size; size = iso_stream_get_size(iso->stream); @@ -170,8 +166,25 @@ int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node) free(ipath); return ret; } + ret = iso_file_src_create(img, iso, src); + if (ret < 0) { + return ret; + } + return 0; +} - ret = iso_file_src_create(img, iso, &src); + +/** + * Create a new ECMA-119 node representing a regular file from a iso file + * node. + */ +static +int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node) +{ + int ret; + IsoFileSrc *src; + + ret = create_file_src(img, iso, &src); if (ret < 0) { return ret; } @@ -271,58 +284,76 @@ void ecma119_node_free(Ecma119Node *node) } /** - * + * @param flag + * bit0= iso is in a hidden directory. Thus hide it. * @return * 1 success, 0 node ignored, < 0 error * */ static int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree, - int depth, int pathlen) + int depth, int pathlen, int flag) { - int ret; - Ecma119Node *node; + int ret, hidden; + Ecma119Node *node = NULL; int max_path; - char *iso_name= NULL; + char *iso_name= NULL, *ipath = NULL; + IsoFileSrc *src = NULL; if (image == NULL || iso == NULL || tree == NULL) { return ISO_NULL_POINTER; } + *tree = NULL; + hidden = flag & 1; if (iso->hidden & LIBISO_HIDE_ON_RR) { - /* file will be ignored */ - return 0; + hidden = 1; + if (!((iso->hidden & LIBISO_HIDE_BUT_WRITE) || + iso->type == LIBISO_BOOT)) { + return 0; /* file will be ignored */ + } } - ret = get_iso_name(image, iso, &iso_name); - if (ret < 0) { - return ret; - } - max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0); - if (!image->rockridge) { - if ((iso->type == LIBISO_DIR && depth > 8) && !image->allow_deep_paths) { - char *ipath = iso_tree_get_node_path(iso); - return iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG, 0, - "File \"%s\" can't be added, because directory depth " - "is greater than 8.", ipath); - free(iso_name); - free(ipath); - return ret; - } else if (max_path > 255 && !image->allow_longer_paths) { - char *ipath = iso_tree_get_node_path(iso); - ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG, 0, - "File \"%s\" can't be added, because path length " - "is greater than 255 characters", ipath); - free(iso_name); - free(ipath); - return ret; + + if (!hidden) { + ret = get_iso_name(image, iso, &iso_name); + if (ret < 0) { + iso_name = NULL; /* invalid, do not free */ + goto ex; + } + max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0); + if (!image->rockridge) { + if ((iso->type == LIBISO_DIR && depth > 8) && + !image->allow_deep_paths) { + ipath = iso_tree_get_node_path(iso); + ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG, + 0, "File \"%s\" can't be added, " + "because directory depth " + "is greater than 8.", ipath); + goto ex; + } else if (max_path > 255 && !image->allow_longer_paths) { + ipath = iso_tree_get_node_path(iso); + ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG, + 0, "File \"%s\" can't be added, " + "because path length " + "is greater than 255 characters", ipath); + goto ex; + } } } switch (iso->type) { case LIBISO_FILE: - ret = create_file(image, (IsoFile*)iso, &node); + if (hidden) { + ret = create_file_src(image, (IsoFile *) iso, &src); + } else { + ret = create_file(image, (IsoFile*)iso, &node); + } break; case LIBISO_SYMLINK: + if (hidden) { + ret = 0; /* Hidden means non-existing */ + goto ex; + } if (image->rockridge) { ret = create_symlink(image, (IsoSymlink*)iso, &node); } else { @@ -335,6 +366,10 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree, } break; case LIBISO_SPECIAL: + if (hidden) { + ret = 0; /* Hidden means non-existing */ + goto ex; + } if (image->rockridge) { ret = create_special(image, (IsoSpecial*)iso, &node); } else { @@ -348,7 +383,11 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree, break; case LIBISO_BOOT: if (image->eltorito) { - ret = create_boot_cat(image, (IsoBoot*)iso, &node); + if (hidden) { + ret = el_torito_catalog_file_src_create(image, &src); + } else { + ret = create_boot_cat(image, (IsoBoot*)iso, &node); + } } else { /* log and ignore */ ret = iso_msg_submit(image->image->id, ISO_FILE_IGNORED, 0, @@ -359,21 +398,26 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree, { IsoNode *pos; IsoDir *dir = (IsoDir*)iso; - ret = create_dir(image, dir, &node); - if (ret < 0) { - return ret; + + if (!hidden) { + ret = create_dir(image, dir, &node); + if (ret < 0) { + goto ex; + } } pos = dir->children; while (pos) { int cret; Ecma119Node *child; - cret = create_tree(image, pos, &child, depth + 1, max_path); + cret = create_tree(image, pos, &child, depth + 1, max_path, + !!hidden); if (cret < 0) { /* error */ - ecma119_node_free(node); + if (!hidden) + ecma119_node_free(node); ret = cret; break; - } else if (cret == ISO_SUCCESS) { + } else if (cret == ISO_SUCCESS && !hidden) { /* add child to this node */ int nchildren = node->info.dir->nchildren++; node->info.dir->children[nchildren] = child; @@ -385,15 +429,30 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree, break; default: /* should never happen */ - return ISO_ASSERT_FAILURE; + ret = ISO_ASSERT_FAILURE; + goto ex; } if (ret <= 0) { - free(iso_name); - return ret; + goto ex; } - node->iso_name = iso_name; - *tree = node; - return ISO_SUCCESS; + if (!hidden) { + node->iso_name = iso_name; + iso_name = NULL; /* now owned by node, do not free */ + *tree = node; + node = NULL; /* now owned by caller, do not free */ + } + ret = ISO_SUCCESS; +ex: + if (iso_name != NULL) + free(iso_name); + if (ipath != NULL) + free(ipath); + if (node != NULL) + ecma119_node_free(node); + if (hidden && ret == ISO_SUCCESS) + ret = 0; + /* The sources of hidden files are now owned by the rb-tree */ + return ret; } /** @@ -985,7 +1044,7 @@ int ecma119_tree_create(Ecma119Image *img) int ret; Ecma119Node *root; - ret = create_tree(img, (IsoNode*)img->image->root, &root, 1, 0); + ret = create_tree(img, (IsoNode*)img->image->root, &root, 1, 0, 0); if (ret <= 0) { if (ret == 0) { /* unexpected error, root ignored!! This can't happen */ diff --git a/libisofs/eltorito.c b/libisofs/eltorito.c index a30621f..5e63eae 100644 --- a/libisofs/eltorito.c +++ b/libisofs/eltorito.c @@ -674,6 +674,18 @@ int iso_image_set_boot_catalog_weight(IsoImage *image, int sort_weight) return 1; } +/* API */ +int iso_image_set_boot_catalog_hidden(IsoImage *image, int hide_attrs) +{ + if (image->bootcat == NULL) + return 0; + if (image->bootcat->node == NULL) + return 0; + iso_node_set_hidden((IsoNode *) image->bootcat->node, hide_attrs); + return 1; +} + + void el_torito_boot_catalog_free(struct el_torito_boot_catalog *cat) { struct el_torito_boot_image *image; diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 033f345..1360592 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -168,7 +168,17 @@ enum IsoHideNodeFlag { /** Hide the node in the Joliet tree, if Joliet extension are enabled */ LIBISO_HIDE_ON_JOLIET = 1 << 1, /** Hide the node in the ISO-9660:1999 tree, if that format is enabled */ - LIBISO_HIDE_ON_1999 = 1 << 2 + LIBISO_HIDE_ON_1999 = 1 << 2, + + /** With IsoNode and IsoBoot: Write data content even if the node is + * not visible in any tree. + * With directory nodes : Write data content of IsoNode and IsoBoot + * in the directory's tree unless they are + * explicitely marked LIBISO_HIDE_ON_RR + * without LIBISO_HIDE_BUT_WRITE. + * @since 0.6.34 + */ + LIBISO_HIDE_BUT_WRITE = 1 << 3 }; /** @@ -2449,6 +2459,26 @@ void iso_image_remove_boot_image(IsoImage *image); */ int iso_image_set_boot_catalog_weight(IsoImage *image, int sort_weight); +/** + * Hides the boot catalog file from directory trees. + * + * For the meaning of hiding files see iso_node_set_hidden(). + * + * + * @param image + * The image to manipulate. + * @param hide_attrs + * Or-combination of values from enum IsoHideNodeFlag to set the trees + * in which the record. + * @return + * 0= no boot catalog attached , 1= ok , <0 = error + * + * @since 0.6.32 + */ +int iso_image_set_boot_catalog_hidden(IsoImage *image, int hide_attrs); + + + /** * Get the boot media type as of parameter "type" of iso_image_set_boot_image() * resp. iso_image_add_boot_image(). @@ -2958,21 +2988,22 @@ void iso_node_set_ctime(IsoNode *node, time_t time); time_t iso_node_get_ctime(const IsoNode *node); /** - * Set if the node will be hidden in RR/ISO tree, Joliet tree or both. + * Set whether the node will be hidden in the directory trees of RR/ISO 9660, + * or of Joliet (if enabled at all), or of ISO-9660:1999 (if enabled at all). * - * If the file is set as hidden in one tree, it wil not be included there, so - * it won't be visible in a OS accessing CD using that tree. For example, - * GNU/Linux systems access to Rock Ridge / ISO9960 tree in order to see - * what is recorded on CD, while MS Windows make use of the Joliet tree. If a - * file is hidden only in Joliet, it wil not be visible in Windows systems, - * while still visible in GNU/Linux. + * A hidden file does not show up by name in the affected directory tree. + * For example, if a file is hidden only in Joliet, it will normally + * not be visible on Windows systems, while being shown on GNU/Linux. * - * If a file is hidden in both trees, it will not be written to image. + * If a file is not shown in any of the enabled trees, then its content will + * not be written to the image, unless LIBISO_HIDE_BUT_WRITE is given (which + * is available only since release 0.6.34). * * @param node * The node that is to be hidden. * @param hide_attrs - * IsoHideNodeFlag's to set the trees in which file will be hidden. + * Or-combination of values from enum IsoHideNodeFlag to set the trees + * in which the node's name shall be hidden. * * @since 0.6.2 */ @@ -3675,8 +3706,9 @@ void iso_tree_set_follow_symlinks(IsoImage *image, int follow); int iso_tree_get_follow_symlinks(IsoImage *image); /** - * Set whether to skip or not hidden files when adding a directory recursibely. - * Default behavior is to not ignore them, i.e., to add hidden files to image. + * Set whether to skip or not disk files with names beginning by '.' + * when adding a directory recursively. + * Default behavior is to not ignore them. * * @since 0.6.2 */