Compare commits

...

18 Commits

Author SHA1 Message Date
125789feef Version leap to 1.2.2 2012-04-02 19:00:27 +02:00
37efffcf26 Removed obsolete development comments 2012-04-02 11:36:16 +02:00
b2c281d0c6 Updated ChangeLog 2012-03-27 13:51:52 +02:00
8a2fa9fe2e New API call iso_write_opts_set_allow_7bit_ascii(). 2012-03-22 11:18:44 +01:00
1247edff95 Reacted on warnings of cppcheck. 2012-03-21 20:28:15 +01:00
a2fe1a4100 Corrected flaws of revision 926. 2012-03-14 13:50:46 +01:00
4eb4146474 Improved standards compliance for ISO level 1 names with partly relaxed
constraints.
2012-03-14 09:07:59 +01:00
ce35aefb32 Bug fix: Directory name mapping to ISO level 1 was too liberal if
iso_write_opts_set_allow_dir_id_ext() was enabled.
2012-03-13 09:38:29 +01:00
269e0b19a5 Improved the ISO level 1 mapping of file names which begin by a dot. 2012-03-13 09:20:20 +01:00
0a8bb0e9b8 Made sure that empty relocation directory name leads to root directory. 2012-03-10 11:29:03 +01:00
76f2a5f4d3 New API call iso_write_opts_set_rr_reloc() 2012-03-09 19:59:51 +01:00
e49f9672bc Disabled skipping of ECMA-119 directory /RR_MOVED by name. 2012-03-06 16:18:05 +01:00
37f880797d Small comment change in libisofs/libisofs.h 2012-03-06 15:14:45 +01:00
475eb36978 Small change in doc/iso_hybrid_fs.txt 2012-03-06 15:13:45 +01:00
ac9116c64e Fixed a typo in doc/iso_hybrid_fs.txt 2012-02-22 18:06:23 +01:00
b1c218c280 Described the opportunities and constraints of ISO 9660 hybrid fileystems,
and the libisofs implementation needs when adding further filesystem types.
2012-02-21 22:30:29 +01:00
ebea7c29ef Reporting name of base file with error message for filtered streams 2012-02-11 19:09:40 +01:00
09c49f777a Version leap to 1.2.1 2012-01-27 15:57:45 +01:00
15 changed files with 747 additions and 72 deletions

View File

