New API call iso_write_opts_set_rr_reloc()
This commit is contained in:
parent
e49f9672bc
commit
76f2a5f4d3
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -89,6 +89,14 @@ void ecma119_image_free(Ecma119Image *t)
|
||||
writer->free_data(writer);
|
||||
free(writer);
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
if (t->rr_reloc_dir != NULL)
|
||||
free(t->rr_reloc_dir);
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
if (t->input_charset != NULL)
|
||||
free(t->input_charset);
|
||||
if (t->output_charset != NULL)
|
||||
@ -1673,6 +1681,22 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
|
||||
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
|
||||
target->dir_rec_mtime = opts->dir_rec_mtime;
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
target->rr_reloc_dir = NULL;
|
||||
if (opts->rr_reloc_dir != NULL) {
|
||||
target->rr_reloc_dir = strdup(opts->rr_reloc_dir);
|
||||
if (target->rr_reloc_dir == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto target_cleanup;
|
||||
}
|
||||
}
|
||||
target->rr_reloc_flags = opts->rr_reloc_flags;
|
||||
target->rr_reloc_node = NULL;
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
target->sort_files = opts->sort_files;
|
||||
|
||||
target->replace_uid = opts->replace_uid ? 1 : 0;
|
||||
@ -2310,6 +2334,69 @@ int bs_set_size(struct burn_source *bs, off_t size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
static
|
||||
int dive_to_depth_8(IsoDir *dir, int depth)
|
||||
{
|
||||
int ret;
|
||||
IsoNode *pos;
|
||||
|
||||
if (depth >= 8)
|
||||
return 1;
|
||||
pos = dir->children;
|
||||
for (pos = dir->children; pos != NULL; pos = pos->next) {
|
||||
if (pos->type != LIBISO_DIR)
|
||||
continue;
|
||||
ret = dive_to_depth_8((IsoDir *) pos, depth + 1);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int make_reloc_dir_if_needed(IsoImage *img, IsoWriteOpts *opts, int flag)
|
||||
{
|
||||
int ret;
|
||||
IsoDir *dir;
|
||||
|
||||
/* Two forms to express the root directory */
|
||||
if (opts->rr_reloc_dir == NULL)
|
||||
return 1;
|
||||
if (opts->rr_reloc_dir[0] == 0)
|
||||
return 1;
|
||||
|
||||
if (strchr(opts->rr_reloc_dir, '/') != NULL)
|
||||
return 0;
|
||||
|
||||
/* Check existence of opts->rr_reloc_dir */
|
||||
ret = iso_dir_get_node(img->root, opts->rr_reloc_dir, NULL);
|
||||
if (ret > 0)
|
||||
return 1;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Check whether there is a directory of depth 8 (root is depth 1) */
|
||||
ret = dive_to_depth_8(img->root, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret == 0)
|
||||
return 1;
|
||||
|
||||
/* Make IsoDir with same permissions as root directory */
|
||||
ret = iso_tree_add_new_dir(img->root, opts->rr_reloc_dir, &dir);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
opts->rr_reloc_flags |= 2; /* Auto-created relocation directory */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
|
||||
int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
|
||||
struct burn_source **burn_src)
|
||||
{
|
||||
@ -2326,6 +2413,16 @@ int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
if (!opts->allow_deep_paths) {
|
||||
ret = make_reloc_dir_if_needed(image, opts, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
ret = ecma119_image_new(image, opts, &target);
|
||||
if (ret < 0) {
|
||||
free(source);
|
||||
@ -2434,6 +2531,13 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||
wopts->fifo_size = 1024; /* 2 MB buffer */
|
||||
wopts->sort_files = 1; /* file sorting is always good */
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
wopts->rr_reloc_dir = NULL;
|
||||
wopts->rr_reloc_flags = 0;
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
wopts->system_area_data = NULL;
|
||||
wopts->system_area_options = 0;
|
||||
wopts->vol_creation_time = 0;
|
||||
@ -2470,6 +2574,14 @@ void iso_write_opts_free(IsoWriteOpts *opts)
|
||||
return;
|
||||
}
|
||||
free(opts->output_charset);
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
if (opts->rr_reloc_dir != NULL)
|
||||
free(opts->rr_reloc_dir);
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
if (opts->system_area_data != NULL)
|
||||
free(opts->system_area_data);
|
||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||
@ -2711,6 +2823,22 @@ int iso_write_opts_set_dir_rec_mtime(IsoWriteOpts *opts, int allow)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_rr_reloc(IsoWriteOpts *opts, char *name, int flags)
|
||||
{
|
||||
if (opts->rr_reloc_dir != name) {
|
||||
if (opts->rr_reloc_dir != NULL)
|
||||
free(opts->rr_reloc_dir);
|
||||
opts->rr_reloc_dir = NULL;
|
||||
if (name != NULL) {
|
||||
opts->rr_reloc_dir = strdup(name);
|
||||
if (opts->rr_reloc_dir == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
}
|
||||
opts->rr_reloc_flags = flags & 1;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_sort_files(IsoWriteOpts *opts, int sort)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -206,6 +206,24 @@ struct iso_write_opts {
|
||||
*/
|
||||
unsigned int dir_rec_mtime :3;
|
||||
|
||||
/**
|
||||
* This describes the directory where to store Rock Ridge relocated
|
||||
* directories.
|
||||
* If not relaxation "allow_deep_paths" is in effect, it is necessary to
|
||||
* relocate directories so that no ECMA-119 file path has more than
|
||||
* 8 components. For Rock Ridge the relocated directories are linked forth
|
||||
* and back to a placeholder at their original position in path level 8
|
||||
* (entries CL and PL). Directories marked by entry RE are to be considered
|
||||
* artefacts of relocation and shall not be read into a Rock Ridge tree.
|
||||
* For plain ECMA-119, the relocation directory is just a normal directory
|
||||
* which contains normal files and directories.
|
||||
*/
|
||||
char *rr_reloc_dir; /* IsoNode name in root directory */
|
||||
int rr_reloc_flags; /* bit0= mark auto-created rr_reloc_dir by RE
|
||||
bit1= directory was auto-created
|
||||
(cannot be set via API)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Compute MD5 checksum for the whole session and record it as index 0 of
|
||||
* the checksum blocks after the data area of the session. The layout and
|
||||
@ -482,6 +500,12 @@ struct ecma119_image
|
||||
*/
|
||||
unsigned int dir_rec_mtime :3;
|
||||
|
||||
/* The ECMA-119 directory where to store Rock Ridge relocated directories.
|
||||
*/
|
||||
char *rr_reloc_dir; /* IsoNode name in root directory */
|
||||
int rr_reloc_flags;
|
||||
Ecma119Node *rr_reloc_node; /* Directory node in ecma119_image */
|
||||
|
||||
unsigned int md5_session_checksum :1;
|
||||
unsigned int md5_file_checksums :2;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -434,6 +434,20 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
||||
if (ret < 0) {
|
||||
goto ex;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
if (depth == 1) { /* root is default */
|
||||
image->rr_reloc_node = node;
|
||||
} else if (depth == 2) { /* directories in root may be used */
|
||||
if (image->rr_reloc_dir != NULL)
|
||||
if (strcmp(iso->name, image->rr_reloc_dir) == 0)
|
||||
image->rr_reloc_node = node;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
|
||||
}
|
||||
ret = ISO_SUCCESS;
|
||||
pos = dir->children;
|
||||
@ -750,7 +764,7 @@ int mangle_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
||||
}
|
||||
|
||||
static
|
||||
int mangle_tree(Ecma119Image *img, int recurse)
|
||||
int mangle_tree(Ecma119Image *img, Ecma119Node *dir, int recurse)
|
||||
{
|
||||
int max_file, max_dir;
|
||||
Ecma119Node *root;
|
||||
@ -765,7 +779,9 @@ int mangle_tree(Ecma119Image *img, int recurse)
|
||||
} else {
|
||||
max_file = max_dir = 31;
|
||||
}
|
||||
if (img->eff_partition_offset > 0) {
|
||||
if (dir != NULL) {
|
||||
root = dir;
|
||||
} else if (img->eff_partition_offset > 0) {
|
||||
root = img->partition_root;
|
||||
} else {
|
||||
root = img->root;
|
||||
@ -891,17 +907,34 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir, int level, int pathlen)
|
||||
{
|
||||
int ret;
|
||||
size_t max_path;
|
||||
Ecma119Node *root;
|
||||
Ecma119Node *reloc;
|
||||
|
||||
max_path = pathlen + 1 + max_child_name_len(dir);
|
||||
|
||||
if (level > 8 || max_path > 255) {
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
reloc = img->rr_reloc_node;
|
||||
if (reloc == NULL) {
|
||||
if (img->eff_partition_offset > 0) {
|
||||
root = img->partition_root;
|
||||
reloc = img->partition_root;
|
||||
} else {
|
||||
root = img->root;
|
||||
reloc = img->root;
|
||||
}
|
||||
ret = reparent(dir, root);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (img->eff_partition_offset > 0) {
|
||||
reloc = img->partition_root;
|
||||
} else {
|
||||
reloc = img->root;
|
||||
}
|
||||
|
||||
#endif /* ! Libisofs_with_rr_reloc_diR */
|
||||
|
||||
ret = reparent(dir, reloc);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -1115,6 +1148,8 @@ int ecma119_tree_create(Ecma119Image *img)
|
||||
img->root = root;
|
||||
}
|
||||
|
||||
/* >>> ts B20307 : Shouldn't relocation be done here ? */
|
||||
|
||||
iso_msg_debug(img->image->id, "Matching hardlinks...");
|
||||
ret = match_hardlinks(img, root, 0);
|
||||
if (ret < 0) {
|
||||
@ -1125,14 +1160,14 @@ int ecma119_tree_create(Ecma119Image *img)
|
||||
sort_tree(root);
|
||||
|
||||
iso_msg_debug(img->image->id, "Mangling names...");
|
||||
ret = mangle_tree(img, 1);
|
||||
ret = mangle_tree(img, NULL, 1);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (img->rockridge && !img->allow_deep_paths) {
|
||||
|
||||
/* reorder the tree, acording to RRIP, 4.1.5 */
|
||||
/* Relocate deep directories, acording to RRIP, 4.1.5 */
|
||||
ret = reorder_tree(img, root, 1, 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@ -1143,7 +1178,15 @@ int ecma119_tree_create(Ecma119Image *img)
|
||||
* above could insert new directories into the root.
|
||||
* Note that recurse = 0, as we don't need to recurse.
|
||||
*/
|
||||
ret = mangle_tree(img, 0);
|
||||
|
||||
/* >>> ts B20307 : Shouldn't one mangle _after_ relocating ? */
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
ret = mangle_tree(img, img->rr_reloc_node, 0);
|
||||
#else
|
||||
ret = mangle_tree(img, NULL, 0);
|
||||
#endif
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -1536,6 +1536,45 @@ int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit);
|
||||
*/
|
||||
int iso_write_opts_set_allow_deep_paths(IsoWriteOpts *opts, int allow);
|
||||
|
||||
/**
|
||||
* This call describes the directory where to store Rock Ridge relocated
|
||||
* directories.
|
||||
* If not iso_write_opts_set_allow_deep_paths(,1) is in effect, then it is
|
||||
* necessary to relocate directories so that no ECMA-119 file path
|
||||
* has more than 8 components. These directories are grafted into either
|
||||
* the root directory of the ISO image or into a dedicated relocation
|
||||
* directory.
|
||||
* For Rock Ridge, the relocated directories are linked forth and back to
|
||||
* placeholders at their original positions in path level 8. Directories
|
||||
* marked by Rock Ridge entry RE are to be considered artefacts of relocation
|
||||
* and shall not be read into a Rock Ridge tree. Instead they are to be read
|
||||
* via their placeholders and their links.
|
||||
* For plain ECMA-119, the relocation directory and the relocated directories
|
||||
* are just normal directories which contain normal files and directories.
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param name
|
||||
* The name of the relocation directory in the root directory. Do not
|
||||
* prepend "/". An empty name or NULL will direct relocated directories
|
||||
* into the root directory. This is the default.
|
||||
* If the given name does not exist in the root directory when
|
||||
* iso_image_create_burn_source() is called, and if there are directories
|
||||
* at path level 8, then directory /name will be created automatically.
|
||||
* The name given by this call will be compared with iso_node_get_name()
|
||||
* of the directories in the root directory, not with the final ECMA-119
|
||||
* names of those directories.
|
||||
* @parm flags
|
||||
* Bitfield for control purposes.
|
||||
* bit0= Mark the relocation directory by a Rock Ridge RE entry, if it
|
||||
* gets created during iso_image_create_burn_source(). This will
|
||||
* make it invisible for most Rock Ridge readers.
|
||||
* bit1= not settable via API (used internally)
|
||||
* @return
|
||||
* 1 success, < 0 error
|
||||
* @since 1.2.2
|
||||
*/
|
||||
int iso_write_opts_set_rr_reloc(IsoWriteOpts *opts, char *name, int flags);
|
||||
|
||||
/**
|
||||
* Allow path in the ISO-9660 tree to have more than 255 characters.
|
||||
* This breaks ECMA-119 specification. Use with caution.
|
||||
@ -7170,6 +7209,11 @@ struct burn_source {
|
||||
/* currently none being tested */
|
||||
|
||||
|
||||
/* Perform the operations promised by iso_write_opts_set_rr_reloc() */
|
||||
#define Libisofs_with_rr_reloc_diR yes
|
||||
|
||||
|
||||
|
||||
/* ---------------------------- Experiments ---------------------------- */
|
||||
|
||||
|
||||
|
@ -301,6 +301,7 @@ iso_write_opts_set_relaxed_vol_atts;
|
||||
iso_write_opts_set_replace_mode;
|
||||
iso_write_opts_set_replace_timestamps;
|
||||
iso_write_opts_set_rockridge;
|
||||
iso_write_opts_set_rr_reloc;
|
||||
iso_write_opts_set_rrip_1_10_px_ino;
|
||||
iso_write_opts_set_rrip_version_1_10;
|
||||
iso_write_opts_set_scdbackup_tag;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -406,12 +406,15 @@ int rrip_SL_append_comp(size_t *n, uint8_t ***comps, char *s, int size, char fl)
|
||||
#ifdef Libisofs_with_rrip_rR
|
||||
|
||||
/**
|
||||
* Add to the given tree node a RR System Use Entry. This is an obsolete
|
||||
* entry from before RRIP-1.10. Nevertheless mkisofs produces it and there
|
||||
* is the suspicion that Solaris takes it as indication for Rock Ridge.
|
||||
* Add a RR System Use Entry to the given tree node. This is an obsolete
|
||||
* entry from before RRIP-1.10. Nevertheless mkisofs produces it. There
|
||||
* is the suspicion that some operating systems could take it as indication
|
||||
* for Rock Ridge.
|
||||
*
|
||||
* I once saw a copy of a RRIP spec which mentioned RR. Here i just use
|
||||
* the same constant 5 bytes as produced by mkisofs.
|
||||
* The meaning of the payload byte is documented e.g. in
|
||||
* /usr/src/linux/fs/isofs/rock.h
|
||||
* It announces the presence of entries PX, PN, SL, NM, CL, PL, RE, TF
|
||||
* by payload byte bits 0 to 7.
|
||||
*/
|
||||
static
|
||||
int rrip_add_RR(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||
@ -426,7 +429,14 @@ int rrip_add_RR(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||
RR[1] = 'R';
|
||||
RR[2] = 5;
|
||||
RR[3] = 1;
|
||||
RR[4] = 0201;
|
||||
|
||||
/* <<< ts B20307 : Not all directories have NM, many files have more entries */
|
||||
RR[4] = 0x89; /* TF, NM , PX */
|
||||
|
||||
/* >>> ts B20307 : find out whether n carries
|
||||
PX, PN, SL, NM, CL, PL, RE, TF and mark by bit0 to bit7 in RR[4]
|
||||
*/
|
||||
|
||||
return susp_append(t, susp, RR);
|
||||
}
|
||||
|
||||
@ -1422,6 +1432,18 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
goto add_susp_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
} else if(t->rr_reloc_node == n && n != t->root &&
|
||||
(t->rr_reloc_flags & 3) == 3) {
|
||||
/* The dedicated relocation directory shall be marked by RE */
|
||||
ret = rrip_add_RE(t, node, info);
|
||||
if (ret < 0)
|
||||
goto add_susp_cleanup;
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
}
|
||||
} else if (n->type == ECMA119_SPECIAL) {
|
||||
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {
|
||||
|
Loading…
Reference in New Issue
Block a user