You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

936 lines
30 KiB

/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* vim: set noet ts=8 sts=8 sw=8 : */
/**
* Create an ISO-9660 data volume with Rock Ridge and Joliet extensions.
* Usage is easy:
* - Create a new volume.
* - Add files and directories.
* - Write the volume to a file or create a burn source for use with Libburn.
*/
#ifndef LIBISO_LIBISOFS_H
#define LIBISO_LIBISOFS_H
#include <sys/types.h>
#include <stdint.h>
/* #include <libburn.h> */
struct burn_source;
/**
* Data volume.
* @see volume.h for details.
*/
struct iso_volume;
/**
* A set of data volumes.
* @see volume.h for details.
*/
struct iso_volset;
/**
* A node in the filesystem tree.
*
* This is opaque struct that represent any kind of nodes. When needed,
* you can get the type with iso_tree_node_get_type and cast it to the
* appropiate subtype:
*
* iso_tree_node_dir
* iso_tree_node_file
* iso_tree_node_symlink
*
* \see tree.h
*/
struct iso_tree_node;
/**
* The type of an iso_tree_node.
* When an user gets an iso_tree_node from libisofs, (s)he can use
* iso_tree_node_get_type to get the current type of the node, and then
* cast to the appropriate subtype. For example:
*
* struct iso_tree_node *node = iso... TODO
* if ( iso_tree_node_get_type(node) == LIBISO_NODE_DIR ) {
* struct iso_tree_node_dir *dir = (struct iso_tree_node_dir *)node;
* ...
* }
*
* Useful macros are provided.
*/
enum iso_tree_node_type {
LIBISO_NODE_DIR,
LIBISO_NODE_FILE,
LIBISO_NODE_SYMLINK,
LIBISO_NODE_BOOTCATALOG
};
#define LIBISO_ISDIR(n) (iso_tree_node_get_type(n) == LIBISO_NODE_DIR)
#define LIBISO_ISREG(n) (iso_tree_node_get_type(n) == LIBISO_NODE_FILE)
#define LIBISO_ISLNK(n) (iso_tree_node_get_type(n) == LIBISO_NODE_SYMLINK)
/**
* A directory in the filesystem tree.
* The first member of this is an iso_tree_node.
* \see tree.h
*/
struct iso_tree_node_dir;
/**
* A node in the filesystem tree that represents a regular file
*/
struct iso_tree_node_file;
/**
* A node in the filesystem tree that represents a symbolic link
*/
struct iso_tree_node_symlink;
/**
* A node that represents a boot catalog
* FIXME I'm not very sure how this should be treated.
*/
struct iso_tree_node_boot_catalog;
/**
* El-Torito boot image
* \see eltorito.h
*/
struct el_torito_boot_image;
/** Iterator for dir children. */
struct iso_tree_iter;
/**
* The procedence of the node.
*/
enum tree_node_from {
/** The node has been added by the user */
LIBISO_NEW = 0,
/**
* The node comes from a previous image. That can be from a previous
* session on disc, or from an ISO file we want to modify.
*/
LIBISO_PREVIMG
};
/**
* Extensions addition to ECMA-119 (ISO-9660) image. Usage of at least
* one of these flags is highly recommended if the disc will be used on a
* modern OS.
*/
enum ecma119_extension_flag {
/**
* Add the standard Rock Ridge extensions. This adds POSIX filesystem
* features to the ECMA-119 image. Thus, usage of this flag is highly
* recommended for images used on GNU/Linux systems. With the usage
* of RR extension, the resulting image will have long filenames (up to
* 255 characters), deeper directory structure, POSIX permissions and
* owner info on files and directories, support for symbolic links or
* special files... All that attributes can be modified/setted with the
* appropiate function.
*/
ECMA119_ROCKRIDGE = (1<<0),
/**
* Add the non-standard Joliet extension to the image. This extension is
* heavily used in Microsoft Windows systems, so if you plan to use your
* disc on such a system you should add this extension. Usage of Joliet
* supplies longer filesystem length (up to 64 unicode characters), and
* deeper directory structure.
*/
ECMA119_JOLIET = (1<<1)
};
/**
* Flag used to hide a file in the RR/ISO or Joliet tree.
*
* \see iso_tree_node_set_hidden
*/
enum hide_node_flag {
LIBISO_HIDE_ON_RR = 1 << 0,
LIBISO_HIDE_ON_JOLIET = 1 << 1
};
/**
* El-Torito bootable image type.
*/
enum eltorito_boot_media_type {
ELTORITO_FLOPPY_EMUL,
ELTORITO_HARD_DISC_EMUL,
ELTORITO_NO_EMUL
};
enum ecma119_relaxed_constraints_flag {
ECMA119_OMIT_VERSION_NUMBERS = (1<<0),
/* 37 char filenames involves no version number */
ECMA119_37_CHAR_FILENAMES = (1<<1) | (1<<0),
ECMA119_NO_DIR_REALOCATION = (1<<2),
ECMA119_RELAXED_FILENAMES = (1<<3)
};
/**
* Holds the options for the image generation.
*/
struct ecma119_source_opts {
int volnum; /**< The volume in the set which you want to write (usually 0) */
int level; /**< ISO level to write at. */
int flags; /**< Which extensions to support. */
int relaxed_constraints; /**< see ecma119_relaxed_constraints_flag */
unsigned int no_cache_inodes:1;
/**< If use inode caching or not. Set it to 1 to prevent
* inode caching.
* Usage of inode caching allows detection of hard-links,
* which contents are only written once to disc this way.
* Don't use inode caching in systems with non unique inodes
* per device.
*/
unsigned int sort_files:1;
/**< If files should be sorted based on their weight. */
unsigned int default_mode:1;
/**<
* The default values for files and directory permissions,
* gid and uid. This option can be overwritten when set
* one of the following.
* 0 to use useful values, 1 to use node modes (this are
* the same as filesystem ones if not changed after added
* to tree).
*/
unsigned int replace_dir_mode:1;
/**<
* When 1, permissions for all dirs will be replaced by the
* specified in dir_mode field.
*/
unsigned int replace_file_mode:1;
/**<
* When 1, permissions for all files will be replaced by the
* specified in file_mode field.
*/
unsigned int replace_uid:1;
/**<
* When 1, uid of all nodes (both files and dirs) will be
* replaced by the specified in uid field.
*/
unsigned int replace_gid:1;
/**<
* When 1, gid of all nodes (both files and dirs) will be
* replaced by the specified in gid field.
*/
mode_t dir_mode; /**< Mode to use on dirs when replace_dir_mode is set. */
mode_t file_mode; /**< Mode to use on files when replace_file_mode is set. */
gid_t gid; /**< gid to use when replace_gid is set. */
uid_t uid; /**< uid to use when replace_uid is set. */
char *input_charset; /**< NULL to use default charset */
char *ouput_charset; /**< NULL to use default charset */
uint32_t ms_block;
/**<
* Start block for multisession. When this is greater than 0,
* it's suppossed to be the lba of the next writable address
* on disc; all block lba on image will take this into account,
* and files from a previous session will not be written on
* image. This behavior is only suitable for images to be
* appended to a multisession disc.
* When this is 0, no multisession image will be created. If
* some files are taken from a previous image, its contents
* will be written again to the new image. Use this with new
* images or if you plan to modify an existin image.
*/
struct data_source* src;
/**<
* When modifying a image, this is the source of the original
* image, used to read file contents.
* Otherwise it can be NULL.
*/
};
/**
* FIXME documentar isto!!!
*/
struct ecma119_read_opts {
int tree_to_read;
int block; /** Block where the image begins, usually 0, can be
* different on a multisession disc.
*/
//TODO....
unsigned int norock:1; /*< Do not read Rock Ridge extensions */
//nojoliet
//check -> convert names to lower case
//uid, gid (when no RR)
//file and dir mode (when no RR)
/* modified by the function */
unsigned int hasRR:1; /*< It will be set to 1 if RR extensions are present,
to 0 if not. */
//hasJoliet
int error;
};
/**
* Data source used by libisofs for reading an existing image.
* It contains suitable methods to read arbitrary block. Usually, the block
* size is 2048 bytes.
*/
struct data_source {
/**
* Reference count for the data source. Should be 1 when a new source
* is created. Increment it to take a reference for yourself. Use
* data_source_free to destroy your reference to it.
*/
int refcount;
/**
* Read data from the source.
* @param lba Block to be read.
* @param buffer Buffer where the data will be written. Its size must
* be at least 2048 bytes.
* @return
* 0 if ok, < 0 on error
*/
int (*read_block)(struct data_source *src, int lba, unsigned char *buffer);
/** Get the size (number of block) of the source's data */
int (*get_size)(struct data_source *);
/** Clean up the source specific data */
void (*free_data)(struct data_source *);
/** Source specific data */
void *data;
};
/**
* This will hold the error code for some functions, if them fail.
*/
int libisofs_errno;
/* an unexpected internal error */
#define INTERNAL_ERROR -1
/* file don't exists, or can't be stat'ed */
#define NO_FILE 1
/* user haven't read access to file */
#define NO_READ_ACCESS 2
/* unexpected file type, eg., passing a dir instead of a regular file */
#define UNEXPECTED_FILE_TYPE 3
/* invalid boot image size */
#define ELTORITO_WRONG_IMAGE_SIZE 4
/**
* Controls the bahavior of iso_tree_radd_dir function
*/
struct iso_tree_radd_dir_behavior {
char** excludes; /**< List of paths (file or directory) to be ignored. */
//int follow_sym_link;
int stop_on_error; /**< Stop when an error was found?. */
int error; /**< set to 1 on error */
//int notify_errors;
//char** errors;
};
/**
* Create a new volume.
* The parameters can be set to NULL if you wish to set them later.
*/
struct iso_volume *iso_volume_new(const char *volume_id,
const char *publisher_id,
const char *data_preparer_id);
struct iso_volume *iso_volume_new_with_root(const char *volume_id,
const char *publisher_id,
const char *data_preparer_id,
struct iso_tree_node_dir *root);
/**
* Free a volume.
*/
void iso_volume_free(struct iso_volume *volume);
/**
* Free a set of data volumes.
*/
void iso_volset_free(struct iso_volset *volume);
/**
* Get a volume from a volume set.
*/
struct iso_volume *iso_volset_get_volume(struct iso_volset *volset, int volnum);
/**
* Get the root directory for a volume.
*/
struct iso_tree_node_dir *iso_volume_get_root(const struct iso_volume *volume);
/**
* Fill in the volume identifier for a volume.
*/
void iso_volume_set_volume_id(struct iso_volume *volume,
const char *volume_id);
/**
* Get the volume identifier.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_volume_id(struct iso_volume *volume);
/**
* Fill in the publisher for a volume.
*/
void iso_volume_set_publisher_id(struct iso_volume *volume,
const char *publisher_id);
/**
* Get the publisher of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_publisher_id(struct iso_volume *volume);
/**
* Fill in the data preparer for a volume.
*/
void iso_volume_set_data_preparer_id(struct iso_volume *volume,
const char *data_preparer_id);
/**
* Get the data preparer of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_data_preparer_id(struct iso_volume *volume);
/**
* Fill in the system id for a volume. Up to 32 characters.
*/
void iso_volume_set_system_id(struct iso_volume *volume,
const char *system_id);
/**
* Get the system id of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_system_id(struct iso_volume *volume);
/**
* Fill in the application id for a volume. Up to 128 chars.
*/
void iso_volume_set_application_id(struct iso_volume *volume,
const char *application_id);
/**
* Get the application id of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_application_id(struct iso_volume *volume);
/**
* Fill copyright information for the volume. Usually this refers
* to a file on disc. Up to 37 characters.
*/
void iso_volume_set_copyright_file_id(struct iso_volume *volume,
const char *copyright_file_id);
/**
* Get the copyright information of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_copyright_file_id(struct iso_volume *volume);
/**
* Fill abstract information for the volume. Usually this refers
* to a file on disc. Up to 37 characters.
*/
void iso_volume_set_abstract_file_id(struct iso_volume *volume,
const char *abstract_file_id);
/**
* Get the abstract information of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_abstract_file_id(struct iso_volume *volume);
/**
* Fill biblio information for the volume. Usually this refers
* to a file on disc. Up to 37 characters.
*/
void iso_volume_set_biblio_file_id(struct iso_volume *volume,
const char *biblio_file_id);
/**
* Get the biblio information of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_biblio_file_id(struct iso_volume *volume);
/**
* Create a bootable volume by adding a El-Torito boot image.
*
* \param volume The volume to make bootable.
* \param image The tree node with the file to use as default boot image.
* \param type The boot media type. This can be one of 3 types:
* - Floppy emulation: Boot image files must be exactly
* 1200 kB, 1440 kB or 2880 kB.
* - Hard disc emulation: The image must begin with a master
* boot record with a single image.
* - No emulation. You should specify load segment and load size
* of image.
* \param dir The directory node where the boot catalog will be located
* in image. Usually both boot catalog and boot image will be
* located in the same dir, maybe /boot.
* \param name The name of the boot catalog.
*
* \return The default El-Torito bootable image. If specified image file
* seems to be not correct, this returns NULL and libisofs_errno
* is set propertly.
*
* \pre \p volume is a volume without any boot catalog yet
* \pre \p image is a file tree node already inserted in the volume tree.
* \pre \p dir is a directory node already inserted in the volume tree.
* \pre \p name There isn't any dir child with the same name.
*
*/
struct el_torito_boot_image *
iso_volume_create_boot_catalog(struct iso_volume *volume,
struct iso_tree_node *image,
enum eltorito_boot_media_type type,
struct iso_tree_node_dir *dir,
char *name);
/**
* Sets the load segment for the initial boot image. This is only for
* no emulation boot images, and is a NOP for other image types.
*/
void
el_torito_set_load_seg(struct el_torito_boot_image *bootimg, int segment);
/**
* Sets the number of sectors (512b) to be load at load segment during
* the initial boot procedure. This is only for
* no emulation boot images, and is a NOP for other image types.
*/
void
el_torito_set_load_size(struct el_torito_boot_image *bootimg, int sectors);
/**
* Marks the specified boot image as not bootable
*/
void
el_torito_set_no_bootable(struct el_torito_boot_image *bootimg);
/**
* Specifies that this image needs to be patched. This involves the writting
* of a 56 bytes boot information table at offset 8 of the boot image file.
* Be aware that libisofs will modify original boot image file, so do a backup
* if needed.
* This is needed for isolinux boot images.
*/
void
el_torito_set_write_boot_info(struct el_torito_boot_image *bootimg);
/**
* Locate a node by its path on disc.
*
* \param volume The volume to search in.
* \param path The path, in the image, of the file.
*
* \return The node found or NULL.
*/
struct iso_tree_node *iso_tree_volume_path_to_node(struct iso_volume *volume, const char *path);
/**
* TODO I don't like this kind of functions here. I think it should be
* in genisofs
* Add a file or a directory (recursively) to a volume by specifying its path on the volume.
*
* \param volume The volume to add the file to.
* \param disc_path The path on the disc at which to add the disc.
* \param path The path, on the local filesystem, of the file.
*
* \return The node for the file or NULL if the parent doesn't exists on the disc.
*/
//struct iso_tree_node *iso_tree_volume_add_path(struct iso_volume *volume,
// const char *disc_path,
// const char *path);
/**
* TODO I don't like this kind of functions here. I think it should be
* in genisofs
* Creates a new, empty directory on the volume.
*
* \param volume The volume to add the directory to.
* \param disc_path The path on the volume at which to add the directory.
*
* \return A pointer to the newly created directory.
*/
//struct iso_tree_node *iso_tree_volume_add_new_dir(struct iso_volume *volume,
// const char *disc_path);
/**
* Create a new Volume Set consisting of only one volume.
* @param volume The first and only volume for the volset to contain.
* @param volset_id The Volume Set ID.
* @return A new iso_volset.
*/
struct iso_volset *iso_volset_new(struct iso_volume *volume,
const char *volset_id);
/**
* Creates a new root dir for a filesystem tree
*/
struct iso_tree_node_dir *iso_tree_new_root();
/**
* Add a file to a directory.
*
* \param path The path, on the local filesystem, of the file.
*
* \pre \p parent is non-NULL.
* \pre \p path is non-NULL.
* \return An iso_tree_node_file whose path is \p path and whose parent is
* \p parent.
* On error, returns NULL and libisofs_errno is set appropriately:
* NO_FILE if path doesn't point to a valid file.
* NO_READ_ACCESS if user haven't read access on file
* UNEXPECTED_FILE_TYPE if path doesn't point to a regular file
*/
struct iso_tree_node *iso_tree_add_file(struct iso_tree_node_dir *parent,
const char *path);
/**
* Add a symbolic link to a directory.
*
* \param name The name of the symbolic link
* \param dest The distination of the link, i.e., the file this link points
* to
*
* \pre \p parent, name and dest are non-NULL.
*
* \return An iso_tree_node_symlink
*/
struct iso_tree_node *iso_tree_add_symlink(struct iso_tree_node_dir *parent,
const char *name, const char *dest);
/**
* Add a new, empty directory to the tree.
*
* \pre \p parent is non-NULL.
* \pre \p name is unique among the children and files belonging to \p parent.
* Also, it doesn't contain '/' characters.
*
* \post \p parent contains a child directory whose name is \p name and whose
* POSIX attributes are the same as \p parent's.
* \return a pointer to the newly created directory.
*/
struct iso_tree_node_dir *iso_tree_add_dir(struct iso_tree_node_dir *parent,
const char *name);
/* TODO iso_tree_new_special */
/**
* Add a file to a directory.
*
* \param path The path, on the local filesystem, of the file.
*
* \pre \p parent is non-NULL.
* \pre \p path is non-NULL and is a valid path to a file or directory on the local
* filesystem.
* \return An iso_tree_node whose path is \p path and whose parent is \p parent.
* On error, returns NULL and libisofs_errno is set appropriately:
* NO_FILE if path doesn't point to a valid file.
* NO_READ_ACCESS if user haven't read access on file
* UNEXPECTED_FILE_TYPE if path refers to non supported file type
* (at the momment, only dirs, symlinks and regular
* files are supported).
*/
struct iso_tree_node *iso_tree_add_node(struct iso_tree_node_dir *parent,
const char *path);
/**
* TODO I don't like this kind of functions here. I think it should be
* in genisofs
*
* Recursively add an existing directory to the tree.
* Warning: when using this, you'll lose pointers to files or subdirectories.
* If you want to have pointers to all files and directories,
* use iso_tree_add_file, iso_tree_add_node and iso_tree_add_dir.
*
* \param path The path, on the local filesystem, of the directory to add.
*
* \pre \p parent is non-NULL.
* \pre \p path is non-NULL and is a valid path to a directory on the local
* filesystem.
*/
void iso_tree_radd_dir(struct iso_tree_node_dir *parent, const char *path,
struct iso_tree_radd_dir_behavior *behavior);
/**
* Get the type of an iso_tree_node
*/
enum iso_tree_node_type iso_tree_node_get_type(struct iso_tree_node *node);
/**
* Set the name of a tree node (using the current locale).
*/
void iso_tree_node_set_name(struct iso_tree_node *node, const char *name);
/**
* Get the name of a tree node (using the current locale).
* The returned string belongs to the node and should not be modified nor
* freed. Use strdup if you really need your own copy.
*/
const char *iso_tree_node_get_name(struct iso_tree_node *node);
/**
* Set if the node will be hidden in RR/ISO tree, Joliet tree or both.
*
* If the file is setted as hidden in one tree, it won't be included there, so
* it won't be visible in a OS accessing CD using that tree. For example,
* GNU/Linux systems access to Rock Ridge / ISO9960 tree in order to see
* what is recorded on CD, while MS Windows make use of the Joliet tree. If a
* file is hidden only in Joliet, it won't be visible in Windows systems,
* while still visible in Linux.
*
* If a file is hidden in both trees, it won't be written to image.
*
* \param node The node that is to be hidden.
* \param hide_attrs hide_node_flag's to set the trees in which file
* will be hidden.
*/
void iso_tree_node_set_hidden(struct iso_tree_node *node, int hide_attrs);
/**
* Check if a node will be hidden in RR/ISO tree, Joliet tree or both.
*
* @return
* 0 if the node won't be hidden, otherwise you can AND the return value
* with hide_node_flag's to get in what trees the node will be hidden.
*/
int iso_tree_node_is_hidden(struct iso_tree_node *node);
/**
* Set the group id for the node. This attribute is only useful when
* Rock Ridge extensions are enabled.
*/
void iso_tree_node_set_gid(struct iso_tree_node *node, gid_t gid);
/**
* Get the group id of the node.
*/
gid_t iso_tree_node_get_gid(struct iso_tree_node *node);
/**
* Set the user id for the node. This attribute is only useful when
* Rock Ridge extensions are enabled.
*/
void iso_tree_node_set_uid(struct iso_tree_node *node, uid_t uid);
/**
* Get the user id of the node.
*/
uid_t iso_tree_node_get_uid(struct iso_tree_node *node);
/**
* Set the permissions for the node. This attribute is only useful when
* Rock Ridge extensions are enabled.
*
* \param mode bitmask with the permissions of the node, as specified
* in 'man 2 stat'. The file type bitfields will be ignored,
* only file permissions will be modified.
*/
void iso_tree_node_set_permissions(struct iso_tree_node *node, mode_t mode);
/** Get the permissions for the node */
mode_t iso_tree_node_get_permissions(struct iso_tree_node *node);
/**
* Sets the order in which a node will be written on image. High weihted files
* will be written first, so in a disc them will be written near the center.
*
* \param node The node which weight will be changed. If it's a dir, this
* function will change the weight of all its children. For nodes
* other that dirs or regular files, this function has no effect.
* \param w The weight as a integer number, the greater this value is, the
* closer from the begining of image the file will be written.
*/
void iso_tree_node_set_sort_weight(struct iso_tree_node *node, int w);
/**
* Sets the destination of a symbolic link
*/
void iso_tree_node_symlink_set_dest(struct iso_tree_node_symlink *node, const char *dest);
/**
* Get the destination of a symbolic link.
* The returned string is owned by libisofs and should not be freed nor modified.
*/
const char *iso_tree_node_symlink_get_dest(struct iso_tree_node_symlink *node);
/**
* Get an iterator for the children of the given dir.
* You can iterate over the children with iso_tree_iter_next. When finished,
* you should free the iterator with iso_tree_iter_free.
* You musn't delete a child of the same dir, using iso_tree_node_take() or
* iso_tree_node_remove(), while you're using the iterator. You can use
* iso_tree_node_take_iter() or iso_tree_node_remove_iter() instead.
*
* The usage of an iterator is:
*
* struct iso_tree_iter *iter;
* struct iso_tree_node *node;
* iter = iso_tree_node_children(dir);
* while ( (node = iso_tree_iter_next(iter)) != NULL ) {
* // do something with the child
* }
* iso_tree_iter_free(iter);
*
* An iterator is intended to be used in a single iteration over the
* children of a dir. Thus, it should be treated as a temporary object,
* and free as soon as possible.
*/
struct iso_tree_iter *iso_tree_node_children(struct iso_tree_node_dir *dir);
/**
* Get the next child.
* Take care that the node is owned by libisofs, and will be freed whit the
* tree it belongs. If you want your own ref to it, call iso_tree_node_ref()
* on it.
* This returns NULL if no more children are available.
*/
struct iso_tree_node *iso_tree_iter_next(struct iso_tree_iter *iter);
/** Free an iteration */
void iso_tree_iter_free(struct iso_tree_iter *iter);
/**
* Removes a child from a directory.
* The child is not freed, so you will become the owner of the node. Later
* you can add the node to another dir (calling iso_tree_add_child), or free
* it if you don't need it (with iso_tree_free).
*
* @return 0 on success, -1 if the node doesn't belong to the dir.
*/
int iso_tree_node_take(struct iso_tree_node_dir *dir,
struct iso_tree_node *node);
/**
* Removes a child from a directory and free (unref) it.
* If you want to keep the child alive, you need to iso_tree_node_ref() it
* before this call, but in that case iso_tree_node_take() is a better
* alternative.
*
* @return 0 on success, -1 if the node doesn't belong to the dir (in this
* last case the node is not freed).
*/
int iso_tree_node_remove(struct iso_tree_node_dir *dir,
struct iso_tree_node *node);
/**
* Removes a child from a directory during an iteration, without freeing it.
* It's like iso_tree_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_tree_iter_next
* between then is undefined, and should never occur. (TODO protect against this?)
*
* @return 0 on success, < 0 on an invalid usage, i.e., if the user call this
* before an inicial iso_tree_iter_next() or if last
* iso_tree_iter_next() has returned NULL.
*/
int iso_tree_node_take_iter(struct iso_tree_iter *iter);
/**
* Removes a child from a directory during an iteration and free it.
* It's like iso_tree_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?)
*
* @return 0 on success, < 0 on an invalid usage, i.e., if the user call this
* before an inicial iso_tree_iter_next() or if last
* iso_tree_iter_next() has returned NULL.
*/
int iso_tree_node_remove_iter(struct iso_tree_iter *iter);
/*
* Get the parent of the given iso tree node.
* This returns NULL if the node is the root of the tree, or is a node
* that doesn't pertain to any tree (it was removed/take)
*/
struct iso_tree_node_dir *iso_tree_node_get_parent(struct iso_tree_node *node);
/**
* Adds a child to a directory.
* The child will be freed when the parent is freed, so you must be the
* owner of the child (maybe calling iso_tree_node_ref) before calling this.
*
* \pre parent has no child with the same name as \p child
*/
void iso_tree_add_child(struct iso_tree_node_dir *parent,
struct iso_tree_node *child);
/**
* Increments the reference counting of the given node.
* If you call this, you must remember call iso_tree_free when the
* node is no more needed.
*/
void iso_tree_node_ref(struct iso_tree_node *node);
/**
* Recursively free a directory.
*
* \param root The root of the directory heirarchy to free.
*
* \pre \p root is non-NULL.
*/
void iso_tree_free(struct iso_tree_node *root);
/**
* Recursively print a directory to stdout.
* \param spaces The initial number of spaces on the left. Set to 0 if you
* supply a root directory.
*/
void iso_tree_print(const struct iso_tree_node *root, int spaces);
/** Create a burn_source which can be used as a data source for a track
*
* The volume set used to create the libburn_source can _not_ be modified
* until the libburn_source is freed.
*
* \param volumeset The volume set from which you want to write
* \param opts The options for image generation
*
* \pre \p volumeset is non-NULL
* \pre \p volnum is less than \p volset->volset_size.
* \return A burn_source to be used for the data source for a track
*/
struct burn_source* iso_source_new_ecma119(struct iso_volset *volumeset,
struct ecma119_source_opts *opts);
/**
* Creates a new data source from the given file.
*
* Returns NULL on error
*/
struct data_source *data_source_from_file(const char *path);
/** Free a given data source (decrease its refcount and maybe free it) */
void data_source_free(struct data_source*);
/**
* Read an existing ISO image.
*
* TODO documentar
*/
struct iso_volset *iso_volset_read(struct data_source *src,
struct ecma119_read_opts *opts);
#endif /* LIBISO_LIBISOFS_H */