2010-05-15 18:48:10 +00:00
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007 - 2010 Thomas Schmitt , < scdbackup @ gmx . net >
Provided under GPL version 2 or later .
This file contains functions which operate on drives and media .
*/
2010-05-16 09:32:14 +00:00
# ifdef HAVE_CONFIG_H
# include "../config.h"
# endif
2010-05-15 18:48:10 +00:00
# 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 [ BURN_DRIVE_ADR_LEN + SfileadrL ] ;
char * abs_pt , abs_adr [ 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 ) ;
return ( - 1 ) ;
}
ret = Sfile_add_to_path ( abs_adr , path_pt , 0 ) ;
if ( ret < = 0 )
return ( - 1 ) ;
}
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 )
return ( ret ) ;
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 ) ;
return ( 0 ) ;
}
/* if in greylist and not MMC and not stdio prefix: reject */
if ( is_known_mmc < 0 )
return ( ret ) ;
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 )
return ( ret ) ;
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 ) ;
return ( 0 ) ;
}
}
ok : ;
if ( strncmp ( adr , " mmc: " , 4 ) = = 0 ) {
if ( Sfile_str ( result , path_pt , 0 ) < = 0 )
return ( 0 ) ;
} else if ( adr = = path_pt & & is_known_mmc < = 0 ) {
Sfile_str ( result , " stdio: " , 0 ) ;
if ( Sfile_str ( result , adr , 1 ) < = 0 )
return ( 0 ) ;
} else {
if ( Sfile_str ( result , adr , 0 ) < = 0 )
return ( 0 ) ;
}
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 ) ;
return ( 0 ) ;
}
}
return ( 1 ) ;
}
/* @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 ;
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 [ SfileadrL ] , * boot_fate , * sev ;
size_t value_length ;
char * value = NULL ;
double num ;
char volid [ 33 ] , adr_data [ 163 ] , * adr_pt ;
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 ) ;
return ( - 1 ) ;
}
ret = Xorriso_give_up_drive ( xorriso , ( flag & 3 ) | 8 ) ;
if ( ret < = 0 )
return ( ret ) ;
if ( flag & 1 )
xorriso - > isofs_st_out = time ( 0 ) - 1 ;
ret = Xorriso_auto_driveadr ( xorriso , adr , libburn_adr , 0 ) ;
if ( ret < = 0 )
return ( ret ) ;
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 ) ;
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 ;
}
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 ;
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 */
}
}
state = isoburn_disc_get_status ( drive ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
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 ) ;
2010-06-23 17:54:41 +00:00
xorriso - > boot_count = 0 ;
2010-05-15 18:48:10 +00:00
/* 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 ;
# ifdef isoburn_ropt_nomd5
if ( ! ( xorriso - > do_md5 & 1 ) )
ext | = isoburn_ropt_nomd5 ;
# endif
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 ) ) ;
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 = = ISO_SB_TREE_CORRUPTED & & ( xorriso - > do_md5 & 1 ) ) {
Xorriso_msgs_submit ( xorriso , 0 ,
" You might get a questionable ISO image tree by option -md5 '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 ;
2010-06-26 11:40:36 +00:00
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 ;
2010-05-15 18:48:10 +00:00
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 ) {
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 ) ;
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 ;
char sfe [ 5 * SfileadrL ] ;
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 %s " ,
Text_shellsafe ( xorriso - > indev , sfe , 0 ) ) ;
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 [ SfileadrL ] , sfe [ 5 * 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 %s " ,
Text_shellsafe ( xorriso - > outdev , sfe , 0 ) ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
return ( 1 ) ;
}
sprintf ( xorriso - > info_text , " Re-aquiring -outdev %s " ,
Text_shellsafe ( drive_name , sfe , 0 ) ) ;
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 %s " ,
Text_shellsafe ( xorriso - > outdev , sfe , 0 ) ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
return ( ret ) ;
}
return ( 1 ) ;
}
/* @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 num_payload = 0 , num_wasted = 0 , num_nondata = 0 , not_reconizable = 0 ;
char profile_name [ 80 ] , * respt , * devadr , * typetext = " " ;
struct burn_toc_entry toc_entry ;
struct burn_drive_info * dinfo ;
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 ;
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: " ) ;
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 ) ;
drive_role = burn_drive_get_drive_role ( drive ) ;
if ( drive_role = = 2 )
sprintf ( respt + strlen ( respt ) , " , overwriteable " ) ;
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_reconizable = 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_reconizable )
sprintf ( respt + strlen ( respt ) , " is not recognizable \n " ) ;
else
sprintf ( respt + strlen ( respt ) , " is written , is closed \n " ) ;
} else if ( s = = BURN_DISC_APPENDABLE ) {
sprintf ( respt + strlen ( respt ) , " is written , is appendable \n " ) ;
} else if ( s = = BURN_DISC_BLANK ) {
sprintf ( respt + strlen ( respt ) , " is blank \n " ) ;
} else if ( s = = BURN_DISC_EMPTY )
sprintf ( respt + strlen ( respt ) , " is not present \n " ) ;
else
sprintf ( respt + strlen ( respt ) , " is not recognizable \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 ) ;
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 = 0 ; 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 ) ;
if ( ret > 0 ) {
sprintf ( respt , " ISO session : %3d , %9d , %9ds , %s \n " ,
1 , 0 , image_blocks , volume_id ) ;
nwa = image_blocks ;
} else {
nwa = 0 ;
ret = burn_disc_get_formats ( drive , & status , & size , & dummy ,
& num_formats ) ;
if ( ret > 0 & & status = = BURN_FORMAT_IS_FORMATTED )
nwa = size / 2048 ;
sprintf ( respt , " %13s: %3d , %9d , %9ds , \n " ,
typetext , 1 , 0 , nwa ) ;
}
if ( ! ( flag & 1 ) )
Xorriso_toc_line ( xorriso , flag & 8 ) ;
last_track_start = lba ;
num_payload = num_data = last_track_size = nwa ;
num_sessions = 1 ;
} else {
sessions = isoburn_toc_disc_get_sessions ( disc , & num_sessions ) ;
for ( session_no = 0 ; session_no < num_sessions & & ! ( xorriso - > request_to_abort ) ;
session_no + + ) {
tracks = isoburn_toc_session_get_tracks ( sessions [ session_no ] , & num_tracks ) ;
if ( tracks = = NULL )
continue ;
for ( track_no = 0 ; track_no < num_tracks & & ! ( xorriso - > request_to_abort ) ;
track_no + + ) {
track_count + + ;
is_data = 0 ;
isoburn_toc_track_get_entry ( tracks [ track_no ] , & toc_entry ) ;
if ( toc_entry . extensions_valid & 1 ) {
/* DVD extension valid */
lba = toc_entry . start_lba ;
track_size = toc_entry . track_blocks ;
} else {
lba = burn_msf_to_lba ( toc_entry . pmin , toc_entry . psec ,
toc_entry . pframe ) ;
if ( track_no = = num_tracks - 1 ) {
isoburn_toc_session_get_leadout_entry ( sessions [ session_no ] ,
& next_toc_entry ) ;
} else {
isoburn_toc_track_get_entry ( tracks [ track_no + 1 ] , & next_toc_entry ) ;
}
track_size = burn_msf_to_lba ( next_toc_entry . pmin , next_toc_entry . psec ,
next_toc_entry . pframe ) - lba ;
}
if ( flag & ( 1 | 4 ) )
ret = 0 ;
else {
ret = isoburn_toc_track_get_emul ( tracks [ track_no ] , & emul_lba ,
& image_blocks , volume_id , 0 ) ;
if ( ret < = 0 )
ret = isoburn_read_iso_head ( drive , lba , & image_blocks , volume_id , 1 ) ;
if ( image_blocks > track_size ) {
sprintf ( xorriso - > info_text ,
" Session %d bears ISO image size %ds larger than track size %ds " ,
session_no + 1 , image_blocks , track_size ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " ,
0 ) ;
image_blocks = track_size ;
}
}
if ( ret > 0 & & track_no = = 0 ) {
sprintf ( respt , " ISO session : %3d , %9d , %9ds , %s \n " ,
session_no + 1 , lba , image_blocks , volume_id ) ;
} else if ( ret > 0 ) {
sprintf ( respt , " ISO track : %3d , %9d , %9ds , %s \n " ,
track_count , lba , image_blocks , volume_id ) ;
} else if ( track_no = = 0 ) {
typetext = " Other session " ;
if ( flag & 4 )
typetext = " Session " ;
sprintf ( respt , " %13s: %3d , %9d , %9ds , \n " ,
typetext , session_no + 1 , lba , track_size ) ;
} else {
typetext = " Other track " ;
if ( flag & 4 )
typetext = " Track " ;
sprintf ( respt , " %13s: %3d , %9d , %9ds , \n " ,
typetext , track_count , lba , track_size ) ;
}
if ( ! ( flag & 1 ) )
Xorriso_toc_line ( xorriso , flag & 8 ) ;
if ( track_no > 0 )
num_payload + = lba - last_track_start ;
last_track_start = lba ;
if ( ( toc_entry . control & 7 ) > = 4 ) /* data track */
is_data = 1 ;
}
isoburn_toc_session_get_leadout_entry ( sessions [ session_no ] , & toc_entry ) ;
if ( toc_entry . extensions_valid & 1 ) {
lba = toc_entry . start_lba ;
burn_lba_to_msf ( lba , & pmin , & psec , & pframe ) ;
} else {
lba = burn_msf_to_lba ( pmin , psec , pframe ) ;
lba = burn_msf_to_lba ( toc_entry . pmin , toc_entry . psec , toc_entry . pframe ) ;
}
last_track_size = lba - last_track_start ;
num_payload + = last_track_size ;
if ( is_data )
num_data + = last_track_size ;
}
}
if ( xorriso - > request_to_abort )
{ ret = 1 ; goto ex ; }
num_wasted = lba - num_payload ;
num_nondata = lba - num_data ;
Sfile_scale ( ( ( double ) num_data ) * 2048.0 , mem_text , 5 , 1e4 , 1 ) ;
sprintf ( respt , " Media summary: %d session%s, %d data blocks, %s data " ,
num_sessions , ( num_sessions = = 1 ? " " : " s " ) , num_data , mem_text ) ;
num_free = isoburn_disc_available_space ( drive , NULL ) ;
Sfile_scale ( ( double ) num_free , mem_text , 5 , 1e4 , 1 ) ;
sprintf ( respt + strlen ( respt ) , " , %s free " , mem_text ) ;
sprintf ( respt + strlen ( respt ) , " \n " ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
if ( s = = BURN_DISC_APPENDABLE & & nwa ! = 0 ) {
ret = isoburn_disc_track_lba_nwa ( drive , NULL , 0 , & lba , & nwa ) ;
if ( ret > 0 ) {
sprintf ( respt , " Media nwa : %ds \n " , nwa ) ;
if ( ! ( flag & 1 ) )
Xorriso_toc_line ( xorriso , flag & 8 ) ;
}
}
if ( disc ! = NULL )
isoburn_toc_disc_free ( disc ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
ret = 1 ;
ex : ;
return ( ret ) ;
}
int Xorriso_show_devices ( struct XorrisO * xorriso , int flag )
{
char adr [ BURN_DRIVE_ADR_LEN ] ;
int i , j , max_dev_len = 1 , pad ;
struct burn_drive_info * drive_list = NULL ;
unsigned int drive_count ;
char * respt , perms [ 8 ] ;
struct stat stbuf ;
sprintf ( xorriso - > info_text , " Beginning to scan for devices ... \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
burn_drive_clear_whitelist ( ) ;
while ( ! burn_drive_scan ( & drive_list , & drive_count ) ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
usleep ( 100000 ) ;
}
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( drive_count < = 0 ) {
/* >>> was a drive_list created at all ? */
/* >>> must it be freed ? */
sprintf ( xorriso - > info_text , " No drives found " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " SORRY " , 0 ) ;
return ( 0 ) ;
}
sprintf ( xorriso - > info_text , " Full drive scan done \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
sprintf ( xorriso - > info_text , " ----------------------------------------------------------------------------- \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
respt = xorriso - > result_line ;
for ( i = 0 ; i < drive_count & & ! ( xorriso - > request_to_abort ) ; i + + ) {
if ( burn_drive_get_adr ( & ( drive_list [ i ] ) , adr ) < = 0 )
strcpy ( adr , " -get_adr_failed- " ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( strlen ( adr ) > max_dev_len )
max_dev_len = strlen ( adr ) ;
}
for ( i = 0 ; i < drive_count & & ! ( xorriso - > request_to_abort ) ; i + + ) {
if ( burn_drive_get_adr ( & ( drive_list [ i ] ) , adr ) < = 0 )
strcpy ( adr , " -get_adr_failed- " ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( stat ( adr , & stbuf ) = = - 1 ) {
sprintf ( perms , " errno=%d " , errno ) ;
} else {
strcpy ( perms , " ------ " ) ;
if ( stbuf . st_mode & S_IRUSR ) perms [ 0 ] = ' r ' ;
if ( stbuf . st_mode & S_IWUSR ) perms [ 1 ] = ' w ' ;
if ( stbuf . st_mode & S_IRGRP ) perms [ 2 ] = ' r ' ;
if ( stbuf . st_mode & S_IWGRP ) perms [ 3 ] = ' w ' ;
if ( stbuf . st_mode & S_IROTH ) perms [ 4 ] = ' r ' ;
if ( stbuf . st_mode & S_IWOTH ) perms [ 5 ] = ' w ' ;
}
sprintf ( respt , " %d -dev '%s' " , i , adr ) ;
pad = max_dev_len - strlen ( adr ) ;
if ( pad > 0 )
for ( j = 0 ; j < pad ; j + + )
strcat ( respt , " " ) ;
sprintf ( respt + strlen ( respt ) , " %s : '%-8.8s' '%s' \n " ,
perms , drive_list [ i ] . vendor , drive_list [ i ] . product ) ;
Xorriso_result ( xorriso , 0 ) ;
}
sprintf ( xorriso - > info_text , " ----------------------------------------------------------------------------- \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
burn_drive_info_free ( drive_list ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( 1 ) ;
}
int Xorriso_tell_media_space ( struct XorrisO * xorriso ,
int * media_space , int * free_space , int flag )
{
int ret ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
struct burn_write_opts * burn_options ;
( * free_space ) = ( * media_space ) = 0 ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to -tell_media_space " , 2 ) ;
if ( ret < = 0 )
return ( 0 ) ;
ret = Xorriso_make_write_options ( xorriso , drive , & burn_options , 0 ) ;
if ( ret < = 0 )
return ( - 1 ) ;
( * free_space ) = ( * media_space ) =
isoburn_disc_available_space ( drive , burn_options ) / ( off_t ) 2048 ;
burn_write_opts_free ( burn_options ) ;
if ( xorriso - > volset_change_pending ) {
ret = Xorriso_write_session ( xorriso , 1 ) ;
if ( ret > 0 )
( * free_space ) - = ret ;
}
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( 1 ) ;
}
/* @return <=0 error, 1 success
*/
int Xorriso_list_formats ( struct XorrisO * xorriso , int flag )
{
int ret , i , status , num_formats , profile_no , type ;
off_t size ;
unsigned dummy ;
char status_text [ 80 ] , profile_name [ 90 ] , * respt ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
respt = xorriso - > result_line ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to obtain format descriptor list " , 1 | 2 ) ;
if ( ret < = 0 )
return ( 0 ) ;
if ( ret = = 2 )
goto ex ;
ret = burn_disc_get_formats ( drive , & status , & size , & dummy ,
& num_formats ) ;
if ( ret < = 0 ) {
sprintf ( xorriso - > info_text , " Cannot obtain format list info " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
ret = 0 ; goto ex ;
}
ret = Xorriso_toc ( xorriso , 3 ) ;
if ( ret < = 0 )
goto ex ;
ret = burn_disc_get_profile ( drive , & profile_no , profile_name ) ;
if ( ret < = 0 )
goto ex ;
if ( status = = BURN_FORMAT_IS_UNFORMATTED )
sprintf ( status_text , " unformatted, up to %.1f MiB " ,
( ( double ) size ) / 1024.0 / 1024.0 ) ;
else if ( status = = BURN_FORMAT_IS_FORMATTED ) {
if ( profile_no = = 0x12 | | profile_no = = 0x13 | | profile_no = = 0x1a | |
profile_no = = 0x43 )
sprintf ( status_text , " formatted, with %.1f MiB " ,
( ( double ) size ) / 1024.0 / 1024.0 ) ;
else
sprintf ( status_text , " written, with %.1f MiB " ,
( ( double ) size ) / 1024.0 / 1024.0 ) ;
} else if ( status = = BURN_FORMAT_IS_UNKNOWN ) {
if ( profile_no > 0 )
sprintf ( status_text , " intermediate or unknown " ) ;
else
sprintf ( status_text , " no media or unknown media " ) ;
} else
sprintf ( status_text , " illegal status according to MMC-5 " ) ;
sprintf ( respt , " Format status: %s \n " , status_text ) ;
Xorriso_result ( xorriso , 0 ) ;
for ( i = 0 ; i < num_formats ; i + + ) {
ret = burn_disc_get_format_descr ( drive , i , & type , & size , & dummy ) ;
if ( ret < = 0 )
continue ;
sprintf ( respt , " Format idx %-2d: %2.2Xh , %.fs , %.1f MiB \n " ,
i , type , ( ( double ) size ) / 2048.0 , ( ( double ) size ) / 1024.0 / 1024.0 ) ;
Xorriso_result ( xorriso , 0 ) ;
}
ret = 1 ;
ex : ;
return ( ret ) ;
}
/* @param flag bit0= cdrecord style
bit1 = obtain outdrive , else indrive
@ return < = 0 error , 1 success
*/
int Xorriso_list_profiles ( struct XorrisO * xorriso , int flag )
{
int ret , i ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
int num_profiles , profiles [ 64 ] ;
char is_current [ 64 ] , profile_name [ 90 ] , * respt ;
respt = xorriso - > result_line ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to obtain profile list " , 1 | ( flag & 2 ) ) ;
if ( ret < = 0 )
return ( 0 ) ;
burn_drive_get_all_profiles ( drive , & num_profiles , profiles , is_current ) ;
for ( i = 0 ; i < num_profiles ; i + + ) {
ret = burn_obtain_profile_name ( profiles [ i ] , profile_name ) ;
if ( ret < = 0 )
strcpy ( profile_name , " unknown " ) ;
sprintf ( respt , " %s 0x%4.4X (%s)%s \n " ,
flag & 1 ? " Profile: " : " Profile : " ,
( unsigned int ) profiles [ i ] ,
profile_name , is_current [ i ] ? " (current) " : " " ) ;
Xorriso_result ( xorriso , 0 ) ;
}
return ( 1 ) ;
}
/* @param flag bit0= -inq
bit1 = - checkdrive
*/
int Xorriso_atip ( struct XorrisO * xorriso , int flag )
{
int ret , profile_number = 0 ;
char * respt , profile_name [ 80 ] ;
double x_speed_max , x_speed_min = - 1.0 ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
enum burn_disc_status s ;
char * manuf = NULL , * media_code1 = NULL , * media_code2 = NULL ;
char * book_type = NULL , * product_id = NULL ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to print drive and media info " , 2 ) ;
if ( ret < = 0 )
return ( 0 ) ;
respt = xorriso - > result_line ;
sprintf ( respt , " Device type : " ) ;
ret = burn_drive_get_drive_role ( drive ) ;
if ( ret = = 0 )
sprintf ( respt + strlen ( respt ) , " %s \n " , " Emulated (null-drive) " ) ;
else if ( ret = = 2 )
sprintf ( respt + strlen ( respt ) , " %s \n " ,
" Emulated (stdio-drive, 2k random read-write) " ) ;
else if ( ret = = 3 )
sprintf ( respt + strlen ( respt ) , " %s \n " ,
" Emulated (stdio-drive, sequential write-only) " ) ;
else if ( ret ! = 1 )
sprintf ( respt + strlen ( respt ) , " %s \n " , " Emulated (stdio-drive) " ) ;
else
sprintf ( respt + strlen ( respt ) , " %s \n " , " Removable CD-ROM " ) ;
sprintf ( respt + strlen ( respt ) , " Vendor_info : '%s' \n " , dinfo - > vendor ) ;
sprintf ( respt + strlen ( respt ) , " Identifikation : '%s' \n " , dinfo - > product ) ;
sprintf ( respt + strlen ( respt ) , " Revision : '%s' \n " , dinfo - > revision ) ;
Xorriso_result ( xorriso , 1 ) ;
if ( flag & 1 )
return ( 1 ) ;
sprintf ( respt , " Driver flags : BURNFREE \n " ) ;
sprintf ( respt + strlen ( respt ) , " Supported modes: SAO TAO \n " ) ;
Xorriso_result ( xorriso , 1 ) ;
if ( flag & 2 )
return ( 1 ) ;
s = burn_disc_get_status ( drive ) ;
ret = burn_disc_get_profile ( drive , & profile_number , profile_name ) ;
if ( ret < = 0 ) {
profile_number = 0 ;
strcpy ( profile_name , " -unidentified- " ) ;
}
if ( s ! = BURN_DISC_UNSUITABLE ) {
ret = burn_disc_read_atip ( drive ) ;
if ( ret > 0 ) {
ret = burn_drive_get_min_write_speed ( drive ) ;
x_speed_min = ( ( double ) ret ) / 176.4 ;
}
}
if ( s = = BURN_DISC_EMPTY ) {
sprintf ( respt , " Current: none \n " ) ;
Xorriso_result ( xorriso , 1 ) ;
return ( 1 ) ;
} else
sprintf ( respt , " Current: %s \n " , profile_name ) ;
Xorriso_result ( xorriso , 1 ) ;
Xorriso_list_profiles ( xorriso , 1 | 2 ) ;
if ( strstr ( profile_name , " BD " ) = = profile_name ) {
printf ( " Mounted Media: %2.2Xh, %s \n " , profile_number , profile_name ) ;
} else if ( strstr ( profile_name , " DVD " ) = = profile_name ) {
sprintf ( respt , " book type: %s (emulated booktype) \n " , profile_name ) ;
Xorriso_result ( xorriso , 1 ) ;
if ( profile_number = = 0x13 ) {
sprintf ( respt , " xorriso: message for sdvdbackup: \" (growisofs mode Restricted Overwrite) \" \n " ) ;
Xorriso_result ( xorriso , 1 ) ;
}
} else {
sprintf ( respt , " ATIP info from disk: \n " ) ;
Xorriso_result ( xorriso , 1 ) ;
if ( burn_disc_erasable ( drive ) )
sprintf ( respt , " Is erasable \n " ) ;
else
sprintf ( respt , " Is not erasable \n " ) ;
Xorriso_result ( xorriso , 1 ) ;
{ int start_lba , end_lba , min , sec , fr ;
ret = burn_drive_get_start_end_lba ( drive , & start_lba , & end_lba , 0 ) ;
if ( ret > 0 ) {
burn_lba_to_msf ( start_lba , & min , & sec , & fr ) ;
sprintf ( respt , " ATIP start of lead in: %d (%-2.2d:%-2.2d/%-2.2d) \n " ,
start_lba , min , sec , fr ) ;
Xorriso_result ( xorriso , 1 ) ;
burn_lba_to_msf ( end_lba , & min , & sec , & fr ) ;
sprintf ( respt , " ATIP start of lead out: %d (%-2.2d:%-2.2d/%-2.2d) \n " ,
end_lba , min , sec , fr ) ;
Xorriso_result ( xorriso , 1 ) ;
}
}
ret = burn_drive_get_write_speed ( drive ) ;
x_speed_max = ( ( double ) ret ) / 176.4 ;
if ( x_speed_min < 0 )
x_speed_min = x_speed_max ;
sprintf ( respt ,
" 1T speed low: %.f 1T speed high: %.f \n " , x_speed_min , x_speed_max ) ;
Xorriso_result ( xorriso , 1 ) ;
}
ret = burn_disc_get_media_id ( drive , & product_id , & media_code1 , & media_code2 ,
& book_type , 0 ) ;
if ( ret > 0 & & media_code1 ! = NULL & & media_code2 ! = NULL )
manuf = burn_guess_manufacturer ( profile_number , media_code1 , media_code2 , 0 ) ;
if ( product_id ! = NULL ) {
sprintf ( respt , " Product Id: %s \n " , product_id ) ;
Xorriso_result ( xorriso , 1 ) ;
}
if ( manuf ! = NULL ) {
sprintf ( respt , " Producer: %s \n " , manuf ) ;
Xorriso_result ( xorriso , 1 ) ;
}
if ( profile_number = = 0x09 | | profile_number = = 0x0a ) {
sprintf ( respt , " Manufacturer: %s \n " , manuf ) ;
Xorriso_result ( xorriso , 1 ) ;
} else if ( product_id ! = NULL & & media_code1 ! = NULL & & media_code2 ! = NULL ) {
free ( product_id ) ;
free ( media_code1 ) ;
free ( media_code2 ) ;
if ( book_type ! = NULL )
free ( book_type ) ;
product_id = media_code1 = media_code2 = book_type = NULL ;
ret = burn_disc_get_media_id ( drive , & product_id , & media_code1 , & media_code2 ,
& book_type , 1 ) ;
if ( ret > 0 ) {
sprintf ( respt , " Manufacturer: '%s' \n " , media_code1 ) ;
Xorriso_result ( xorriso , 1 ) ;
if ( media_code2 [ 0 ] ) {
sprintf ( respt , " Media type: '%s' \n " , media_code2 ) ;
Xorriso_result ( xorriso , 1 ) ;
}
}
}
if ( manuf ! = NULL )
free ( manuf ) ;
if ( media_code1 ! = NULL )
free ( media_code1 ) ;
if ( media_code2 ! = NULL )
free ( media_code2 ) ;
if ( book_type ! = NULL )
free ( book_type ) ;
if ( product_id ! = NULL )
free ( product_id ) ;
return ( 1 ) ;
}
/* @param flag bit1= outdev rather than indev
@ return < 0 error , 0 = no profile to see , 1 = ok , 2 = ok , is CD profile
3 = ok , is BD profile
*/
int Xorriso_get_profile ( struct XorrisO * xorriso , int * profile_number ,
char profile_name [ 80 ] , int flag )
{
int ret ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
* profile_number = 0 ;
profile_name [ 0 ] = 0 ;
if ( ( ( flag & 2 ) & & xorriso - > out_drive_handle = = NULL ) | |
( ( ! ( flag & 2 ) ) & & xorriso - > in_drive_handle = = NULL ) )
return ( 0 ) ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to determine media type " , flag & 2 ) ;
if ( ret < = 0 )
return ( 0 ) ;
ret = burn_disc_get_profile ( drive , profile_number , profile_name ) ;
if ( ret < = 0 )
return ( ret ) ;
if ( * profile_number = = 0x08 | | * profile_number = = 0x09 | | * profile_number = = 0x0a )
return ( 2 ) ;
if ( * profile_number = = 0x40 | | * profile_number = = 0x41 | |
* profile_number = = 0x42 | | * profile_number = = 0x43 )
return ( 3 ) ;
return ( 0 ) ;
}
/* @param flag bit0= grow_overwriteable_iso
bit1 = obtain info from outdev
bit2 = no need to obtain msc2 ( NWA )
*/
int Xorriso_msinfo ( struct XorrisO * xorriso , int * msc1 , int * msc2 , int flag )
{
int ret , dummy ;
struct burn_drive * drive ;
struct burn_drive_info * dinfo ;
enum burn_disc_status disc_state ;
* msc1 = * msc2 = - 1 ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to obtain msinfo " , flag & 2 ) ;
if ( ret < = 0 )
return ( ret ) ;
if ( flag & 1 )
disc_state = isoburn_disc_get_status ( drive ) ;
else
disc_state = burn_disc_get_status ( drive ) ;
if ( disc_state ! = BURN_DISC_APPENDABLE & &
! ( disc_state = = BURN_DISC_FULL & & ( flag & 4 ) ) ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ! ( flag & 4 ) ) {
sprintf ( xorriso - > info_text ,
" %s media is not appendable. Cannot obtain -msinfo. " ,
( flag & 2 ) ? " Output " : " Input " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
}
return ( 0 ) ;
}
ret = isoburn_disc_get_msc1 ( drive , msc1 ) ;
if ( ret < = 0 ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
sprintf ( xorriso - > info_text , " Cannot obtain address of most recent session " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
return ( 0 ) ;
}
if ( flag & 4 )
return ( 1 ) ;
ret = isoburn_disc_track_lba_nwa ( drive , NULL , 0 , & dummy , msc2 ) ;
if ( ret < 0 ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
sprintf ( xorriso - > info_text , " Cannot obtain next writeable address on media " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
return ( 0 ) ;
}
return ( 1 ) ;
}
/* @param flag bit0=input drive
bit1 = output drive
bit2 = wake up rather than calm down
*/
int Xorriso_drive_snooze ( struct XorrisO * xorriso , int flag )
{
int in_is_out_too , ret ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
in_is_out_too = ( xorriso - > in_drive_handle = = xorriso - > out_drive_handle ) ;
if ( ( flag & 1 ) & & xorriso - > in_drive_handle ! = NULL ) {
Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to calm drive " , 0 ) ;
burn_drive_snooze ( drive , ! ! ( flag & 4 ) ) ;
if ( in_is_out_too )
{ ret = 1 ; goto ex ; }
}
if ( ( flag & 2 ) & & xorriso - > out_drive_handle ! = NULL ) {
Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to calm drive " , 2 ) ;
burn_drive_snooze ( drive , ! ! ( flag & 4 ) ) ;
}
ret = 1 ;
ex : ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( ret ) ;
}
/* @param flag bit0= enable SCSI command logging to stderr */
int Xorriso_scsi_log ( struct XorrisO * xorriso , int flag )
{
if ( flag = = 0 )
burn_set_scsi_logging ( 0 ) ;
else
burn_set_scsi_logging ( 2 | 4 ) ;
return ( 1 ) ;
}
int Xorriso_check_md5_range ( struct XorrisO * xorriso , off_t start_lba ,
off_t end_lba , char md5 [ 16 ] , int flag )
{
int ret ;
struct burn_drive_info * dinfo = NULL ;
struct burn_drive * drive = NULL ;
off_t pos , data_count , to_read ;
char data [ 64 * 1024 ] , data_md5 [ 16 ] ;
void * ctx = NULL ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to check session MD5 checksum " , 0 ) ;
if ( ret < = 0 )
goto ex ;
ret = iso_md5_start ( & ctx ) ;
if ( ret < = 0 ) {
Xorriso_no_malloc_memory ( xorriso , NULL , 0 ) ;
goto ex ;
}
for ( pos = start_lba ; pos < end_lba ; pos + = 32 ) {
to_read = 32 ;
if ( pos + to_read > end_lba )
to_read = end_lba - pos ;
ret = burn_read_data ( drive , pos * ( off_t ) 2048 , data ,
to_read * ( off_t ) 2048 , & data_count , 0 ) ;
if ( ret < = 0 )
goto ex ;
iso_md5_compute ( ctx , data , ( int ) data_count ) ;
xorriso - > pacifier_count + = data_count ;
xorriso - > pacifier_byte_count + = data_count ;
Xorriso_pacifier_callback ( xorriso , " content bytes read " ,
xorriso - > pacifier_count , 0 , " " , 0 ) ;
}
iso_md5_end ( & ctx , data_md5 ) ;
ret = 1 ;
if ( ! iso_md5_match ( md5 , data_md5 ) )
ret = 0 ;
ex : ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ctx ! = NULL )
iso_md5_end ( & ctx , data_md5 ) ;
return ( ret ) ;
}
int Xorriso_check_session_md5 ( struct XorrisO * xorriso , char * severity ,
int flag )
{
int ret , i ;
IsoImage * image ;
uint32_t start_lba , end_lba ;
char md5 [ 16 ] , md5_text [ 33 ] ;
ret = Xorriso_get_volume ( xorriso , & image , 0 ) ;
if ( ret < = 0 )
return ( ret ) ;
ret = iso_image_get_session_md5 ( image , & start_lba , & end_lba , md5 , 0 ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ret < 0 )
return ( ret ) ;
if ( ret = = 0 ) {
sprintf ( xorriso - > info_text ,
" No session MD5 is recorded with the loaded session " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
return ( 0 ) ;
}
sprintf ( xorriso - > info_text , " Checking loaded session by its recorded MD5. \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
for ( i = 0 ; i < 16 ; i + + )
sprintf ( md5_text + 2 * i , " %2.2x " , ( ( unsigned char * ) md5 ) [ i ] ) ;
sprintf ( xorriso - > result_line ,
" Session MD5 %s , LBA %.f , %.f blocks \n " ,
md5_text , ( double ) start_lba , ( double ) end_lba - start_lba ) ;
Xorriso_result ( xorriso , 0 ) ;
ret = Xorriso_check_md5_range ( xorriso , ( off_t ) start_lba , ( off_t ) end_lba ,
md5 , 0 ) ;
return ( ret ) ;
}
/* @param flag bit0= this is a follow-up session (i.e. on CD: TAO)
bit1 = no pacifier messages
bit2 = compute stream MD5 and look out for checksum tag
@ return < = 0 error , 1 = done , 2 = aborted due to limit
*/
int Xorriso_check_interval ( struct XorrisO * xorriso , struct SpotlisT * spotlist ,
struct CheckmediajoB * job ,
int from_lba , int block_count , int read_chunk ,
int md5_start , int flag )
{
int i , j , ret , total_count = 0 , sectors = - 1 , sector_size = - 1 , skip_reading ;
int prev_quality = - 1 , quality = - 1 , retry = 0 , profile_no , is_cd = 0 ;
int start_sec , end_sec , first_value , fret ;
char profile_name [ 80 ] ;
int start_lba = 0 ;
struct burn_drive * drive ;
struct burn_drive_info * dinfo ;
char data [ 64 * 1024 ] , sfe [ 5 * SfileadrL ] ;
off_t data_count , to_read , read_count = 0 , write_amount ;
double pre_read_time , post_read_time , time_diff , total_time_diff = 0 ;
double last_abort_file_time = 0 ;
struct stat stbuf ;
void * ctx = NULL , * cloned_ctx = NULL ;
char md5 [ 16 ] , tag_md5 [ 16 ] ;
uint32_t pos , range_start , range_size , next_tag = 0 , lba , md5_spot_lba = 0 ;
int md5_spot_value = Xorriso_read_quality_untesteD , chain_broken = 0 ;
int tag_type = 0 , valid , was_sb_tag = 0 , in_track_gap = 0 ;
char * comparison = " " , * sev_text = " DEBUG " , * tag_type_name = " " ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to check media readability " ,
2 * ! ! job - > use_dev ) ;
if ( ret < = 0 )
goto ex ;
ret = burn_disc_get_profile ( drive , & profile_no , profile_name ) ;
if ( ret > 0 )
if ( profile_no > = 0x08 & & profile_no < = 0x0a )
is_cd = 1 ;
if ( job - > sector_map ! = NULL ) {
Sectorbitmap_get_layout ( job - > sector_map , & sectors , & sector_size , 0 ) ;
sector_size / = 2048 ;
}
if ( job - > retry > 0 )
retry = 1 ;
else if ( job - > retry = = 0 & & is_cd )
retry = 1 ;
if ( flag & 4 ) {
ret = iso_md5_start ( & ctx ) ;
if ( ret < 0 ) {
Xorriso_no_malloc_memory ( xorriso , NULL , 0 ) ;
ret = - 1 ; goto ex ;
}
}
start_lba = from_lba ;
to_read = read_chunk ;
post_read_time = Sfile_microtime ( 0 ) ;
for ( i = 0 ; i < block_count ; i + = to_read ) {
skip_reading = 0 ;
if ( job - > abort_file_path [ 0 ] ) {
if ( post_read_time - last_abort_file_time > = 0.1 ) {
if ( stat ( job - > abort_file_path , & stbuf ) ! = - 1 ) {
if ( stbuf . st_mtime > = xorriso - > start_time ) {
sprintf ( xorriso - > info_text ,
" -check_media: Found fresh abort_file=%s " ,
job - > abort_file_path ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
goto abort_check ;
}
}
last_abort_file_time = post_read_time ;
}
}
if ( job - > item_limit > 0 & &
Spotlist_count ( spotlist , 0 ) + 2 > = job - > item_limit ) {
sprintf ( xorriso - > info_text , " -check_media: Reached item_limit=%d " ,
job - > item_limit ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
goto abort_check ;
}
pre_read_time = Sfile_microtime ( 0 ) ;
if ( job - > time_limit > 0
& & job - > start_time + job - > time_limit < pre_read_time ) {
sprintf ( xorriso - > info_text , " -check_media: Reached time_limit=%d " ,
job - > time_limit ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
abort_check : ;
if ( prev_quality > = 0 ) {
ret = Spotlist_add_item ( spotlist , start_lba , i + from_lba - start_lba ,
prev_quality , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
ret = Spotlist_add_item ( spotlist , i + from_lba , block_count - i ,
Xorriso_read_quality_untesteD , 0 ) ;
if ( ret > 0 )
ret = 2 ;
goto ex ;
}
to_read = read_chunk ;
if ( i + to_read > block_count )
to_read = block_count - i ;
if ( is_cd & & i + to_read + 2 > = block_count ) {
/* Read last 2 blocks of CD track separately, because with TAO tracks
they are always unreadable but with SAO tracks they contain data .
*/
if ( to_read > 2 )
to_read - = 2 ;
else if ( to_read > 1 ) {
if ( flag & 1 ) {
quality = Xorriso_read_quality_tao_enD ;
skip_reading = 1 ;
} else
to_read - - ;
}
}
if ( sector_size = = read_chunk & & from_lba % read_chunk = = 0
& & ! skip_reading ) {
if ( Sectorbitmap_is_set ( job - > sector_map , ( i + from_lba ) / sector_size , 0 ) ) {
quality = Xorriso_read_quality_valiD ;
skip_reading = 1 ;
}
} else if ( sector_size > 0 & & ! skip_reading ) {
start_sec = ( i + from_lba ) / sector_size ;
end_sec = ( i + to_read + from_lba ) / sector_size ;
first_value = Sectorbitmap_is_set ( job - > sector_map , start_sec , 0 ) ;
for ( j = start_sec ; j < end_sec ; j + + )
if ( Sectorbitmap_is_set ( job - > sector_map , j , 0 ) ! = first_value )
break ;
to_read = j * sector_size - i - from_lba ;
skip_reading = ! ! first_value ;
if ( skip_reading )
quality = Xorriso_read_quality_valiD ;
}
if ( skip_reading ) {
pre_read_time = post_read_time = Sfile_microtime ( 0 ) ;
} else {
data_count = 0 ;
pre_read_time = Sfile_microtime ( 0 ) ;
ret = burn_read_data ( drive , ( ( off_t ) ( i + from_lba ) ) * ( off_t ) 2048 , data ,
to_read * ( off_t ) 2048 , & data_count , 4 * ! retry ) ;
post_read_time = Sfile_microtime ( 0 ) ;
time_diff = post_read_time - pre_read_time ;
total_time_diff + = time_diff ;
total_count + + ;
if ( ret < = 0 ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( data_count / 2048 < to_read ) {
if ( data_count > 0 & & retry ) {
if ( prev_quality > = 0 ) {
ret = Spotlist_add_item ( spotlist , start_lba ,
i + from_lba - start_lba , prev_quality , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
ret = Spotlist_add_item ( spotlist , i + from_lba , data_count / 2048 ,
Xorriso_read_quality_partiaL , 0 ) ;
if ( ret < = 0 )
goto ex ;
start_lba = i + from_lba + data_count / 2048 ;
prev_quality = Xorriso_read_quality_unreadablE ;
}
quality = Xorriso_read_quality_unreadablE ;
if ( retry )
to_read = data_count / 2048 + 1 ;
} else
quality = Xorriso_read_quality_partiaL ;
fret = Xorriso_eval_problem_status ( xorriso , ret , 1 | 2 ) ;
if ( fret < 0 )
goto ex ;
} else {
quality = Xorriso_read_quality_gooD ;
if ( time_diff > job - > slow_threshold_seq & & job - > slow_threshold_seq > 0 & &
i > 0 )
quality = Xorriso_read_quality_sloW ;
}
/* MD5 checksumming */
if ( ctx ! = NULL ) {
for ( j = 0 ; j < to_read ; j + + ) {
lba = i + j + from_lba ;
if ( lba < md5_start )
continue ;
ret = 0 ;
if ( lba > md5_start + 16 & &
( next_tag = = 0 | | chain_broken | | lba = = next_tag ) ) {
ret = iso_util_decode_md5_tag ( data + j * 2048 , & tag_type ,
& pos , & range_start , & range_size ,
& next_tag , tag_md5 , ! ! chain_broken ) ;
}
valid = ( ret = = 1 | | ret = = ISO_MD5_AREA_CORRUPTED ) & & pos = = lba ;
if ( valid & & tag_type = = 2 & & ( lba < md5_start + 32 | | in_track_gap ) ) {
tag_type_name = " superblock " ;
was_sb_tag = 1 ;
if ( in_track_gap & & range_start ! = md5_start & & range_start < lba & &
lba - range_start < = j ) {
/* Looking for next session : start computing in hindsight.
Session start and superblock tag are supposed to be in the
same 64 kB chunk .
*/
iso_md5_end ( & ctx , md5 ) ;
ret = iso_md5_start ( & ctx ) ;
if ( ret < 0 ) {
Xorriso_no_malloc_memory ( xorriso , NULL , 0 ) ;
ret = - 1 ; goto ex ;
}
iso_md5_compute ( & ctx , data + ( j - ( lba - range_start ) ) * 2048 ,
( lba - range_start ) * 2048 ) ;
md5_start = range_start ;
in_track_gap = 0 ;
}
} else if ( valid & & tag_type = = 4 & & lba < 32 ) {
tag_type_name = " relocated 64kB superblock " ;
} else if ( valid & & tag_type = = 3 & & was_sb_tag ) {
tag_type_name = " tree " ;
} else if ( valid & & tag_type = = 1 ) {
/* >>> ??? allow this without superblock and tree tag ? */
tag_type_name = " session " ;
} else {
tag_type_name = " " ;
}
if ( tag_type_name [ 0 ] ) {
if ( range_start ! = md5_start ) {
sprintf ( xorriso - > info_text ,
" Found MD5 %s tag which covers different data range " ,
tag_type_name ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
sprintf ( xorriso - > info_text ,
" Expected: %u Found: %u " ,
( unsigned int ) md5_start , range_start ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
chain_broken = 1 ;
valid = 0 ;
} else {
ret = iso_md5_clone ( ctx , & cloned_ctx ) ;
if ( ret < = 0 ) {
Xorriso_no_malloc_memory ( xorriso , NULL , 0 ) ;
ret = - 1 ; goto ex ;
}
iso_md5_end ( & cloned_ctx , md5 ) ;
if ( ret = = ISO_MD5_AREA_CORRUPTED ) {
comparison = " CORRUPTED " ;
sev_text = " WARNING " ;
md5_spot_value = Xorriso_read_quality_md5_mismatcH ;
chain_broken = 1 ;
} else if ( ! iso_md5_match ( tag_md5 , md5 ) ) {
comparison = " NON-MATCHING " ;
sev_text = " WARNING " ;
md5_spot_value = Xorriso_read_quality_md5_mismatcH ;
chain_broken = 1 ;
} else {
comparison = " matching " ;
sev_text = " UPDATE " ;
md5_spot_value = Xorriso_read_quality_md5_matcH ;
}
md5_spot_lba = lba ;
sprintf ( xorriso - > info_text ,
" Found %s MD5 %s tag: start=%d size=%d " ,
comparison , tag_type_name , md5_start , lba - md5_start ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 ,
sev_text , 0 ) ;
}
if ( valid & & ( tag_type = = 1 | |
( tag_type = = 4 & & pos = = lba & & lba < 32 ) ) ) {
if ( md5_spot_value ! = Xorriso_read_quality_untesteD ) {
ret = Spotlist_add_item ( spotlist , md5_start ,
md5_spot_lba - md5_start , md5_spot_value , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
md5_spot_value = Xorriso_read_quality_untesteD ;
md5_start = lba + 1 ;
if ( md5_start % 32 )
md5_start = md5_start + ( 32 - ( md5_start % 32 ) ) ;
next_tag = 0 ;
iso_md5_end ( & ctx , md5 ) ;
ret = iso_md5_start ( & ctx ) ;
if ( ret < 0 ) {
Xorriso_no_malloc_memory ( xorriso , NULL , 0 ) ;
ret = - 1 ; goto ex ;
}
if ( tag_type = = 1 )
in_track_gap = 1 ;
continue ;
}
}
iso_md5_compute ( ctx , data + j * 2048 , 2048 ) ;
}
}
write_amount = data_count ;
if ( data_count > 0 ) {
read_count + = data_count ;
if ( job - > data_to_limit > = 0 & & read_count > job - > data_to_limit )
write_amount - = ( read_count - job - > data_to_limit ) ;
}
if ( write_amount > 0 ) {
if ( job - > data_to_fd > = 0 ) {
ret = lseek ( job - > data_to_fd ,
( ( off_t ) ( i + from_lba ) ) * ( off_t ) 2048 + job - > data_to_offset ,
SEEK_SET ) ;
if ( ret = = - 1 ) {
failed_to_write : ;
sprintf ( xorriso - > info_text , " Cannot write %d bytes to lba %d of %s " ,
( int ) data_count , i + from_lba ,
Text_shellsafe ( job - > data_to_path , sfe , 0 ) ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , errno ,
" FAILURE " , 0 ) ;
{ ret = 0 ; goto ex ; }
}
ret = write ( job - > data_to_fd , data , write_amount ) ;
if ( ret = = - 1 )
goto failed_to_write ;
}
}
}
if ( quality ! = prev_quality ) {
if ( prev_quality > = 0 ) {
ret = Spotlist_add_item ( spotlist , start_lba , i + from_lba - start_lba ,
prev_quality , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
start_lba = i + from_lba ;
prev_quality = quality ;
}
if ( ! ( flag & 2 ) ) {
xorriso - > pacifier_count + = to_read ;
if ( post_read_time - xorriso - > last_update_time > =
xorriso - > pacifier_interval )
Xorriso_pacifier_callback ( xorriso , " sectors examined " ,
xorriso - > pacifier_count , xorriso - > pacifier_total , " " , 0 ) ;
}
}
if ( prev_quality > = 0 ) {
ret = Spotlist_add_item ( spotlist , start_lba ,
block_count + from_lba - start_lba , prev_quality , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
/* <<< for calibration of quality */
if ( total_count > 0 ) {
sprintf ( xorriso - > info_text , " Xorriso_check_interval: %.1f s / %d = %f " ,
total_time_diff , total_count , total_time_diff / total_count ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " DEBUG " , 0 ) ;
}
/* MD5 checksumming : register result */
/* >>> ??? allow chain_broken to be a match ? */
if ( next_tag > 0 ) {
sprintf ( xorriso - > info_text , " Missing announced MD5 tag: start=%d pos=%d " ,
md5_start , next_tag ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
md5_spot_value = Xorriso_read_quality_md5_mismatcH ;
md5_spot_lba = next_tag ;
}
if ( md5_spot_value ! = Xorriso_read_quality_untesteD ) {
ret = Spotlist_add_item ( spotlist , md5_start , md5_spot_lba - md5_start ,
md5_spot_value , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
ret = 1 ;
ex :
if ( ctx ! = NULL )
iso_md5_end ( & ctx , md5 ) ;
return ( ret ) ;
}
int Xorriso_check_media ( struct XorrisO * xorriso , struct SpotlisT * * spotlist ,
struct CheckmediajoB * job , int flag )
{
int media_blocks = 0 , read_chunk = 16 , ret , mode , start_lba = 0 ;
int blocks , os_errno , i , j , last_track_end = - 1 , track_blocks , track_lba ;
int num_sessions , num_tracks , declare_untested = 0 , md5_start ;
int read_capacity = - 1 , end_lba , hret , count , quality ;
char * toc_info = NULL ;
struct burn_drive * drive ;
struct burn_drive_info * dinfo ;
struct isoburn_toc_disc * isoburn_disc = NULL ;
struct isoburn_toc_session * * isoburn_sessions ;
struct isoburn_toc_track * * iso_burn_tracks ;
struct burn_toc_entry isoburn_entry ;
struct stat stbuf ;
struct burn_multi_caps * caps = NULL ;
* spotlist = NULL ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to check media readability " ,
2 * ! ! job - > use_dev ) ;
if ( ret < = 0 )
goto ex ;
/* >>> determine media type dependent blocking factor:
32 kB for CD ( with 2 kB retry ) and DVD , 64 kB for BD
eventually adjust read_chunk
*/ ;
if ( job - > min_block_size ! = 0 )
read_chunk = job - > min_block_size ;
ret = Spotlist_new ( spotlist , 0 ) ;
if ( ret < = 0 )
{ ret = - 1 ; goto ex ; }
if ( job - > sector_map_path [ 0 ] ) {
Sectorbitmap_destroy ( & ( job - > sector_map ) , 0 ) ;
if ( stat ( job - > sector_map_path , & stbuf ) ! = - 1 ) {
ret = Sectorbitmap_from_file ( & ( job - > sector_map ) , job - > sector_map_path ,
xorriso - > info_text , & os_errno , 0 ) ;
if ( ret < = 0 ) {
if ( xorriso - > info_text [ 0 ] )
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , os_errno ,
" FAILURE " , 0 ) ;
goto ex ;
}
}
Xorriso_toc_to_string ( xorriso , & toc_info , 4 * ! job - > map_with_volid ) ;
}
ret = Xorriso_open_job_data_to ( xorriso , job , 0 ) ;
if ( ret < = 0 )
goto ex ;
Xorriso_pacifier_reset ( xorriso , 0 ) ;
job - > start_time = time ( NULL ) ;
mode = job - > mode ;
if ( job - > min_lba > 0 ) {
start_lba = job - > min_lba ;
ret = Spotlist_add_item ( * spotlist , 0 , job - > min_lba ,
Xorriso_read_quality_untesteD , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
ret = burn_get_read_capacity ( drive , & read_capacity , 0 ) ;
if ( ret < = 0 )
read_capacity = - 1 ;
if ( job - > max_lba > = 0 ) {
blocks = job - > max_lba + 1 - start_lba ;
xorriso - > pacifier_total = blocks ;
ret = Xorriso_check_interval ( xorriso , * spotlist , job , start_lba , blocks ,
read_chunk , 0 , 0 ) ;
if ( ret < = 0 )
goto ex ;
} else if ( mode = = 0 ) { /* track by track */
isoburn_disc = isoburn_toc_drive_get_disc ( drive ) ;
if ( isoburn_disc = = NULL )
goto no_content_visible ;
isoburn_sessions =
isoburn_toc_disc_get_sessions ( isoburn_disc , & num_sessions ) ;
for ( i = 0 ; i < num_sessions ; i + + ) {
iso_burn_tracks = isoburn_toc_session_get_tracks ( isoburn_sessions [ i ] ,
& num_tracks ) ;
for ( j = 0 ; j < num_tracks ; j + + ) {
isoburn_toc_track_get_entry ( iso_burn_tracks [ j ] , & isoburn_entry ) ;
if ( ! ( isoburn_entry . extensions_valid & 1 ) ) /* should not happen */
continue ;
track_lba = isoburn_entry . start_lba ;
track_blocks = isoburn_entry . track_blocks ;
md5_start = track_lba ;
if ( i = = 0 & & j = = 0 ) {
if ( track_lba = = 32 ) {
ret = burn_disc_get_multi_caps ( drive , BURN_WRITE_NONE , & caps , 0 ) ;
if ( ret > 0 ) {
if ( caps - > start_adr ) {
/* block 0 to 31 are the overall mount entry of overwriteable */
track_lba = 0 ;
track_blocks + = 32 ;
}
}
}
}
if ( last_track_end > = 0 & & last_track_end < track_lba & &
last_track_end > = start_lba ) {
ret = Spotlist_add_item ( * spotlist , last_track_end ,
track_lba - last_track_end ,
Xorriso_read_quality_off_tracK , 0 ) ;
if ( ret < = 0 )
goto ex ;
xorriso - > pacifier_count + = track_lba - last_track_end ;
}
last_track_end = track_lba + track_blocks ;
if ( track_lba < start_lba ) {
track_blocks - = start_lba - track_lba ;
track_lba = start_lba ;
}
if ( track_blocks < = 0 )
continue ;
if ( declare_untested ) {
ret = Spotlist_add_item ( * spotlist , track_lba , track_blocks ,
Xorriso_read_quality_untesteD , 0 ) ;
if ( ret < = 0 )
goto ex ;
} else {
ret = Xorriso_check_interval ( xorriso , * spotlist , job , track_lba ,
track_blocks , read_chunk , md5_start ,
( i > 0 ) | ( 4 * ( xorriso - > do_md5 & 1 ) ) ) ;
if ( ret < = 0 )
goto ex ;
if ( ret = = 2 )
declare_untested = 1 ;
}
}
}
} else if ( mode = = 1 ) { /* isoburn disc capacity */
isoburn_disc = isoburn_toc_drive_get_disc ( drive ) ;
if ( isoburn_disc = = NULL ) {
no_content_visible : ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
sprintf ( xorriso - > info_text , " No content detected on media " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
{ ret = 0 ; goto ex ; }
}
blocks = media_blocks = isoburn_toc_disc_get_sectors ( isoburn_disc ) ;
if ( start_lba > = 0 )
blocks - = start_lba ;
if ( media_blocks < = 0 )
goto no_content_visible ;
xorriso - > pacifier_total = blocks ;
ret = Xorriso_check_interval ( xorriso , * spotlist , job , start_lba , blocks ,
read_chunk , 0 , 0 ) ;
if ( ret < = 0 )
goto ex ;
} else if ( mode = = 2 ) {
/* >>> single sweep over libburn media capacity */ ;
}
Xorriso_pacifier_callback ( xorriso , " sectors examined " ,
xorriso - > pacifier_count , xorriso - > pacifier_total , " " , 1 ) ;
ret = 1 ;
ex : ;
if ( job - > data_to_fd ! = - 1 )
close ( job - > data_to_fd ) ;
job - > data_to_fd = - 1 ;
if ( read_capacity > = 0 ) {
count = Spotlist_count ( * spotlist , 0 ) ;
end_lba = 0 ;
for ( i = 0 ; i < count ; i + + ) {
Spotlist_get_item ( * spotlist , i , & start_lba , & blocks , & quality , 0 ) ;
if ( start_lba + blocks > end_lba )
end_lba = start_lba + blocks ;
}
if ( read_capacity > end_lba ) {
hret = Spotlist_add_item ( * spotlist , end_lba , read_capacity - end_lba ,
Xorriso_read_quality_untesteD , 0 ) ;
if ( hret < ret )
ret = hret ;
}
}
if ( ret > 0 )
ret = Xorriso_update_in_sector_map ( xorriso , * spotlist , read_chunk , job , 0 ) ;
if ( ret > 0 ) {
ret = Xorriso_spotlist_to_sectormap ( xorriso , * spotlist , read_chunk ,
& ( job - > sector_map ) , ! ! job - > untested_valid ) ;
if ( ret > 0 & & job - > sector_map_path [ 0 ] ) {
ret = Sectorbitmap_to_file ( job - > sector_map , job - > sector_map_path , toc_info ,
xorriso - > info_text , & os_errno , 0 ) ;
if ( ret < = 0 ) {
if ( xorriso - > info_text [ 0 ] )
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , os_errno ,
" FAILURE " , 0 ) ;
}
}
}
if ( toc_info ! = NULL )
free ( toc_info ) ;
if ( ret < = 0 )
Spotlist_destroy ( spotlist , 0 ) ;
if ( caps ! = NULL )
burn_disc_free_multi_caps ( & caps ) ;
return ( ret ) ;
}
/* @param flag
bit0 = if not MMC drive print NOTE and return 2
bit1 = obtain outdrive , else indrive
bit4 = do not report failure
*/
int Xorriso_get_drive_handles ( struct XorrisO * xorriso ,
struct burn_drive_info * * dinfo ,
struct burn_drive * * drive ,
char * attempt , int flag )
{
int ret ;
if ( flag & 2 )
* dinfo = ( struct burn_drive_info * ) xorriso - > out_drive_handle ;
else
* dinfo = ( struct burn_drive_info * ) xorriso - > in_drive_handle ;
if ( * dinfo = = NULL & & ! ( flag & 16 ) ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
sprintf ( xorriso - > info_text , " No %s drive aquired %s " ,
( flag & 2 ? " output " : " input " ) , attempt ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
}
if ( * dinfo = = NULL )
return ( 0 ) ;
* drive = ( * dinfo ) [ 0 ] . drive ;
if ( flag & 1 ) {
ret = burn_drive_get_drive_role ( * drive ) ;
if ( ret ! = 1 ) {
sprintf ( xorriso - > info_text ,
" Output device is not an MMC drive. Desired operation does not apply. " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
return ( 2 ) ;
}
}
return ( ( * drive ) ! = NULL ) ;
}