diff --git a/doc/susp_aaip_isofs_names.txt b/doc/susp_aaip_isofs_names.txt index 59217a6..ecff23a 100644 --- a/doc/susp_aaip_isofs_names.txt +++ b/doc/susp_aaip_isofs_names.txt @@ -22,6 +22,8 @@ Purpose: END is also the block address of the start of the checksum recording area in the image. See also isofs.cx . + This attribute shall eventually be attached to the root directory entry + and be global for the whole image. Format of Value: START_LEN | START_BYTES | END_LEN | END_BYTES | @@ -150,7 +152,7 @@ Registered: ------------------------------------------------------------------------------- This text is under -Copyright (c) 2009 - 2010 Thomas Schmitt +Copyright (c) 2009 - 2011 Thomas Schmitt It shall only be modified in sync with libisofs and other software which makes use of AAIP. Please mail change requests to mailing list or to the copyright holder in private. diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 3f8a45a..52844c8 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -4649,11 +4649,18 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent, * @param new_parent * The existing directory node where to insert the cloned node. * @param new_name - * The name for the cloned node. It must not yet exist in new_parent. + * The name for the cloned node. It must not yet exist in new_parent, + * unless it is a directory and node is a directory and flag bit0 is set. * @param new_node - * Will return a reference to the newly created clone. + * Will return a pointer (without reference) to the newly created clone. * @param flag - * Unused yet. Submit 0. + * Bitfield for control purposes. Submit any undefined bits as 0. + * bit0= Merge directories rather than returning ISO_NODE_NAME_NOT_UNIQUE. + * This will not allow to overwrite any existing node. + * Attributes of existing directories will not be overwritten. + * @return + * <0 means error, 1 = new node created, + * 2 = if flag bit0 is set: new_node is a directory which already existed. * * @since 1.0.2 */ diff --git a/libisofs/messages.c b/libisofs/messages.c index 7326246..13a9442 100644 --- a/libisofs/messages.c +++ b/libisofs/messages.c @@ -97,6 +97,8 @@ int iso_node_xinfo_make_clonable(iso_node_xinfo_func proc, { struct iso_xinfo_cloner_assoc *assoc; + /* >>> look for existing assoc of proc */; + assoc = calloc(1, sizeof(struct iso_xinfo_cloner_assoc)); if (assoc == NULL) return ISO_OUT_OF_MEM; diff --git a/libisofs/tree.c b/libisofs/tree.c index 4035439..46b66d3 100644 --- a/libisofs/tree.c +++ b/libisofs/tree.c @@ -1015,6 +1015,9 @@ int iso_tree_copy_node_attr(IsoNode *old_node, IsoNode *new_node, int flag) return ISO_SUCCESS; } +/* + @param flag bit0= merge directory with *new_node +*/ static int iso_tree_clone_dir(IsoDir *old_dir, IsoDir *new_parent, char *new_name, IsoNode **new_node, @@ -1025,12 +1028,15 @@ int iso_tree_clone_dir(IsoDir *old_dir, IsoDirIter *iter = NULL; int ret; - *new_node = NULL; - - ret = iso_tree_add_new_dir(new_parent, new_name, &new_dir); - if (ret < 0) - return ret; - /* Avoid early grafting of directory to allow cloning of old_dir to a + if (flag & 1) { + new_dir = (IsoDir *) *new_node; + } else { + *new_node = NULL; + ret = iso_tree_add_new_dir(new_parent, new_name, &new_dir); + if (ret < 0) + return ret; + } + /* Avoid traversal of target directory to allow cloning of old_dir to a subordinate of old_dir. */ iso_node_take((IsoNode *) new_dir); @@ -1043,24 +1049,30 @@ int iso_tree_clone_dir(IsoDir *old_dir, if (ret == 0) break; ret = iso_tree_clone(sub_node, new_dir, sub_node->name, &new_sub_node, - 0); + flag & 1); if (ret < 0) goto ex; } - /* Now really graft in the new tree */ + /* Now graft in the new tree resp. graft back the merged tree */ ret = iso_dir_add_node(new_parent, (IsoNode *) new_dir, 0); if (ret < 0) goto ex; - *new_node = (IsoNode *) new_dir; + if (!(flag & 1)) + *new_node = (IsoNode *) new_dir; ret = ISO_SUCCESS; ex:; if (iter != NULL) iso_dir_iter_free(iter); if (ret < 0 && new_dir != NULL) { - iso_node_remove_tree((IsoNode *) new_dir, NULL); - *new_node = NULL; + if (flag & 1) { + /* graft back the merged tree (eventually with half copy) */ + iso_dir_add_node(new_parent, (IsoNode *) new_dir, 0); + } else { + iso_node_remove_tree((IsoNode *) new_dir, NULL); + *new_node = NULL; + } } return ret; } @@ -1141,12 +1153,18 @@ int iso_tree_clone(IsoNode *node, { int ret = ISO_SUCCESS; - if (iso_dir_get_node(new_parent, new_name, NULL) == 1) - return ISO_NODE_NAME_NOT_UNIQUE; + if (iso_dir_get_node(new_parent, new_name, new_node) == 1) { + if (! (node->type == LIBISO_DIR && (*new_node)->type == LIBISO_DIR && + (flag & 1))) { + *new_node = NULL; + return ISO_NODE_NAME_NOT_UNIQUE; + } + } else + flag &= ~1; if (node->type == LIBISO_DIR) { ret = iso_tree_clone_dir((IsoDir *) node, new_parent, new_name, - new_node, 0); + new_node, flag & 1); } else if (node->type == LIBISO_FILE) { ret = iso_tree_clone_file((IsoFile *) node, new_parent, new_name, new_node, 0); @@ -1161,6 +1179,8 @@ int iso_tree_clone(IsoNode *node, } if (ret < 0) return ret; + if (flag & 1) + return 2; /* merged two directories, *new_node is not new */ ret = iso_tree_copy_node_attr(node, *new_node, 0); return ret; }