From 69fe1d6074dbb1d413bc8d675903a70cf8ae94fd Mon Sep 17 00:00:00 2001 From: Vreixo Formoso Date: Sat, 8 Mar 2008 17:28:40 +0100 Subject: [PATCH] Implement iso_tree_add_new_file() to add new files from scratch. --- TODO | 1 - libisofs/libisofs.h | 40 +++++++++++++++++++----- libisofs/tree.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index bad313f..e94a680 100644 --- a/TODO +++ b/TODO @@ -9,7 +9,6 @@ TODO #00004 (libisofs.h) -> Add a get_mime_type() function. #00005 (node.c) -> optimize iso_dir_iter_take. #00006 (libisofs.h) -> define more replace values when adding a node to a dir -#00007 (libisofs.h) -> expose iso_tree_add_new_file #00008 (data_dource.c) -> guard against partial reads #00009 (ecma119_tree.c/h) -> add true support for harlinks and inode numbers #00010 (buffer.c) -> optimize ring buffer diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index a5bd199..72e20c7 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -2131,8 +2131,8 @@ void iso_dir_iter_free(IsoDirIter *iter); * It's like iso_node_take(), but to be used during a directory iteration. * The node removed will be the last returned by the iteration. * - * The behavior on two call to this function without calling iso_dir_iter_next - * between then is undefined, and should never occur. (TODO protect against this?) + * If you call this function twice without calling iso_dir_iter_next between + * them is not allowed and you will get an ISO_ERROR in second call. * * @return * 1 on succes, < 0 error @@ -2150,8 +2150,8 @@ int iso_dir_iter_take(IsoDirIter *iter); * It's like iso_node_remove(), but to be used during a directory iteration. * The node removed will be the last returned by the iteration. * - * The behavior on two call to this function without calling iso_tree_iter_next - * between then is undefined, and should never occur. (TODO protect against this?) + * If you call this function twice without calling iso_dir_iter_next between + * them is not allowed and you will get an ISO_ERROR in second call. * * @return * 1 on succes, < 0 error @@ -2469,10 +2469,36 @@ int iso_node_get_old_image_lba(IsoNode *node, uint32_t *lba, int flag); */ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir); -/* - TODO #00007 expose Stream and this function: - int iso_tree_add_new_file(IsoDir *parent, const char *name, stream, file) +/** + * Add a new regular file to the iso tree. Permissions are set to 0444, + * owner and hidden atts are taken from parent. You can modify any of them + * later. + * + * @param parent + * the dir where the new file will be created + * @param name + * name for the new file. If a node with same name already exists on + * parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE. + * @param stream + * IsoStream for the contents of the file. The reference will be taken + * by the newly created file, you will need to take an extra ref to it + * if you need it. + * @param file + * place where to store a pointer to the newly created file. No extra + * ref is addded, so you will need to call iso_node_ref() if you really + * need it. You can pass NULL in this parameter if you don't need the + * pointer + * @return + * number of nodes in parent if success, < 0 otherwise + * Possible errors: + * ISO_NULL_POINTER, if parent, name or dest are NULL + * ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists + * ISO_OUT_OF_MEM + * + * @since 0.6.4 */ +int iso_tree_add_new_file(IsoDir *parent, const char *name, IsoStream *stream, + IsoFile **file); /** * Add a new symlink to the directory tree. Permissions are set to 0777, diff --git a/libisofs/tree.c b/libisofs/tree.c index 420b611..a53e62d 100644 --- a/libisofs/tree.c +++ b/libisofs/tree.c @@ -256,6 +256,81 @@ int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode, return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER); } +/** + * Add a new regular file to the iso tree. Permissions are set to 0444, + * owner and hidden atts are taken from parent. You can modify any of them + * later. + * + * @param parent + * the dir where the new file will be created + * @param name + * name for the new file. If a node with same name already exists on + * parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE. + * @param stream + * IsoStream for the contents of the file + * @param file + * place where to store a pointer to the newly created file. No extra + * ref is addded, so you will need to call iso_node_ref() if you really + * need it. You can pass NULL in this parameter if you don't need the + * pointer + * @return + * number of nodes in parent if success, < 0 otherwise + * Possible errors: + * ISO_NULL_POINTER, if parent, name or dest are NULL + * ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists + * ISO_OUT_OF_MEM + * + * @since 0.6.4 + */ +int iso_tree_add_new_file(IsoDir *parent, const char *name, IsoStream *stream, + IsoFile **file) +{ + int ret; + char *n; + IsoFile *node; + IsoNode **pos; + time_t now; + + if (parent == NULL || name == NULL || stream == NULL) { + return ISO_NULL_POINTER; + } + if (file) { + *file = NULL; + } + + /* find place where to insert */ + if (iso_dir_exists(parent, name, &pos)) { + /* a node with same name already exists */ + return ISO_NODE_NAME_NOT_UNIQUE; + } + + n = strdup(name); + ret = iso_node_new_file(n, stream, &node); + if (ret < 0) { + free(n); + return ret; + } + + /* permissions from parent */ + iso_node_set_permissions((IsoNode*)node, 0444); + iso_node_set_uid((IsoNode*)node, parent->node.uid); + iso_node_set_gid((IsoNode*)node, parent->node.gid); + iso_node_set_hidden((IsoNode*)node, parent->node.hidden); + + /* current time */ + now = time(NULL); + iso_node_set_atime((IsoNode*)node, now); + iso_node_set_ctime((IsoNode*)node, now); + iso_node_set_mtime((IsoNode*)node, now); + + if (file) { + *file = node; + } + + /* add to dir */ + return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER); +} + /** * Set whether to follow or not symbolic links when added a file from a source * to IsoImage.