@ -1,3 +1,13 @@
bzr branch lp:libisofs/for-libisoburn (to become libisofs-1.2.2.tar.gz)
===============================================================================
* New API call iso_write_opts_set_rr_reloc()
* Bug fix: Directory name mapping to ISO level 1 was too liberal if
iso_write_opts_set_allow_dir_id_ext() was enabled
* New API call iso_write_opts_set_allow_7bit_ascii()
* Improved standards compliance for ISO level 1 names with partly relaxed
constraints.
libisofs-1.2.0.tar.gz Sat Jan 28 2012
===============================================================================
* Extended influence of iso_write_opts_set_dir_rec_mtime() to Joliet and

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.2.0], [http://libburnia-project.org])
AC_INIT([libisofs], [1.2.2], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -41,7 +41,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=2
LIBISOFS_MICRO_VERSION=0
LIBISOFS_MICRO_VERSION=2
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -52,9 +52,9 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2012.01.28 development jump has not yet happened
# SONAME = 62 - 56 = 6 . Library name = libisofs.6.56.0
LT_CURRENT=62
LT_AGE=56
# SONAME = 64 - 58 = 6 . Library name = libisofs.6.58.0
LT_CURRENT=64
LT_AGE=58
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`

159
doc/iso_hybrid_fs.txt Normal file
View File

@ -0,0 +1,159 @@
Overview of ISO 9660 hybrid filesystems as libisofs output
by Thomas Schmitt - mailto:scdbackup@gmx.net
Libburnia project - mailto:libburn-hackers@pykix.org
21 Feb 2012
The overall framework for the filesystem images produced by libisofs is given
by ECMA-119, which is also known as ISO 9660. The hybrid aspect is the
opportunity to add access structures of other filesystems.
The framework suggests a logical block size of 2048 and divides the space of
filesystem blocks into several parts:
- The System Area. Beginning at the image start block.
32 KiB of arbitrary data, which are not considered to be
part of structure or payload of the ISO image.
- The Volume Descriptors. Beginning at image start block + 16.
The Primary Volume Descriptor block is the starting point of the ECMA-119
tree of directories and files. Among other information, it records the size
of the image block space. Other descriptor blocks may lead to boot images
or to the directory trees of add-on filesystems (e.g. Joliet).
- The area of directory structures and data file content.
libisofs divides it into two sub areas:
- Directory structures.
They record the file names and attributes of the ECMA-119 tree and
of eventual add-on filesystem.
- Data file content.
The blocks in this area are referred by zero or more file entries in the
directory trees. They store the data content or regular files. Start block
address of a file and exact byte count are stored in the trees.
libisofs may slide-in some data blocks which are neither part of the structure
nor part of file content. See doc/checksums.txt, Checksum Array, Checksum Tags.
In the same way, the superblocks of other filesystems could be inserted into
the image.
The only block addresses which are fixely occupied are image_start+16 (Primary
Volume Descriptor) and image_start+17 (first possible position of Volume
Descriptor Set Terminator).
Nevertheless, libisofs considers as reserved the blocks image_start+16 to
image_start+31, because add-ons like El Torito, Joliet, or ISO 9660:1999
need their own volume descriptors stored before the volume descriptor set
terminator block. Only one volume descriptor per add-on filesystem may be
written there, and its exact position will be chosen by libisofs.
The System Area in image_start to image_start+15 may be used for a partition
table or the superblock of an additional filesystem structure.
Another place for superblocks is after image_start+31. E.g. UDF stores its
Anchor at block address 256, or at media_size - 1 - 256, or at media_size - 1.
In both cases the superblocks would point to filesystem-specific data which
are stored in the area of directory structures. These data would then refer to
the same file contents as the ECMA-119 directory structure.
-----------------------------------------------------------------------
What libisofs needs to get implemented for a new add-on filesystem:
The emerging overall image is represented by an Ecma119Image object.
This is an instance of quite fat struct ecma119_image which, among many
others, holds some parameters which are specific to the implemented add-on
filesystems. It is defined in libisofs/ecma119.h.
It gets programmed by applications via API calls for IsoWriteOpts which is
defined as struct iso_write_opts in libisofs/ecma119.h.
The content of the System Area may be submitted opaquely via
Ecma119Image.system_area_data or it may get generated underneath
libisofs/system_area.c:iso_write_system_area() by a specific "System area type"
in Ecma119Image.system_area_options. The latter happens when the block adresses
of all components, directories, and files are determined. (One may have to
dig deep in the graph of objects to obtain everything.)
If a new system area type is needed, then it has to be documented in
libisofs/ecma119.h at struct ecma119_image.system_area_options and in
libisofs/libisofs.h at call iso_write_opts_set_system_area(). See e.g.
"MIPS Big Endian Volume Header".
The layout of the areas above image_start+16 is defined in function
libisofs/ecma119.c:ecma119_image_new(). This is done by creating and
registering writer objects.
Writers are instances of typedef struct Iso_Image_Writer IsoImageWriter.
The struct is defined in libisofs/writer.h.
The Joliet writer is a comprehensive example of an add-on filesystem writer.
First it gets counted for the allocation of the registration array
if (target->joliet) {
nwriters++;
}
Later it gets created and registered
if (target->joliet) {
ret = joliet_writer_create(target);
The function libisofs/joliet.c:joliet_writer_create() accounts for one block
that will hold the Joliet volume descriptor
/* we need the volume descriptor */
target->curblock++;
Not all add-on filesystems will need a volume descriptor. Joliet does.
joliet_writer_create() further generates a tree of JolietNode objects by
traversing the image model tree of IsoNode objects.
ret = joliet_tree_create(target);
If a JolietNode represents a regular file then it refers to an IsoFileSrc
object, which represents its data content in the emerging image.
struct Iso_File_Src is defined in libisofs/filesrc.h.
libisofs will call the methods of the writer object when it computes the
block addresses of the various image components, when it writes volume
descriptors, when it writes directory trees, and when it finally disposes the
Ecma119Image object.
The method IsoImageWriter.compute_data_blocks() has to predict the storage
needs in the area of directory trees.
It computes and records Joliet-specific addresses and sizes:
Ecma119Image.joliet_ndirs, Ecma119Image.joliet_l_path_table_pos,
Ecma119Image.joliet_m_path_table_pos , Ecma119Image.joliet_path_table_size
Ecma119Image.j_part_l_path_table_pos, Ecma119Image.j_part_m_path_table_pos
as well as the sizes and block addresses of Joliet directories.
It increases the counter of virtually written blocks:
Ecma119Image.curblock
which is used to determine the start addresses of the image parts and
finally gives the overall image size.
The method IsoImageWriter.write_vol_desc() composes and writes the Joliet
volume descriptor. (Such writing is not necessarily needed for add-on
filesystems.)
IsoImageWriter.write_data() writes the records of the Joliet directory tree.
This has to be exactly the same number of blocks by which Ecma119Image.curblock
was increased during IsoImageWriter.compute_data_blocks().
When it gets called, the number of content data extents, their sizes, and their
addresses are known: JolietNode.IsoFileSrc->nsections, ->sections[].size,
->sections[].block.
struct iso_file_section is defined in libisofs/libisofs.h.
IsoImageWriter.free_data() disposes the writer and the JolietNode tree.
-------------------------------------------------------------------------------
This text is under
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
It shall only be modified in sync with libisofs. Please mail change requests to
mailing list <libburn-hackers@pykix.org> or to the copyright holder in private.
If you make use of the license to derive modified versions of libisofs then
you are entitled to modify this text under that same license.

View File

@ -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)
@ -1666,6 +1674,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->no_force_dots = opts->no_force_dots;
target->allow_lowercase = opts->allow_lowercase;
target->allow_full_ascii = opts->allow_full_ascii;
target->allow_7bit_ascii = opts->allow_7bit_ascii;
target->relaxed_vol_atts = opts->relaxed_vol_atts;
target->joliet_longer_paths = opts->joliet_longer_paths;
target->joliet_long_names = opts->joliet_long_names;
@ -1673,6 +1682,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 +2335,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 +2414,18 @@ 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) {
free(source);
return ret;
}
}
#endif /* Libisofs_with_rr_reloc_diR */
ret = ecma119_image_new(image, opts, &target);
if (ret < 0) {
free(source);
@ -2434,6 +2534,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 +2577,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++)
@ -2642,6 +2757,16 @@ int iso_write_opts_set_allow_full_ascii(IsoWriteOpts *opts, int allow)
return ISO_SUCCESS;
}
int iso_write_opts_set_allow_7bit_ascii(IsoWriteOpts *opts, int allow)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->allow_7bit_ascii = allow ? 1 : 0;
return ISO_SUCCESS;
}
int iso_write_opts_set_relaxed_vol_atts(IsoWriteOpts *opts, int allow)
{
if (opts == NULL) {
@ -2711,6 +2836,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) {

View File

@ -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
@ -149,6 +149,13 @@ struct iso_write_opts {
*/
unsigned int allow_full_ascii :1;
/**
* If not allow_full_ascii is set: allow all 7 bit characters that would
* be allowed by allow_full_ascii. But still map lowercase to uppercase if
* not allow_lowercase is set to 1.
*/
unsigned int allow_7bit_ascii :1;
/**
* Allow all characters to be part of Volume and Volset identifiers on
* the Primary Volume Descriptor. This breaks ISO-9660 contraints, but
@ -206,6 +213,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
@ -459,6 +484,7 @@ struct ecma119_image
unsigned int no_force_dots :2;
unsigned int allow_lowercase :1;
unsigned int allow_full_ascii :1;
unsigned int allow_7bit_ascii :1;
unsigned int relaxed_vol_atts : 1;
@ -482,6 +508,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;

View File

@ -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
@ -32,7 +32,7 @@
static
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
{
int ret, relaxed, free_ascii_name= 0, force_dots = 0, max_len;
int ret, relaxed, free_ascii_name= 0, force_dots = 0;
char *ascii_name;
char *isoname= NULL;
@ -59,6 +59,8 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
} else {
relaxed = (int)img->allow_lowercase;
}
if (img->allow_7bit_ascii)
relaxed |= 4;
if (iso->type == LIBISO_DIR && !(img->allow_dir_id_ext)) {
if (img->untranslated_name_len > 0) {
if (strlen(ascii_name) > img->untranslated_name_len) {
@ -73,11 +75,22 @@ needs_transl:;
} else if (img->max_37_char_filenames) {
isoname = iso_r_dirid(ascii_name, 37, relaxed);
} else if (img->iso_level == 1) {
#ifdef Libisofs_old_ecma119_nameS
if (relaxed) {
isoname = iso_r_dirid(ascii_name, 8, relaxed);
} else {
isoname = iso_1_dirid(ascii_name);
isoname = iso_1_dirid(ascii_name, 0);
}
#else /* Libisofs_old_ecma119_nameS */
isoname = iso_1_dirid(ascii_name, relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
} else {
if (relaxed) {
isoname = iso_r_dirid(ascii_name, 31, relaxed);
@ -94,7 +107,12 @@ needs_transl:;
} else if (img->max_37_char_filenames) {
isoname = iso_r_fileid(ascii_name, 36, relaxed, force_dots);
} else if (img->iso_level == 1) {
if (relaxed || !force_dots) {
#ifdef Libisofs_old_ecma119_nameS
int max_len;
if (relaxed) {
if (strchr(ascii_name, '.') == NULL)
max_len = 8;
else
@ -102,8 +120,15 @@ needs_transl:;
isoname = iso_r_fileid(ascii_name, max_len, relaxed,
force_dots);
} else {
isoname = iso_1_fileid(ascii_name);
isoname = iso_1_fileid(ascii_name, 0, force_dots);
}
#else /* Libisofs_old_ecma119_nameS */
isoname = iso_1_fileid(ascii_name, relaxed, force_dots);
#endif /* ! Libisofs_old_ecma119_nameS */
} else {
if (relaxed || !force_dots) {
isoname = iso_r_fileid(ascii_name, 30, relaxed, force_dots);
@ -126,6 +151,21 @@ needs_transl:;
}
}
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node)
{
#ifdef Libisofs_with_rr_reloc_diR
if (img->rr_reloc_node == node &&
node != img->root && node != img->partition_root &&
(img->rr_reloc_flags & 2))
return 1;
#endif /* Libisofs_with_rr_reloc_diR */
return 0;
}
static
int create_ecma119_node(Ecma119Image *img, IsoNode *iso, Ecma119Node **node)
{
@ -434,6 +474,22 @@ 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 as relocation dir */
if (image->rr_reloc_dir != NULL)
if (image->rr_reloc_dir[0] != 0 &&
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 +806,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 +821,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;
@ -887,43 +945,77 @@ int reparent(Ecma119Node *child, Ecma119Node *parent)
* 1 success, < 0 error
*/
static
int reorder_tree(Ecma119Image *img, Ecma119Node *dir, int level, int pathlen)
int reorder_tree(Ecma119Image *img, Ecma119Node *dir,
int dir_level, int dir_pathlen)
{
int ret;
size_t max_path;
Ecma119Node *root;
int ret, level, pathlen, newpathlen;
size_t max_path, i;
Ecma119Node *reloc, *child;
/* might change by relocation */
level = dir_level;
pathlen = dir_pathlen;
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;
}
if (reloc == img->root || reloc == img->partition_root) {
/*
* we are appended to the root's children now, so there is no
* need to recurse (the root will hit us again)
*/
} else {
size_t i;
return ISO_SUCCESS;
}
/* dir is now the relocated Ecma119Node */
pathlen = 37 + 1; /* The dir name might get longer by mangling */
level = 2;
if (img->rr_reloc_dir != NULL) {
pathlen += strlen(img->rr_reloc_node->iso_name) + 1;
if(img->rr_reloc_dir[0] != 0)
level = 3;
}
}
if (ecma119_is_dedicated_reloc_dir(img, (Ecma119Node *) dir))
return ISO_SUCCESS;
for (i = 0; i < dir->info.dir->nchildren; i++) {
Ecma119Node *child = dir->info.dir->children[i];
child = dir->info.dir->children[i];
if (child->type == ECMA119_DIR) {
int newpathlen = pathlen + 1 + strlen(child->iso_name);
newpathlen = pathlen + 1 + strlen(child->iso_name);
ret = reorder_tree(img, child, level + 1, newpathlen);
if (ret < 0) {
if (ret < 0)
return ret;
}
}
}
}
return ISO_SUCCESS;
}
@ -1125,14 +1217,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;
@ -1140,10 +1232,16 @@ int ecma119_tree_create(Ecma119Image *img)
/*
* and we need to remangle the root directory, as the function
* above could insert new directories into the root.
* above could insert new directories into the relocation directory.
* Note that recurse = 0, as we don't need to recurse.
*/
ret = mangle_tree(img, 0);
#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;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* 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
@ -96,5 +97,11 @@ void ecma119_node_free(Ecma119Node *node);
*/
Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node);
/**
* Tell whether node is a dedicated relocation directory which only contains
* relocated directories.
*/
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node);
#endif /*LIBISO_ECMA119_TREE_H_*/

View File

@ -26,6 +26,8 @@
#include <string.h>
#include <limits.h>
/* <<< */
#include <stdio.h>
#ifdef Xorriso_standalonE
@ -345,6 +347,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
void *ctx= NULL;
char md5[16], pre_md5[16];
int pre_md5_valid = 0;
IsoStream *stream, *inp;
#ifdef Libisofs_with_libjtE
int jte_begun = 0;
#endif
@ -381,7 +384,14 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
}
res = filesrc_open(file);
iso_stream_get_file_name(file->stream, name);
/* Get file name from end of filter chain */
for (stream = file->stream; ; stream = inp) {
inp = iso_stream_get_input_stream(stream, 0);
if (inp == NULL)
break;
}
iso_stream_get_file_name(stream, name);
if (res < 0) {
/*
* UPS, very ugly error, the best we can do is just to write

View File

@ -141,11 +141,12 @@ void update_next(IsoDirIter *iter)
static
int find_iter_next(IsoDirIter *iter, IsoNode **node)
{
struct find_iter_data *data = iter->data;
struct find_iter_data *data;
if (iter == NULL || node == NULL) {
return ISO_NULL_POINTER;
}
data = iter->data;
if (data->err < 0) {
return data->err;

View File

@ -522,18 +522,30 @@ int read_dir(ImageFileSourceData *data)
continue;
}
/*
/* (Vreixo:)
* What about ignoring files with existence flag?
* if (record->flags[0] & 0x01)
* continue;
* ts B20306 : >>> One should rather record that flag and write it
* >>> to the new image.
*/
/*
#ifdef Libisofs_wrongly_skip_rr_moveD
/* ts B20306 :
This skipping by name is wrong resp. redundant:
If no rr reading is enabled, then it is the only access point for
the content of relocated directories. So one should not ignore it.
If rr reading is enabled, then the RE entry of mkisofs' RR_MOVED
will cause it to be skipped.
*/
/* (Vreixo:)
* For a extrange reason, mkisofs relocates directories under
* a RR_MOVED dir. It seems that it is only used for that purposes,
* and thus it should be removed from the iso tree before
* generating a new image with libisofs, that don't uses it.
*/
if (data->parent == NULL && record->len_fi[0] == 8
&& !strncmp((char*)record->file_id, "RR_MOVED", 8)) {
@ -544,6 +556,8 @@ int read_dir(ImageFileSourceData *data)
continue;
}
#endif /* Libisofs_wrongly_skip_rr_moveD */
/*
* We pass a NULL parent instead of dir, to prevent the circular
* reference from child to parent.

View File

@ -84,7 +84,7 @@
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 2
#define iso_lib_header_version_micro 0
#define iso_lib_header_version_micro 2
/**
* Get version of the libisofs library at runtime.
@ -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 may
* become 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.
@ -1545,7 +1584,7 @@ int iso_write_opts_set_allow_deep_paths(IsoWriteOpts *opts, int allow);
int iso_write_opts_set_allow_longer_paths(IsoWriteOpts *opts, int allow);
/**
* Allow a single file or directory hierarchy to have up to 37 characters.
* Allow a single file or directory identifier to have up to 37 characters.
* This is larger than the 31 characters allowed by ISO level 2, and the
* extra space is taken from the version number, so this also forces
* omit_version_numbers.
@ -1576,13 +1615,15 @@ int iso_write_opts_set_no_force_dots(IsoWriteOpts *opts, int no);
* Allow lowercase characters in ISO-9660 filenames. By default, only
* uppercase characters, numbers and a few other characters are allowed.
* This breaks ECMA-119 specification. Use with caution.
* If lowercase is not allowed then those letters get mapped to uppercase
* letters.
*
* @since 0.6.2
*/
int iso_write_opts_set_allow_lowercase(IsoWriteOpts *opts, int allow);
/**
* Allow all ASCII characters to be appear on an ISO-9660 filename. Note
* Allow all 8-bit characters to appear on an ISO-9660 filename. Note
* that "/" and 0x0 characters are never allowed, even in RR names.
* This breaks ECMA-119 specification. Use with caution.
*
@ -1590,6 +1631,20 @@ int iso_write_opts_set_allow_lowercase(IsoWriteOpts *opts, int allow);
*/
int iso_write_opts_set_allow_full_ascii(IsoWriteOpts *opts, int allow);
/**
* If not iso_write_opts_set_allow_full_ascii() is set to 1:
* Allow all 7-bit characters that would be allowed by allow_full_ascii, but
* map lowercase to uppercase if iso_write_opts_set_allow_lowercase()
* is not set to 1.
* @param opts
* The option set to be manipulated.
* @param allow
* If not zero, then allow what is described above.
*
* @since 1.2.2
*/
int iso_write_opts_set_allow_7bit_ascii(IsoWriteOpts *opts, int allow);
/**
* Allow all characters to be part of Volume and Volset identifiers on
* the Primary Volume Descriptor. This breaks ISO-9660 contraints, but
@ -7170,6 +7225,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 ---------------------------- */

View File

@ -265,6 +265,7 @@ iso_write_opts_get_data_start;
iso_write_opts_new;
iso_write_opts_set_aaip;
iso_write_opts_set_aaip_susp_1_10;
iso_write_opts_set_allow_7bit_ascii;
iso_write_opts_set_allow_deep_paths;
iso_write_opts_set_allow_dir_id_ext;
iso_write_opts_set_allow_full_ascii;
@ -301,6 +302,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;

View File

@ -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);
}
@ -1236,7 +1246,17 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
/* we need to add a RE entry */
su_size += 4;
}
#ifdef Libisofs_with_rr_reloc_diR
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
(t->rr_reloc_flags & 1)) {
/* The dedicated relocation directory shall be marked by RE */
su_size += 4;
}
#endif /* Libisofs_with_rr_reloc_diR */
} else if (n->type == ECMA119_SPECIAL) {
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {
/* block or char device, we need a PN entry */
@ -1422,6 +1442,18 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
goto add_susp_cleanup;
}
}
#ifdef Libisofs_with_rr_reloc_diR
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
(t->rr_reloc_flags & 1)) {
/* 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)) {

View File

@ -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
@ -685,8 +685,37 @@ static int valid_j_char(uint16_t c)
&& cmp_ucsbe(&c, '\\');
}
/* @param relaxed bit0+1 0= strict ECMA-119
1= additionally allow lowercase (else map to upper)
2= allow all 8-bit characters
bit2 allow all 7-bit characters (but map to upper if
not bit0+1 == 2)
*/
static char map_fileid_char(char c, int relaxed)
{
char upper;
if (c == '/') /* Allowing slashes would cause lots of confusion */
return '_';
if ((relaxed & 3) == 2)
return c;
if (valid_d_char(c))
return c;
if ((relaxed & 4) && (c & 0x7f) == c && (c < 'a' || c > 'z'))
return c;
upper= toupper(c);
if (valid_d_char(upper)) {
if (relaxed & 3) {
/* lower chars are allowed */
return c;
}
return upper;
}
return '_';
}
static
char *iso_dirid(const char *src, int size)
char *iso_dirid(const char *src, int size, int relaxed)
{
size_t len, i;
char name[32];
@ -696,25 +725,35 @@ char *iso_dirid(const char *src, int size)
len = size;
}
for (i = 0; i < len; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= toupper(src[i]);
name[i] = valid_d_char(c) ? c : '_';
#else /* Libisofs_old_ecma119_nameS */
name[i] = map_fileid_char(src[i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
name[len] = '\0';
return strdup(name);
}
char *iso_1_dirid(const char *src)
char *iso_1_dirid(const char *src, int relaxed)
{
return iso_dirid(src, 8);
return iso_dirid(src, 8, relaxed);
}
char *iso_2_dirid(const char *src)
{
return iso_dirid(src, 31);
return iso_dirid(src, 31, 0);
}
char *iso_1_fileid(const char *src)
char *iso_1_fileid(const char *src, int relaxed, int force_dots)
{
char *dot; /* Position of the last dot in the filename, will be used
* to calculate lname and lext. */
@ -725,7 +764,8 @@ char *iso_1_fileid(const char *src)
return NULL;
}
dot = strrchr(src, '.');
if (dot == src && strlen(src) > 4)
dot = NULL; /* Use the long extension instead of the empty name */
lext = dot ? strlen(dot + 1) : 0;
lname = strlen(src) - lext - (dot ? 1 : 0);
@ -738,19 +778,43 @@ char *iso_1_fileid(const char *src)
/* Convert up to 8 characters of the filename. */
for (i = 0; i < lname && i < 8; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= toupper(src[i]);
dest[pos++] = valid_d_char(c) ? c : '_';
#else /* Libisofs_old_ecma119_nameS */
if (dot == NULL && src[i] == '.')
dest[pos++] = '_'; /* make sure that ignored dots do not appear */
else
dest[pos++] = map_fileid_char(src[i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
/* This dot is mandatory, even if there is no extension. */
if (force_dots || lext > 0)
dest[pos++] = '.';
/* Convert up to 3 characters of the extension, if any. */
for (i = 0; i < lext && i < 3; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= toupper(src[lname + 1 + i]);
dest[pos++] = valid_d_char(c) ? c : '_';
#else /* Libisofs_old_ecma119_nameS */
dest[pos++] = map_fileid_char(src[lname + 1 + i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
dest[pos] = '\0';
@ -817,8 +881,11 @@ char *iso_2_fileid(const char *src)
* @param size
* Max len for the name
* @param relaxed
* 0 only allow d-characters, 1 allow also lowe case chars,
* 2 allow all characters
* bit0+1: 0 only allow d-characters,
* 1 allow also lowe case chars,
* 2 allow all 8-bit characters,
* bit2: allow 7-bit characters (but map lowercase to uppercase if
* not bit0+1 == 2)
*/
char *iso_r_dirid(const char *src, int size, int relaxed)
{
@ -833,6 +900,9 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
if (dest == NULL)
return NULL;
for (i = 0; i < len; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= src[i];
if (relaxed == 2) {
/* all chars are allowed */
@ -853,6 +923,13 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
dest[i] = '_';
}
}
#else /* Libisofs_old_ecma119_nameS */
dest[i] = map_fileid_char(src[i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
dest[len] = '\0';
@ -860,13 +937,17 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
}
/**
* Create a file name suitable for an ISO image with relaxed constraints.
* Create a file name suitable for an ISO image with level > 1 and
* with relaxed constraints.
*
* @param len
* Max len for the name, without taken the "." into account.
* @param relaxed
* 0 only allow d-characters, 1 allow also lowe case chars,
* 2 allow all characters
* bit0+1: 0 only allow d-characters,
* 1 allow also lowe case chars,
* 2 allow all 8-bit characters,
* bit2: allow 7-bit characters (but map lowercase to uppercase if
* not bit0+1 == 2)
* @param forcedot
* Whether to ensure that "." is added
*/
@ -913,6 +994,9 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
/* Convert up to lnname characters of the filename. */
for (i = 0; i < lnname; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= src[i];
if (relaxed == 2) {
/* all chars are allowed */
@ -933,6 +1017,13 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
dest[pos++] = '_';
}
}
#else /* Libisofs_old_ecma119_nameS */
dest[pos++] = map_fileid_char(src[i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
if (lnext > 0 || forcedot) {
dest[pos++] = '.';
@ -940,6 +1031,9 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
/* Convert up to lnext characters of the extension, if any. */
for (i = lname + 1; i < lname + 1 + lnext; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= src[i];
if (relaxed == 2) {
/* all chars are allowed */
@ -960,6 +1054,13 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
dest[pos++] = '_';
}
}
#else /* Libisofs_old_ecma119_nameS */
dest[pos++] = map_fileid_char(src[i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
dest[pos] = '\0';

View File

@ -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
@ -93,8 +93,11 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output);
*
* @param src
* The identifier, in ASCII encoding.
* @param relaxed
* 0 only allow d-characters, 1 allow also lowe case chars,
* 2 allow all characters
*/
char *iso_1_dirid(const char *src);
char *iso_1_dirid(const char *src, int relaxed);
/**
* Create a level 2 directory identifier.
@ -124,8 +127,13 @@ char *iso_r_dirid(const char *src, int size, int relaxed);
*
* @param src
* The identifier, in ASCII encoding.
* @param relaxed
* 0 only allow d-characters, 1 allow also lowe case chars,
* 2 allow all characters
* @param force_dots
* If 1 then prepend empty extension by SEPARATOR1 = '.'
*/
char *iso_1_fileid(const char *src);
char *iso_1_fileid(const char *src, int relaxed, int force_dots);
/**
* Create a level 2 file identifier.