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
|
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.
|
* Holds the options for the image generation.
|
||||||
*/
|
*/
|
||||||
@ -770,11 +791,6 @@ void iso_node_set_hidden(IsoNode *node, int hide_attrs);
|
|||||||
* @param replace
|
* @param replace
|
||||||
* if the dir already contains a node with the same name, whether to
|
* if the dir already contains a node with the same name, whether to
|
||||||
* replace or not the old node with this.
|
* 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
|
* @return
|
||||||
* number of nodes in dir if succes, < 0 otherwise
|
* number of nodes in dir if succes, < 0 otherwise
|
||||||
* Possible errors:
|
* 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_NODE_NAME_NOT_UNIQUE, a node with same name already exists
|
||||||
* ISO_WRONG_ARG_VALUE, if child == dir, or replace != (0,1)
|
* 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.
|
* 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
|
* 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
|
* messenger objects and thus to direct their messages to the libisofs
|
||||||
* message queue. See also: libburn, API function burn_set_messenger().
|
* 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.
|
* 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
|
* Otherwise this function will return a failure, and the child won't be
|
||||||
* inserted.
|
* 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
|
* @return
|
||||||
* number of nodes in dir if succes, < 0 otherwise
|
* 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;
|
IsoNode **pos;
|
||||||
|
|
||||||
@ -281,32 +285,8 @@ int iso_dir_add_node(IsoDir *dir, IsoNode *child, int replace)
|
|||||||
return ISO_NODE_ALREADY_ADDED;
|
return ISO_NODE_ALREADY_ADDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = &(dir->children);
|
iso_dir_find(dir, child->name, &pos);
|
||||||
while (*pos != NULL && strcmp((*pos)->name, child->name) < 0) {
|
return iso_dir_insert(dir, child, pos, replace);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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)
|
int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node)
|
||||||
{
|
{
|
||||||
IsoNode *pos;
|
int ret;
|
||||||
|
IsoNode **pos;
|
||||||
if (dir == NULL || name == NULL) {
|
if (dir == NULL || name == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = dir->children;
|
ret = iso_dir_exists(dir, name, &pos);
|
||||||
while (pos != NULL && strcmp(pos->name, name) < 0) {
|
if (ret == 0) {
|
||||||
pos = pos->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos == NULL || strcmp(pos->name, name)) {
|
|
||||||
if (node) {
|
if (node) {
|
||||||
*node = NULL;
|
*node = NULL;
|
||||||
}
|
}
|
||||||
@ -346,7 +323,7 @@ int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
*node = pos;
|
*node = *pos;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -686,6 +663,53 @@ int iso_node_is_valid_link_dest(const char *dest)
|
|||||||
return ret;
|
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)
|
int iso_node_new_root(IsoDir **root)
|
||||||
{
|
{
|
||||||
IsoDir *dir;
|
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);
|
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_*/
|
#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;
|
return ISO_WRONG_ARG_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find place where to insert */
|
/* find place where to insert and check if it exists */
|
||||||
pos = &(parent->children);
|
if (iso_dir_exists(parent, name, &pos)) {
|
||||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
|
|
||||||
pos = &((*pos)->next);
|
|
||||||
}
|
|
||||||
if (*pos != NULL && !strcmp((*pos)->name, name)) {
|
|
||||||
/* a node with same name already exists */
|
/* a node with same name already exists */
|
||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
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.ctime = now;
|
||||||
node->node.mtime = now;
|
node->node.mtime = now;
|
||||||
|
|
||||||
/* add to dir */
|
|
||||||
node->node.parent = parent;
|
|
||||||
node->node.next = *pos;
|
|
||||||
*pos = (IsoNode*)node;
|
|
||||||
|
|
||||||
if (dir) {
|
if (dir) {
|
||||||
*dir = node;
|
*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 */
|
/* find place where to insert */
|
||||||
pos = &(parent->children);
|
if (iso_dir_exists(parent, name, &pos)) {
|
||||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
|
|
||||||
pos = &((*pos)->next);
|
|
||||||
}
|
|
||||||
if (*pos != NULL && !strcmp((*pos)->name, name)) {
|
|
||||||
/* a node with same name already exists */
|
/* a node with same name already exists */
|
||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
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.ctime = now;
|
||||||
node->node.mtime = now;
|
node->node.mtime = now;
|
||||||
|
|
||||||
/* add to dir */
|
|
||||||
node->node.parent = parent;
|
|
||||||
node->node.next = *pos;
|
|
||||||
*pos = (IsoNode*)node;
|
|
||||||
|
|
||||||
if (link) {
|
if (link) {
|
||||||
*link = node;
|
*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 */
|
/* find place where to insert */
|
||||||
pos = &(parent->children);
|
if (iso_dir_exists(parent, name, &pos)) {
|
||||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
|
|
||||||
pos = &((*pos)->next);
|
|
||||||
}
|
|
||||||
if (*pos != NULL && !strcmp((*pos)->name, name)) {
|
|
||||||
/* a node with same name already exists */
|
/* a node with same name already exists */
|
||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
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.ctime = now;
|
||||||
node->node.mtime = now;
|
node->node.mtime = now;
|
||||||
|
|
||||||
/* add to dir */
|
|
||||||
node->node.parent = parent;
|
|
||||||
node->node.next = *pos;
|
|
||||||
*pos = (IsoNode*)node;
|
|
||||||
|
|
||||||
if (special) {
|
if (special) {
|
||||||
*special = node;
|
*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);
|
name = iso_file_source_get_name(src);
|
||||||
|
|
||||||
/* find place where to insert */
|
/* find place where to insert */
|
||||||
pos = &(parent->children);
|
result = iso_dir_exists(parent, name, &pos);
|
||||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
|
free(name);
|
||||||
pos = &((*pos)->next);
|
if (result) {
|
||||||
}
|
|
||||||
if (*pos != NULL && !strcmp((*pos)->name, name)) {
|
|
||||||
/* a node with same name already exists */
|
/* a node with same name already exists */
|
||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
}
|
}
|
||||||
free(name);
|
|
||||||
|
|
||||||
result = builder->create_node(builder, image, src, &new);
|
result = builder->create_node(builder, image, src, &new);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* finally, add node to parent */
|
|
||||||
new->parent = parent;
|
|
||||||
new->next = *pos;
|
|
||||||
*pos = new;
|
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
*node = new;
|
*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,
|
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 */
|
/* find place where to insert */
|
||||||
flag = 0;
|
flag = 0;
|
||||||
pos = &(parent->children);
|
if (iso_dir_exists(parent, name, &pos)) {
|
||||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
|
|
||||||
pos = &((*pos)->next);
|
|
||||||
}
|
|
||||||
if (*pos != NULL && !strcmp((*pos)->name, name)) {
|
|
||||||
flag = 1;
|
flag = 1;
|
||||||
if (action == 1 && image->recOpts.replace == 0) {
|
if (action == 1 && image->recOpts.replace == 0) {
|
||||||
action = 2;
|
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 */
|
/* ok, node has correctly created, we need to add it */
|
||||||
if (flag) {
|
iso_dir_insert(parent, new, pos, flag ? ISO_REPLACE_ALWAYS :
|
||||||
/* replace node */
|
ISO_REPLACE_NEVER);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* finally, if the node is a directory we need to recurse */
|
/* finally, if the node is a directory we need to recurse */
|
||||||
if (new->type == LIBISO_DIR) {
|
if (new->type == LIBISO_DIR) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user