diff --git a/libisofs/ecma119_tree.c b/libisofs/ecma119_tree.c index 5645954..d31ce6a 100644 --- a/libisofs/ecma119_tree.c +++ b/libisofs/ecma119_tree.c @@ -18,6 +18,12 @@ static size_t calc_dirent_len(struct ecma119_tree_node *n) return ret; } +/** + * Replace the file permissions and user/group id of an ECMA-119 node. + * This is used when a replace mode is selected, i.e., when we want to + * create a disc where the mode of each file or directory will be + * different than the mode in the original source. + */ static void replace_node_mode(struct ecma119_write_target *t, struct stat *st) { @@ -65,6 +71,19 @@ replace_node_mode(struct ecma119_write_target *t, struct stat *st) } } +/** + * Creates a new ECMA-119 node from the given iso tree node, and initializes + * the fields that are common to all kind of nodes (dir, reg file, symlink...). + * + * @param t + * The options for the ECMA-119 tree that is being created + * @param parent + * The parent of the node, or NULL if it's the root. + * @param iso + * The node from which this function creates a ECMA-119 node + * @return + * The created node. + */ static struct ecma119_tree_node* create_ecma119_node(struct ecma119_write_target *t, struct ecma119_tree_node *parent, @@ -92,13 +111,22 @@ create_ecma119_node(struct ecma119_write_target *t, iso_name(iso->name, t->input_charset) ) : NULL; ret->dirent_len = calc_dirent_len(ret); + + /* iso node keeps the same file attribs as the original file. */ ret->attrib = iso->attrib; + + /* + * When using RR extension and replace mode, we will replace the + * permissions and uid/gid of each file with those previously selected + * by the user. + */ if ( t->rockridge && t->replace_mode ) replace_node_mode(t, &ret->attrib); if (!iso->name) ret->full_name = NULL; else if ( strcmp(t->input_charset,t->ouput_charset) ) + /* convert the file name charset */ ret->full_name = convert_str(iso->name, t->input_charset, t->ouput_charset); else @@ -108,6 +136,10 @@ create_ecma119_node(struct ecma119_write_target *t, return ret; } +/** + * Create a new ECMA-119 node representing a directory from a iso directory + * node. + */ static struct ecma119_tree_node* create_dir(struct ecma119_write_target *t, struct ecma119_tree_node *parent, @@ -127,6 +159,10 @@ create_dir(struct ecma119_write_target *t, return ret; } +/** + * Create a new ECMA-119 node representing a regular file from a iso file + * node. + */ static struct ecma119_tree_node* create_file(struct ecma119_write_target *t, struct ecma119_tree_node *parent, @@ -143,6 +179,10 @@ create_file(struct ecma119_write_target *t, /* get iso_file struct */ file = iso_file_table_lookup(t->file_table, iso); if ( file == NULL ) { + /* + * If the file is not already added to the disc, we add it now + * to the file table, and get a new inode number for it. + */ file = iso_file_new(iso); iso_file_table_add_file(t->file_table, file); file->ino = ++t->ino; @@ -157,6 +197,12 @@ create_file(struct ecma119_write_target *t, return ret; } +/** + * Create a new ECMA-119 node representing a placeholder for a relocated + * dir. + * + * See IEEE P1282, section 4.1.5 for details + */ static struct ecma119_tree_node* create_placeholder(struct ecma119_write_target *t, struct ecma119_tree_node *parent, @@ -191,6 +237,10 @@ create_placeholder(struct ecma119_write_target *t, return ret; } +/** + * Create a new ECMA-119 node representing a symbolic link from a iso symlink + * node. + */ static struct ecma119_tree_node* create_symlink(struct ecma119_write_target *t, struct ecma119_tree_node *parent, @@ -212,6 +262,14 @@ create_symlink(struct ecma119_write_target *t, return ret; } +/** + * Create a new ECMA-119 node representing a boot catalog. This is like a + * regular file, but its contents are taken from a El-Torito boot catalog, + * and not from a file in the local filesystem. + * + * See "El Torito" Bootable CD-ROM Format Specification Version 1.0 for + * more details. + */ static struct ecma119_tree_node* create_boot_catalog(struct ecma119_write_target *t, struct ecma119_tree_node *parent, @@ -239,6 +297,11 @@ create_boot_catalog(struct ecma119_write_target *t, return ret; } +/** + * Create a new ECMA-119 node that corresponds to the given iso tree node. + * If that node is a dir, this function recurses over all their children, + * thus creating a ECMA-119 tree whose root is the given iso dir. + */ static struct ecma119_tree_node* create_tree(struct ecma119_write_target *t, struct ecma119_tree_node *parent, @@ -316,6 +379,12 @@ max_child_name_len(struct ecma119_tree_node *root) return ret; } +/** + * Relocates a directory, as specified in Rock Ridge Specification + * (see IEEE P1282, section 4.1.5). This is needed when the number of levels + * on a directory hierarchy exceeds 8, or the length of a path is higher + * than 255 characters, as specified in ECMA-119, section 6.8.2.1 + */ static void reparent(struct ecma119_tree_node *child, struct ecma119_tree_node *parent) @@ -350,6 +419,8 @@ reparent(struct ecma119_tree_node *child, * Reorder the tree, if necessary, to ensure that * - the depth is at most 8 * - each path length is at most 255 characters + * This restriction is imposed by ECMA-119 specification (see ECMA-119, + * 6.8.2.1). */ static void reorder_tree(struct ecma119_write_target *t, @@ -400,6 +471,9 @@ reorder_tree(struct ecma119_write_target *t, } } +/** + * Compare the iso name of two ECMA-119 nodes + */ static int cmp_node(const void *f1, const void *f2) { @@ -408,6 +482,10 @@ cmp_node(const void *f1, const void *f2) return strcmp(f->iso_name, g->iso_name); } +/** + * Sorts a the children of each directory in the ECMA-119 tree represented + * by \p root, acording to the order specified in ECMA-119, section 9.3. + */ static void sort_tree(struct ecma119_tree_node *root) { @@ -470,6 +548,10 @@ mangle_name(char **name, int num_change, int level, int seq_num) sprintf(*name, fmt, base, seq_num, ext); } +/** + * Ensures that the ISO name of each children of the given dir is unique, + * changing some of them if needed. + */ static void mangle_all(struct ecma119_tree_node *dir) { diff --git a/libisofs/rockridge.c b/libisofs/rockridge.c index 6531301..c2d7b4b 100755 --- a/libisofs/rockridge.c +++ b/libisofs/rockridge.c @@ -14,6 +14,30 @@ #include #include +/** See IEEE P1281 Draft Version 1.12/5.5 FIXME: this is rockridge */ +void +rrip_add_ER(struct ecma119_write_target *t, struct ecma119_tree_node *dir) +{ + unsigned char *ER = malloc(182); + + assert(dir->type == ECMA119_DIR); + + ER[0] = 'E'; + ER[1] = 'R'; + ER[2] = 182; + ER[3] = 1; + ER[4] = 9; + ER[5] = 72; + ER[6] = 93; + ER[7] = 1; + memcpy(&ER[8], "IEEE_1282", 9); + memcpy(&ER[17], "THE IEEE 1282 PROTOCOL PROVIDES SUPPORT FOR POSIX " + "FILE SYSTEM SEMANTICS.", 72); + memcpy(&ER[89], "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, " + "PISCATAWAY, NJ, USA FOR THE 1282 SPECIFICATION.", 93); + susp_append(t, &dir->info.dir.self_susp, ER); +} + /* create a PX field from the permissions on the current node. */ uint8_t *rrip_make_PX(struct ecma119_write_target *t, struct ecma119_tree_node *node) diff --git a/libisofs/rockridge.h b/libisofs/rockridge.h index 7909a0c..63e4f6a 100755 --- a/libisofs/rockridge.h +++ b/libisofs/rockridge.h @@ -1,6 +1,11 @@ /* vim: set noet ts=8 sts=8 sw=8 : */ -/** Functions and structures used for Rock Ridge support. */ +/** + * Functions and structures used for Rock Ridge support. + * + * See IEEE P1282, Rock Ridge Interchange Protocol, Draft Standard version + * 1.12 for further details. + */ #ifndef ISO_ROCKRIDGE_H #define ISO_ROCKRIDGE_H @@ -8,18 +13,99 @@ struct ecma119_write_target; struct ecma119_tree_node; +/** + * Add a SUSP "ER" System Use Entry to identify the Rock Ridge specification. + * + * The "ER" System Use Entry is used to uniquely identify a specification + * compliant with SUSP. This method adds to the given tree node "." entry + * the "ER" corresponding to the RR protocol. + * + * See IEEE P1281, section 5.5 and IEEE P1282, section 4.3 for more details. + */ +void rrip_add_ER(struct ecma119_write_target *, struct ecma119_tree_node *); + +/** + * Add a PX System Use Entry to the given tree node and, if that node is + * a directory, to its "." and ".." entries. The PX System Use Entry is + * used to add POSIX file attributes, such as access permissions or user and + * group id, to a ECMA 119 directory record. + * + * See IEEE P1282, section 4.1.1 for more details. + */ void rrip_add_PX(struct ecma119_write_target *, struct ecma119_tree_node *); + +/** + * Add a PN System Use Entry to the given tree node. + * The PN System Use Entry is used to store the device number, and it's + * mandatory if the tree node corresponds to a character or block device. + * + * See IEEE P1282, section 4.1.2 for more details. + */ void rrip_add_PN(struct ecma119_write_target *, struct ecma119_tree_node *); + +/** + * Add a SL System Use Entry to the given tree node. This is used to store + * the content of a symbolic link, and is mandatory if the tree node + * indicates a symbolic link. + * + * See IEEE P1282, section 4.1.3 for more details. + */ void rrip_add_SL(struct ecma119_write_target *, struct ecma119_tree_node *); + +/** + * Add a NM System Use Entry to the given tree node. The purpose of this + * System Use Entry is to store the content of an Alternate Name to support + * POSIX-style or other names. + * + * See IEEE P1282, section 4.1.4 for more details. + */ void rrip_add_NM(struct ecma119_write_target *, struct ecma119_tree_node *); + +/* + * The next 3 System Use Entries are used to handle Deep Directory + * Hierarchies, i.e., hierarchies where the number of directory levels + * exceed the eight limit of ECMA-119. + */ + +/** + * Add to the given tree node a CL System Use Entry, that is used to record + * the new location of a directory which has been relocated. + * + * See IEEE P1282, section 4.1.5.1 for more details. + */ void rrip_add_CL(struct ecma119_write_target *, struct ecma119_tree_node *); + +/** + * Add a PL System Use Entry, used to record the location of the original + * parent directory of a directory which has been relocated. + * + * This is special because it doesn't modify the susp fields of the directory + * that gets passed to it; it modifies the susp fields of the ".." entry in + * that directory. + * + * See IEEE P1282, section 4.1.5.2 for more details. + */ +void rrip_add_PL(struct ecma119_write_target *, struct ecma119_tree_node *); + +/** + * Add a RE System Use Entry to the given tree node. The purpose of the + * this System Use Entry is to indicate to an RRIP-compliant receiving + * system that the Directory Record in which an "RE" System Use Entry is + * recorded has been relocated from another position in the original + * Directory Hierarchy. + * + * See IEEE P1282, section 4.1.5.3 for more details. + */ void rrip_add_RE(struct ecma119_write_target *, struct ecma119_tree_node *); + +/** + * Add to the given tree node a TF System Use Entry, used to record some + * time stamps related to the file. + * + * See IEEE P1282, section 4.1.6 for more details. + */ void rrip_add_TF(struct ecma119_write_target *, struct ecma119_tree_node *); -/* This is special because it doesn't modify the susp fields of the directory - * that gets passed to it; it modifies the susp fields of the ".." entry in - * that directory. */ -void rrip_add_PL(struct ecma119_write_target *, struct ecma119_tree_node *); void rrip_finalize(struct ecma119_write_target *, struct ecma119_tree_node *); diff --git a/libisofs/susp.c b/libisofs/susp.c index a29d8b3..5e9889b 100755 --- a/libisofs/susp.c +++ b/libisofs/susp.c @@ -155,30 +155,6 @@ static void susp_add_ST(struct ecma119_write_target *t, } #endif -/** See IEEE P1281 Draft Version 1.12/5.5 FIXME: this is rockridge */ -void -rrip_add_ER(struct ecma119_write_target *t, struct ecma119_tree_node *dir) -{ - unsigned char *ER = malloc(182); - - assert(dir->type == ECMA119_DIR); - - ER[0] = 'E'; - ER[1] = 'R'; - ER[2] = 182; - ER[3] = 1; - ER[4] = 9; - ER[5] = 72; - ER[6] = 93; - ER[7] = 1; - memcpy(&ER[8], "IEEE_1282", 9); - memcpy(&ER[17], "THE IEEE 1282 PROTOCOL PROVIDES SUPPORT FOR POSIX " - "FILE SYSTEM SEMANTICS.", 72); - memcpy(&ER[89], "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, " - "PISCATAWAY, NJ, USA FOR THE 1282 SPECIFICATION.", 93); - susp_append(t, &dir->info.dir.self_susp, ER); -} - /* calculate the location of the CE areas. Since CE areas don't need to be * aligned to a block boundary, we contatenate all CE areas from a single * directory and dump them immediately after all the directory records. diff --git a/libisofs/susp.h b/libisofs/susp.h index 31dd2cf..5e7b95e 100755 --- a/libisofs/susp.h +++ b/libisofs/susp.h @@ -1,6 +1,10 @@ /* vim: set noet ts=8 sts=8 sw=8 : */ -/** Functions and structures used for SUSP (IEEE 1281). +/** + * Functions and structures used for SUSP (IEEE 1281). + * + * Please refer to IEEE P1281 System Use Sharing Protocol, draft standard + * version 1.12 for more details. */ #ifndef __ISO_SUSP @@ -28,13 +32,23 @@ struct susp_info * will go in a CE area. */ }; +/** + * Add a CE System Use Entry to the given tree node. A "CE" is used to add + * a continuation area, where additional System Use Entry can be written. + * See IEEE P1281, section 5.1. + */ void susp_add_CE(struct ecma119_write_target *, struct ecma119_tree_node *); -/* these next 2 are special because they don't modify the susp fields of the - * directory; they modify the susp fields of the - * "." entry in the directory. */ +/** + * Add a SP System Use Entry to the "." entry of the directory. The SP provide + * an identifier that the SUSP is used within the volume. The SP shall be + * recorded in the "." entry of the root directory. + * See IEEE P1281, section 5.3 for more details. + * + * this is special because it doesn't modify the susp fields of the + * directory; it modifies the susp fields of the "." entry in the directory. + */ void susp_add_SP(struct ecma119_write_target *, struct ecma119_tree_node *); -void rrip_add_ER(struct ecma119_write_target *, struct ecma119_tree_node *); /** Once all the directories and files are laid out, recurse through the tree * and finalize all SUSP CE entries. */