diff --git a/demo/iso_grow.c b/demo/iso_grow.c index 4b0a07e..157966e 100644 --- a/demo/iso_grow.c +++ b/demo/iso_grow.c @@ -109,26 +109,28 @@ int main(int argc, char **argv) } iso_read_opts_free(ropts); + iso_tree_set_replace_mode(image, ISO_REPLACE_IF_NEWER); + /* add new dir */ result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]); if (result < 0) { printf ("Error adding directory %d\n", result); return 1; } - + /* generate a multisession image with new contents */ result = iso_write_opts_new(&opts, 1); if (result < 0) { printf("Cant create write opts, error %d\n", result); return 1; } - + /* round up to 32kb aligment = 16 block */ ms_block = ((features->size + 15) / 16 ) * 16; iso_write_opts_set_ms_block(opts, ms_block); iso_write_opts_set_appendable(opts, 1); iso_write_opts_set_overwrite_buf(opts, buf); - + free(features); result = iso_image_create_burn_source(image, opts, &burn_src); diff --git a/src/libisofs.h b/src/libisofs.h index aea05c4..404e45d 100644 --- a/src/libisofs.h +++ b/src/libisofs.h @@ -85,10 +85,22 @@ enum iso_replace_mode { /** * Always replace the old node with the new. */ - ISO_REPLACE_ALWAYS + ISO_REPLACE_ALWAYS, + /** + * Replace with the new node if it is the same file type + */ + ISO_REPLACE_IF_SAME_TYPE, + /** + * Replace with the new node if it is the same file type and its ctime + * is newer than the old one. + */ + ISO_REPLACE_IF_SAME_TYPE_AND_NEWER, + /** + * Replace with the new node if its ctime is newer than the old one. + */ + ISO_REPLACE_IF_NEWER /* * TODO #00006 define more values - * -to replace only if both are the same kind of file * -if both are dirs, add contents (and what to do with conflicts?) */ }; diff --git a/src/node.c b/src/node.c index 0ef070e..04846db 100644 --- a/src/node.c +++ b/src/node.c @@ -704,20 +704,42 @@ int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos, { if (*pos != NULL && !strcmp((*pos)->name, node->name)) { /* a node with same name already exists */ - if (replace == ISO_REPLACE_NEVER) { + switch(replace) { + case ISO_REPLACE_NEVER: return ISO_NODE_NAME_NOT_UNIQUE; - } else if (replace == ISO_REPLACE_ALWAYS) { - node->next = (*pos)->next; - (*pos)->parent = NULL; - (*pos)->next = NULL; - iso_node_unref(*pos); - *pos = node; - node->parent = dir; - return dir->nchildren; - } else { + case ISO_REPLACE_IF_NEWER: + if ((*pos)->mtime >= node->mtime) { + /* old file is newer */ + return ISO_NODE_NAME_NOT_UNIQUE; + } + break; + case ISO_REPLACE_IF_SAME_TYPE_AND_NEWER: + if ((*pos)->mtime >= node->mtime) { + /* old file is newer */ + return ISO_NODE_NAME_NOT_UNIQUE; + } + /* fall down */ + case ISO_REPLACE_IF_SAME_TYPE: + if ((node->mode & S_IFMT) != ((*pos)->mode & S_IFMT)) { + /* different file types */ + return ISO_NODE_NAME_NOT_UNIQUE; + } + break; + case ISO_REPLACE_ALWAYS: + break; + default: /* CAN'T HAPPEN */ return ISO_ASSERT_FAILURE; } + + /* if we are reach here we have to replace */ + node->next = (*pos)->next; + (*pos)->parent = NULL; + (*pos)->next = NULL; + iso_node_unref(*pos); + *pos = node; + node->parent = dir; + return dir->nchildren; } node->next = *pos; diff --git a/src/tree.c b/src/tree.c index 25565e8..4c9e161 100644 --- a/src/tree.c +++ b/src/tree.c @@ -555,12 +555,24 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir) ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret, "Error when adding file %s", path); goto dir_rec_continue; - } else { - iso_msg_debug(image->id, "Adding file %s", path); } /* ok, node has correctly created, we need to add it */ - iso_dir_insert(parent, new, pos, replace); + ret = iso_dir_insert(parent, new, pos, replace); + if (ret < 0) { + iso_node_unref(new); + if (ret != ISO_NODE_NAME_NOT_UNIQUE) { + /* error */ + goto dir_rec_continue; + } else { + /* file ignored because a file with same node already exists */ + iso_msg_debug(image->id, "Skipping file %s. A node with same " + "file already exists", path); + ret = 0; + } + } else { + iso_msg_debug(image->id, "Added file %s", path); + } /* finally, if the node is a directory we need to recurse */ if (new->type == LIBISO_DIR && S_ISDIR(info.st_mode)) {