New API call isoburn_assess_written_features()

This commit is contained in:
Thomas Schmitt 2022-09-20 10:14:10 +02:00
parent 3318fa47a3
commit d2fd48fcbc
3 changed files with 289 additions and 64 deletions

View File

@ -137,16 +137,106 @@ int isoburn_root_defaults(IsoImage *image, int flag)
}
/* @return <=0 = error , 1 = ok , 2 = no ISO filesystem found
*/
int isoburn_make_iso_read_opts(struct burn_drive *d,
struct isoburn *o,
struct isoburn_read_opts *read_opts,
IsoReadOpts **ropts)
{
int ret, int_num, dummy;
uint32_t ms_block;
char *msg= NULL;
msg= calloc(1, 160);
*ropts= NULL;
ret = isoburn_disc_get_msc1(d, &int_num);
if (ret <= 0)
{ret= -2; goto ex;}
ms_block= int_num;
if (o != NULL)
o->image_start_lba= ms_block;
ret = isoburn_read_iso_head(d, int_num, &dummy, NULL, 0);
if (ret <= 0) {
sprintf(msg, "No ISO 9660 image at LBA %d.", int_num);
isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0);
{ret= 2; goto ex;}
}
if(read_opts->displacement != 0 && abs(read_opts->displacement_sign) == 1) {
/* Apply reverse displacement to session start */
if(read_opts->displacement_sign == -1) {
if(ms_block+ read_opts->displacement < ms_block) {
displacement_rollover:;
sprintf(msg, "Displacement offset leads outside 32 bit range.");
isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
ms_block+= read_opts->displacement;
} else {
if(ms_block < read_opts->displacement)
goto displacement_rollover;
ms_block-= read_opts->displacement;
}
}
ret = iso_read_opts_new(ropts, 0);
if (ret < 0) {
isoburn_report_iso_error(ret, "Cannot create write opts", 0, "FATAL", 0);
goto ex;
}
iso_read_opts_set_start_block(*ropts, ms_block);
iso_read_opts_set_no_rockridge(*ropts, read_opts->norock);
iso_read_opts_set_no_aaip(*ropts, read_opts->noaaip);
if(read_opts->nomd5 == 2)
int_num= 2;
else if(read_opts->nomd5 == 1)
int_num= 1;
else
int_num= 0;
iso_read_opts_set_no_md5(*ropts, int_num);
if(read_opts->do_ecma119_map)
iso_read_opts_set_ecma119_map(*ropts, read_opts->map_mode);
if(read_opts->do_joliet_map)
iso_read_opts_set_joliet_map(*ropts, read_opts->joliet_map_mode);
iso_read_opts_set_new_inos(*ropts, read_opts->noino);
iso_read_opts_set_no_joliet(*ropts, read_opts->nojoliet);
iso_read_opts_set_no_iso1999(*ropts, read_opts->noiso1999);
iso_read_opts_set_preferjoliet(*ropts, read_opts->preferjoliet);
iso_read_opts_set_default_permissions(*ropts,
read_opts->mode, read_opts->dirmode);
iso_read_opts_set_default_uid(*ropts, read_opts->uid);
iso_read_opts_set_default_gid(*ropts, read_opts->gid);
iso_read_opts_set_input_charset(*ropts, read_opts->input_charset);
iso_read_opts_auto_input_charset(*ropts, read_opts->auto_input_charset);
iso_read_opts_load_system_area(*ropts, 1);
iso_read_opts_keep_import_src(*ropts, 1);
ret= 1;
ex:;
if(ret <= 0) {
if(*ropts != NULL)
iso_read_opts_free(*ropts);
*ropts= NULL;
}
if(msg != NULL)
free(msg);
return(ret);
}
/* API function. See libisoburn.h
*/
int isoburn_read_image(struct burn_drive *d,
struct isoburn_read_opts *read_opts,
IsoImage **image)
{
int ret, int_num, dummy, ignore_aclea= 0;
int ret, ignore_aclea= 0;
IsoReadOpts *ropts= NULL;
IsoReadImageFeatures *features= NULL;
uint32_t ms_block;
char *msg= NULL;
enum burn_disc_status status= BURN_DISC_BLANK;
IsoDataSource *ds= NULL;
@ -223,73 +313,19 @@ create_blank_image:;
{ret= -4; goto ex;}
}
ret = isoburn_disc_get_msc1(d, &int_num);
if (ret <= 0)
{ret= -2; goto ex;}
ms_block= int_num;
if (o != NULL)
o->image_start_lba= ms_block;
ret = isoburn_read_iso_head(d, int_num, &dummy, NULL, 0);
if (ret <= 0) {
sprintf(msg, "No ISO 9660 image at LBA %d. Creating blank image.", int_num);
/* create the data source */
ret= isoburn_make_iso_read_opts(d, o, read_opts, &ropts);
if(ret <= 0)
goto ex;
if(ret == 2) {
sprintf(msg, "Creating blank image.");
isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0);
goto create_blank_image;
}
if(read_opts->displacement != 0 && abs(read_opts->displacement_sign) == 1) {
/* Apply reverse displacement to session start */
if(read_opts->displacement_sign == -1) {
if(ms_block+ read_opts->displacement < ms_block) {
displacement_rollover:;
sprintf(msg, "Displacement offset leads outside 32 bit range.");
isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
ms_block+= read_opts->displacement;
} else {
if(ms_block < read_opts->displacement)
goto displacement_rollover;
ms_block-= read_opts->displacement;
}
}
/* create the data source */
ret = iso_read_opts_new(&ropts, 0);
if (ret < 0) {
isoburn_report_iso_error(ret, "Cannot create write opts", 0, "FATAL", 0);
goto ex;
}
/* Important: do not return until iso_read_opts_free() */
iso_read_opts_set_start_block(ropts, ms_block);
iso_read_opts_set_no_rockridge(ropts, read_opts->norock);
iso_read_opts_set_no_aaip(ropts, read_opts->noaaip);
if(read_opts->nomd5 == 2)
int_num= 2;
else if(read_opts->nomd5 == 1)
int_num= 1;
else
int_num= 0;
iso_read_opts_set_no_md5(ropts, int_num);
if(read_opts->do_ecma119_map)
iso_read_opts_set_ecma119_map(ropts, read_opts->map_mode);
if(read_opts->do_joliet_map)
iso_read_opts_set_joliet_map(ropts, read_opts->joliet_map_mode);
iso_read_opts_set_new_inos(ropts, read_opts->noino);
iso_read_opts_set_no_joliet(ropts, read_opts->nojoliet);
iso_read_opts_set_no_iso1999(ropts, read_opts->noiso1999);
iso_read_opts_set_preferjoliet(ropts, read_opts->preferjoliet);
iso_read_opts_set_default_permissions(ropts,
read_opts->mode, read_opts->dirmode);
iso_read_opts_set_default_uid(ropts, read_opts->uid);
iso_read_opts_set_default_gid(ropts, read_opts->gid);
iso_read_opts_set_input_charset(ropts, read_opts->input_charset);
iso_read_opts_auto_input_charset(ropts, read_opts->auto_input_charset);
iso_read_opts_load_system_area(ropts, 1);
iso_read_opts_keep_import_src(ropts, 1);
ret= iso_image_set_truncate_mode(o->image, read_opts->truncate_mode,
read_opts->truncate_length);
if(ret < 0)
@ -346,6 +382,170 @@ ex:;
}
/* API function. See libisoburn.h
*/
int isoburn_assess_written_features(struct burn_drive *d,
struct isoburn_read_opts *read_opts,
IsoReadImageFeatures **features,
struct isoburn_imgen_opts **imgen_opts,
int flag)
{
int ret, type, ext;
int64_t num_value;
void *pt_value;
size_t pt_size;
IsoReadOpts *ropts= NULL;
char *msg= NULL;
enum burn_disc_status status= BURN_DISC_BLANK;
IsoDataSource *ds= NULL;
struct isoburn *o= NULL;
IsoWriteOpts *write_opts= NULL;
msg= calloc(1, 160);
if(d != NULL) {
ret = isoburn_find_emulator(&o, d, 0);
if (ret < 0 || o == NULL)
{ret= 0; goto ex;}
status = isoburn_disc_get_status(d);
o->image_start_lba= -1;
}
if(read_opts==NULL) {
isoburn_msgs_submit(o, 0x00060000,
"Program error: isoburn_read_image: read_opts==NULL",
0, "FATAL", 0);
{ret= -1; goto ex;}
}
if (d == NULL || read_opts->pretend_blank ||
(status != BURN_DISC_APPENDABLE && status != BURN_DISC_FULL)) {
isoburn_msgs_submit(o, 0x00060000,
"Empty drive, unsuitable medium state, or read option 'pretend_blank'",
0, "FAILURE", 0);
{ret= 0; goto ex;}
}
ret= isoburn_make_iso_read_opts(d, o, read_opts, &ropts);
if(ret <= 0)
goto ex;
if(ret == 2)
{ret= 0; goto ex;}
/* ??? Only if o->iso_data_source == NULL ? */
ds = isoburn_data_source_new(d, read_opts->displacement,
read_opts->displacement_sign,
read_opts->cache_tiles, read_opts->cache_tile_blocks);
if (ds == NULL) {
isoburn_report_iso_error(ret, "Cannot create IsoDataSource object", 0,
"FATAL", 0);
ret= -1; goto ex;
}
if(o->iso_data_source != NULL)
iso_data_source_unref(o->iso_data_source);
o->iso_data_source= ds;
ret= iso_assess_written_features(ds, ropts, features, &write_opts);
if(ret < 0) {
isoburn_report_iso_error(ret, "Failed to assess ISO filesystem features",
0, "FAILURE", 0);
ret= 0; goto ex;
}
ret= isoburn_igopt_new(imgen_opts, 0);
if(ret <= 0)
goto ex;
/* Convert features to imgen_opts */
if(iso_read_image_feature_named(*features, "iso_level", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
isoburn_igopt_set_level(*imgen_opts, num_value);
ext= 0;
if(iso_read_image_feature_named(*features, "rock_ridge", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_rockridge * !!num_value;
if(iso_read_image_feature_named(*features, "joliet", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_joliet * !!num_value;
if(iso_read_image_feature_named(*features, "iso1999", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_iso1999 * !!num_value;
if(iso_read_image_feature_named(*features, "aaip", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_aaip * !!num_value;
if(iso_read_image_feature_named(*features, "record_md5_session", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_session_md5 * !!num_value;
if(iso_read_image_feature_named(*features, "record_md5_files", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_file_md5 * !!num_value;
isoburn_igopt_set_extensions(*imgen_opts, ext);
ext= 0;
if(iso_read_image_feature_named(*features, "omit_version_numbers", NULL, &type,
&num_value, &pt_value, &pt_size) == 1) {
if((num_value & 3) == 2)
ext|= isoburn_igopt_only_iso_versions;
else if(num_value & 3)
ext|= isoburn_igopt_omit_version_numbers;
}
if(iso_read_image_feature_named(*features, "allow_deep_paths", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_allow_deep_paths * !!num_value;
if(iso_read_image_feature_named(*features, "allow_longer_paths", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_allow_longer_paths * !!num_value;
if(iso_read_image_feature_named(*features, "max_37_char_filenames", NULL,
&type, &num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_max_37_char_filenames * !!num_value;
if(iso_read_image_feature_named(*features, "no_force_dots", NULL, &type,
&num_value, &pt_value, &pt_size) == 1) {
if(num_value & 1)
ext|= isoburn_igopt_only_iso_versions;
if(num_value & 2)
ext|= isoburn_igopt_no_force_dots;
}
if(iso_read_image_feature_named(*features, "allow_lowercase", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_allow_lowercase * !!num_value;
if(iso_read_image_feature_named(*features, "allow_full_ascii", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_allow_full_ascii * !!num_value;
if(iso_read_image_feature_named(*features, "joliet_longer_paths", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_joliet_longer_paths * !!num_value;
if(iso_read_image_feature_named(*features, "rrip_version_1_10", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_rrip_version_1_10 * !!num_value;
if(iso_read_image_feature_named(*features, "aaip_susp_1_10", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_aaip_susp_1_10 * !!num_value;
if(iso_read_image_feature_named(*features, "allow_dir_id_ext", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_allow_dir_id_ext * !!num_value;
if(iso_read_image_feature_named(*features, "joliet_long_names", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_joliet_long_names * !!num_value;
if(iso_read_image_feature_named(*features, "joliet_utf16", NULL, &type,
&num_value, &pt_value, &pt_size) == 1)
ext|= isoburn_igopt_joliet_utf16 * !!num_value;
isoburn_igopt_set_relaxed(*imgen_opts, ext);
if(iso_read_image_feature_named(*features, "untranslated_name_len", NULL,
&type, &num_value, &pt_value, &pt_size) == 1)
isoburn_igopt_set_untranslated_name_len(*imgen_opts, num_value);
ret= 1;
ex:;
if(msg != NULL)
free(msg);
if(ropts != NULL)
iso_read_opts_free(ropts);
if(write_opts != NULL)
iso_write_opts_free(write_opts);
return(ret);
}
/* API function. See libisoburn.h
*/
int isoburn_attach_image(struct burn_drive *d, IsoImage *image)

View File

@ -1310,7 +1310,7 @@ int isoburn_igopt_get_extensions(struct isoburn_imgen_opts *o, int *ext);
prefixed ES fields. This saves 5 to 10 bytes per file and
might avoid problems with readers which only accept RRIP.
SUSP-1.10 allows it, SUSP-1.12 frowns on it.
bit12= only_iso_numbers
bit12= only_iso_versions
Same as bit1 omit_version_number but restricted to the names
in the eventual Joliet tree.
@since 0.5.4
@ -2447,6 +2447,30 @@ int isoburn_set_read_pacifier(struct burn_drive *drive,
int isoburn_get_img_partition_offset(struct burn_drive *drive,
uint32_t *block_offset_2k);
/** Assess features of the importable directory trees and an estimation of the
write options which would cause the recognized features.
@since 1.5.6
@param d The drive with the ISO filesystem
@param read_opts The read options which would be used by
isoburn_read_image()
@param features Returned information which may be inquired by
iso_read_image_features_*() or by
iso_read_image_feature_named().
Dispose by iso_read_image_features_destroy() when
no longer needed.
@param imgen_opts Returned set of write options which were derived
from the features.
Dispose by isoburn_igopt_destroy when no longer
needed.
@param flag Bitfield for control purposes, submit 0 for now.
@return 1= success, <= 0 = error
*/
int isoburn_assess_written_features(struct burn_drive *d,
struct isoburn_read_opts *read_opts,
IsoReadImageFeatures **features,
struct isoburn_imgen_opts **imgen_opts,
int flag);
/** Set the IsoImage to be used with a drive. This eventually releases
the reference to the old IsoImage attached to the drive.

View File

@ -1,6 +1,7 @@
LIBISOBURN1 {
global:
isoburn_activate_session;
isoburn_assess_written_features;
isoburn_attach_image;
isoburn_attach_start_lba;
isoburn_conv_name_chars;