You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
843 lines
22 KiB
843 lines
22 KiB
|
|
/* |
|
cc -g -c \ |
|
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE \ |
|
burn_wrap.c |
|
*/ |
|
/* libburn wrappers for libisoburn |
|
|
|
Copyright 2007 Thomas Schmitt, <scdbackup@gmx.net> |
|
*/ |
|
|
|
/* <<< A70929 : hardcoded CD-RW with fabricated -msinfo |
|
#define Hardcoded_cd_rW 1 |
|
#define Hardcoded_cd_rw_c1 12999 |
|
#define Hardcoded_cd_rw_nwA 152660 |
|
*/ |
|
|
|
#include <stdio.h> |
|
#include <ctype.h> |
|
#include <sys/types.h> |
|
#include <unistd.h> |
|
#include <string.h> |
|
#include <stdlib.h> |
|
#include <sys/stat.h> |
|
#include <fcntl.h> |
|
|
|
|
|
#ifndef Xorriso_standalonE |
|
|
|
#include <libburn/libburn.h> |
|
|
|
#include <libisofs/libisofs.h> |
|
|
|
#else /* ! Xorriso_standalonE */ |
|
|
|
#include "../libisofs/libisofs.h" |
|
#include "../libburn/libburn.h" |
|
|
|
#endif /* Xorriso_standalonE */ |
|
|
|
|
|
#include "libisoburn.h" |
|
#include "isoburn.h" |
|
|
|
|
|
/* The global list of isoburn objects. Usually there is only one. */ |
|
extern struct isoburn *isoburn_list_start; /* in isoburn.c */ |
|
|
|
|
|
int isoburn_initialize(char msg[1024], int flag) |
|
{ |
|
int major, minor, micro, bad_match= 0; |
|
|
|
|
|
/* First two ugly compile time checks for header version compatibility. |
|
If everthing matches, then they produce no C code. In case of mismatch, |
|
intentionally faulty C code will be inserted. |
|
*/ |
|
|
|
#ifdef iso_lib_header_version_major |
|
/* The minimum requirement of libisoburn towards the libisofs header |
|
at compile time is defined in libisoburn/libisoburn.h : |
|
isoburn_libisofs_req_major |
|
isoburn_libisofs_req_minor |
|
isoburn_libisofs_req_micro |
|
It gets compared against the version macros in libisofs/libisofs.h : |
|
iso_lib_header_version_major |
|
iso_lib_header_version_minor |
|
iso_lib_header_version_micro |
|
If the header is too old then the following code shall cause failure of |
|
cdrskin compilation rather than to allow production of a program with |
|
unpredictable bugs or memory corruption. |
|
The compiler messages supposed to appear in this case are: |
|
error: 'LIBISOFS_MISCONFIGURATION' undeclared (first use in this function) |
|
error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisofs_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h' undeclared (first use in this function) |
|
error: 'LIBISOFS_MISCONFIGURATION_' undeclared (first use in this function) |
|
*/ |
|
/* The indendation is an advise of man gcc to help old compilers ignoring */ |
|
#if isoburn_libisofs_req_major > iso_lib_header_version_major |
|
#define Isoburn_libisofs_dot_h_too_olD 1 |
|
#endif |
|
#if isoburn_libisofs_req_major == iso_lib_header_version_major && isoburn_libisofs_req_minor > iso_lib_header_version_minor |
|
#define Isoburn_libisofs_dot_h_too_olD 1 |
|
#endif |
|
#if isoburn_libisofs_req_minor == iso_lib_header_version_minor && isoburn_libisofs_req_micro > iso_lib_header_version_micro |
|
#define Isoburn_libisofs_dot_h_too_olD 1 |
|
#endif |
|
|
|
#ifdef Isoburn_libisofs_dot_h_too_olD |
|
LIBISOFS_MISCONFIGURATION = 0; |
|
INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisofs_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h = 0; |
|
LIBISOFS_MISCONFIGURATION_ = 0; |
|
#endif |
|
|
|
#endif /* iso_lib_header_version_major */ |
|
|
|
/* The minimum requirement of libisoburn towards the libburn header |
|
at compile time is defined in libisoburn/libisoburn.h : |
|
isoburn_libburn_req_major |
|
isoburn_libburn_req_minor |
|
isoburn_libburn_req_micro |
|
It gets compared against the version macros in libburn/libburn.h : |
|
burn_header_version_major |
|
burn_header_version_minor |
|
burn_header_version_micro |
|
If the header is too old then the following code shall cause failure of |
|
cdrskin compilation rather than to allow production of a program with |
|
unpredictable bugs or memory corruption. |
|
The compiler messages supposed to appear in this case are: |
|
error: 'LIBBURN_MISCONFIGURATION' undeclared (first use in this function) |
|
error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libburn_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h' undeclared (first use in this function) |
|
error: 'LIBBURN_MISCONFIGURATION_' undeclared (first use in this function) |
|
*/ |
|
|
|
/* The indendation is an advise of man gcc to help old compilers ignoring */ |
|
#if isoburn_libburn_req_major > burn_header_version_major |
|
#define Isoburn_libburn_dot_h_too_olD 1 |
|
#endif |
|
#if isoburn_libburn_req_major == burn_header_version_major && isoburn_libburn_req_minor > burn_header_version_minor |
|
#define Isoburn_libburn_dot_h_too_olD 1 |
|
#endif |
|
#if isoburn_libburn_req_minor == burn_header_version_minor && isoburn_libburn_req_micro > burn_header_version_micro |
|
#define Isoburn_libburn_dot_h_too_olD 1 |
|
#endif |
|
|
|
#ifdef Isoburn_libburn_dot_h_too_olD |
|
LIBBURN_MISCONFIGURATION = 0; |
|
INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libburn_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h = 0; |
|
LIBBURN_MISCONFIGURATION_ = 0; |
|
#endif |
|
|
|
/* End of ugly compile time tests (scroll up for explanation) */ |
|
|
|
|
|
|
|
msg[0]= 0; |
|
if(iso_init()<0) { |
|
sprintf(msg+strlen(msg), "Cannot initialize libisofs\n"); |
|
return(0); |
|
} |
|
iso_lib_version(&major, &minor, µ); |
|
sprintf(msg+strlen(msg), "libisofs-%d.%d.%d ", major, minor, micro); |
|
#ifdef iso_lib_header_version_major |
|
if(iso_lib_is_compatible(iso_lib_header_version_major, |
|
iso_lib_header_version_minor, |
|
iso_lib_header_version_micro)) { |
|
sprintf(msg+strlen(msg), "ok, "); |
|
} else { |
|
sprintf(msg+strlen(msg),"- TOO OLD -, need at least libisofs-%d.%d.%d ,\n", |
|
iso_lib_header_version_major, iso_lib_header_version_minor, |
|
iso_lib_header_version_micro); |
|
bad_match= 1; |
|
} |
|
#else |
|
if(iso_lib_is_compatible(isoburn_libisofs_req_major, |
|
isoburn_libisofs_req_minor, |
|
isoburn_libisofs_req_micro)) { |
|
sprintf(msg+strlen(msg), "suspicious, "); |
|
} else { |
|
sprintf(msg+strlen(msg),"- TOO OLD -, need at least libisofs-%d.%d.%d ,\n", |
|
isoburn_libisofs_req_major, isoburn_libisofs_req_minor, |
|
isoburn_libisofs_req_micro); |
|
bad_match= 1; |
|
} |
|
#endif /* ! iso_lib_header_version_major */ |
|
|
|
if(!burn_initialize()) { |
|
sprintf(msg+strlen(msg), "Cannot initialize libburn\n"); |
|
return(0); |
|
} |
|
burn_version(&major, &minor, µ); |
|
sprintf(msg+strlen(msg), "libburn-%d.%d.%d ", major, minor, micro); |
|
if(major > burn_header_version_major |
|
|| (major == burn_header_version_major |
|
&& (minor > burn_header_version_minor |
|
|| (minor == burn_header_version_minor |
|
&& micro >= burn_header_version_micro)))) { |
|
sprintf(msg+strlen(msg), "ok, "); |
|
} else { |
|
sprintf(msg+strlen(msg), "- TOO OLD -, need at least libburn-%d.%d.%d ,\n", |
|
burn_header_version_major, burn_header_version_minor, |
|
burn_header_version_micro); |
|
bad_match= 1; |
|
} |
|
|
|
isoburn_version(&major, &minor, µ); |
|
sprintf(msg+strlen(msg), "for libisoburn-%d.%d.%d", major, minor, micro); |
|
if(bad_match) |
|
return(0); |
|
|
|
isoburn_destroy_all(&isoburn_list_start, 0); /* isoburn_list_start= NULL */ |
|
return(1); |
|
} |
|
|
|
|
|
/* API @since 0.1.0 */ |
|
int isoburn_libisofs_req(int *major, int *minor, int *micro) |
|
{ |
|
*major= iso_lib_header_version_major; |
|
*minor= iso_lib_header_version_minor; |
|
*micro= iso_lib_header_version_micro; |
|
return(1); |
|
} |
|
|
|
|
|
/* API @since 0.1.0 */ |
|
int isoburn_libburn_req(int *major, int *minor, int *micro) |
|
{ |
|
*major= burn_header_version_major; |
|
*minor= burn_header_version_minor; |
|
*micro= burn_header_version_micro; |
|
return(1); |
|
} |
|
|
|
|
|
/** Examine the media and sets appropriate emulation if needed. |
|
@param flag bit0= pretent blank on overwriteable media |
|
*/ |
|
static int isoburn_welcome_media(struct isoburn **o, struct burn_drive *d, |
|
int flag) |
|
{ |
|
int ret, lba, nwa; |
|
struct burn_multi_caps *caps= NULL; |
|
|
|
ret= burn_disc_get_multi_caps(d, BURN_WRITE_NONE, &caps, 0); |
|
if(ret<0) /* == 0 is read-only media, but it is too early to reject it here */ |
|
goto ex; |
|
ret= isoburn_new(o, 0); |
|
if(ret<=0) |
|
goto ex; |
|
(*o)->drive= d; |
|
|
|
#ifdef Hardcoded_cd_rW |
|
/* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ |
|
caps->start_adr= 0; |
|
(*o)->fabricated_disc_status= BURN_DISC_APPENDABLE; |
|
#endif |
|
|
|
if(caps->start_adr) { /* set emulation to overwriteable */ |
|
(*o)->emulation_mode= 1; |
|
|
|
if(flag&1) { |
|
(*o)->nwa= 0; |
|
(*o)->fabricated_disc_status= BURN_DISC_BLANK; |
|
} else { |
|
ret= isoburn_start_emulation(*o, 0); |
|
if(ret<=0) { |
|
(*o)->emulation_mode= -1; |
|
goto ex; |
|
} |
|
} |
|
} else { |
|
|
|
/* >>> recognize unsuitable media (but allow read-only media) */; |
|
|
|
#ifdef Hardcoded_cd_rW |
|
(*o)->nwa= Hardcoded_cd_rw_nwA; |
|
#else |
|
ret= burn_disc_track_lba_nwa(d, NULL, 0, &lba, &nwa); |
|
if(ret>0) |
|
(*o)->nwa= nwa; |
|
#endif |
|
|
|
} |
|
ret= 1; |
|
ex: |
|
if(caps!=NULL) |
|
burn_disc_free_multi_caps(&caps); |
|
return(ret); |
|
} |
|
|
|
|
|
/** |
|
@param flag bit0= load |
|
bit1= regard overwriteable media as blank |
|
bit2= if the drive is a regular disk file: truncate it to |
|
the write start address |
|
*/ |
|
int isoburn_drive_aquire(struct burn_drive_info *drive_infos[], |
|
char *adr, int flag) |
|
{ |
|
int ret, conv_ret, drive_grabbed= 0; |
|
char libburn_drive_adr[BURN_DRIVE_ADR_LEN]; |
|
struct isoburn *o= NULL; |
|
char msg[BURN_MSGS_MESSAGE_LEN+4096]; |
|
|
|
conv_ret= burn_drive_convert_fs_adr(adr, libburn_drive_adr); |
|
if(conv_ret<=0) { |
|
sprintf(msg, "Unsuitable drive address: '%s'\n",adr); |
|
msg[BURN_MSGS_MESSAGE_LEN-1]= 0; |
|
burn_msgs_submit(0x00060000, msg, 0, "FAILURE", NULL); |
|
ret= 0; goto ex; |
|
} |
|
|
|
ret= burn_drive_scan_and_grab(drive_infos, libburn_drive_adr, flag&1); |
|
if(ret<=0) |
|
goto ex; |
|
drive_grabbed= 1; |
|
ret= isoburn_welcome_media(&o, (*drive_infos)[0].drive, !!(flag&2)); |
|
if(ret<=0) |
|
goto ex; |
|
|
|
if(flag&4) { |
|
ret= isoburn_find_emulator(&o, (*drive_infos)[0].drive, 0); |
|
if(ret>0 && o!=NULL) |
|
o->truncate= 1; |
|
} |
|
|
|
ret= 1; |
|
ex: |
|
if(ret<=0) { |
|
if(drive_grabbed) |
|
burn_drive_release((*drive_infos)[0].drive, 0); |
|
isoburn_destroy(&o, 0); |
|
} |
|
return(ret); |
|
} |
|
|
|
|
|
int isoburn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], |
|
char *adr, int load) |
|
{ |
|
int ret; |
|
|
|
ret= isoburn_drive_aquire(drive_infos, adr, !!load); |
|
return(ret); |
|
} |
|
|
|
|
|
int isoburn_drive_grab(struct burn_drive *drive, int load) |
|
{ |
|
int ret; |
|
struct isoburn *o= NULL; |
|
|
|
ret= burn_drive_grab(drive, load); |
|
if(ret<=0) |
|
goto ex; |
|
ret= isoburn_welcome_media(&o, drive, 0); |
|
if(ret<=0) |
|
goto ex; |
|
|
|
ret= 1; |
|
ex: |
|
if(ret<=0) |
|
isoburn_destroy(&o,0); |
|
return(ret); |
|
} |
|
|
|
|
|
/** Retrieve media emulation and eventual isoburn emulator of drive. |
|
@return -1 unsuitable media, 0 generic media, 1 emulated media. |
|
*/ |
|
int isoburn_find_emulator(struct isoburn **pt, |
|
struct burn_drive *drive, int flag) |
|
{ |
|
int ret; |
|
|
|
ret= isoburn_find_by_drive(pt, drive, 0); |
|
if(ret<=0) |
|
return(0); |
|
if((*pt)->emulation_mode==-1) { |
|
burn_msgs_submit(0x00060000, |
|
"Unsuitable drive and media state", 0, "FAILURE", NULL); |
|
return(-1); |
|
} |
|
if((*pt)->emulation_mode==0) |
|
return(0); |
|
return(1); |
|
} |
|
|
|
|
|
enum burn_disc_status isoburn_disc_get_status(struct burn_drive *drive) |
|
{ |
|
int ret; |
|
struct isoburn *o; |
|
|
|
ret= isoburn_find_emulator(&o, drive, 0); |
|
if(ret<0) |
|
return(BURN_DISC_UNSUITABLE); |
|
if(o!=NULL) |
|
if(o->fabricated_disc_status!=BURN_DISC_UNREADY) |
|
return(o->fabricated_disc_status); |
|
if(ret==0) |
|
return(burn_disc_get_status(drive)); |
|
|
|
/* emulated status */ |
|
if(o->emulation_mode==-1) |
|
return(BURN_DISC_UNSUITABLE); |
|
if(o->nwa>0) |
|
return(BURN_DISC_APPENDABLE); |
|
return(BURN_DISC_BLANK); |
|
} |
|
|
|
|
|
int isoburn_disc_erasable(struct burn_drive *d) |
|
{ |
|
int ret; |
|
struct isoburn *o; |
|
|
|
ret= isoburn_find_emulator(&o, d, 0); |
|
if(ret>0) |
|
if(o->emulation_mode==1) |
|
return(1); |
|
return burn_disc_erasable(d); |
|
} |
|
|
|
|
|
void isoburn_disc_erase(struct burn_drive *drive, int fast) |
|
{ |
|
int ret; |
|
struct isoburn *o; |
|
|
|
ret= isoburn_find_emulator(&o, drive, 0); |
|
if(ret>0) { |
|
if(o->emulation_mode==-1) { |
|
/* To cause a negative reply with burn_drive_wrote_well() */ |
|
burn_drive_cancel(drive); |
|
return; |
|
} |
|
if(o->emulation_mode>0) { |
|
ret= isoburn_invalidate_iso(o, 0); |
|
if(ret<=0) |
|
burn_drive_cancel(drive); |
|
return; |
|
} |
|
} |
|
burn_disc_erase(drive, fast); |
|
} |
|
|
|
|
|
off_t isoburn_disc_available_space(struct burn_drive *d, |
|
struct burn_write_opts *opts) |
|
{ |
|
int ret; |
|
struct isoburn *o; |
|
off_t avail; |
|
|
|
ret= isoburn_find_emulator(&o, d, 0); |
|
if(ret>0 && o!=NULL) |
|
if(o->emulation_mode!=0) |
|
burn_write_opts_set_start_byte(opts, ((off_t) o->nwa) * (off_t) 2048); |
|
avail= burn_disc_available_space(d, opts); |
|
return(avail); |
|
} |
|
|
|
|
|
int isoburn_disc_get_msc1(struct burn_drive *d, int *start_lba) |
|
{ |
|
int ret; |
|
struct isoburn *o; |
|
|
|
#ifdef Hardcoded_cd_rW |
|
/* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ |
|
*start_lba= Hardcoded_cd_rw_c1; |
|
return(1); |
|
#endif |
|
|
|
if(isoburn_disc_get_status(d)!=BURN_DISC_APPENDABLE && |
|
isoburn_disc_get_status(d)!=BURN_DISC_FULL) { |
|
burn_msgs_submit(0x00060000, |
|
"Media contains no recognizable data", 0, "SORRY",NULL); |
|
return(0); |
|
} |
|
ret= isoburn_find_emulator(&o, d, 0); |
|
if(ret<0) |
|
return(0); |
|
if(ret>0) if(o->emulation_mode>0) { |
|
*start_lba= 0; |
|
return(1); |
|
} |
|
return(burn_disc_get_msc1(d, start_lba)); |
|
} |
|
|
|
|
|
int isoburn_disc_track_lba_nwa(struct burn_drive *d, |
|
struct burn_write_opts *opts, |
|
int trackno, int *lba, int *nwa) |
|
{ |
|
int ret; |
|
struct isoburn *o; |
|
|
|
#ifdef Hardcoded_cd_rW |
|
/* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ |
|
*lba= Hardcoded_cd_rw_c1; |
|
*nwa= Hardcoded_cd_rw_nwA; |
|
return(1); |
|
#endif |
|
|
|
*nwa= *lba= 0; |
|
ret= isoburn_find_emulator(&o, d, 0); |
|
if(ret<0) |
|
return(0); |
|
if(ret>0) if(o->emulation_mode>0) { |
|
*lba= 0; |
|
*nwa= o->nwa; |
|
return(1); |
|
} |
|
if(burn_drive_get_drive_role(d) != 1) |
|
return(1); |
|
return(burn_disc_track_lba_nwa(d, opts, trackno, lba, nwa)); |
|
} |
|
|
|
|
|
void isoburn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc) |
|
{ |
|
int ret; |
|
off_t nwa= 0; |
|
struct isoburn *o; |
|
struct burn_drive *drive; |
|
char reasons[BURN_REASONS_LEN],msg[160+BURN_REASONS_LEN]; |
|
char adr[BURN_DRIVE_ADR_LEN]; |
|
enum burn_write_types write_type; |
|
struct stat stbuf; |
|
|
|
drive= burn_write_opts_get_drive(opts); |
|
ret= isoburn_find_emulator(&o, drive, 0); |
|
if(ret<0) |
|
return; |
|
if(o!=NULL) { |
|
o->wrote_well= -1; |
|
if(o->emulation_mode!=0) { |
|
burn_write_opts_set_multi(opts, 0); |
|
if(o->emulation_mode>0 && o->nwa >= 0) { |
|
burn_write_opts_set_start_byte(opts, ((off_t) o->nwa) * (off_t) 2048); |
|
nwa= o->nwa; |
|
} |
|
} |
|
} |
|
|
|
write_type= burn_write_opts_auto_write_type(opts, disc, reasons, 0); |
|
if (write_type == BURN_WRITE_NONE) { |
|
sprintf(msg, "Failed to find a suitable write mode:\n%s", reasons); |
|
burn_msgs_submit(0x00060000, msg, 0, "FAILURE", NULL); |
|
if(o!=NULL) |
|
o->wrote_well= 0; |
|
/* To cause a negative reply with burn_drive_wrote_well() */ |
|
burn_drive_cancel(drive); |
|
return; |
|
} |
|
|
|
/* |
|
sprintf(reasons, "%d", (int) write_type); |
|
fprintf(stderr, "isoburn_EXPERIMENTAL: write_type = %s\n", |
|
(write_type == BURN_WRITE_SAO ? "SAO" : |
|
(write_type == BURN_WRITE_TAO ? "TAO" : reasons))); |
|
*/ |
|
|
|
#ifdef Hardcoded_cd_rW |
|
/* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ |
|
fprintf(stderr, "Setting write address to LBA %d\n", Hardcoded_cd_rw_nwA); |
|
burn_write_opts_set_start_byte(opts, |
|
((off_t) Hardcoded_cd_rw_nwA) * (off_t) 2048); |
|
#endif |
|
|
|
if(o->truncate) { |
|
ret= burn_drive_get_drive_role(drive); |
|
if(ret==2) { |
|
ret= burn_drive_d_get_adr(drive, adr); |
|
if(ret>0) { |
|
ret= lstat(adr, &stbuf); |
|
if(ret!=-1) |
|
if(S_ISREG(stbuf.st_mode)) |
|
truncate(adr, nwa * (off_t) 2048); |
|
} |
|
} |
|
} |
|
|
|
burn_disc_write(opts, disc); |
|
} |
|
|
|
|
|
void isoburn_drive_release(struct burn_drive *drive, int eject) |
|
{ |
|
int ret; |
|
struct isoburn *o; |
|
|
|
ret= isoburn_find_emulator(&o, drive, 0); |
|
if(ret<0) |
|
return; |
|
if(o!=NULL) { |
|
isoburn_destroy(&o, 0); |
|
} |
|
burn_drive_release(drive, eject); |
|
} |
|
|
|
|
|
void isoburn_finish(void) |
|
{ |
|
isoburn_destroy_all(&isoburn_list_start, 0); |
|
burn_finish(); |
|
iso_finish(); |
|
} |
|
|
|
|
|
int isoburn_needs_emulation(struct burn_drive *drive) |
|
{ |
|
int ret; |
|
struct isoburn *o; |
|
enum burn_disc_status s; |
|
|
|
s= isoburn_disc_get_status(drive); |
|
if(s!=BURN_DISC_BLANK && s!=BURN_DISC_APPENDABLE) |
|
return(-1); |
|
ret= isoburn_find_emulator(&o, drive, 0); |
|
if(ret<0) |
|
return(-1); |
|
if(ret>0) |
|
if(o->emulation_mode>0) |
|
return(1); |
|
return(0); |
|
} |
|
|
|
|
|
int isoburn_set_start_byte(struct isoburn *o, off_t value, int flag) |
|
{ |
|
int ret; |
|
struct burn_drive *drive = o->drive; |
|
struct burn_multi_caps *caps= NULL; |
|
|
|
ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); |
|
if(ret<=0) |
|
goto ex; |
|
if(!caps->start_adr) { |
|
burn_msgs_submit(0x00060000, |
|
"Cannot set start byte address with this type of media", |
|
0, "FAILURE", NULL); |
|
{ret= 0; goto ex;} |
|
} |
|
o->min_start_byte= value; |
|
if(value % caps->start_alignment) |
|
value+= caps->start_alignment - (value % caps->start_alignment); |
|
o->nwa= value/2048; |
|
/* If suitable for alignment, round up to full 16 sector addresses */ |
|
if((o->nwa%16) && ((16*2048) % caps->start_alignment)==0 ) |
|
o->nwa+= 16 - (o->nwa%16); |
|
ret= 1; |
|
ex: |
|
if(caps!=NULL) |
|
burn_disc_free_multi_caps(&caps); |
|
return(ret); |
|
} |
|
|
|
|
|
int isoburn_get_min_start_byte(struct burn_drive *d, off_t *start_byte, |
|
int flag) |
|
{ |
|
int ret; |
|
struct isoburn *o; |
|
|
|
ret= isoburn_find_emulator(&o, d, 0); |
|
if(ret<0) |
|
return(-1); |
|
if(ret==0) |
|
return(0); |
|
*start_byte= o->min_start_byte; |
|
if(o->min_start_byte<=0) |
|
return(0); |
|
return(1); |
|
} |
|
|
|
|
|
int isoburn_drive_wrote_well(struct burn_drive *d) |
|
{ |
|
int ret; |
|
struct isoburn *o; |
|
|
|
ret= isoburn_find_emulator(&o, d, 0); |
|
if(ret<0) |
|
return(-1); |
|
if(o!=NULL) |
|
if(o->wrote_well>=0) |
|
return(o->wrote_well); |
|
ret= burn_drive_wrote_well(d); |
|
return ret; |
|
} |
|
|
|
|
|
int isoburn_get_fifo_status(struct burn_drive *d, int *size, int *free_bytes, |
|
char **status_text) |
|
{ |
|
int ret; |
|
struct isoburn *o; |
|
#ifdef Libisoburn_no_fifO |
|
size_t hsize= 0, hfree_bytes= 0; |
|
#endif |
|
|
|
ret= isoburn_find_emulator(&o, d, 0); |
|
if(ret<0) |
|
return(-1); |
|
|
|
#ifdef Libisoburn_no_fifO |
|
if(o==NULL) |
|
return(-1); |
|
if(o->iso_source==NULL) |
|
return(-1); |
|
ret= iso_ring_buffer_get_status(o->iso_source, &hsize, &hfree_bytes); |
|
if(hsize > 1024*1024*1024) |
|
*size= 1024*1024*1024; |
|
else |
|
*size= hsize; |
|
if(hfree_bytes > 1024*1024*1024) |
|
*free_bytes= 1024*1024*1024; |
|
else |
|
*free_bytes= hfree_bytes; |
|
*status_text= ""; |
|
if(ret==0) |
|
*status_text= "standby"; |
|
else if(ret==1) |
|
*status_text= "active"; |
|
else if(ret==2) |
|
*status_text= "ending"; |
|
else if(ret==3) |
|
*status_text= "failing"; |
|
else if(ret==4) |
|
*status_text= "unused"; |
|
else if(ret==5) |
|
*status_text= "abandoned"; |
|
else if(ret==6) |
|
*status_text= "ended"; |
|
else if(ret==7) |
|
*status_text= "aborted"; |
|
#else |
|
if(o==NULL) |
|
return(0); |
|
if(o->fifo==NULL) |
|
return(0); |
|
ret= burn_fifo_inquire_status(o->fifo, size, free_bytes, status_text); |
|
#endif /* ! Libisoburn_no_fifO */ |
|
|
|
return(ret); |
|
} |
|
|
|
|
|
|
|
/* <<< to be replaced by libburn-0.4.3 API call burn_sev_to_text(). |
|
This is a copy of libdax_msgs__sev_to_text() which is not exposed |
|
by the API of of libburn-0.4.2 . As soon as xorriso gets based on |
|
libburn-0.4.4 this redundancy is to be removed. |
|
It is safe, nevertheless, because the severity codes are eternal. |
|
*/ |
|
#define LIBDAX_MSGS_SEV_ALL 0x00000000 |
|
#define LIBDAX_MSGS_SEV_DEBUG 0x10000000 |
|
#define LIBDAX_MSGS_SEV_UPDATE 0x20000000 |
|
#define LIBDAX_MSGS_SEV_NOTE 0x30000000 |
|
#define LIBDAX_MSGS_SEV_HINT 0x40000000 |
|
#define LIBDAX_MSGS_SEV_WARNING 0x50000000 |
|
#define LIBDAX_MSGS_SEV_SORRY 0x60000000 |
|
#define LIBDAX_MSGS_SEV_MISHAP 0x64000000 |
|
#define LIBDAX_MSGS_SEV_FAILURE 0x68000000 |
|
#define LIBDAX_MSGS_SEV_FATAL 0x70000000 |
|
#define LIBDAX_MSGS_SEV_ABORT 0x71000000 |
|
#define LIBDAX_MSGS_SEV_NEVER 0x7fffffff |
|
|
|
int isoburn__sev_to_text(int severity, char **severity_name, |
|
int flag) |
|
{ |
|
if(flag&1) { |
|
*severity_name= "NEVER\nABORT\nFATAL\nFAILURE\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nALL"; |
|
return(1); |
|
} |
|
*severity_name= ""; |
|
if(severity>=LIBDAX_MSGS_SEV_NEVER) |
|
*severity_name= "NEVER"; |
|
else if(severity>=LIBDAX_MSGS_SEV_ABORT) |
|
*severity_name= "ABORT"; |
|
else if(severity>=LIBDAX_MSGS_SEV_FATAL) |
|
*severity_name= "FATAL"; |
|
else if(severity>=LIBDAX_MSGS_SEV_FAILURE) |
|
*severity_name= "FAILURE"; |
|
else if(severity>=LIBDAX_MSGS_SEV_MISHAP) |
|
*severity_name= "MISHAP"; |
|
else if(severity>=LIBDAX_MSGS_SEV_SORRY) |
|
*severity_name= "SORRY"; |
|
else if(severity>=LIBDAX_MSGS_SEV_WARNING) |
|
*severity_name= "WARNING"; |
|
else if(severity>=LIBDAX_MSGS_SEV_HINT) |
|
*severity_name= "HINT"; |
|
else if(severity>=LIBDAX_MSGS_SEV_NOTE) |
|
*severity_name= "NOTE"; |
|
else if(severity>=LIBDAX_MSGS_SEV_UPDATE) |
|
*severity_name= "UPDATE"; |
|
else if(severity>=LIBDAX_MSGS_SEV_DEBUG) |
|
*severity_name= "DEBUG"; |
|
else if(severity>=LIBDAX_MSGS_SEV_ALL) |
|
*severity_name= "ALL"; |
|
else { |
|
*severity_name= ""; |
|
return(0); |
|
} |
|
return(1); |
|
} |
|
|
|
|
|
int isoburn__text_to_sev(char *severity_name, int *severity_number, int flag) |
|
{ |
|
int ret= 1; |
|
|
|
if(severity_name[0]==0) |
|
*severity_number= 0; |
|
else if(strcmp(severity_name, "MISHAP")==0) |
|
*severity_number= LIBDAX_MSGS_SEV_MISHAP; |
|
else |
|
ret= burn_text_to_sev(severity_name, severity_number, 0); |
|
return(ret); |
|
} |
|
|
|
|
|
int isoburn_report_iso_error(int iso_error_code, char msg_text[], int os_errno, |
|
char min_severity[], int flag) |
|
{ |
|
int error_code, iso_sev, min_sev, ret; |
|
char *sev_text_pt, *msg_text_pt= NULL; |
|
|
|
error_code= iso_error_get_code(iso_error_code); |
|
if(error_code < 0x00030000 || error_code >= 0x00040000) |
|
error_code= (error_code & 0xffff) | 0x00050000; |
|
|
|
if(iso_error_code<0) |
|
msg_text_pt= (char *) iso_error_to_msg(iso_error_code); |
|
if(msg_text_pt==NULL) |
|
msg_text_pt= msg_text; |
|
iso_sev= iso_error_get_severity(iso_error_code); |
|
sev_text_pt= min_severity; |
|
burn_text_to_sev(min_severity, &min_sev, 0); |
|
|
|
/* <<< Tunnel MISHAP through libburn which knows no MISHAP |
|
with libburn-0.4.4 this is not necessary */ |
|
if(iso_sev==LIBDAX_MSGS_SEV_MISHAP) { |
|
iso_sev= LIBDAX_MSGS_SEV_SORRY; |
|
error_code= 0x0005ff73; |
|
} |
|
|
|
if(min_sev < iso_sev) { |
|
|
|
/* >>> with libburn-0.4.4 do: burn_sev_to_text(iso_sev, &sev_text_pt, 0); */ |
|
isoburn__sev_to_text(iso_sev, &sev_text_pt, 0); |
|
|
|
} |
|
|
|
ret= burn_msgs_submit(error_code, msg_text_pt, os_errno, sev_text_pt, NULL); |
|
return(ret); |
|
} |
|
|
|
|