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.
1157 lines
40 KiB
1157 lines
40 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_tree_iter_next(iter); |
|
* 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_BOOT |
|
}; |
|
|
|
#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 an El-Torito file. |
|
*/ |
|
struct iso_tree_node_boot; |
|
|
|
/** |
|
* Information about 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 |
|
}; |
|
|
|
/** |
|
* ISO-9660 (ECMA-119) has important restrictions in both file/dir names |
|
* and deep of the directory hierarchy. These are intented for compatibility |
|
* with old systems, and most modern operative system can safety deal with |
|
* ISO filesystems with relaxed constraints. |
|
* You can use some of these flags to generate that kind of filesystems with |
|
* libisofs. Of course, all these options will lead to an image not conforming |
|
* with ISO-9660 specification, so use them with caution. |
|
* Moreover, note that there are much better options to have an ISO-9660 image |
|
* compliant with modern systems, such as the Rock Ridge and Joliet extensions, |
|
* that add support for longer filenames, deeper directory hierarchy and even |
|
* file permissions (in case of RR), while keeping a standard ISO structure |
|
* suitable for old systems. |
|
* Thus, in most cases you don't want to use the relaxed constraints. |
|
*/ |
|
enum ecma119_relaxed_constraints_flag { |
|
ECMA119_OMIT_VERSION_NUMBERS = (1<<0), |
|
/**< |
|
* ISO-9660 requires a version number at the end of each file name. |
|
* That number is just ignored on most systems, so you can omit them |
|
* if you want. |
|
*/ |
|
ECMA119_37_CHAR_FILENAMES = (1<<1) | (1<<0), |
|
/**< |
|
* Allow ISO-9660 filenames to be up to 37 characters long. The extra |
|
* space is taken from the version number, so this option involves |
|
* no version number |
|
*/ |
|
ECMA119_NO_DIR_REALOCATION = (1<<2), |
|
/**< |
|
* In ISO-9660 images the depth of the directory hierarchy can't be |
|
* greater than 8 levels. In addition, a path to a file on disc can't |
|
* be more than 255 characteres. Use the ECMA119_NO_DIR_REALOCATION |
|
* to disable this restriction. |
|
*/ |
|
ECMA119_RELAXED_FILENAMES = (1<<3) |
|
/**< |
|
* Allow filenames with any character. Note that with this flag, the |
|
* filename provide by the user will be used without any modification |
|
* other that a truncate to max. length. |
|
*/ |
|
}; |
|
|
|
/** |
|
* 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 copy_eltorito:1; |
|
/**< |
|
* In multisession discs, select whether to copy el-torito catalog |
|
* and boot image. Copy is needed for isolinux images, that need to |
|
* be patched. However, it can lead to problems when the image is |
|
* not present in the iso filesystem, because we can't figure out |
|
* its size. In those cases, we only copy 1 block of data. |
|
*/ |
|
|
|
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. |
|
*/ |
|
uint8_t *overwrite; |
|
/**< |
|
* When not NULL, it should point to a buffer of at least |
|
* 64KiB, where libisofs will write the contents that should |
|
* be written at the beginning of a overwriteable media, to |
|
* grow the image. |
|
* You shoudl initialize the buffer either with 0s, or with |
|
* the contents of the first blocks of the image you're |
|
* growing. In most cases, 0 is good enought. |
|
*/ |
|
}; |
|
|
|
/** |
|
* Options for image reading. |
|
* There are four kind of options: |
|
* - Related to multisession support. |
|
* In most cases, an image begins at LBA 0 of the data source. However, |
|
* in multisession discs, the later image begins in the last session on |
|
* disc. The block option can be used to specify the start of that last |
|
* session. |
|
* - Related to the tree that will be read. |
|
* As default, when Rock Ridge extensions are present in the image, that |
|
* will be used to get the tree. If RR extensions are not present, libisofs |
|
* will use the Joliet extensions if available. Finally, the plain ISO-9660 |
|
* tree is used if neither RR nor Joliet extensions are available. With |
|
* norock, nojoliet, and preferjoliet options, you can change this |
|
* default behavior. |
|
* - Related to default POSIX attributes. |
|
* When Rock Ridege extensions are not used, libisofs can't figure out what |
|
* are the the permissions, uid or gid for the files. You should supply |
|
* default values for that. |
|
* - Return information for image. |
|
* Both size, hasRR and hasJoliet will be filled by libisofs with suitable values. |
|
* Also, error is set to non-0 if some error happens (error codes are |
|
* private now) |
|
*/ |
|
struct ecma119_read_opts { |
|
uint32_t block; /** Block where the image begins, usually 0, can be |
|
* different on a multisession disc. |
|
*/ |
|
|
|
unsigned int norock:1; /*< Do not read Rock Ridge extensions */ |
|
unsigned int nojoliet:1; /*< Do not read Joliet extensions */ |
|
unsigned int preferjoliet:1; |
|
/*< When both Joliet and RR extensions are present, the RR |
|
* tree is used. If you prefer using Joliet, set this to 1. */ |
|
|
|
uid_t uid; /**< Default uid when no RR */ |
|
gid_t gid; /**< Default uid when no RR */ |
|
mode_t mode; /**< Default mode when no RR (only permissions) */ |
|
//TODO differ file and dir mode |
|
//option to convert names to lower case? |
|
|
|
/* modified by the function */ |
|
unsigned int hasRR:1; /*< It will be set to 1 if RR extensions are present, |
|
to 0 if not. */ |
|
unsigned int hasJoliet:1; /*< It will be set to 1 if Joliet extensions are |
|
present, to 0 if not. */ |
|
uint32_t size; /**< Will be filled with the size (in 2048 byte block) of |
|
* the image, as reported in the PVM. */ |
|
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 |
|
/* invalid image */ |
|
#define ELTORITO_WRONG_IMAGE 5 |
|
|
|
/** |
|
* 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; |
|
}; |
|
|
|
/** |
|
* Initialize libisofs. You must call this before any usage of the library. |
|
* @return 1 on success, 0 on error |
|
*/ |
|
int iso_init(); |
|
|
|
/** |
|
* Finalize libisofs. |
|
*/ |
|
void iso_finish(); |
|
|
|
/** |
|
* 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); |
|
|
|
void iso_volset_ref(struct iso_volset *volset); |
|
|
|
/** |
|
* 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. |
|
* |
|
* This also add a catalog tree node to the image filesystem tree. The tree |
|
* node for the image will be replaced with a iso_tree_node_boot node, that |
|
* acts as a placeholder for the real 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 image is a file tree node that refers to a newly added file, not |
|
* one from a previous session. FIXME allow prev session files too |
|
* \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_set_boot_image(struct iso_volume *volume, |
|
struct iso_tree_node *image, |
|
enum eltorito_boot_media_type type, |
|
struct iso_tree_node_dir *dir, |
|
char *name); |
|
|
|
struct el_torito_boot_image* |
|
iso_volume_set_boot_image_hidden(struct iso_volume *volume, |
|
const char* path, |
|
enum eltorito_boot_media_type type); |
|
|
|
/** |
|
* Get El-Torito boot image of the volume, if any. |
|
* |
|
* This can be useful, for example, to check if a volume read from a previous |
|
* session or an existing image is bootable. It can also be useful to get |
|
* the image and catalog tree nodes. An application would want those, for |
|
* example, to prevent the user removing it. |
|
* |
|
* Both tree nodes are owned by libisofs and should not be freed. You can check |
|
* if the node is already on the tree by getting its parent (note that when |
|
* reading El-Torito info from a previous image, the nodes might not be on |
|
* the tree even if you haven't removed them). Remember that you'll need to |
|
* get a new ref (with iso_tree_node_ref()) before inserting them again to the |
|
* tree, and probably you will also need to set the name or permissions. |
|
* |
|
* \param imgnode When not NULL, it will be filled with the image tree node, if |
|
* any. |
|
* \param catnode When not NULL, it will be filled with the catalog tree node, |
|
* if any. |
|
* |
|
* \return The default El-Torito bootable image, or NULL is the volume is not |
|
* bootable. |
|
*/ |
|
struct el_torito_boot_image* |
|
iso_volume_get_boot_image(struct iso_volume *volume, |
|
struct iso_tree_node **imgnode, |
|
struct iso_tree_node **catnode); |
|
|
|
/** |
|
* Removes the El-Torito bootable image. Both the catalog and image tree nodes |
|
* are also removed from the image filesystem tree, if there. |
|
* If the volume is not bootable (don't have el-torito image) this function is |
|
* a nop. |
|
*/ |
|
void |
|
iso_volume_remove_boot_image(struct iso_volume *volume); |
|
|
|
/** |
|
* 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. |
|
* The original boot image file won't be modified. |
|
* This is needed for isolinux boot images. |
|
*/ |
|
void |
|
el_torito_patch_isolinux_image(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); |
|
|
|
/** Get the size of the node, in bytes */ |
|
off_t iso_tree_node_get_size(struct iso_tree_node *node); |
|
|
|
/** Set the time of last modification of the file */ |
|
void iso_tree_node_set_mtime(struct iso_tree_node *node, time_t time); |
|
|
|
/** Get the time of last modification of the file */ |
|
time_t iso_tree_node_get_mtime(struct iso_tree_node *node); |
|
|
|
/** Set the time of last access to the file */ |
|
void iso_tree_node_set_atime(struct iso_tree_node *node, time_t time); |
|
|
|
/** Get the time of last access to the file */ |
|
time_t iso_tree_node_get_atime(struct iso_tree_node *node); |
|
|
|
/** Set the time of last status change of the file */ |
|
void iso_tree_node_set_ctime(struct iso_tree_node *node, time_t time); |
|
|
|
/** Get the time of last status change of the file */ |
|
time_t iso_tree_node_get_ctime(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); |
|
|
|
/** |
|
* Check if there're more children. |
|
* @return |
|
* 1 if next call to iso_tree_iter_next() will return != NULL, |
|
* 0 otherwise |
|
*/ |
|
int iso_tree_iter_has_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); |
|
|
|
/** |
|
* Control queueing and stderr printing of messages from libisofs. |
|
* Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", |
|
* "NOTE", "UPDATE", "DEBUG", "ALL". |
|
* |
|
* @param queue_severity Gives the minimum limit for messages to be queued. |
|
* Default: "NEVER". If you queue messages then you |
|
* must consume them by iso_msgs_obtain(). |
|
* @param print_severity Does the same for messages to be printed directly |
|
* to stderr. |
|
* @param print_id A text prefix to be printed before the message. |
|
* @return >0 for success, <=0 for error |
|
*/ |
|
int iso_msgs_set_severities(char *queue_severity, |
|
char *print_severity, char *print_id); |
|
|
|
#define ISO_MSGS_MESSAGE_LEN 4096 |
|
|
|
/** |
|
* Obtain the oldest pending libisofs message from the queue which has at |
|
* least the given minimum_severity. This message and any older message of |
|
* lower severity will get discarded from the queue and is then lost forever. |
|
* |
|
* Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", |
|
* "NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER" |
|
* will discard the whole queue. |
|
* |
|
* @param error_code Will become a unique error code as listed in messages.h |
|
* @param msg_text Must provide at least ISO_MSGS_MESSAGE_LEN bytes. |
|
* @param os_errno Will become the eventual errno related to the message |
|
* @param severity Will become the severity related to the message and |
|
* should provide at least 80 bytes. |
|
* @return 1 if a matching item was found, 0 if not, <0 for severe errors |
|
*/ |
|
int iso_msgs_obtain(char *minimum_severity, |
|
int *error_code, char msg_text[], int *os_errno, |
|
char severity[]); |
|
|
|
/** Return the messenger object handle used by libisofs. This handle |
|
may be used by related libraries to replace their own compatible |
|
messenger objects and thus to direct their messages to the libisofs |
|
message queue. See also: libburn, API function burn_set_messenger(). |
|
@return the handle. Do only use with compatible |
|
*/ |
|
void *iso_get_messenger(void); |
|
|
|
#endif /* LIBISO_LIBISOFS_H */
|
|
|