Encapsulate insertion of nodes in node.c. Define replace behavior.
This commit is contained in:
parent
bff5cb9333
commit
f118b0a48d
@ -68,6 +68,27 @@ enum eltorito_boot_media_type {
|
||||
ELTORITO_NO_EMUL
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace mode used when addding a node to a file.
|
||||
* TODO comment
|
||||
*/
|
||||
enum iso_replace_mode {
|
||||
/**
|
||||
* Never replace an existing node, and instead fail with
|
||||
* ISO_NODE_NAME_NOT_UNIQUE.
|
||||
*/
|
||||
ISO_REPLACE_NEVER,
|
||||
/**
|
||||
* Always replace the old node with the new.
|
||||
*/
|
||||
ISO_REPLACE_ALWAYS
|
||||
/*
|
||||
* 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?)
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds the options for the image generation.
|
||||
*/
|
||||
@ -770,11 +791,6 @@ void iso_node_set_hidden(IsoNode *node, int hide_attrs);
|
||||
* @param replace
|
||||
* if the dir already contains a node with the same name, whether to
|
||||
* replace or not the old node with this.
|
||||
* - 0 not replace (will fail with ISO_NODE_NAME_NOT_UNIQUE)
|
||||
* - 1 replace
|
||||
* 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?)
|
||||
* @return
|
||||
* number of nodes in dir if succes, < 0 otherwise
|
||||
* Possible errors:
|
||||
@ -783,7 +799,8 @@ void iso_node_set_hidden(IsoNode *node, int hide_attrs);
|
||||
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
|
||||
* ISO_WRONG_ARG_VALUE, if child == dir, or replace != (0,1)
|
||||
*/
|
||||
int iso_dir_add_node(IsoDir *dir, IsoNode *child, int replace);
|
||||
int iso_dir_add_node(IsoDir *dir, IsoNode *child,
|
||||
enum iso_replace_mode replace);
|
||||
|
||||
/**
|
||||
* Locate a node inside a given dir.
|
||||
@ -1251,7 +1268,7 @@ int iso_image_obtain_msgs(IsoImage *image, char *minimum_severity,
|
||||
|
||||
/**
|
||||
* Return the messenger object handle used by the given image. This handle
|
||||
* may be used by related libraries to replace their own compatible
|
||||
* may be used by related libraries to their own compatible
|
||||
* messenger objects and thus to direct their messages to the libisofs
|
||||
* message queue. See also: libburn, API function burn_set_messenger().
|
||||
*
|
||||
|
94
src/node.c
94
src/node.c
@ -259,10 +259,14 @@ void iso_node_set_hidden(IsoNode *node, int hide_attrs)
|
||||
* to other dir, and that the node name is unique inside the child.
|
||||
* Otherwise this function will return a failure, and the child won't be
|
||||
* inserted.
|
||||
* @param replace
|
||||
* if the dir already contains a node with the same name, whether to
|
||||
* replace or not the old node with this.
|
||||
* @return
|
||||
* number of nodes in dir if succes, < 0 otherwise
|
||||
*/
|
||||
int iso_dir_add_node(IsoDir *dir, IsoNode *child, int replace)
|
||||
int iso_dir_add_node(IsoDir *dir, IsoNode *child,
|
||||
enum iso_replace_mode replace)
|
||||
{
|
||||
IsoNode **pos;
|
||||
|
||||
@ -281,32 +285,8 @@ int iso_dir_add_node(IsoDir *dir, IsoNode *child, int replace)
|
||||
return ISO_NODE_ALREADY_ADDED;
|
||||
}
|
||||
|
||||
pos = &(dir->children);
|
||||
while (*pos != NULL && strcmp((*pos)->name, child->name) < 0) {
|
||||
pos = &((*pos)->next);
|
||||
}
|
||||
if (*pos != NULL && !strcmp((*pos)->name, child->name)) {
|
||||
/* a node with same name already exists */
|
||||
if (replace == 0) {
|
||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||
} else if (replace == 1) {
|
||||
child->next = (*pos)->next;
|
||||
(*pos)->parent = NULL;
|
||||
(*pos)->next = NULL;
|
||||
iso_node_unref(*pos);
|
||||
*pos = child;
|
||||
child->parent = dir;
|
||||
return dir->nchildren;
|
||||
} else {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
child->next = *pos;
|
||||
*pos = child;
|
||||
child->parent = dir;
|
||||
|
||||
return ++dir->nchildren;
|
||||
iso_dir_find(dir, child->name, &pos);
|
||||
return iso_dir_insert(dir, child, pos, replace);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -328,17 +308,14 @@ int iso_dir_add_node(IsoDir *dir, IsoNode *child, int replace)
|
||||
*/
|
||||
int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node)
|
||||
{
|
||||
IsoNode *pos;
|
||||
int ret;
|
||||
IsoNode **pos;
|
||||
if (dir == NULL || name == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
pos = dir->children;
|
||||
while (pos != NULL && strcmp(pos->name, name) < 0) {
|
||||
pos = pos->next;
|
||||
}
|
||||
|
||||
if (pos == NULL || strcmp(pos->name, name)) {
|
||||
ret = iso_dir_exists(dir, name, &pos);
|
||||
if (ret == 0) {
|
||||
if (node) {
|
||||
*node = NULL;
|
||||
}
|
||||
@ -346,7 +323,7 @@ int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node)
|
||||
}
|
||||
|
||||
if (node) {
|
||||
*node = pos;
|
||||
*node = *pos;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -686,6 +663,53 @@ int iso_node_is_valid_link_dest(const char *dest)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iso_dir_find(IsoDir *dir, const char *name, IsoNode ***pos)
|
||||
{
|
||||
*pos = &(dir->children);
|
||||
while (**pos != NULL && strcmp((**pos)->name, name) < 0) {
|
||||
*pos = &((**pos)->next);
|
||||
}
|
||||
}
|
||||
|
||||
int iso_dir_exists(IsoDir *dir, const char *name, IsoNode ***pos)
|
||||
{
|
||||
IsoNode **node;
|
||||
|
||||
iso_dir_find(dir, name, &node);
|
||||
if (pos) {
|
||||
*pos = node;
|
||||
}
|
||||
return (*node != NULL && !strcmp((*node)->name, name)) ? 1 : 0;
|
||||
}
|
||||
|
||||
int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos,
|
||||
enum iso_replace_mode replace)
|
||||
{
|
||||
if (*pos != NULL && !strcmp((*pos)->name, node->name)) {
|
||||
/* a node with same name already exists */
|
||||
if (replace == 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 {
|
||||
/* CAN'T HAPPEN */
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
node->next = *pos;
|
||||
*pos = node;
|
||||
node->parent = dir;
|
||||
|
||||
return ++dir->nchildren;
|
||||
}
|
||||
|
||||
int iso_node_new_root(IsoDir **root)
|
||||
{
|
||||
IsoDir *dir;
|
||||
|
46
src/node.h
46
src/node.h
@ -123,4 +123,50 @@ int iso_node_is_valid_name(const char *name);
|
||||
*/
|
||||
int iso_node_is_valid_link_dest(const char *dest);
|
||||
|
||||
/**
|
||||
* Find the position where to insert a node
|
||||
*
|
||||
* @param dir
|
||||
* A valid dir. It can't be NULL
|
||||
* @param name
|
||||
* The node name to search for. It can't be NULL
|
||||
* @param pos
|
||||
* Will be filled with the position where to insert. It can't be NULL
|
||||
*/
|
||||
void iso_dir_find(IsoDir *dir, const char *name, IsoNode ***pos);
|
||||
|
||||
/**
|
||||
* Check if a node with the given name exists in a dir.
|
||||
*
|
||||
* @param dir
|
||||
* A valid dir. It can't be NULL
|
||||
* @param name
|
||||
* The node name to search for. It can't be NULL
|
||||
* @param pos
|
||||
* If not NULL, will be filled with the position where to insert. If the
|
||||
* node exists, (**pos) will refer to the given node.
|
||||
* @return
|
||||
* 1 if node exists, 0 if not
|
||||
*/
|
||||
int iso_dir_exists(IsoDir *dir, const char *name, IsoNode ***pos);
|
||||
|
||||
/**
|
||||
* Inserts a given node in a dir, at the specified position.
|
||||
*
|
||||
* @param dir
|
||||
* Dir where to insert. It can't be NULL
|
||||
* @param node
|
||||
* The node to insert. It can't be NULL
|
||||
* @param pos
|
||||
* Position where the node will be inserted. It is a pointer previously
|
||||
* obtained with a call to iso_dir_exists() or iso_dir_find().
|
||||
* It can't be NULL.
|
||||
* @param replace
|
||||
* Whether to replace an old node with the same name with the new node.
|
||||
* @return
|
||||
* If success, number of children in dir. < 0 on error
|
||||
*/
|
||||
int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos,
|
||||
enum iso_replace_mode replace);
|
||||
|
||||
#endif /*LIBISO_NODE_H_*/
|
||||
|
88
src/tree.c
88
src/tree.c
@ -62,12 +62,8 @@ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir)
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
|
||||
/* find place where to insert */
|
||||
pos = &(parent->children);
|
||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
|
||||
pos = &((*pos)->next);
|
||||
}
|
||||
if (*pos != NULL && !strcmp((*pos)->name, name)) {
|
||||
/* find place where to insert and check if it exists */
|
||||
if (iso_dir_exists(parent, name, &pos)) {
|
||||
/* a node with same name already exists */
|
||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||
}
|
||||
@ -97,15 +93,12 @@ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir)
|
||||
node->node.ctime = now;
|
||||
node->node.mtime = now;
|
||||
|
||||
/* add to dir */
|
||||
node->node.parent = parent;
|
||||
node->node.next = *pos;
|
||||
*pos = (IsoNode*)node;
|
||||
|
||||
if (dir) {
|
||||
*dir = node;
|
||||
}
|
||||
return ++parent->nchildren;
|
||||
|
||||
/* add to dir */
|
||||
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,11 +151,7 @@ int iso_tree_add_new_symlink(IsoDir *parent, const char *name,
|
||||
}
|
||||
|
||||
/* find place where to insert */
|
||||
pos = &(parent->children);
|
||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
|
||||
pos = &((*pos)->next);
|
||||
}
|
||||
if (*pos != NULL && !strcmp((*pos)->name, name)) {
|
||||
if (iso_dir_exists(parent, name, &pos)) {
|
||||
/* a node with same name already exists */
|
||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||
}
|
||||
@ -199,15 +188,12 @@ int iso_tree_add_new_symlink(IsoDir *parent, const char *name,
|
||||
node->node.ctime = now;
|
||||
node->node.mtime = now;
|
||||
|
||||
/* add to dir */
|
||||
node->node.parent = parent;
|
||||
node->node.next = *pos;
|
||||
*pos = (IsoNode*)node;
|
||||
|
||||
if (link) {
|
||||
*link = node;
|
||||
}
|
||||
return ++parent->nchildren;
|
||||
|
||||
/* add to dir */
|
||||
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -271,11 +257,7 @@ int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode,
|
||||
}
|
||||
|
||||
/* find place where to insert */
|
||||
pos = &(parent->children);
|
||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
|
||||
pos = &((*pos)->next);
|
||||
}
|
||||
if (*pos != NULL && !strcmp((*pos)->name, name)) {
|
||||
if (iso_dir_exists(parent, name, &pos)) {
|
||||
/* a node with same name already exists */
|
||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||
}
|
||||
@ -307,15 +289,12 @@ int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode,
|
||||
node->node.ctime = now;
|
||||
node->node.mtime = now;
|
||||
|
||||
/* add to dir */
|
||||
node->node.parent = parent;
|
||||
node->node.next = *pos;
|
||||
*pos = (IsoNode*)node;
|
||||
|
||||
if (special) {
|
||||
*special = node;
|
||||
}
|
||||
return ++parent->nchildren;
|
||||
|
||||
/* add to dir */
|
||||
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -395,30 +374,24 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent,
|
||||
name = iso_file_source_get_name(src);
|
||||
|
||||
/* find place where to insert */
|
||||
pos = &(parent->children);
|
||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
|
||||
pos = &((*pos)->next);
|
||||
}
|
||||
if (*pos != NULL && !strcmp((*pos)->name, name)) {
|
||||
result = iso_dir_exists(parent, name, &pos);
|
||||
free(name);
|
||||
if (result) {
|
||||
/* a node with same name already exists */
|
||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||
}
|
||||
free(name);
|
||||
|
||||
result = builder->create_node(builder, image, src, &new);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* finally, add node to parent */
|
||||
new->parent = parent;
|
||||
new->next = *pos;
|
||||
*pos = new;
|
||||
|
||||
if (node) {
|
||||
*node = new;
|
||||
}
|
||||
return ++parent->nchildren;
|
||||
|
||||
/* finally, add node to parent */
|
||||
return iso_dir_insert(parent, (IsoNode*)new, pos, ISO_REPLACE_NEVER);
|
||||
}
|
||||
|
||||
int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
|
||||
@ -513,11 +486,7 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||
|
||||
/* find place where to insert */
|
||||
flag = 0;
|
||||
pos = &(parent->children);
|
||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
|
||||
pos = &((*pos)->next);
|
||||
}
|
||||
if (*pos != NULL && !strcmp((*pos)->name, name)) {
|
||||
if (iso_dir_exists(parent, name, &pos)) {
|
||||
flag = 1;
|
||||
if (action == 1 && image->recOpts.replace == 0) {
|
||||
action = 2;
|
||||
@ -569,21 +538,8 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||
}
|
||||
|
||||
/* ok, node has correctly created, we need to add it */
|
||||
if (flag) {
|
||||
/* replace node */
|
||||
new->next = (*pos)->next;
|
||||
(*pos)->parent = NULL;
|
||||
(*pos)->next = NULL;
|
||||
iso_node_unref(*pos);
|
||||
*pos = new;
|
||||
new->parent = parent;
|
||||
} else {
|
||||
/* just add */
|
||||
new->next = *pos;
|
||||
*pos = new;
|
||||
new->parent = parent;
|
||||
++parent->nchildren;
|
||||
}
|
||||
iso_dir_insert(parent, new, pos, flag ? ISO_REPLACE_ALWAYS :
|
||||
ISO_REPLACE_NEVER);
|
||||
|
||||
/* finally, if the node is a directory we need to recurse */
|
||||
if (new->type == LIBISO_DIR) {
|
||||
|
Loading…
Reference in New Issue
Block a user