/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007 - 2011 Thomas Schmitt , < scdbackup @ gmx . net >
Provided under GPL version 2 or later .
This file contains functions which operate on drives and media .
*/
# ifdef HAVE_CONFIG_H
# include "../config.h"
# endif
# include <ctype.h>
# include <sys/types.h>
# include <unistd.h>
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <sys/stat.h>
# include <sys/time.h>
# include <time.h>
# include <errno.h>
# include "xorriso.h"
# include "xorriso_private.h"
# include "lib_mgt.h"
# include "drive_mgt.h"
# include "iso_img.h"
# include "sort_cmp.h"
# include "write_run.h"
# include "read_run.h"
static const char * un0 ( const char * text )
{
if ( text = = NULL )
return ( " " ) ;
return ( text ) ;
}
int Xorriso_auto_driveadr ( struct XorrisO * xorriso , char * adr , char * result ,
int flag )
{
int ret , is_known_mmc = 0 ;
char * path_pt , * libburn_adr = NULL ;
char * abs_pt , * abs_adr = NULL ;
Xorriso_alloc_meM ( libburn_adr , char , BURN_DRIVE_ADR_LEN + SfileadrL ) ;
Xorriso_alloc_meM ( abs_adr , char , SfileadrL ) ;
path_pt = adr ;
if ( strncmp ( adr , " stdio: " , 6 ) = = 0 )
path_pt = adr + 6 ;
else if ( strncmp ( adr , " mmc: " , 4 ) = = 0 )
path_pt = adr + 4 ;
/* <<< replace by Xorriso_normalize_img_path() ? */ ;
if ( path_pt [ 0 ] ! = ' / ' ) {
abs_pt = getcwd ( abs_adr , SfileadrL - 1 ) ;
if ( abs_pt = = NULL ) {
Xorriso_msgs_submit ( xorriso , 0 ,
" Relative drive path given. Cannot determine working directory. " ,
errno , " FAILURE " , 0 ) ;
{ ret = - 1 ; goto ex ; }
}
ret = Sfile_add_to_path ( abs_adr , path_pt , 0 ) ;
if ( ret < = 0 )
{ ret = - 1 ; goto ex ; }
}
is_known_mmc = burn_drive_convert_fs_adr ( path_pt , libburn_adr ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
ret = Xorriso_is_in_patternlist ( xorriso , xorriso - > drive_whitelist , path_pt , 0 ) ;
if ( ret > 0 )
goto ok ;
ret = Xorriso_is_in_patternlist ( xorriso , xorriso - > drive_blacklist , path_pt , 0 ) ;
if ( ret < 0 )
goto ex ;
if ( ret ) {
strcpy ( xorriso - > info_text , " Drive address " ) ;
Text_shellsafe ( adr , xorriso - > info_text , 1 ) ;
strcat ( xorriso - > info_text ,
" rejected because: -drive_class 'banned' " ) ;
Text_shellsafe ( Xorriso_get_pattern ( xorriso , xorriso - > drive_blacklist ,
ret - 1 , 0 ) ,
xorriso - > info_text , 1 ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
{ ret = 0 ; goto ex ; }
}
/* if in greylist and not MMC and not stdio prefix: reject */
if ( is_known_mmc < 0 )
goto ex ;
if ( adr = = path_pt & & ! is_known_mmc ) { /* no prefix, no MMC */
ret = Xorriso_is_in_patternlist ( xorriso , xorriso - > drive_greylist , path_pt , 0 ) ;
if ( ret < 0 )
goto ex ;
if ( ret ) {
strcpy ( xorriso - > info_text , " Drive address " ) ;
Text_shellsafe ( adr , xorriso - > info_text , 1 ) ;
strcat ( xorriso - > info_text ,
" rejected because: not MMC and -drive_class 'risky' " ) ;
Text_shellsafe ( Xorriso_get_pattern ( xorriso , xorriso - > drive_greylist ,
ret - 1 , 0 ) ,
xorriso - > info_text , 1 ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
Xorriso_msgs_submit ( xorriso , 0 ,
" If the address is a legitimate target, prepend \" stdio: \" " ,
0 , " HINT " , 0 ) ;
{ ret = 0 ; goto ex ; }
}
}
ok : ;
if ( strncmp ( adr , " mmc: " , 4 ) = = 0 ) {
if ( Sfile_str ( result , path_pt , 0 ) < = 0 )
{ ret = 0 ; goto ex ; }
} else if ( adr = = path_pt & & is_known_mmc < = 0 ) {
Sfile_str ( result , " stdio: " , 0 ) ;
if ( Sfile_str ( result , adr , 1 ) < = 0 )
{ ret = 0 ; goto ex ; }
} else {
if ( Sfile_str ( result , adr , 0 ) < = 0 )
{ ret = 0 ; goto ex ; }
}
if ( strncmp ( result , " stdio: " , 6 ) = = 0 ) {
if ( xorriso - > ban_stdio_write ) {
strcpy ( xorriso - > info_text , " Drive address banned by -ban_stdio_write : " ) ;
Text_shellsafe ( result , xorriso - > info_text , 1 ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
{ ret = 0 ; goto ex ; }
}
}
ret = 1 ;
ex : ;
Xorriso_free_meM ( libburn_adr ) ;
Xorriso_free_meM ( abs_adr ) ;
return ( ret ) ;
}
/* @param flag bit0= aquire as isoburn input drive
bit1 = aquire as libburn output drive ( as isoburn drive if bit0 )
bit2 = regard overwriteable media as blank
bit3 = if the drive is a regular disk file : truncate it to
the write start address
bit5 = do not print toc
bit6 = do not calm down drive after aquiring it
@ return < = 0 failure , 1 = ok
2 = success , but not writeable with bit1
3 = success , but not blank and not ISO with bit0
*/
int Xorriso_aquire_drive ( struct XorrisO * xorriso , char * adr , int flag )
{
int ret , hret , not_writeable = 0 , has_what , aquire_flag , load_lba , ext ;
int lba , track , session , params_flag , adr_mode , read_ret ;
uint32_t size , offst ;
struct burn_drive_info * dinfo = NULL , * out_dinfo , * in_dinfo ;
struct burn_drive * drive = NULL , * out_drive , * in_drive ;
enum burn_disc_status state ;
IsoImage * volset = NULL ;
IsoNode * root_node ;
struct isoburn_read_opts * ropts = NULL ;
char * libburn_adr = NULL , * boot_fate , * sev ;
size_t value_length ;
char * value = NULL ;
double num ;
char volid [ 33 ] , * adr_data = NULL , * adr_pt ;
Xorriso_alloc_meM ( libburn_adr , char , SfileadrL ) ;
Xorriso_alloc_meM ( adr_data , char , 163 ) ;
if ( ( flag & 3 ) = = 0 ) {
sprintf ( xorriso - > info_text ,
" XORRISOBURN program error : Xorriso_aquire_drive bit0+bit1 not set " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FATAL " , 0 ) ;
{ ret = - 1 ; goto ex ; }
}
ret = Xorriso_give_up_drive ( xorriso , ( flag & 3 ) | 8 ) ;
if ( ret < = 0 )
goto ex ;
if ( flag & 1 )
xorriso - > isofs_st_out = time ( 0 ) - 1 ;
ret = Xorriso_auto_driveadr ( xorriso , adr , libburn_adr , 0 ) ;
if ( ret < = 0 )
goto ex ;
if ( strcmp ( libburn_adr , " stdio:/dev/fd/1 " ) = = 0 ) {
if ( xorriso - > dev_fd_1 < 0 ) {
sprintf ( xorriso - > info_text ,
" -*dev \" stdio:/dev/fd/1 \" was not a start argument. Cannot use it now. " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
{ ret = 0 ; goto ex ; }
} else {
sprintf ( libburn_adr , " stdio:/dev/fd/%d " , xorriso - > dev_fd_1 ) ;
}
}
if ( ( flag & 3 ) = = 1 & & xorriso - > out_drive_handle ! = NULL ) {
ret = Xorriso_get_drive_handles ( xorriso , & out_dinfo , & out_drive ,
" on attempt to compare new indev with outdev " , 2 ) ;
if ( ret < = 0 )
goto ex ;
ret = burn_drive_equals_adr ( out_drive , libburn_adr , 1 ) ;
if ( ret = = 1 ) {
dinfo = out_dinfo ;
xorriso - > indev_is_exclusive = xorriso - > outdev_is_exclusive ;
}
} else if ( ( flag & 3 ) = = 2 & & xorriso - > in_drive_handle ! = NULL ) {
ret = Xorriso_get_drive_handles ( xorriso , & in_dinfo , & in_drive ,
" on attempt to compare new outdev with indev " , 0 ) ;
if ( ret < = 0 )
goto ex ;
ret = burn_drive_equals_adr ( in_drive , libburn_adr , 1 ) ;
if ( ret = = 1 ) {
dinfo = in_dinfo ;
xorriso - > outdev_is_exclusive = xorriso - > indev_is_exclusive ;
}
}
if ( dinfo = = NULL ) {
aquire_flag = 1 | ( ( flag & ( 8 | 4 ) ) > > 1 ) | ( ( xorriso - > toc_emulation_flag & 3 ) < < 3 ) ;
if ( xorriso - > toc_emulation_flag & 4 )
aquire_flag | = 128 ;
if ( ! ( xorriso - > do_aaip & 1 ) )
aquire_flag | = 32 ;
if ( ( xorriso - > ino_behavior & ( 1 | 2 ) ) & & ! ( xorriso - > do_aaip & ( 4 | 32 ) ) )
aquire_flag | = 64 ;
burn_preset_device_open ( xorriso - > drives_exclusive , 0 , 0 ) ;
burn_allow_drive_role_4 ( 1 | ( xorriso - > early_stdio_test & 14 ) ) ;
ret = isoburn_drive_aquire ( & dinfo , libburn_adr , aquire_flag ) ;
burn_preset_device_open ( 1 , 0 , 0 ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ret < = 0 ) {
sprintf ( xorriso - > info_text , " Cannot aquire drive '%s' " , adr ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
ret = 0 ; goto ex ;
}
state = isoburn_disc_get_status ( dinfo [ 0 ] . drive ) ;
ret = isoburn_get_img_partition_offset ( dinfo [ 0 ] . drive , & offst ) ;
if ( ( state = = BURN_DISC_APPENDABLE | | state = = BURN_DISC_FULL ) & & ret = = 1 ) {
sprintf ( xorriso - > info_text ,
" ISO image bears MBR with -boot_image any partition_offset=%lu " ,
( unsigned long ) offst ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
}
if ( flag & 1 )
if ( xorriso - > image_start_mode & ( 1 < < 31 ) ) /* used up setting */
xorriso - > image_start_mode = 0 ; /* no need to perform auto setting */
if ( flag & 1 )
xorriso - > indev_is_exclusive = xorriso - > drives_exclusive ;
if ( flag & 2 )
xorriso - > outdev_is_exclusive = xorriso - > drives_exclusive ;
}
drive = dinfo [ 0 ] . drive ;
state = isoburn_disc_get_status ( drive ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( flag & 1 ) {
if ( xorriso - > image_start_mode & ( 1 < < 31 ) ) /* used up setting */
xorriso - > image_start_mode & = ~ 0xffff ; /* perform auto setting */
if ( ( xorriso - > image_start_mode & ( 1 < < 30 ) ) ) { /* if enabled at all */
adr_pt = xorriso - > image_start_value ;
adr_mode = xorriso - > image_start_mode & 0xffff ;
if ( adr_mode = = 4 & & strlen ( adr_pt ) < = 80 ) {
/* Convert volid search expression into lba */
params_flag = 0 ;
ret = Xorriso__bourne_to_reg ( xorriso - > image_start_value , adr_data , 0 ) ;
if ( ret = = 1 )
params_flag | = 4 ;
ret = isoburn_get_mount_params ( drive , 4 , adr_data , & lba , & track ,
& session , volid , params_flag ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ret < = 0 )
goto ex ;
if ( session < = 0 | | track < = 0 | | ret = = 2 ) {
Xorriso_msgs_submit ( xorriso , 0 ,
" -load : Given address does not point to an ISO 9660 session " ,
0 , " FAILURE " , 0 ) ;
ret = 0 ; goto ex ;
}
sprintf ( volid , " %d " , lba ) ;
adr_pt = volid ;
adr_mode = 3 ;
}
ret = isoburn_set_msc1 ( drive , adr_mode , adr_pt ,
! ! ( xorriso - > image_start_mode & ( 1 < < 16 ) ) ) ;
if ( ret < = 0 )
goto ex ;
if ( xorriso - > image_start_mode & ( 1 < < 31 ) )
xorriso - > image_start_mode = 0 ; /* disable msc1 setting completely */
else
xorriso - > image_start_mode | = ( 1 < < 31 ) ; /* mark as used up */
}
}
if ( flag & 1 ) {
volset = isoburn_get_attached_image ( drive ) ;
if ( volset ! = NULL ) { /* The image object is already created */
iso_image_unref ( volset ) ;
}
}
if ( flag & 2 ) {
xorriso - > out_drive_handle = dinfo ;
if ( Sfile_str ( xorriso - > outdev , adr , 0 ) < = 0 )
{ ret = - 1 ; goto ex ; }
if ( state ! = BURN_DISC_BLANK & & state ! = BURN_DISC_APPENDABLE ) {
sprintf ( xorriso - > info_text , " Disc status unsuitable for writing " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
not_writeable = 1 ;
}
}
if ( flag & 1 ) {
xorriso - > in_drive_handle = dinfo ;
if ( Sfile_str ( xorriso - > indev , adr , 0 ) < = 0 )
{ ret = - 1 ; goto ex ; }
} else if ( flag & 2 ) {
if ( xorriso - > in_volset_handle = = NULL ) {
/* No volume loaded: create empty one */
ret = Xorriso_create_empty_iso ( xorriso , 0 ) ;
if ( ret < = 0 )
goto ex ;
} else {
iso_image_ref ( ( IsoImage * ) xorriso - > in_volset_handle ) ;
ret = isoburn_attach_image ( drive , ( IsoImage * ) xorriso - > in_volset_handle ) ;
if ( ret < = 0 ) {
sprintf ( xorriso - > info_text ,
" Failed to attach ISO image object to outdev " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FATAL " , 0 ) ;
{ ret = - 1 ; goto ex ; }
}
}
if ( ! ( flag & 32 ) )
Xorriso_toc ( xorriso , 1 | 2 | 8 ) ;
{ ret = 1 + not_writeable ; goto ex ; }
}
if ( xorriso - > in_volset_handle ! = NULL )
iso_image_unref ( ( IsoImage * ) xorriso - > in_volset_handle ) ;
xorriso - > in_volset_handle = NULL ;
Sectorbitmap_destroy ( & ( xorriso - > in_sector_map ) , 0 ) ;
Xorriso_destroy_hln_array ( xorriso , 0 ) ;
Xorriso_destroy_di_array ( xorriso , 0 ) ;
xorriso - > boot_count = 0 ;
/* check for invalid state */
if ( state ! = BURN_DISC_BLANK & & state ! = BURN_DISC_APPENDABLE & &
state ! = BURN_DISC_FULL ) {
sprintf ( xorriso - > info_text ,
" Disc status not blank and unsuitable for reading " ) ;
sev = " FAILURE " ;
if ( xorriso - > img_read_error_mode = = 2 )
sev = " FATAL " ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , sev , 0 ) ;
Xorriso_give_up_drive ( xorriso , 1 | ( ( flag & 32 ) > > 2 ) ) ;
ret = 3 ; goto ex ;
}
/* fill read opts */
ret = isoburn_ropt_new ( & ropts , 0 ) ;
if ( ret < = 0 )
goto ex ;
ext = isoburn_ropt_noiso1999 ;
if ( ( xorriso - > ino_behavior & ( 1 | 2 ) ) & & ! ( xorriso - > do_aaip & ( 1 | 4 | 32 ) )
& & ! ( xorriso - > do_md5 & 1 ) )
ext | = isoburn_ropt_noaaip ;
if ( ! ( xorriso - > do_aaip & 1 ) )
ext | = isoburn_ropt_noacl ;
if ( ! ( xorriso - > do_aaip & 4 ) )
ext | = isoburn_ropt_noea ;
if ( xorriso - > ino_behavior & 1 )
ext | = isoburn_ropt_noino ;
if ( ! ( xorriso - > do_md5 & 1 ) )
ext | = isoburn_ropt_nomd5 ;
if ( xorriso - > do_md5 & 32 )
ext | = isoburn_ropt_nomd5tag ;
isoburn_ropt_set_extensions ( ropts , ext ) ;
isoburn_ropt_set_default_perms ( ropts , ( uid_t ) 0 , ( gid_t ) 0 , ( mode_t ) 0555 ) ;
isoburn_ropt_set_input_charset ( ropts , xorriso - > in_charset ) ;
isoburn_ropt_set_auto_incharset ( ropts , ! ! ( xorriso - > do_aaip & 512 ) ) ;
isoburn_ropt_set_displacement ( ropts , xorriso - > displacement ,
xorriso - > displacement_sign ) ;
Xorriso_set_image_severities ( xorriso , 1 ) ; /* No DEBUG messages */
Xorriso_pacifier_reset ( xorriso , 0 ) ;
isoburn_set_read_pacifier ( drive , Xorriso__read_pacifier , ( void * ) xorriso ) ;
/* <<< Trying to work around too much tolerance on bad image trees.
Better would be a chance to instruct libisofs what to do in
case of image read errors . There is a risk to mistake other SORRYs .
*/
if ( xorriso - > img_read_error_mode > 0 )
iso_set_abort_severity ( " SORRY " ) ;
if ( state ! = BURN_DISC_BLANK ) {
ret = isoburn_disc_get_msc1 ( drive , & load_lba ) ;
if ( ret > 0 ) {
sprintf ( xorriso - > info_text ,
" Loading ISO image tree from LBA %d " , load_lba ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
}
ret = Xorriso_assert_volid ( xorriso , load_lba , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
read_ret = ret = isoburn_read_image ( drive , ropts , & volset ) ;
/* <<< Resetting to normal thresholds */
if ( xorriso - > img_read_error_mode > 0 )
Xorriso_set_abort_severity ( xorriso , 0 ) ;
if ( ret < = 0 ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
Xorriso_set_image_severities ( xorriso , 0 ) ;
Xorriso_give_up_drive ( xorriso , 1 | ( ( flag & 32 ) > > 2 ) ) ;
sprintf ( xorriso - > info_text , " Cannot read ISO image tree " ) ;
sev = " FAILURE " ;
if ( xorriso - > img_read_error_mode = = 2 )
sev = " FATAL " ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , sev , 0 ) ;
if ( read_ret = = ( int ) ISO_SB_TREE_CORRUPTED & & ( xorriso - > do_md5 & 1 ) ) {
Xorriso_msgs_submit ( xorriso , 0 ,
" This might be false MD5 alarm if an add-on session was written by growisofs. " ,
0 , " HINT " , 0 ) ;
Xorriso_msgs_submit ( xorriso , 0 ,
" In this case you get an ISO image tree by option -md5 'load_check_off' " ,
0 , " HINT " , 0 ) ;
} else if ( xorriso - > img_read_error_mode ! = 0 ) {
Xorriso_msgs_submit ( xorriso , 0 , " You might get a partial or altered ISO image tree by option -error_behavior 'image_loading' 'best_effort' if -abort_on is set to be tolerant enough. " ,
0 , " HINT " , 0 ) ;
}
ret = 3 ; goto ex ;
}
Xorriso_pacifier_callback ( xorriso , " nodes read " , xorriso - > pacifier_count , 0 ,
" " , 1 ) ; /* report end count */
xorriso - > in_volset_handle = ( void * ) volset ;
xorriso - > in_sector_map = NULL ;
Xorriso_set_image_severities ( xorriso , 0 ) ;
Xorriso_update_volid ( xorriso , 0 ) ;
strncpy ( xorriso - > application_id ,
un0 ( iso_image_get_application_id ( volset ) ) , 128 ) ;
xorriso - > application_id [ 128 ] = 0 ;
strncpy ( xorriso - > publisher , un0 ( iso_image_get_publisher_id ( volset ) ) , 128 ) ;
xorriso - > publisher [ 128 ] = 0 ;
strncpy ( xorriso - > system_id , un0 ( iso_image_get_system_id ( volset ) ) , 32 ) ;
xorriso - > system_id [ 32 ] = 0 ;
strncpy ( xorriso - > volset_id , un0 ( iso_image_get_volset_id ( volset ) ) , 128 ) ;
xorriso - > volset_id [ 128 ] = 0 ;
strncpy ( xorriso - > copyright_file ,
un0 ( iso_image_get_copyright_file_id ( volset ) ) , 37 ) ;
xorriso - > copyright_file [ 37 ] = 0 ;
strncpy ( xorriso - > biblio_file , un0 ( iso_image_get_biblio_file_id ( volset ) ) , 37 ) ;
xorriso - > biblio_file [ 37 ] = 0 ;
strncpy ( xorriso - > abstract_file ,
un0 ( iso_image_get_abstract_file_id ( volset ) ) , 37 ) ;
xorriso - > abstract_file [ 37 ] = 0 ;
if ( xorriso - > out_drive_handle ! = NULL & &
xorriso - > out_drive_handle ! = xorriso - > in_drive_handle ) {
ret = Xorriso_get_drive_handles ( xorriso , & out_dinfo , & out_drive ,
" on attempt to attach ISO image volset to outdev " , 2 ) ;
if ( ret < = 0 )
goto ex ;
iso_image_ref ( ( IsoImage * ) xorriso - > in_volset_handle ) ;
isoburn_attach_image ( out_drive , xorriso - > in_volset_handle ) ;
}
Xorriso_process_msg_queues ( xorriso , 0 ) ;
isoburn_ropt_get_size_what ( ropts , & size , & has_what ) ;
if ( has_what & isoburn_ropt_has_el_torito ) {
if ( xorriso - > boot_image_bin_path [ 0 ] )
boot_fate = " replaced by new boot image " ;
else if ( xorriso - > patch_isolinux_image & 1 )
boot_fate = " patched at boot info table " ;
else if ( xorriso - > keep_boot_image )
boot_fate = " kept unchanged " ;
else
boot_fate = " discarded " ;
sprintf ( xorriso - > info_text ,
" Detected El-Torito boot information which currently is set to be %s " ,
boot_fate ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
Xorriso_record_boot_info ( xorriso , 0 ) ;
}
if ( flag & 1 ) {
/* Look for isofs.st and put it into xorriso->isofs_st_in */ ;
root_node = ( IsoNode * ) iso_image_get_root ( volset ) ;
ret = iso_node_lookup_attr ( root_node , " isofs.st " , & value_length , & value , 0 ) ;
if ( ret > 0 ) {
if ( value_length > 0 ) {
sscanf ( value , " %lf " , & num ) ;
if ( num > 0 )
xorriso - > isofs_st_in = num ;
}
free ( value ) ;
}
}
if ( ! ( flag & 32 ) ) {
Xorriso_toc ( xorriso , 1 | 8 ) ;
if ( xorriso - > loaded_volid [ 0 ] ! = 0 & &
( state = = BURN_DISC_APPENDABLE | | state = = BURN_DISC_FULL ) ) {
sprintf ( xorriso - > info_text , " Volume id : '%s' \n " ,
xorriso - > loaded_volid ) ;
Xorriso_info ( xorriso , 0 ) ;
}
if ( strcmp ( xorriso - > loaded_volid , xorriso - > volid ) ! = 0 & &
! xorriso - > volid_default ) {
sprintf ( xorriso - > info_text , " New volume id: '%s' \n " , xorriso - > volid ) ;
Xorriso_info ( xorriso , 0 ) ;
}
}
ret = 1 + not_writeable ;
ex :
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ret < = 0 ) {
hret = Xorriso_give_up_drive ( xorriso , ( flag & 3 ) | ( ( flag & 32 ) > > 2 ) ) ;
if ( hret < ret )
ret = hret ;
} else {
if ( drive ! = NULL & & ( xorriso - > do_calm_drive & 1 ) & & ! ( flag & 64 ) )
burn_drive_snooze ( drive , 0 ) ; /* No need to make noise from start */
}
if ( ropts ! = NULL )
isoburn_ropt_destroy ( & ropts , 0 ) ;
Xorriso_free_meM ( libburn_adr ) ;
Xorriso_free_meM ( adr_data ) ;
return ( ret ) ;
}
/* @param flag bit0=input drive
bit1 = output drive
bit2 = eject
bit3 = no info message or toc
*/
int Xorriso_give_up_drive ( struct XorrisO * xorriso , int flag )
{
int in_is_out_too , ret , do_eject ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
in_is_out_too = ( xorriso - > in_drive_handle = = xorriso - > out_drive_handle ) ;
if ( ( flag & 4 ) & & in_is_out_too & & ( flag & ( 1 | 2 ) ) ) {
if ( ( flag & 3 ) ! = 3 ) {
sprintf ( xorriso - > info_text , " Giving up for -eject whole -dev " ) ;
Text_shellsafe ( xorriso - > indev , xorriso - > info_text , 1 ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
}
flag | = 3 ; /* give up in/out drive to eject it */
}
if ( ( flag & 1 ) & & xorriso - > in_drive_handle ! = NULL ) {
Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to give up drive " , 0 ) ;
if ( ! in_is_out_too ) {
do_eject = ! ! ( flag & 4 ) ;
if ( ( flag & 4 ) & & ! xorriso - > indev_is_exclusive ) {
sprintf ( xorriso - > info_text ,
" Will not eject media in non-exclusively aquired input drive. " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
do_eject = 0 ;
}
if ( drive ! = NULL )
isoburn_drive_release ( drive , do_eject ) ;
if ( dinfo ! = NULL )
burn_drive_info_free ( dinfo ) ;
}
xorriso - > in_drive_handle = NULL ;
xorriso - > indev [ 0 ] = 0 ;
if ( xorriso - > in_volset_handle ! = NULL )
iso_image_unref ( ( IsoImage * ) xorriso - > in_volset_handle ) ;
xorriso - > in_volset_handle = NULL ;
Sectorbitmap_destroy ( & ( xorriso - > in_sector_map ) , 0 ) ;
Xorriso_destroy_di_array ( xorriso , 0 ) ;
Xorriso_destroy_hln_array ( xorriso , 0 ) ;
xorriso - > loaded_volid [ 0 ] = 0 ;
xorriso - > isofs_st_out = time ( 0 ) - 1 ;
xorriso - > isofs_st_in = 0 ;
xorriso - > volset_change_pending = 0 ;
xorriso - > no_volset_present = 0 ;
xorriso - > loaded_boot_bin_lba = 0 ;
xorriso - > loaded_boot_cat_path [ 0 ] = 0 ;
xorriso - > boot_count = 0 ;
in_is_out_too = 0 ;
}
if ( ( flag & 2 ) & & xorriso - > out_drive_handle ! = NULL ) {
do_eject = ! ! ( flag & 4 ) ;
if ( ( flag & 4 ) & & ! xorriso - > outdev_is_exclusive ) {
sprintf ( xorriso - > info_text ,
" Will not eject media in non-exclusively aquired drive. " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
do_eject = 0 ;
}
Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to give up drive " , 2 ) ;
if ( ! in_is_out_too ) {
if ( drive ! = NULL )
isoburn_drive_release ( drive , do_eject ) ;
if ( dinfo ! = NULL )
burn_drive_info_free ( dinfo ) ;
}
xorriso - > out_drive_handle = NULL ;
xorriso - > outdev [ 0 ] = 0 ;
} else if ( ( flag & 1 ) & & xorriso - > out_drive_handle ! = NULL ) {
ret = Xorriso_create_empty_iso ( xorriso , 0 ) ;
if ( ret < = 0 )
return ( ret ) ;
if ( ! ( flag & 8 ) ) {
sprintf ( xorriso - > info_text ,
" Only the output drive remains. Created empty ISO image. \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
Xorriso_toc ( xorriso , 1 | 2 | 8 ) ;
}
}
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( 1 ) ;
}
int Xorriso_may_burn ( struct XorrisO * xorriso , int flag )
{
if ( xorriso - > outdev_is_exclusive )
return ( 1 ) ;
sprintf ( xorriso - > info_text , " The output drive was not aquired exclusively. " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
sprintf ( xorriso - > info_text , " A possible remedy is: -osirrox 'o_excl_on' " ) ;
if ( xorriso - > outdev [ 0 ] ) {
strcat ( xorriso - > info_text , " -outdev " ) ;
Text_shellsafe ( xorriso - > outdev , xorriso - > info_text , 1 ) ;
}
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " HINT " , 0 ) ;
return ( 0 ) ;
}
/* @param flag bit2=do not try to read ISO heads
*/
int Xorriso_toc_to_string ( struct XorrisO * xorriso , char * * toc_text , int flag )
{
int ret , stack_handle , toc_ret , l ;
struct Xorriso_lsT * results = NULL , * infos = NULL , * lpt ;
* toc_text = NULL ;
ret = Xorriso_push_outlists ( xorriso , & stack_handle , 1 ) ;
if ( ret < = 0 )
goto ex ;
toc_ret = Xorriso_toc ( xorriso , flag & 4 ) ;
ret = Xorriso_pull_outlists ( xorriso , stack_handle , & results , & infos , 0 ) ;
if ( ret < = 0 )
goto ex ;
if ( toc_ret < = 0 )
{ ret = toc_ret ; goto ex ; }
l = 0 ;
for ( lpt = results ; lpt ! = NULL ; lpt = Xorriso_lst_get_next ( lpt , 0 ) )
l + = strlen ( Xorriso_lst_get_text ( lpt , 0 ) ) ;
* toc_text = calloc ( l + 1 , 1 ) ;
l = 0 ;
for ( lpt = results ; lpt ! = NULL ; lpt = Xorriso_lst_get_next ( lpt , 0 ) ) {
strcpy ( ( * toc_text ) + l , Xorriso_lst_get_text ( lpt , 0 ) ) ;
l + = strlen ( Xorriso_lst_get_text ( lpt , 0 ) ) ;
}
ex : ;
Xorriso_lst_destroy_all ( & results , 0 ) ;
Xorriso_lst_destroy_all ( & infos , 0 ) ;
return ( ret ) ;
}
/* @param flag bit0+1= what to aquire after giving up outdev
0 = none , 1 = indev , 2 = outdev , 3 = both
*/
int Xorriso_reaquire_outdev ( struct XorrisO * xorriso , int flag )
{
int ret , aq_flag ;
char * drive_name = NULL ;
Xorriso_alloc_meM ( drive_name , char , SfileadrL ) ;
aq_flag = flag & 3 ;
strcpy ( drive_name , xorriso - > outdev ) ;
Xorriso_give_up_drive ( xorriso , aq_flag ) ;
if ( aq_flag = = 0 ) {
sprintf ( xorriso - > info_text , " Gave up -outdev " ) ;
Text_shellsafe ( xorriso - > outdev , xorriso - > info_text , 1 ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
{ ret = 1 ; goto ex ; }
}
sprintf ( xorriso - > info_text , " Re-aquiring -outdev " ) ;
Text_shellsafe ( drive_name , xorriso - > info_text , 1 ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
ret = Xorriso_aquire_drive ( xorriso , drive_name , aq_flag ) ;
if ( ret < = 0 ) {
sprintf ( xorriso - > info_text , " Could not re-aquire -outdev " ) ;
Text_shellsafe ( xorriso - > outdev , xorriso - > info_text , 1 ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
goto ex ;
}
ret = 1 ;
ex : ;
Xorriso_free_meM ( drive_name ) ;
return ( ret ) ;
}
/* @param flag
bit3 = report to info channel ( else to result channel )
*/
int Xorriso_toc_line ( struct XorrisO * xorriso , int flag )
{
if ( ! ( flag & 8 ) ) {
Xorriso_result ( xorriso , 0 ) ;
return ( 1 ) ;
}
strcpy ( xorriso - > info_text , xorriso - > result_line ) ;
Xorriso_info ( xorriso , 0 ) ;
return ( 1 ) ;
}
/* @param flag
bit1 = report about output drive
bit3 = report to info channel ( else to result channel )
bit4 = do no report failure if no drive aquired
*/
int Xorriso_media_product ( struct XorrisO * xorriso , int flag )
{
int ret , profile_no ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
char * product_id = NULL , * media_code1 = NULL , * media_code2 = NULL ;
char * book_type = NULL , * manuf = NULL , profile_name [ 80 ] , * respt ;
respt = xorriso - > result_line ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to print media product info " ,
flag & ( 2 | 16 ) ) ;
if ( ret < = 0 )
return ( ret ) ;
ret = burn_disc_get_media_id ( drive , & product_id , & media_code1 , & media_code2 ,
& book_type , 0 ) ;
if ( ret > 0 ) {
ret = burn_disc_get_profile ( drive , & profile_no , profile_name ) ;
if ( ret < = 0 )
return ( ret ) ;
sprintf ( respt , " Media product: %s , " , product_id ) ;
manuf = burn_guess_manufacturer ( profile_no , media_code1 , media_code2 , 0 ) ;
if ( manuf ! = NULL ) {
if ( strncmp ( manuf , " Unknown " , 8 ) = = 0 )
sprintf ( respt + strlen ( respt ) , " (not found in manufacturer list) \n " ) ;
else
sprintf ( respt + strlen ( respt ) , " %s \n " , manuf ) ;
} else
sprintf ( respt + strlen ( respt ) , " (error during manufacturer lookup) \n " ) ;
free ( product_id ) ;
free ( media_code1 ) ;
free ( media_code2 ) ;
if ( book_type ! = NULL )
free ( book_type ) ;
if ( manuf ! = NULL )
free ( manuf ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
}
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( 1 ) ;
}
/* @param flag bit0=short report form
bit1 = report about output drive
bit2 = do not try to read ISO heads
bit3 = report to info channel ( else to result channel )
bit4 = do no report failure if no drive aquired
bit5 = only report " Drive current " and " Drive type "
bit6 = report " Media product " with bit0
bit7 = only report " Drive current "
*/
int Xorriso_toc ( struct XorrisO * xorriso , int flag )
{
int num_sessions = 0 , num_tracks = 0 , lba = 0 , nwa = - 1 , pmin , psec , pframe , ret ;
int track_count = 0 , session_no , track_no , profile_no = - 1 , track_size ;
int last_track_start = 0 , last_track_size = - 1 , num_data = 0 , is_data = 0 ;
int is_inout_drive = 0 , drive_role , status , num_formats , emul_lba ;
int not_recognizable = 0 ;
char profile_name [ 80 ] , * respt , * devadr , * typetext = " " ;
struct burn_toc_entry toc_entry ;
struct burn_drive_info * dinfo ;
struct burn_multi_caps * caps = NULL ;
struct burn_drive * drive ;
enum burn_disc_status s ;
char mem_text [ 80 ] ;
off_t start_byte = 0 , num_free = 0 , size ;
unsigned dummy ;
struct isoburn_toc_disc * disc = NULL ;
struct isoburn_toc_session * * sessions ;
struct isoburn_toc_track * * tracks ;
int image_blocks = 0 ;
char volume_id [ 33 ] ;
struct burn_toc_entry next_toc_entry ;
/*
int num_payload = 0 , num_wasted = 0 , num_nondata = 0 ;
*/
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to print Table Of Content " ,
flag & ( 2 | 16 ) ) ;
if ( ret < = 0 )
{ ret = 0 ; goto ex ; }
respt = xorriso - > result_line ;
if ( strcmp ( xorriso - > indev , xorriso - > outdev ) = = 0 )
is_inout_drive = 1 ;
if ( flag & 2 )
devadr = xorriso - > outdev ;
else
devadr = xorriso - > indev ;
sprintf ( respt , " Drive current: %s '%s' \n " ,
( is_inout_drive ? " -dev " : ( flag & 2 ? " -outdev " : " -indev " ) ) ,
devadr ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
if ( flag & 128 )
{ ret = 1 ; goto ex ; }
sprintf ( respt , " Drive type : vendor '%s' product '%s' revision '%s' \n " ,
dinfo [ 0 ] . vendor , dinfo [ 0 ] . product , dinfo [ 0 ] . revision ) ;
if ( ( flag & 32 ) | ! ( flag & 1 ) )
Xorriso_toc_line ( xorriso , flag & 8 ) ;
if ( flag & 32 )
{ ret = 1 ; goto ex ; }
ret = burn_disc_get_profile ( drive , & profile_no , profile_name ) ;
s = isoburn_disc_get_status ( drive ) ;
if ( profile_no = = 0x0002 & & s = = BURN_DISC_EMPTY )
profile_no = 0 ;
sprintf ( respt , " Media current: " ) ;
drive_role = burn_drive_get_drive_role ( drive ) ;
if ( profile_no > 0 & & ret > 0 ) {
if ( profile_name [ 0 ] )
sprintf ( respt + strlen ( respt ) , " %s " , profile_name ) ;
else
sprintf ( respt + strlen ( respt ) , " %4.4Xh " , profile_no ) ;
if ( drive_role = = 2 )
sprintf ( respt + strlen ( respt ) , " , overwriteable " ) ;
else if ( drive_role = = 4 )
sprintf ( respt + strlen ( respt ) , " , random read-only " ) ;
else if ( drive_role = = 5 )
sprintf ( respt + strlen ( respt ) , " , random write-only " ) ;
else if ( drive_role = = 0 | | drive_role = = 3 )
sprintf ( respt + strlen ( respt ) , " , sequential " ) ;
strcat ( respt , " \n " ) ;
} else {
sprintf ( respt + strlen ( respt ) , " is not recognizable \n " ) ;
not_recognizable = 1 ;
}
Xorriso_toc_line ( xorriso , flag & 8 ) ;
if ( ( flag & 64 ) | | ! ( flag & 1 ) ) {
Xorriso_media_product ( xorriso , flag & ( 2 | 8 | 16 ) ) ;
if ( xorriso - > request_to_abort )
{ ret = 1 ; goto ex ; }
}
sprintf ( respt , " Media status : " ) ;
if ( s = = BURN_DISC_FULL ) {
if ( not_recognizable )
sprintf ( respt + strlen ( respt ) , " is not recognizable \n " ) ;
else
sprintf ( respt + strlen ( respt ) , " is written , is closed " ) ;
} else if ( s = = BURN_DISC_APPENDABLE ) {
sprintf ( respt + strlen ( respt ) , " is written , is appendable " ) ;
} else if ( s = = BURN_DISC_BLANK ) {
sprintf ( respt + strlen ( respt ) , " is blank " ) ;
} else if ( s = = BURN_DISC_EMPTY )
sprintf ( respt + strlen ( respt ) , " is not present " ) ;
else
sprintf ( respt + strlen ( respt ) , " is not recognizable " ) ;
if ( s = = BURN_DISC_APPENDABLE | | s = = BURN_DISC_BLANK ) {
ret = burn_disc_next_track_is_damaged ( drive , 0 ) ;
if ( ret & 1 )
sprintf ( respt + strlen ( respt ) , " , but next track is damaged " ) ;
else if ( ret & 2 )
sprintf ( respt + strlen ( respt ) , " , but no writable address " ) ;
else if ( profile_no = = 0x14 ) { /* DVD-RW sequential */
ret = burn_disc_get_multi_caps ( drive , BURN_WRITE_TAO , & caps , 0 ) ;
if ( ret = = 0 )
sprintf ( respt + strlen ( respt ) , " , but will need -close on " ) ;
if ( caps ! = NULL )
burn_disc_free_multi_caps ( & caps ) ;
} else if ( profile_no = = 0x15 ) { /* DVD-RW DL */
sprintf ( respt + strlen ( respt ) , " , but will need -close \" on \" " ) ;
}
}
strcat ( respt , " \n " ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
if ( s = = BURN_DISC_BLANK ) {
sprintf ( respt , " Media summary: 0 sessions, 0 data blocks, 0 data " ) ;
num_free = isoburn_disc_available_space ( drive , NULL ) ;
Sfile_scale ( ( double ) num_free , mem_text , 5 , 1e4 , 1 ) ;
sprintf ( respt + strlen ( respt ) , " , %s free \n " , mem_text ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
}
if ( s ! = BURN_DISC_FULL & & s ! = BURN_DISC_APPENDABLE )
{ ret = 1 ; goto ex ; }
if ( xorriso - > request_to_abort )
{ ret = 1 ; goto ex ; }
if ( ! ( flag & 2 ) )
Xorriso_show_boot_info ( xorriso , 1 | ( flag & 8 ) | ( ( flag & 1 ) < < 1 ) ) ;
disc = isoburn_toc_drive_get_disc ( drive ) ;
if ( flag & 4 )
sprintf ( respt , " TOC layout : %3s , %9s , %10s \n " ,
" Idx " , " sbsector " , " Size " ) ;
else
sprintf ( respt , " TOC layout : %3s , %9s , %10s , %s \n " ,
" Idx " , " sbsector " , " Size " , " Volume Id " ) ;
if ( ! ( flag & 1 ) )
Xorriso_toc_line ( xorriso , flag & 8 ) ;
if ( disc = = NULL ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( drive_role = = 5 & & s = = BURN_DISC_APPENDABLE ) {
ret = burn_disc_track_lba_nwa ( drive , NULL , 0 , & lba , & nwa ) ;
if ( ret ! = 1 )
lba = 0 ;
} else {
ret = isoburn_get_min_start_byte ( drive , & start_byte , 0 ) ;
nwa = start_byte / 2048 ;
if ( ret < = 0 ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( flag & 1 )
{ ret = 1 ; goto ex ; }
sprintf ( xorriso - > info_text , " Cannot obtain Table Of Content " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " SORRY " , 0 ) ;
{ ret = 0 ; goto ex ; }
}
}
/* fabricate TOC */
typetext = " Other session " ;
if ( flag & 4 ) {
ret = 0 ;
typetext = " Session " ;
} else
ret = isoburn_read_iso_head ( drive , 0 , & image_blocks , volume_id , 1 ) ;