diff --git a/demo/iso.c b/demo/iso.c index 2fdaf0e..fd9b612 100644 --- a/demo/iso.c +++ b/demo/iso.c @@ -31,7 +31,15 @@ int main(int argc, char **argv) 1, /* rockridge */ 0, /* omit_version_numbers */ 0, /* allow_deep_paths */ - 0 /* sort files */ + 0, /* sort files */ + 0, /* replace_dir_mode */ + 0, /* replace_file_mode */ + 0, /* replace_uid */ + 0, /* replace_gid */ + 0, /* dir_mode */ + 0, /* file_mode */ + 0, /* uid */ + 0 /* gid */ }; if (argc < 2) { diff --git a/src/ecma119.c b/src/ecma119.c index a0d60fb..7752242 100644 --- a/src/ecma119.c +++ b/src/ecma119.c @@ -735,6 +735,16 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts, target->omit_version_numbers = opts->omit_version_numbers; target->allow_deep_paths = opts->allow_deep_paths; target->sort_files = opts->sort_files; + + target->replace_uid = opts->replace_uid ? 1 : 0; + target->replace_gid = opts->replace_gid ? 1 : 0; + target->replace_dir_mode = opts->replace_dir_mode ? 1 : 0; + target->replace_file_mode = opts->replace_file_mode ? 1 : 0; + + target->uid = opts->replace_uid == 2 ? opts->uid : 0; + target->gid = opts->replace_gid == 2 ? opts->gid : 0; + target->dir_mode = opts->replace_dir_mode == 2 ? opts->dir_mode : 0555; + target->file_mode = opts->replace_file_mode == 2 ? opts->file_mode : 0444; target->now = time(NULL); target->ms_block = 0; diff --git a/src/ecma119.h b/src/ecma119.h index 915bccb..f998ea2 100644 --- a/src/ecma119.h +++ b/src/ecma119.h @@ -35,23 +35,22 @@ struct ecma119_image { /* relaxed constraints */ unsigned int omit_version_numbers:1; unsigned int allow_deep_paths:1; - // int relaxed_constraints; /**< see ecma119_relaxed_constraints_flag */ -// -// int replace_mode; /**< Replace ownership and modes of files -// * -// * 0. filesystem values -// * 1. useful values -// * bits 1-4 bitmask: -// * 2 - replace dir -// * 3 - replace file -// * 4 - replace gid -// * 5 - replace uid -// */ -// mode_t dir_mode; -// mode_t file_mode; -// gid_t gid; -// uid_t uid; + + /* + * Mode replace. If one of these flags is set, the correspodent values are + * replaced with values below. + */ + unsigned int replace_uid:1; + unsigned int replace_gid:1; + unsigned int replace_file_mode:1; + unsigned int replace_dir_mode:1; + + uid_t uid; + gid_t gid; + mode_t file_mode; + mode_t dir_mode; + int sort_files; /**< if sort files or not. Sorting is based of * the weight of each file */ diff --git a/src/libisofs.h b/src/libisofs.h index 5a7a96f..2453a95 100644 --- a/src/libisofs.h +++ b/src/libisofs.h @@ -79,41 +79,30 @@ typedef struct { * its size. In those cases, we only copy 1 block of data. */ + /**< If files should be sorted based on their weight. */ 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. */ + + /** + * The following options set the default values for files and directory + * permissions, gid and uid. All these take one of three values: 0, 1 or 2. + * If 0, the corresponding attribute will be kept as setted in the IsoNode. + * Unless you have changed it, it corresponds to the value on disc, so it + * is suitable for backup purposes. If set to 1, the corresponding attrib. + * will be changed by a default suitable value. Finally, if you set it to + * 2, the attrib. will be changed with the value specified in the options + * below. Note that for mode attributes, only the permissions are set, the + * file type remains unchanged. + */ + unsigned int replace_dir_mode:2; + unsigned int replace_file_mode:2; + unsigned int replace_uid:2; + unsigned int replace_gid:2; + + mode_t dir_mode; /** Mode to use on dirs when replace_dir_mode == 2. */ + mode_t file_mode; /** Mode to use on files when replace_file_mode == 2. */ + gid_t gid; /** gid to use when replace_gid == 2. */ + uid_t uid; /** uid to use when replace_uid == 2. */ + // char *input_charset; /**< NULL to use default charset */ // char *ouput_charset; /**< NULL to use default charset */ // uint32_t ms_block; diff --git a/src/rockridge.c b/src/rockridge.c index d81fbd7..10365fb 100644 --- a/src/rockridge.c +++ b/src/rockridge.c @@ -43,6 +43,41 @@ int susp_append_ce(Ecma119Image *t, struct susp_info *susp, uint8_t *data) return ISO_SUCCESS; } +static +uid_t px_get_uid(Ecma119Image *t, Ecma119Node *n) +{ + if (t->replace_uid) { + return t->uid; + } else { + return n->node->uid; + } +} + +static +uid_t px_get_gid(Ecma119Image *t, Ecma119Node *n) +{ + if (t->replace_gid) { + return t->gid; + } else { + return n->node->gid; + } +} + +static +mode_t px_get_mode(Ecma119Image *t, Ecma119Node *n) +{ + if ((n->type == ECMA119_DIR || n->type == ECMA119_PLACEHOLDER)) { + if (t->replace_dir_mode) { + return (n->node->mode & S_IFMT) | t->dir_mode; + } + } else { + if (t->replace_file_mode) { + return (n->node->mode & S_IFMT) | t->file_mode; + } + } + return n->node->mode; +} + /** * Add a PX System Use Entry. The PX System Use Entry is used to add POSIX * file attributes, such as access permissions or user and group id, to a @@ -60,10 +95,10 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp) PX[1] = 'X'; PX[2] = 44; PX[3] = 1; - iso_bb(&PX[4], n->node->mode, 4); + iso_bb(&PX[4], px_get_mode(t, n), 4); iso_bb(&PX[12], n->nlink, 4); - iso_bb(&PX[20], n->node->uid, 4); - iso_bb(&PX[28], n->node->gid, 4); + iso_bb(&PX[20], px_get_uid(t, n), 4); + iso_bb(&PX[28], px_get_gid(t, n), 4); iso_bb(&PX[36], n->ino, 4); return susp_append(t, susp, PX); diff --git a/test/test_rockridge.c b/test/test_rockridge.c index 8a34b37..50e63b6 100644 --- a/test/test_rockridge.c +++ b/test/test_rockridge.c @@ -204,6 +204,8 @@ void test_rrip_get_susp_fields_file() Ecma119Image t; uint8_t *entry; + memset(&t, 0, sizeof(Ecma119Image)); + file = malloc(sizeof(IsoFile)); CU_ASSERT_PTR_NOT_NULL_FATAL(file); file->msblock = 0;