#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>
#include <time.h>
#include <regex.h>
#include <libburn/libburn.h>
#include <libisofs/libisofs.h>
#include "libisoburn.h"
#include "isoburn.h"
Go to the source code of this file.
Defines | |
#define | Isoburn_libburn_dot_h_too_olD 1 |
Functions | |
static int | isoburn_emulate_toc (struct burn_drive *d, int flag) |
int | isoburn_initialize (char msg[1024], int flag) |
Overview. | |
int | isoburn_libisofs_req (int *major, int *minor, int *micro) |
The minimum version of libisofs to be used with this version of libisoburn at runtime. | |
int | isoburn_libburn_req (int *major, int *minor, int *micro) |
The minimum version of libburn to be used with this version of libisoburn at runtime. | |
int | isoburn_set_msgs_submit (int(*msgs_submit)(void *handle, int error_code, char msg_text[], int os_errno, char severity[], int flag), void *submit_handle, int submit_flag, int flag) |
Note: Above version numbers are also recorded in configure.ac because libtool wants them as parameters at build time. | |
int | isoburn_is_intermediate_dvd_rw (struct burn_drive *d, int flag) |
static int | isoburn_welcome_media (struct isoburn **o, struct burn_drive *d, int flag) |
Examines the media and sets appropriate emulation if needed. | |
int | isoburn_drive_aquire (struct burn_drive_info *drive_infos[], char *adr, int flag) |
Aquire a target drive by its filesystem path resp. | |
int | isoburn_drive_scan_and_grab (struct burn_drive_info *drive_infos[], char *adr, int load) |
Aquire a target drive by its filesystem path resp. | |
int | isoburn_drive_grab (struct burn_drive *drive, int load) |
Aquire a drive from the burn_drive_info[] array which was obtained by a previous call of burn_drive_scan(). | |
int | isoburn_find_emulator (struct isoburn **pt, struct burn_drive *drive, int flag) |
Retrieve media emulation and eventual isoburn emulator of drive. | |
enum burn_disc_status | isoburn_disc_get_status (struct burn_drive *drive) |
Inquire the media status. | |
int | isoburn_disc_erasable (struct burn_drive *d) |
Tells whether the media can be treated by isoburn_disc_erase(). | |
void | isoburn_disc_erase (struct burn_drive *drive, int fast) |
Mark the media as blank. | |
off_t | isoburn_disc_available_space (struct burn_drive *d, struct burn_write_opts *opts) |
Return the best possible estimation of the currently available capacity of the media. | |
int | isoburn_disc_get_msc1 (struct burn_drive *d, int *start_lba) |
Obtain the start block number of the most recent session on media. | |
int | isoburn_disc_track_lba_nwa (struct burn_drive *d, struct burn_write_opts *opts, int trackno, int *lba, int *nwa) |
Use this with trackno==0 to obtain the predicted start block number of the new session. | |
int | isoburn_get_msc2 (struct isoburn *o, struct burn_write_opts *opts, int *msc2, int flag) |
Obtains the image address offset to be used with image generation. | |
void | isoburn_disc_write (struct burn_write_opts *opts, struct burn_disc *disc) |
Start writing of the new session. | |
void | isoburn_drive_release (struct burn_drive *drive, int eject) |
Release an aquired drive. | |
void | isoburn_finish (void) |
Shutdown all three libraries. | |
int | isoburn_needs_emulation (struct burn_drive *drive) |
Inquire wether the media needs emulation or would be suitable for generic multi-session via libburn. | |
int | isoburn_set_start_byte (struct isoburn *o, off_t value, int flag) |
Set the start address for an emulated add-on session. | |
int | isoburn_get_min_start_byte (struct burn_drive *d, off_t *start_byte, int flag) |
Obtain the size which was attributed to an emulated appendable on actually overwriteable media. | |
int | isoburn_drive_wrote_well (struct burn_drive *d) |
Inquire whether the most recent write run was successful. | |
int | isoburn_get_fifo_status (struct burn_drive *d, int *size, int *free_bytes, char **status_text) |
Inquire state and fill parameters of the fifo which is attached to the emerging track. | |
int | isoburn__sev_to_text (int severity, char **severity_name, int flag) |
int | isoburn__text_to_sev (char *severity_name, int *severity_number, int flag) |
int | isoburn_report_iso_error (int iso_error_code, char msg_text[], int os_errno, char min_severity[], int flag) |
int | isoburn_read_iso_head_parse (struct burn_drive *d, unsigned char *data, int *image_blocks, char *info, int flag) |
int | isoburn_read_iso_head (struct burn_drive *d, int lba, int *image_blocks, char *info, int flag) |
Try whether the data at the given address look like a ISO 9660 image header and obtain its alleged size. | |
int | isoburn_make_toc_entry (struct isoburn *o, int *session_count, int lba, int track_blocks, char *volid, int flag) |
int | isoburn_toc_new_arrays (struct isoburn_toc_disc *o, int session_count, int track_count, int flag) |
int | isoburn_toc_destroy_arrays (struct isoburn_toc_disc *o, int flag) |
struct isoburn_toc_disc * | isoburn_toc_drive_get_disc (struct burn_drive *d) |
Obtain a master handle for the table of content. | |
int | isoburn_toc_disc_get_sectors (struct isoburn_toc_disc *disc) |
Tell the number of 2048 byte blocks covered by the table of content. | |
struct isoburn_toc_session ** | isoburn_toc_disc_get_sessions (struct isoburn_toc_disc *disc, int *num) |
Get the array of session handles from the table of content. | |
int | isoburn_toc_session_get_sectors (struct isoburn_toc_session *s) |
Tell the number of 2048 byte blocks covered by a particular session. | |
int | isoburn_toc_entry_finish (struct burn_toc_entry *entry, int session_no, int track_no, int flag) |
void | isoburn_toc_session_get_leadout_entry (struct isoburn_toc_session *s, struct burn_toc_entry *entry) |
Obtain a copy of the entry which describes the end of a particular session. | |
struct isoburn_toc_track ** | isoburn_toc_session_get_tracks (struct isoburn_toc_session *s, int *num) |
Get the array of track handles from a particular session. | |
void | isoburn_toc_track_get_entry (struct isoburn_toc_track *t, struct burn_toc_entry *entry) |
Obtain a copy of the entry which describes a particular track. | |
int | isoburn_toc_track_get_emul (struct isoburn_toc_track *t, int *start_lba, int *image_blocks, char volid[33], int flag) |
Obtain eventual ISO image parameters of an emulated track. | |
void | isoburn_toc_disc_free (struct isoburn_toc_disc *d) |
Release the memory associated with a master handle of media. | |
int | isoburn_get_track_lba (struct isoburn_toc_track *track, int *lba, int flag) |
int | isoburn_drive_set_msgs_submit (struct burn_drive *d, int(*msgs_submit)(void *handle, int error_code, char msg_text[], int os_errno, char severity[], int flag), void *submit_handle, int submit_flag, int flag) |
Attach to a drive an application provided method for immediate delivery of messages. | |
int | isoburn_set_msc1 (struct burn_drive *d, int adr_mode, char *adr_value, int flag) |
Set up isoburn_disc_get_msc1() to return a fabricated value. | |
int | isoburn_get_mount_params (struct burn_drive *d, int adr_mode, char *adr_value, int *lba, int *track, int *session, char volid[33], int flag) |
Try to convert the given entity address into various entity addresses which would describe it. | |
Variables | |
struct isoburn * | isoburn_list_start |
int(* | libisoburn_default_msgs_submit )(void *handle, int error_code, char msg_text[], int os_errno, char severity[], int flag) |
void * | libisoburn_default_msgs_submit_handle |
int | libisoburn_default_msgs_submit_flag |
#define Isoburn_libburn_dot_h_too_olD 1 |
int isoburn__sev_to_text | ( | int | severity, | |
char ** | severity_name, | |||
int | flag | |||
) |
Definition at line 960 of file burn_wrap.c.
Referenced by isoburn_report_iso_error().
int isoburn__text_to_sev | ( | char * | severity_name, | |
int * | severity_number, | |||
int | flag | |||
) |
Definition at line 973 of file burn_wrap.c.
Referenced by isoburn_report_iso_error().
off_t isoburn_disc_available_space | ( | struct burn_drive * | d, | |
struct burn_write_opts * | o | |||
) |
Return the best possible estimation of the currently available capacity of the media.
This might depend on particular write option settings and on drive state. An eventual start address for emulated multi-session will be subtracted from the capacity estimation given by burn_disc_available_space(). Negative results get defaulted to 0. Wrapper for: burn_disc_available_space()
d | The drive to query. | |
o | If not NULL: write parameters to be set on drive before query |
Definition at line 605 of file burn_wrap.c.
References isoburn::emulation_mode, isoburn_disc_get_status(), isoburn_find_emulator(), and isoburn::nwa.
00607 { 00608 int ret; 00609 struct isoburn *o; 00610 struct burn_write_opts *eff_opts= NULL, *local_opts= NULL; 00611 enum burn_disc_status s; 00612 off_t avail; 00613 00614 eff_opts= opts; 00615 ret= isoburn_find_emulator(&o, d, 0); 00616 if(ret>0 && o!=NULL) 00617 if(o->emulation_mode!=0) { 00618 s= isoburn_disc_get_status(d); 00619 if(s==BURN_DISC_FULL) /* unknown data format in first 64 kB */ 00620 return((off_t) 0); 00621 local_opts= burn_write_opts_new(d); 00622 eff_opts= local_opts; 00623 burn_write_opts_set_start_byte(eff_opts, ((off_t) o->nwa) * (off_t) 2048); 00624 } 00625 avail= burn_disc_available_space(d, eff_opts); 00626 if(local_opts!=NULL) 00627 burn_write_opts_free(local_opts); 00628 local_opts= NULL; 00629 return(avail); 00630 }
int isoburn_disc_erasable | ( | struct burn_drive * | d | ) |
Tells whether the media can be treated by isoburn_disc_erase().
Wrapper for: burn_disc_erasable()
d | The drive to inquire. |
Definition at line 550 of file burn_wrap.c.
References isoburn::emulation_mode, and isoburn_find_emulator().
00551 { 00552 int ret; 00553 struct isoburn *o; 00554 00555 ret= isoburn_find_emulator(&o, d, 0); 00556 if(ret>0) 00557 if(o->emulation_mode==1) 00558 return(1); 00559 return burn_disc_erasable(d); 00560 }
void isoburn_disc_erase | ( | struct burn_drive * | drive, | |
int | fast | |||
) |
Mark the media as blank.
With multi-session media this will call burn_disc_erase(). With random access media, an eventual ISO-9660 filesystem will get invalidated by altering its start blocks on media. In case of success, the media is in status BURN_DISC_BLANK afterwards. Wrapper for: burn_disc_erase()
drive | The drive with the media to erase. | |
fast | 1=fast erase, 0=thorough erase With DVD-RW, fast erase yields media incapable of multi-session. |
Definition at line 563 of file burn_wrap.c.
References isoburn::emulation_mode, isoburn_disc_get_status(), isoburn_find_emulator(), isoburn_invalidate_iso(), and Libisoburn_target_head_sizE.
00564 { 00565 int ret, do_pseudo_blank= 0; 00566 struct isoburn *o; 00567 enum burn_disc_status s; 00568 char zero_buffer[Libisoburn_target_head_sizE]; 00569 struct burn_multi_caps *caps= NULL; 00570 00571 ret= isoburn_find_emulator(&o, drive, 0); 00572 if(ret>0) { 00573 if(o->emulation_mode==-1) { 00574 /* To cause a negative reply with burn_drive_wrote_well() */ 00575 burn_drive_cancel(drive); 00576 goto ex; 00577 } 00578 00579 if(o->emulation_mode > 0) { /* might be readonly with emulated sessions */ 00580 ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); 00581 if(ret > 0 && caps->start_adr) 00582 do_pseudo_blank= 1; 00583 } 00584 if(do_pseudo_blank) { 00585 s= isoburn_disc_get_status(drive); 00586 if(s==BURN_DISC_FULL) { /* unknown data format in first 64 kB */ 00587 memset(zero_buffer, 0, Libisoburn_target_head_sizE); 00588 ret= burn_random_access_write(drive, (off_t) 0, zero_buffer, 00589 (off_t) Libisoburn_target_head_sizE, 1); 00590 } else { 00591 ret= isoburn_invalidate_iso(o, 0); 00592 } 00593 if(ret<=0) 00594 burn_drive_cancel(drive); /* mark run as failure */ 00595 goto ex; 00596 } 00597 } 00598 burn_disc_erase(drive, fast); 00599 ex:; 00600 if(caps!=NULL) 00601 burn_disc_free_multi_caps(&caps); 00602 }
int isoburn_disc_get_msc1 | ( | struct burn_drive * | d, | |
int * | start_lba | |||
) |
Obtain the start block number of the most recent session on media.
In case of random access media this will normally be 0. Successfull return is not a guarantee that there is a ISO-9660 image at all. The call will fail, nevertheless,if isoburn_disc_get_status() returns not BURN_DISC_APPENDABLE or BURN_DISC_FULL. Note: The result of this call may be fabricated by a previous call of isoburn_set_msc1() which can override the rule to load the most recent session. Wrapper for: burn_disc_get_msc1()
d | The drive to inquire | |
start_lba | Contains on success the start address in 2048 byte blocks |
Definition at line 633 of file burn_wrap.c.
References isoburn::emulation_mode, isoburn::fabricated_msc1, isoburn_disc_get_status(), isoburn_find_emulator(), and isoburn_msgs_submit().
Referenced by isoburn_read_image().
00634 { 00635 int ret; 00636 struct isoburn *o; 00637 00638 #ifdef Hardcoded_cd_rW 00639 /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ 00640 *start_lba= Hardcoded_cd_rw_c1; 00641 return(1); 00642 #endif 00643 00644 if(isoburn_disc_get_status(d)!=BURN_DISC_APPENDABLE && 00645 isoburn_disc_get_status(d)!=BURN_DISC_FULL) { 00646 isoburn_msgs_submit(NULL, 0x00060000, 00647 "Media contains no recognizable data", 0, "SORRY", 0); 00648 return(0); 00649 } 00650 ret= isoburn_find_emulator(&o, d, 0); 00651 if(ret<0) 00652 return(0); 00653 if(o->fabricated_msc1>=0) { 00654 *start_lba= o->fabricated_msc1; 00655 return(1); 00656 } 00657 if(ret>0) if(o->emulation_mode>0) { 00658 *start_lba= 0; 00659 return(1); 00660 } 00661 return(burn_disc_get_msc1(d, start_lba)); 00662 }
enum burn_disc_status isoburn_disc_get_status | ( | struct burn_drive * | drive | ) |
Inquire the media status.
Expect the whole spectrum of libburn BURN_DISC_* with multi-session media. Emulated states with random access media are BURN_DISC_BLANK and BURN_DISC_APPENDABLE. Wrapper for: burn_disc_get_status()
drive | The drive to inquire. |
Definition at line 527 of file burn_wrap.c.
References isoburn::emulation_mode, isoburn::fabricated_disc_status, isoburn_find_emulator(), isoburn::nwa, and isoburn::zero_nwa.
Referenced by isoburn_disc_available_space(), isoburn_disc_erase(), isoburn_disc_get_msc1(), isoburn_is_intermediate_dvd_rw(), isoburn_needs_emulation(), isoburn_prepare_disc_aux(), and isoburn_read_image().
00528 { 00529 int ret; 00530 struct isoburn *o; 00531 00532 ret= isoburn_find_emulator(&o, drive, 0); 00533 if(ret<0) 00534 return(BURN_DISC_UNSUITABLE); 00535 if(o!=NULL) 00536 if(o->fabricated_disc_status!=BURN_DISC_UNREADY) 00537 return(o->fabricated_disc_status); 00538 if(ret==0) 00539 return(burn_disc_get_status(drive)); 00540 00541 /* emulated status */ 00542 if(o->emulation_mode==-1) 00543 return(BURN_DISC_UNSUITABLE); 00544 if(o->nwa>o->zero_nwa) 00545 return(BURN_DISC_APPENDABLE); 00546 return(BURN_DISC_BLANK); 00547 }
int isoburn_disc_track_lba_nwa | ( | struct burn_drive * | d, | |
struct burn_write_opts * | o, | |||
int | trackno, | |||
int * | lba, | |||
int * | nwa | |||
) |
Use this with trackno==0 to obtain the predicted start block number of the new session.
The interesting number is returned in parameter nwa. Wrapper for: burn_disc_track_lba_nwa()
d | The drive to inquire | |
o | If not NULL: write parameters to be set on drive before query | |
trackno | Submit 0. | |
lba | return value: start lba | |
nwa | return value: Next Writeable Address |
Definition at line 665 of file burn_wrap.c.
References isoburn::emulation_mode, isoburn_find_emulator(), and isoburn::nwa.
Referenced by isoburn_get_msc2(), and isoburn_prepare_disc_aux().
00668 { 00669 int ret; 00670 struct isoburn *o; 00671 00672 #ifdef Hardcoded_cd_rW 00673 /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ 00674 *lba= Hardcoded_cd_rw_c1; 00675 *nwa= Hardcoded_cd_rw_nwA; 00676 return(1); 00677 #endif 00678 00679 *nwa= *lba= 0; 00680 ret= isoburn_find_emulator(&o, d, 0); 00681 if(ret<0) 00682 return(0); 00683 if(ret>0) if(o->emulation_mode>0) { 00684 *lba= 0; 00685 *nwa= o->nwa; 00686 return(1); 00687 } 00688 if(burn_drive_get_drive_role(d) != 1) 00689 return(1); 00690 return(burn_disc_track_lba_nwa(d, opts, trackno, lba, nwa)); 00691 }
void isoburn_disc_write | ( | struct burn_write_opts * | o, | |
struct burn_disc * | disc | |||
) |
Start writing of the new session.
This call is asynchrounous. I.e. it returns quite soon and the progress has to be watched by a loop with call burn_drive_get_status() until BURN_DRIVE_IDLE is returned. Wrapper for: burn_disc_write()
o | Options which control the burn process. See burnwrite_opts_*() in libburn.h. | |
disc | Disc object created either by isoburn_prepare_disc() or by isoburn_prepare_new_image(). |
Definition at line 711 of file burn_wrap.c.
References isoburn::emulation_mode, isoburn_find_emulator(), isoburn_is_intermediate_dvd_rw(), isoburn_msgs_submit(), isoburn::nwa, isoburn::truncate, and isoburn::wrote_well.
00712 { 00713 int ret; 00714 off_t nwa= 0; 00715 struct isoburn *o; 00716 struct burn_drive *drive; 00717 char reasons[BURN_REASONS_LEN],msg[160+BURN_REASONS_LEN]; 00718 char adr[BURN_DRIVE_ADR_LEN]; 00719 enum burn_write_types write_type; 00720 struct stat stbuf; 00721 00722 drive= burn_write_opts_get_drive(opts); 00723 ret= isoburn_find_emulator(&o, drive, 0); 00724 if(ret<0) 00725 return; 00726 if(o!=NULL) { 00727 o->wrote_well= -1; 00728 if(o->emulation_mode!=0) { 00729 burn_write_opts_set_multi(opts, 0); 00730 if(o->emulation_mode>0 && o->nwa >= 0) { 00731 nwa= o->nwa; 00732 00733 /* This caters for unwritten formatted DVD-RW. They need to be written 00734 sequentially on the first use. Only written areas are random access. 00735 If the first session is not written to LBA 0, then re-opening of 00736 formatting and padding is needed. 00737 This can be done. But when the track gets closed after padding, 00738 this lasts a long time. There is a high risk that an app will not 00739 poll the message queue while waiting for isoburn_disc_write() to 00740 return. The pacifier loop usually happens only afterwards. 00741 So automatic formatting might cause a nervous clueless user. 00742 */ 00743 ret= isoburn_is_intermediate_dvd_rw(drive, 0); 00744 if(ret>0 && nwa>0 && nwa <= o->zero_nwa) { 00745 /* actually this should not happen since such media get recognized 00746 by isoburn_welcome_media and o->zero_nwa gets set to 0 00747 */ 00748 sprintf(msg, 00749 "DVD-RW insufficiently formatted. (Intermediate State, size unknown)"); 00750 isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0); 00751 sprintf(msg, 00752 "It might help to first deformat it and then format it again"); 00753 isoburn_msgs_submit(o, 0x00060000, msg, 0, "HINT", 0); 00754 burn_drive_cancel(drive); /* mark run as failure */ 00755 return; 00756 } 00757 /* end of DVD-RW oriented check */ 00758 00759 burn_write_opts_set_start_byte(opts, nwa * (off_t) 2048); 00760 } 00761 } 00762 } 00763 00764 write_type= burn_write_opts_auto_write_type(opts, disc, reasons, 0); 00765 if (write_type == BURN_WRITE_NONE) { 00766 sprintf(msg, "Failed to find a suitable write mode:\n%s", reasons); 00767 isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0); 00768 if(o!=NULL) 00769 o->wrote_well= 0; 00770 /* To cause a negative reply with burn_drive_wrote_well() */ 00771 burn_drive_cancel(drive); 00772 return; 00773 } 00774 00775 sprintf(reasons, "%d", (int) write_type); 00776 sprintf(msg, "Write_type = %s\n", 00777 (write_type == BURN_WRITE_SAO ? "SAO" : 00778 (write_type == BURN_WRITE_TAO ? "TAO" : reasons))); 00779 isoburn_msgs_submit(o, 0x00060000, msg, 0, "DEBUG", 0); 00780 00781 #ifdef Hardcoded_cd_rW 00782 /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ 00783 fprintf(stderr, "Setting write address to LBA %d\n", Hardcoded_cd_rw_nwA); 00784 burn_write_opts_set_start_byte(opts, 00785 ((off_t) Hardcoded_cd_rw_nwA) * (off_t) 2048); 00786 #endif 00787 00788 if(o->truncate) { 00789 ret= burn_drive_get_drive_role(drive); 00790 if(ret==2) { 00791 ret= burn_drive_d_get_adr(drive, adr); 00792 if(ret>0) { 00793 ret= lstat(adr, &stbuf); 00794 if(ret!=-1) 00795 if(S_ISREG(stbuf.st_mode)) 00796 truncate(adr, nwa * (off_t) 2048); 00797 } 00798 } 00799 } 00800 00801 burn_disc_write(opts, disc); 00802 }
int isoburn_drive_aquire | ( | struct burn_drive_info * | drive_infos[], | |
char * | adr, | |||
int | flag | |||
) |
Aquire a target drive by its filesystem path resp.
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 bit3= if the drive reports a -ROM profile then try to read table of content by scanning for ISO image headers. (depending on media type and drive state this might help or it might make the resulting toc even worse) bit4= do not emulate TOC on overwriteable media bit5= ignore ACL from external filesystems bit6= ignore POSIX Extended Attributes from external filesystems bit7= pretend -ROM profile and scan for table of content |
Definition at line 425 of file burn_wrap.c.
References isoburn::drive, isoburn_destroy(), isoburn_find_emulator(), isoburn_welcome_media(), and isoburn::truncate.
Referenced by isoburn_drive_scan_and_grab().
00427 { 00428 int ret, drive_grabbed= 0; 00429 struct isoburn *o= NULL; 00430 00431 #ifndef NIX 00432 00433 /* <<< should be obsolete by new drive addressing of libburn-0.5.2 */ 00434 /* >>> but helps with kernel 2.4 to use /dev/sr */ 00435 00436 int conv_ret; 00437 char libburn_drive_adr[BURN_DRIVE_ADR_LEN]; 00438 00439 conv_ret= burn_drive_convert_fs_adr(adr, libburn_drive_adr); 00440 if(conv_ret<=0) 00441 strcpy(libburn_drive_adr, adr); 00442 ret= burn_drive_scan_and_grab(drive_infos, libburn_drive_adr, flag&1); 00443 00444 #else 00445 00446 ret= burn_drive_scan_and_grab(drive_infos, adr, flag & 1); 00447 00448 #endif /* ! NIX */ 00449 00450 if(ret<=0) 00451 goto ex; 00452 drive_grabbed= 1; 00453 ret= isoburn_welcome_media(&o, (*drive_infos)[0].drive, 00454 (flag & (8 | 16 | 32 | 64 | 128)) | !!(flag&2)); 00455 if(ret<=0) 00456 goto ex; 00457 00458 if(flag&4) { 00459 ret= isoburn_find_emulator(&o, (*drive_infos)[0].drive, 0); 00460 if(ret>0 && o!=NULL) 00461 o->truncate= 1; 00462 } 00463 00464 ret= 1; 00465 ex: 00466 if(ret<=0) { 00467 if(drive_grabbed) 00468 burn_drive_release((*drive_infos)[0].drive, 0); 00469 isoburn_destroy(&o, 0); 00470 } 00471 return(ret); 00472 }
int isoburn_drive_grab | ( | struct burn_drive * | drive, | |
int | load | |||
) |
Aquire a drive from the burn_drive_info[] array which was obtained by a previous call of burn_drive_scan().
Wrapper for: burn_drive_grab()
drive | The drive to grab. E.g. drive_infos[1].drive . Call isoburn_drive_release(drive) when it it no longer needed. | |
load | 1 attempt to load the disc tray. 0 no attempt, rather failure. |
Definition at line 485 of file burn_wrap.c.
References isoburn_destroy(), and isoburn_welcome_media().
00486 { 00487 int ret; 00488 struct isoburn *o= NULL; 00489 00490 ret= burn_drive_grab(drive, load); 00491 if(ret<=0) 00492 goto ex; 00493 ret= isoburn_welcome_media(&o, drive, 0); 00494 if(ret<=0) 00495 goto ex; 00496 00497 ret= 1; 00498 ex: 00499 if(ret<=0) 00500 isoburn_destroy(&o,0); 00501 return(ret); 00502 }
void isoburn_drive_release | ( | struct burn_drive * | drive, | |
int | eject | |||
) |
Release an aquired drive.
Wrapper for: burn_drive_release()
drive | The drive to be released | |
eject | 1= eject media from drive , 0= do not eject |
Definition at line 805 of file burn_wrap.c.
References isoburn_destroy(), and isoburn_find_emulator().
00806 { 00807 int ret; 00808 struct isoburn *o; 00809 00810 ret= isoburn_find_emulator(&o, drive, 0); 00811 if(ret<0) 00812 return; 00813 if(o!=NULL) { 00814 isoburn_destroy(&o, 0); 00815 } 00816 burn_drive_release(drive, eject); 00817 }
int isoburn_drive_scan_and_grab | ( | struct burn_drive_info * | drive_infos[], | |
char * | adr, | |||
int | load | |||
) |
Aquire a target drive by its filesystem path resp.
libburn persistent address. Wrapper for: burn_drive_scan_and_grab()
drive_infos | On success returns a one element array with the drive (cdrom/burner). Thus use with driveno 0 only. On failure the array has no valid elements at all. The returned array should be freed via burn_drive_info_free() when the drive is no longer needed. But before this is done one has to call isoburn_drive_release(drive_infos[0].drive). | |
adr | The persistent address of the desired drive. | |
load | 1 attempt to load the disc tray. 0 no attempt,rather failure. |
Definition at line 475 of file burn_wrap.c.
References isoburn_drive_aquire().
00477 { 00478 int ret; 00479 00480 ret= isoburn_drive_aquire(drive_infos, adr, !!load); 00481 return(ret); 00482 }
int isoburn_drive_set_msgs_submit | ( | struct burn_drive * | d, | |
int(*)(void *handle, int error_code, char msg_text[], int os_errno, char severity[], int flag) | msgs_submit, | |||
void * | submit_handle, | |||
int | submit_flag, | |||
int | flag | |||
) |
Attach to a drive an application provided method for immediate delivery of messages.
If no method is set or if the method is set to NULL then libisoburn delivers messages of the drive through the global msgs_submit() method set by isoburn_set_msgs_submiti() or by the message queue of libburn.
d | The drive to which this function, handle and flag shall apply | |
msgs_submit | The function call which implements the method | |
submit_handle | Handle to be used as first argument of msgs_submit | |
submit_flag | Flag to be used as last argument of msgs_submit | |
flag | Unused yet, submit 0 |
Definition at line 1610 of file burn_wrap.c.
References isoburn_find_emulator(), isoburn::msgs_submit, isoburn::msgs_submit_flag, and isoburn::msgs_submit_handle.
01615 { 01616 struct isoburn *o; 01617 int ret; 01618 01619 ret= isoburn_find_emulator(&o, d, 0); 01620 if(ret<0 || o==NULL) 01621 return(-1); 01622 o->msgs_submit= msgs_submit; 01623 o->msgs_submit_handle= submit_handle; 01624 o->msgs_submit_flag= submit_flag; 01625 return(1); 01626 }
int isoburn_drive_wrote_well | ( | struct burn_drive * | d | ) |
Inquire whether the most recent write run was successful.
Wrapper for: burn_drive_wrote_well()
d | The drive to inquire |
Definition at line 896 of file burn_wrap.c.
References isoburn_find_emulator(), and isoburn::wrote_well.
00897 { 00898 int ret; 00899 struct isoburn *o; 00900 00901 ret= isoburn_find_emulator(&o, d, 0); 00902 if(ret<0) 00903 return(-1); 00904 if(o!=NULL) 00905 if(o->wrote_well>=0) 00906 return(o->wrote_well); 00907 ret= burn_drive_wrote_well(d); 00908 return ret; 00909 }
int isoburn_emulate_toc | ( | struct burn_drive * | d, | |
int | flag | |||
) | [static] |
Definition at line 1147 of file burn_wrap.c.
References isoburn::emulation_mode, isoburn_find_emulator(), isoburn_make_toc_entry(), isoburn_msgs_submit(), isoburn_read_iso_head(), isoburn_toc_entry_destroy(), Libisoburn_nwa_alignemenT, Libisoburn_overwriteable_starT, Libisoburn_toc_scan_max_gaP, isoburn::toc, and isoburn_toc_entry::track_blocks.
Referenced by isoburn_welcome_media().
01148 { 01149 int ret, image_size= 0, lba, track_blocks, session_count= 0, read_flag= 0; 01150 int scan_start= 0, scan_count= 0, probe_minus_16= 0, growisofs_nwa, role; 01151 int with_enclosure= 0, readable_blocks= -1; 01152 struct isoburn *o; 01153 char msg[160], size_text[80], *sev, volid[33], *volid_pt= NULL; 01154 time_t start_time, last_pacifier, now; 01155 01156 /* is the media emulated multi-session ? */ 01157 ret= isoburn_find_emulator(&o, d, 0); 01158 if(ret<0) 01159 return(-1); 01160 if(o==NULL) 01161 return(-1); 01162 if(o->emulation_mode<=0 && !(flag&1)) 01163 return(0); 01164 01165 ret= burn_get_read_capacity(d, &readable_blocks, 0); 01166 if(ret <= 0) { 01167 01168 role = burn_drive_get_drive_role(d); 01169 if (role == 2) 01170 /* Might be a block device on a system where libburn cannot determine its 01171 size. Try to read anyway. */ 01172 readable_blocks= 0x7ffffff0; /* try to read anyway */ 01173 else 01174 readable_blocks= -1; 01175 } 01176 01177 start_time= last_pacifier= time(NULL); 01178 lba= 0; 01179 if(!(flag&2)) { 01180 ret= isoburn_read_iso_head(d, lba, &image_size, NULL, 0); 01181 if(ret<=0) 01182 {ret= 0; goto failure;} 01183 lba= Libisoburn_overwriteable_starT; 01184 with_enclosure= 1; 01185 if((flag & 16) && o->emulation_mode == 1) { 01186 ret= 1; 01187 goto failure; /* This will represent the media as single session */ 01188 } 01189 } 01190 while(lba<image_size || (flag&2)) { 01191 now= time(NULL); 01192 if(now - last_pacifier >= 5) { 01193 last_pacifier= now; 01194 if(scan_count>=10*512) 01195 sprintf(size_text, "%.f MB", ((double) scan_count) / 512.0); 01196 else 01197 sprintf(size_text, "%.f kB", 2 * (double) scan_count); 01198 sprintf(msg, "Found %d ISO sessions by scanning %s in %.f seconds", 01199 session_count, size_text, (double) (now - start_time)); 01200 isoburn_msgs_submit(o, 0x00060000, msg, 0, "UPDATE", 0); 01201 } 01202 read_flag= 1; 01203 if(flag&2) 01204 read_flag|= (1<<15)|((session_count>0)<<14); 01205 else { 01206 01207 /* growisofs aligns to 16 rather than 32. Overwriteable TOC emulation 01208 relies on not accidentially seeing inter-session trash data. 01209 But one can safely access 16 blocks earlier because a xorriso header 01210 would have overwritten with the unused 16 blocks at its start. 01211 If libisoburn alignment would increase, then this would not be 01212 possible any more. 01213 */ 01214 01215 if(probe_minus_16) 01216 read_flag|= (1<<14); 01217 probe_minus_16= 0; 01218 } 01219 01220 ret= isoburn_read_iso_head(d, lba, &track_blocks, volid, read_flag); 01221 if(ret > 0) { 01222 volid_pt= volid; 01223 } else { 01224 volid_pt= NULL; 01225 if(session_count>0) { 01226 if(flag&2) { 01227 if(ret==0) { 01228 /* try at next 64 k block (check both 32 k halves) */ 01229 lba+= 32; 01230 scan_count+= 32; 01231 if(lba-scan_start <= Libisoburn_toc_scan_max_gaP) 01232 continue; 01233 } 01234 break; 01235 } 01236 sprintf(msg, 01237 "Chain of ISO session headers broken at #%d, LBA %ds", 01238 session_count+1, lba); 01239 isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0); 01240 01241 if(with_enclosure) { 01242 ret= isoburn_make_toc_entry(o, &session_count, 0, image_size, NULL,0); 01243 if(ret<=0) 01244 goto failure; 01245 } 01246 break; /* do not return failure */ 01247 01248 } 01249 {ret= 0; goto failure;} 01250 } 01251 if(ret==2) /* ISO header was found in first half block */ 01252 lba-= 16; 01253 01254 if(readable_blocks >= 0 && lba + track_blocks > readable_blocks) { 01255 sprintf(msg, "ISO image size %ds larger than readable size %ds", 01256 lba + track_blocks, readable_blocks); 01257 isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0); 01258 track_blocks= readable_blocks - lba; 01259 } 01260 ret= isoburn_make_toc_entry(o, &session_count, lba, track_blocks, volid_pt, 01261 0); 01262 if(ret<=0) 01263 goto failure; 01264 lba+= track_blocks; 01265 scan_count+= 32; 01266 01267 /* growisofs aligns to 16 rather than 32 */ 01268 growisofs_nwa= lba; 01269 if(growisofs_nwa % 16) 01270 growisofs_nwa+= 16 - (growisofs_nwa % 16); 01271 if(lba % Libisoburn_nwa_alignemenT) 01272 lba+= Libisoburn_nwa_alignemenT - (lba % Libisoburn_nwa_alignemenT); 01273 scan_start= lba; 01274 if(lba - growisofs_nwa == 16) 01275 probe_minus_16= 1; 01276 } 01277 if(last_pacifier != start_time) 01278 sev= "UPDATE"; 01279 else 01280 sev= "DEBUG"; 01281 now= time(NULL); 01282 if(scan_count>=10*512) 01283 sprintf(size_text, "%.f MB", ((double) scan_count) / 512.0); 01284 else 01285 sprintf(size_text, "%.f kB", 2 * (double) scan_count); 01286 sprintf(msg, "Found %d ISO sessions by scanning %s in %.f seconds", 01287 session_count, size_text, (double) (now - start_time)); 01288 isoburn_msgs_submit(o, 0x00060000, msg, 0, sev, 0); 01289 return(1); 01290 failure:; 01291 isoburn_toc_entry_destroy(&(o->toc), 1); 01292 if(with_enclosure && o->emulation_mode == 1) { 01293 if(readable_blocks >= 0 && image_size > readable_blocks) { 01294 sprintf(msg, "ISO image size %ds larger than readable size %ds", 01295 image_size, readable_blocks); 01296 isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0); 01297 image_size= readable_blocks; 01298 } 01299 session_count= 0; 01300 ret= isoburn_make_toc_entry(o, &session_count, 0, image_size, NULL, 0); 01301 } 01302 return(ret); 01303 }
int isoburn_find_emulator | ( | struct isoburn ** | pt, | |
struct burn_drive * | drive, | |||
int | flag | |||
) |
Retrieve media emulation and eventual isoburn emulator of drive.
Get an eventual isoburn object which is wrapped around the drive.
Definition at line 508 of file burn_wrap.c.
References isoburn_find_by_drive(), and isoburn_msgs_submit().
Referenced by isoburn_activate_session(), isoburn_attach_image(), isoburn_cancel_prepared_write(), isoburn_disc_available_space(), isoburn_disc_erasable(), isoburn_disc_erase(), isoburn_disc_get_msc1(), isoburn_disc_get_status(), isoburn_disc_track_lba_nwa(), isoburn_disc_write(), isoburn_drive_aquire(), isoburn_drive_release(), isoburn_drive_set_msgs_submit(), isoburn_drive_wrote_well(), isoburn_emulate_toc(), isoburn_get_attached_image(), isoburn_get_fifo_status(), isoburn_get_min_start_byte(), isoburn_get_mount_params(), isoburn_needs_emulation(), isoburn_prepare_blind_grow(), isoburn_prepare_disc_aux(), isoburn_read_image(), isoburn_set_msc1(), isoburn_set_read_pacifier(), and isoburn_toc_drive_get_disc().
00510 { 00511 int ret; 00512 00513 ret= isoburn_find_by_drive(pt, drive, 0); 00514 if(ret<=0) 00515 return(0); 00516 if((*pt)->emulation_mode==-1) { 00517 isoburn_msgs_submit(*pt, 0x00060000, 00518 "Unsuitable drive and media state", 0, "FAILURE", 0); 00519 return(-1); 00520 } 00521 if((*pt)->emulation_mode==0) 00522 return(0); 00523 return(1); 00524 }
void isoburn_finish | ( | void | ) |
Shutdown all three libraries.
Wrapper for : iso_finish() and burn_finish().
Definition at line 820 of file burn_wrap.c.
References isoburn_destroy_all().
00821 { 00822 isoburn_destroy_all(&isoburn_list_start, 0); 00823 burn_finish(); 00824 iso_finish(); 00825 }
int isoburn_get_fifo_status | ( | struct burn_drive * | d, | |
int * | size, | |||
int * | free_bytes, | |||
char ** | status_text | |||
) |
Inquire state and fill parameters of the fifo which is attached to the emerging track.
This should be done in the pacifier loop while isoburn_disc_write() or burn_disc_write() are active. This works only with drives obtained by isoburn_drive_scan_and_grab() or isoburn_drive_grab(). If isoburn_prepare_new_image() was used, then parameter out_drive must have announced the track output drive. Hint: If only burn_write_opts and not burn_drive is known, then the drive can be obtained by burn_write_opts_get_drive().
d | The drive to which the track with the fifo gets burned. | |
size | The total size of the fifo | |
free_bytes | The current free capacity of the fifo | |
status_text | Returns a pointer to a constant text, see below |
Definition at line 912 of file burn_wrap.c.
References isoburn::iso_source, and isoburn_find_emulator().
00914 { 00915 int ret; 00916 struct isoburn *o; 00917 size_t hsize= 0, hfree_bytes= 0; 00918 00919 ret= isoburn_find_emulator(&o, d, 0); 00920 if(ret<0) 00921 return(-1); 00922 00923 if(o==NULL) 00924 return(-1); 00925 if(o->iso_source==NULL) 00926 return(-1); 00927 ret= iso_ring_buffer_get_status(o->iso_source, &hsize, &hfree_bytes); 00928 if(hsize > 1024*1024*1024) 00929 *size= 1024*1024*1024; 00930 else 00931 *size= hsize; 00932 if(hfree_bytes > 1024*1024*1024) 00933 *free_bytes= 1024*1024*1024; 00934 else 00935 *free_bytes= hfree_bytes; 00936 *status_text= ""; 00937 if(ret==0) 00938 *status_text= "standby"; 00939 else if(ret==1) 00940 *status_text= "active"; 00941 else if(ret==2) 00942 *status_text= "ending"; 00943 else if(ret==3) 00944 *status_text= "failing"; 00945 else if(ret==4) 00946 *status_text= "unused"; 00947 else if(ret==5) 00948 *status_text= "abandoned"; 00949 else if(ret==6) 00950 *status_text= "ended"; 00951 else if(ret==7) 00952 *status_text= "aborted"; 00953 return(ret); 00954 }
int isoburn_get_min_start_byte | ( | struct burn_drive * | d, | |
off_t * | start_byte, | |||
int | flag | |||
) |
Obtain the size which was attributed to an emulated appendable on actually overwriteable media.
This value is supposed to be <= 2048 * nwa as of isoburn_disc_track_lba_nwa().
d | The drive holding the media. | |
start_byte | The reply value counted in bytes, not in sectors. | |
flag | Unused yet. Submit 0. |
Definition at line 878 of file burn_wrap.c.
References isoburn_find_emulator(), and isoburn::min_start_byte.
00880 { 00881 int ret; 00882 struct isoburn *o; 00883 00884 ret= isoburn_find_emulator(&o, d, 0); 00885 if(ret<0) 00886 return(-1); 00887 if(ret==0) 00888 return(0); 00889 *start_byte= o->min_start_byte; 00890 if(o->min_start_byte<=0) 00891 return(0); 00892 return(1); 00893 }
int isoburn_get_mount_params | ( | struct burn_drive * | d, | |
int | adr_mode, | |||
char * | adr_value, | |||
int * | lba, | |||
int * | track, | |||
int * | session, | |||
char | volid[33], | |||
int | flag | |||
) |
Try to convert the given entity address into various entity addresses which would describe it.
Note: Sessions and tracks are counted beginning with 1, not with 0.
d | The drive where msc1 is to be set | |
adr_mode | Determines how to interpret the input adr_value. If adr_value shall represent a number then decimal ASCII digits are expected. 0= start lba of last session in TOC, ignore adr_value 1= start lba of session number given by adr_value 2= start lba of track given number by adr_value 3= adr_value itself is the lba to be used 4= start lba of last session with volume id given by adr_value | |
adr_value | A string describing the value to be eventually used. | |
lba | returns the block address of the entity, -1 means invalid | |
track | returns the track number of the entity, -1 means invalid | |
session | returns the session number of the entity, -1 means invalid | |
volid | returns the volume id of the entity if it is a ISO session | |
flag | Bitfield for control purposes. bit2= with adr_mode 4: use adr_value as regular expression |
Definition at line 1785 of file burn_wrap.c.
References isoburn_toc_disc::disc, isoburn::fabricated_msc1, isoburn_find_emulator(), isoburn_get_track_lba(), isoburn_read_iso_head(), isoburn_set_msc1(), isoburn_toc_disc_get_sessions(), isoburn_toc_drive_get_disc(), and isoburn_toc_session_get_tracks().
01789 { 01790 int msc1_mem, ret, total_tracks, num_sessions, num_tracks, i, j, track_lba; 01791 int size, is_iso= 0; 01792 struct isoburn *o; 01793 struct isoburn_toc_disc *disc= NULL; 01794 struct isoburn_toc_session **sessions= NULL; 01795 struct isoburn_toc_track **tracks= NULL; 01796 01797 *lba= *track= *session= -1; 01798 volid[0]= 0; 01799 ret= isoburn_find_emulator(&o, d, 0); 01800 if(ret < 0 || o == NULL) 01801 return(-1); 01802 msc1_mem= o->fabricated_msc1; 01803 ret= isoburn_set_msc1(d, adr_mode, adr_value, 2 | (flag & 4)); 01804 if(ret <= 0) 01805 return(ret); 01806 *lba= o->fabricated_msc1; 01807 01808 disc= isoburn_toc_drive_get_disc(d); 01809 if(disc==NULL) 01810 {ret= -1; goto ex;} /* cannot happen because checked by isoburn_set_msc1 */ 01811 sessions= isoburn_toc_disc_get_sessions(disc, &num_sessions); 01812 if(sessions==NULL || num_sessions<=0) 01813 {ret= -1; goto ex;} /* cannot happen because checked by isoburn_set_msc1 */ 01814 total_tracks= 0; 01815 for(i=0; i<num_sessions && *session < 0; i++) { 01816 tracks= isoburn_toc_session_get_tracks(sessions[i], &num_tracks); 01817 if(tracks==NULL) 01818 continue; 01819 for(j= 0; j<num_tracks && *track < 0; j++) { 01820 total_tracks++; 01821 isoburn_get_track_lba(tracks[j], &track_lba, 0); 01822 if(track_lba == *lba) { 01823 *track= total_tracks; 01824 *session= i + 1; 01825 } 01826 } 01827 } 01828 ret= isoburn_read_iso_head(d, *lba, &size, volid, 1); 01829 if(ret <= 0) 01830 volid[0]= 0; 01831 else 01832 is_iso= 1; 01833 01834 ex:; 01835 o->fabricated_msc1= msc1_mem; 01836 return(2 - is_iso); 01837 }
int isoburn_get_msc2 | ( | struct isoburn * | o, | |
struct burn_write_opts * | opts, | |||
int * | msc2, | |||
int | flag | |||
) |
Obtains the image address offset to be used with image generation.
This is either the (emulated) drive nwa or a value set by isoburn_prepare_blind_grow(). In any case this is the address to tell to iso_write_opts_set_ms_block().
o | The isoburn object to be inquired | |
opts | If not NULL: write parameters to be set on drive before query | |
msc2 | The value to be used with iso_write_opts_set_ms_block() | |
flag | unused yet |
Definition at line 694 of file burn_wrap.c.
References isoburn::drive, isoburn::fabricated_msc2, isoburn_disc_track_lba_nwa(), and isoburn::nwa.
Referenced by isoburn_prepare_disc_aux().
00696 { 00697 int ret, lba, nwa; 00698 00699 if(o->fabricated_msc2>=0) 00700 *msc2= o->fabricated_msc2; 00701 else { 00702 ret= isoburn_disc_track_lba_nwa(o->drive, opts, 0, &lba, &nwa); 00703 if(ret<=0) 00704 return(ret); 00705 *msc2= nwa; 00706 } 00707 return(1); 00708 }
int isoburn_get_track_lba | ( | struct isoburn_toc_track * | track, | |
int * | lba, | |||
int | flag | |||
) |
Definition at line 1597 of file burn_wrap.c.
References isoburn_toc_track_get_entry().
Referenced by isoburn_get_mount_params(), and isoburn_set_msc1().
01598 { 01599 struct burn_toc_entry entry; 01600 01601 isoburn_toc_track_get_entry(track, &entry); 01602 if (entry.extensions_valid & 1) 01603 *lba= entry.start_lba; 01604 else 01605 *lba= burn_msf_to_lba(entry.pmin, entry.psec, entry.pframe); 01606 return(1); 01607 }
int isoburn_initialize | ( | char | msg[1024], | |
int | flag | |||
) |
Overview.
libisoburn is a frontend for libraries libburn and libisofs which enables creation and expansion of ISO-9660 filesystems on all CD/DVD media supported by libburn. This includes media like DVD+RW, which do not support multi-session management on media level and even plain disk files or block devices.
The price for that is thorough specialization on data files in ISO-9660 filesystem images. So libisoburn is not suitable for audio (CD-DA) or any other CD layout which does not entirely consist of ISO-9660 sessions.
Connector functions
libisofs and libburn do not depend on each other but share some interfaces by which they can cooperate. libisoburn establishes the connection between both modules by creating the necessary interface objects and attaching them to the right places.
Wrapper functions
The priciple of this frontend is that you may use any call of libisofs or libburn unless it has a isoburn_*() wrapper listed in the following function documentation.
E.g. call isoburn_initialize() rather than iso_init(); burn_initialize(); and call isoburn_drive_scan_and_grab() rather than burn_drive_scan_and_grab(). But you may call burn_disc_get_profile() directly if you want to display the media type.
The wrappers will transparently provide the necessary emulations which are appropriate for particular target drives and media states. To learn about them you have to read both API descriptions: the one of the wrapper and the one of the underlying libburn or libisofs call.
Macros BURN_* and functions burn_*() are documented in <libburn/libburn.h> Macros ISO_* and functions iso_*() are documented in <libisofs/libisofs.h>
Usage model
There may be an input drive and an output drive. Either of them may be missing with the consequence that no reading resp. writing is possible. Both drive roles can be fulfilled by the same drive.
Input can be a random access readable libburn drive: optical media, regular files, block devices. Output can be any writeable libburn drive: writeable optical media in burner, writeable file objects (no directories).
libburn demands rw-permissions to drive device file resp. file object.
If the input drive provides a suitable ISO RockRidge image, then its tree may be loaded into memory and can then be manipulated by libisofs API calls. The loading is done by isoburn_read_image() under control of struct isoburn_read_opts which the application obtains from libisoburn and manipulates by the family of isoburn_ropt_set_*() functions.
Writing of result images is controlled by libisofs related parameters in a struct isoburn_imgen_opts which the application obtains from libisoburn and manipulates by the family of isoburn_igopt_set_*() functions.
All multi-session aspects are handled by libisoburn according to these settings. The application does not have to analyze media state and write job parameters. It rather states its desires which libisoburn tries to fulfill, or else will refuse to start the write run.
Setup for Growing, Modifying or Blind Growing
The connector function family offers alternative API calls for performing the setup for several alternative image generation strategies.
Growing: If input and output drive are the same, then isoburn_prepare_disc() is to be used. It will lead to an add-on session on appendable or overwriteable media with existing ISO image. With blank media it will produce a first session.
Modifying: If the output drive is not the input drive, and if it bears blank media or overwriteable without a valid ISO image, then one may produce a consolidated image with old and new data. This will copy file data from an eventual input drive with valid image, add any newly introduced data from the local filesystem, and produce a first session on output media. To prepare for such an image generation run, use isoburn_prepare_new_image().
Blind Growing: This method reads the old image from one drive and writes the add-on session to a different drive. That output drive is nevertheless supposed to finally lead to the same media from where the session was loaded. Usually it will be stdio:/dev/fd/1 (i.e. stdout) being piped into some burn program like with this classic gesture: mkisofs -M $dev -C $msc1,$nwa | cdrecord -waiti dev=$dev Blind growing is prepared by the call isoburn_prepare_blind_grow(). The input drive should be released immediately after this call in order to allow the consumer of the output stream to access that drive for writing.
After either of these setups, some peripheral libburn drive parameter settings like burn_write_opts_set_simulate(), burn_write_opts_set_multi(), burn_drive_set_speed(), burn_write_opts_set_underrun_proof() should be made. Do not set the write mode. It will be chosen by libisoburn so it matches job and media state.
Writing the image
Then one may start image generation and write threads by isoburn_disc_write(). Progress may be watched at the output drive by burn_drive_get_status() and isoburn_get_fifo_status().
At some time, the output drive will be BURN_DRIVE_IDLE indicating that writing has ended. One should inquire isoburn_drive_wrote_well() to learn about overall success.
Finally one must call isoburn_activate_session() which will complete any eventual multi-session emulation.
Application Constraints
Applications shall include libisofs/libisofs.h , libburn/libburn.h and this file itself: libisoburn/libisoburn.h . They shall link with -lisofs -lburn -lisoburn or with the .o files emerging from building those libraries from their sources.
Applications must use 64 bit off_t, e.g. on 32-bit Linux by defining define _LARGEFILE_SOURCE define _FILE_OFFSET_BITS 64 or take special precautions to interface with the library by 64 bit integers where above .h files prescribe off_t. Not to use 64 bit file i/o will keep the application from producing and processing ISO images of more than 2 GB size. Initialize libisoburn, libisofs and libburn. Wrapper for : iso_init() and burn_initialize()
msg | A character array for eventual messages (e.g. with errors) | |
flag | Bitfield for control purposes (unused yet, submit 0) |
Definition at line 65 of file burn_wrap.c.
References isoburn_destroy_all(), isoburn_libisofs_req_major, isoburn_libisofs_req_micro, isoburn_libisofs_req_minor, and isoburn_version().
00066 { 00067 int major, minor, micro, bad_match= 0; 00068 00069 00070 /* First two ugly compile time checks for header version compatibility. 00071 If everthing matches, then they produce no C code. In case of mismatch, 00072 intentionally faulty C code will be inserted. 00073 */ 00074 00075 #ifdef iso_lib_header_version_major 00076 /* The minimum requirement of libisoburn towards the libisofs header 00077 at compile time is defined in libisoburn/libisoburn.h : 00078 isoburn_libisofs_req_major 00079 isoburn_libisofs_req_minor 00080 isoburn_libisofs_req_micro 00081 It gets compared against the version macros in libisofs/libisofs.h : 00082 iso_lib_header_version_major 00083 iso_lib_header_version_minor 00084 iso_lib_header_version_micro 00085 If the header is too old then the following code shall cause failure of 00086 libisoburn compilation rather than to allow production of a program with 00087 unpredictable bugs or memory corruption. 00088 The compiler messages supposed to appear in this case are: 00089 error: 'LIBISOFS_MISCONFIGURATION' undeclared (first use in this function) 00090 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) 00091 error: 'LIBISOFS_MISCONFIGURATION_' undeclared (first use in this function) 00092 */ 00093 /* The indendation is an advise of man gcc to help old compilers ignoring */ 00094 #if isoburn_libisofs_req_major > iso_lib_header_version_major 00095 #define Isoburn_libisofs_dot_h_too_olD 1 00096 #endif 00097 #if isoburn_libisofs_req_major == iso_lib_header_version_major && isoburn_libisofs_req_minor > iso_lib_header_version_minor 00098 #define Isoburn_libisofs_dot_h_too_olD 1 00099 #endif 00100 #if isoburn_libisofs_req_minor == iso_lib_header_version_minor && isoburn_libisofs_req_micro > iso_lib_header_version_micro 00101 #define Isoburn_libisofs_dot_h_too_olD 1 00102 #endif 00103 00104 #ifdef Isoburn_libisofs_dot_h_too_olD 00105 LIBISOFS_MISCONFIGURATION = 0; 00106 INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisofs_dot_h_TOO_OLD__SEE_libisoburn_dot_h_AND_burn_wrap_dot_h = 0; 00107 LIBISOFS_MISCONFIGURATION_ = 0; 00108 #endif 00109 00110 #endif /* iso_lib_header_version_major */ 00111 00112 /* The minimum requirement of libisoburn towards the libburn header 00113 at compile time is defined in libisoburn/libisoburn.h : 00114 isoburn_libburn_req_major 00115 isoburn_libburn_req_minor 00116 isoburn_libburn_req_micro 00117 It gets compared against the version macros in libburn/libburn.h : 00118 burn_header_version_major 00119 burn_header_version_minor 00120 burn_header_version_micro 00121 If the header is too old then the following code shall cause failure of 00122 cdrskin compilation rather than to allow production of a program with 00123 unpredictable bugs or memory corruption. 00124 The compiler messages supposed to appear in this case are: 00125 error: 'LIBBURN_MISCONFIGURATION' undeclared (first use in this function) 00126 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) 00127 error: 'LIBBURN_MISCONFIGURATION_' undeclared (first use in this function) 00128 */ 00129 00130 /* The indendation is an advise of man gcc to help old compilers ignoring */ 00131 #if isoburn_libburn_req_major > burn_header_version_major 00132 #define Isoburn_libburn_dot_h_too_olD 1 00133 #endif 00134 #if isoburn_libburn_req_major == burn_header_version_major && isoburn_libburn_req_minor > burn_header_version_minor 00135 #define Isoburn_libburn_dot_h_too_olD 1 00136 #endif 00137 #if isoburn_libburn_req_minor == burn_header_version_minor && isoburn_libburn_req_micro > burn_header_version_micro 00138 #define Isoburn_libburn_dot_h_too_olD 1 00139 #endif 00140 00141 #ifdef Isoburn_libburn_dot_h_too_olD 00142 LIBBURN_MISCONFIGURATION = 0; 00143 INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libburn_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h = 0; 00144 LIBBURN_MISCONFIGURATION_ = 0; 00145 #endif 00146 00147 /* End of ugly compile time tests (scroll up for explanation) */ 00148 00149 00150 00151 msg[0]= 0; 00152 if(iso_init()<0) { 00153 sprintf(msg+strlen(msg), "Cannot initialize libisofs\n"); 00154 return(0); 00155 } 00156 iso_lib_version(&major, &minor, µ); 00157 sprintf(msg+strlen(msg), "libisofs-%d.%d.%d ", major, minor, micro); 00158 #ifdef iso_lib_header_version_major 00159 if(iso_lib_is_compatible(iso_lib_header_version_major, 00160 iso_lib_header_version_minor, 00161 iso_lib_header_version_micro)) { 00162 sprintf(msg+strlen(msg), "ok, "); 00163 } else { 00164 sprintf(msg+strlen(msg),"- TOO OLD -, need at least libisofs-%d.%d.%d ,\n", 00165 iso_lib_header_version_major, iso_lib_header_version_minor, 00166 iso_lib_header_version_micro); 00167 bad_match= 1; 00168 } 00169 #else 00170 if(iso_lib_is_compatible(isoburn_libisofs_req_major, 00171 isoburn_libisofs_req_minor, 00172 isoburn_libisofs_req_micro)) { 00173 sprintf(msg+strlen(msg), "suspicious, "); 00174 } else { 00175 sprintf(msg+strlen(msg),"- TOO OLD -, need at least libisofs-%d.%d.%d ,\n", 00176 isoburn_libisofs_req_major, isoburn_libisofs_req_minor, 00177 isoburn_libisofs_req_micro); 00178 bad_match= 1; 00179 } 00180 #endif /* ! iso_lib_header_version_major */ 00181 00182 if(!burn_initialize()) { 00183 sprintf(msg+strlen(msg), "Cannot initialize libburn\n"); 00184 return(0); 00185 } 00186 burn_version(&major, &minor, µ); 00187 sprintf(msg+strlen(msg), "libburn-%d.%d.%d ", major, minor, micro); 00188 if(major > burn_header_version_major 00189 || (major == burn_header_version_major 00190 && (minor > burn_header_version_minor 00191 || (minor == burn_header_version_minor 00192 && micro >= burn_header_version_micro)))) { 00193 sprintf(msg+strlen(msg), "ok, "); 00194 } else { 00195 sprintf(msg+strlen(msg), "- TOO OLD -, need at least libburn-%d.%d.%d ,\n", 00196 burn_header_version_major, burn_header_version_minor, 00197 burn_header_version_micro); 00198 bad_match= 1; 00199 } 00200 00201 isoburn_version(&major, &minor, µ); 00202 sprintf(msg+strlen(msg), "for libisoburn-%d.%d.%d", major, minor, micro); 00203 if(bad_match) 00204 return(0); 00205 00206 isoburn_destroy_all(&isoburn_list_start, 0); /* isoburn_list_start= NULL */ 00207 return(1); 00208 }
int isoburn_is_intermediate_dvd_rw | ( | struct burn_drive * | d, | |
int | flag | |||
) |
Definition at line 243 of file burn_wrap.c.
References isoburn_disc_get_status().
Referenced by isoburn_disc_write(), and isoburn_welcome_media().
00244 { 00245 int profile, ret= 0, format_status, num_formats; 00246 char profile_name[80]; 00247 enum burn_disc_status s; 00248 off_t format_size= -1; 00249 unsigned bl_sas; 00250 00251 s= isoburn_disc_get_status(d); 00252 ret= burn_disc_get_profile(d, &profile, profile_name); 00253 if(ret>0 && profile==0x13) 00254 ret= burn_disc_get_formats(d, &format_status, &format_size, 00255 &bl_sas, &num_formats); 00256 if(ret>0 && profile==0x13 && s==BURN_DISC_BLANK && 00257 format_status==BURN_FORMAT_IS_UNKNOWN) 00258 return(1); 00259 return(0); 00260 }
int isoburn_libburn_req | ( | int * | major, | |
int * | minor, | |||
int * | micro | |||
) |
The minimum version of libburn to be used with this version of libisoburn at runtime.
This is checked already in isoburn_initialize() which will refuse on outdated version. So this call is for information purposes after successful startup only.
major | isoburn_libburn_req_major as seen at build time | |
minor | as seen at build time | |
micro | as seen at build time |
Definition at line 222 of file burn_wrap.c.
int isoburn_libisofs_req | ( | int * | major, | |
int * | minor, | |||
int * | micro | |||
) |
The minimum version of libisofs to be used with this version of libisoburn at runtime.
This is checked already in isoburn_initialize() which will refuse on outdated version. So this call is for information purposes after successful startup only.
major | isoburn_libisofs_req_major as seen at build time | |
minor | as seen at build time | |
micro | as seen at build time |
Definition at line 212 of file burn_wrap.c.
int isoburn_make_toc_entry | ( | struct isoburn * | o, | |
int * | session_count, | |||
int | lba, | |||
int | track_blocks, | |||
char * | volid, | |||
int | flag | |||
) |
Definition at line 1111 of file burn_wrap.c.
References isoburn_msgs_submit(), isoburn_toc_entry_new(), isoburn_toc_entry::session, isoburn_toc_entry::start_lba, isoburn::toc, isoburn_toc_entry::track_blocks, isoburn_toc_entry::track_no, and isoburn_toc_entry::volid.
Referenced by isoburn_emulate_toc().
01113 { 01114 int ret; 01115 struct isoburn_toc_entry *item; 01116 01117 ret= isoburn_toc_entry_new(&item, o->toc, 0); 01118 if(ret<=0) { 01119 no_memory:; 01120 isoburn_msgs_submit(o, 0x00060000, 01121 "Not enough memory for emulated TOC entry object", 01122 0, "FATAL", 0); 01123 return(-1); 01124 } 01125 if(o->toc==NULL) 01126 o->toc= item; 01127 (*session_count)++; 01128 item->session= *session_count; 01129 item->track_no= *session_count; 01130 item->start_lba= lba; 01131 item->track_blocks= track_blocks; 01132 if(volid != NULL) { 01133 item->volid= strdup(volid); 01134 if(item->volid == NULL) 01135 goto no_memory; 01136 } 01137 return(1); 01138 }
int isoburn_needs_emulation | ( | struct burn_drive * | d | ) |
Inquire wether the media needs emulation or would be suitable for generic multi-session via libburn.
d | The drive to inquire |
Definition at line 828 of file burn_wrap.c.
References isoburn::emulation_mode, isoburn_disc_get_status(), and isoburn_find_emulator().
00829 { 00830 int ret; 00831 struct isoburn *o; 00832 enum burn_disc_status s; 00833 00834 s= isoburn_disc_get_status(drive); 00835 if(s!=BURN_DISC_BLANK && s!=BURN_DISC_APPENDABLE) 00836 return(-1); 00837 ret= isoburn_find_emulator(&o, drive, 0); 00838 if(ret<0) 00839 return(-1); 00840 if(ret>0) 00841 if(o->emulation_mode>0) 00842 return(1); 00843 return(0); 00844 }
int isoburn_read_iso_head | ( | struct burn_drive * | d, | |
int | lba, | |||
int * | image_blocks, | |||
char * | info, | |||
int | flag | |||
) |
Try whether the data at the given address look like a ISO 9660 image header and obtain its alleged size.
Depending on the info mode one other string of text information can be retrieved too.
d | The drive with the media to inspect | |
lba | The block number from where to read | |
image_blocks | The number of 2048 bytes blocks | |
info | Caller provided memory, enough to take eventual info reply | |
flag | bit0-7: info return mode 0= do not return anything in info (do not even touch it) 1= copy volume id to info (info needs 33 bytes) 2= |
Definition at line 1065 of file burn_wrap.c.
References isoburn_read_iso_head_parse().
Referenced by isoburn_emulate_toc(), isoburn_get_mount_params(), isoburn_read_image(), and isoburn_set_msc1().
01067 { 01068 unsigned char buffer[64*1024]; 01069 int ret, info_mode, capacity, role; 01070 off_t data_count; 01071 01072 info_mode= flag&255; 01073 *image_blocks= 0; 01074 if(flag&(1<<13)) { 01075 memcpy(buffer, info, 64*1024); 01076 } else { 01077 role = burn_drive_get_drive_role(d); 01078 ret = burn_get_read_capacity(d, &capacity, 0); 01079 if (ret <= 0 && role == 2) { 01080 /* Might be a block device on a system where libburn cannot determine its 01081 size. Try to read anyway. */ 01082 capacity = 0x7ffffff0; 01083 ret = 1; 01084 } 01085 if(ret > 0 && (off_t) capacity * (off_t) 2048 >= (off_t) (64 * 1024)) { 01086 ret = burn_read_data(d, ((off_t) lba) * (off_t) 2048, (char *) buffer, 01087 (off_t) 64*1024, &data_count, 2); /* no error messages */ 01088 } else 01089 ret= 0; 01090 if(ret<=0) 01091 return(-1*!!(flag&(1<<15))); 01092 if(info_mode==2) 01093 memcpy(info, buffer, 64*1024); 01094 } 01095 01096 if(flag&(1<<14)) { 01097 ret= isoburn_read_iso_head_parse(d, buffer, image_blocks, info, info_mode); 01098 if(ret<0) 01099 return(ret); 01100 if(ret>0) 01101 return(2); 01102 } 01103 ret= isoburn_read_iso_head_parse(d, buffer+32*1024, image_blocks, info, 01104 info_mode); 01105 if(ret<=0) 01106 return(ret); 01107 return(1); 01108 }
int isoburn_read_iso_head_parse | ( | struct burn_drive * | d, | |
unsigned char * | data, | |||
int * | image_blocks, | |||
char * | info, | |||
int | flag | |||
) |
Definition at line 1017 of file burn_wrap.c.
References isoburn_msgs_submit().
Referenced by isoburn_read_iso_head().
01019 { 01020 int i, info_mode; 01021 01022 /* is this an ISO image ? */ 01023 if(data[0]!=1) 01024 return(0); 01025 if(strncmp((char *) (data+1),"CD001",5)!=0) 01026 return(0); 01027 /* believe so */ 01028 01029 *image_blocks= data[80] | (data[81]<<8) | (data[82]<<16) | (data[83]<<24); 01030 info_mode= flag&255; 01031 if(info_mode==0) { 01032 ; 01033 } else if(info_mode==1) { 01034 strncpy(info, (char *) (data+40), 32); 01035 info[32]= 0; 01036 for(i= strlen(info)-1; i>=0; i--) 01037 if(info[i]!=' ') 01038 break; 01039 else 01040 info[i]= 0; 01041 } else if(info_mode==2) { 01042 ; 01043 } else { 01044 isoburn_msgs_submit(NULL, 0x00060000, 01045 "Program error: Unknown info mode with isoburn_read_iso_head()", 01046 0, "FATAL", 0); 01047 return(-1); 01048 } 01049 return(1); 01050 }
int isoburn_report_iso_error | ( | int | iso_error_code, | |
char | msg_text[], | |||
int | os_errno, | |||
char | min_severity[], | |||
int | flag | |||
) |
Definition at line 985 of file burn_wrap.c.
References isoburn__sev_to_text(), and isoburn__text_to_sev().
Referenced by isoburn_new(), isoburn_prepare_disc_aux(), and isoburn_read_image().
00987 { 00988 int error_code, iso_sev, min_sev, ret; 00989 char *sev_text_pt, *msg_text_pt= NULL; 00990 00991 error_code= iso_error_get_code(iso_error_code); 00992 if(error_code < 0x00030000 || error_code >= 0x00040000) 00993 error_code= (error_code & 0xffff) | 0x00050000; 00994 00995 if(iso_error_code<0) 00996 msg_text_pt= (char *) iso_error_to_msg(iso_error_code); 00997 if(msg_text_pt==NULL) 00998 msg_text_pt= msg_text; 00999 iso_sev= iso_error_get_severity(iso_error_code); 01000 sev_text_pt= min_severity; 01001 isoburn__text_to_sev(min_severity, &min_sev, 0); 01002 if(min_sev < iso_sev) 01003 isoburn__sev_to_text(iso_sev, &sev_text_pt, 0); 01004 ret= iso_msgs_submit(error_code, msg_text_pt, os_errno, sev_text_pt, 0); 01005 return(ret); 01006 }
int isoburn_set_msc1 | ( | struct burn_drive * | d, | |
int | adr_mode, | |||
char * | adr_value, | |||
int | flag | |||
) |
Set up isoburn_disc_get_msc1() to return a fabricated value.
This makes only sense between aquiring the drive and reading the image. After isoburn_read_image() it will confuse the coordination of libisoburn and libisofs. Note: Sessions and tracks are counted beginning with 1, not with 0.
d | The drive where msc1 is to be set | |
adr_mode | Determines how to interpret adr_value and to set msc1. If adr_value shall represent a number then decimal ASCII digits are expected. 0= start lba of last session in TOC, ignore adr_value 1= start lba of session number given by adr_value 2= start lba of track given number by adr_value 3= adr_value itself is the lba to be used 4= start lba of last session with volume id given by adr_value | |
adr_value | A string describing the value to be eventually used. | |
flag | Bitfield for control purposes. bit0= |
Definition at line 1633 of file burn_wrap.c.
References isoburn_toc_disc::disc, isoburn::fabricated_msc1, isoburn_find_emulator(), isoburn_get_track_lba(), isoburn_msgs_submit(), isoburn_read_iso_head(), isoburn_toc_disc_free(), isoburn_toc_disc_get_sessions(), isoburn_toc_drive_get_disc(), isoburn_toc_session_get_tracks(), and isoburn_toc_track_get_emul().
Referenced by isoburn_get_mount_params().
01635 { 01636 int ret, num_sessions, num_tracks, adr_num, i, j, total_tracks; 01637 int lba, best_lba, size, re_valid= 0, track_count= 0; 01638 time_t start_time= 0, last_pacifier= 0, now; 01639 char volid[33], msg[160]; 01640 struct isoburn *o; 01641 struct isoburn_toc_disc *disc= NULL; 01642 struct isoburn_toc_session **sessions= NULL; 01643 struct isoburn_toc_track **tracks= NULL; 01644 static char mode_names[][20]= {"auto", "session", "track", "lba", "volid"}; 01645 static int max_mode_names= 4; 01646 regex_t re; 01647 regmatch_t match[1]; 01648 01649 ret= isoburn_find_emulator(&o, d, 0); 01650 if(ret<0) 01651 return(-1); 01652 if(o==NULL) 01653 return(-1); 01654 01655 start_time= last_pacifier= time(NULL); 01656 adr_num= atoi(adr_value); 01657 if(adr_mode!=3 || (flag & 2)) { 01658 disc= isoburn_toc_drive_get_disc(d); 01659 if(disc==NULL) { 01660 not_found:; 01661 if(adr_mode<0 || adr_mode>max_mode_names) 01662 goto unknown_mode; 01663 sprintf(msg, "Failed to find %s %s", mode_names[adr_mode], 01664 strlen(adr_value)<=80 ? adr_value : "-oversized-string-"); 01665 isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0); 01666 ret= 0; goto ex; 01667 } 01668 sessions= isoburn_toc_disc_get_sessions(disc, &num_sessions); 01669 if(sessions==NULL || num_sessions<=0) 01670 goto not_found; 01671 } 01672 if(adr_mode==0) { 01673 /* Set fabricated_msc1 to last session in TOC */ 01674 tracks= isoburn_toc_session_get_tracks(sessions[num_sessions-1], 01675 &num_tracks); 01676 if(tracks==NULL || num_tracks<=0) 01677 goto not_found; 01678 isoburn_get_track_lba(tracks[0], &(o->fabricated_msc1), 0); 01679 01680 } else if(adr_mode==1) { 01681 /* Use adr_num as session index (first session is 1, not 0) */ 01682 if(adr_num<1 || adr_num>num_sessions) 01683 goto not_found; 01684 tracks= isoburn_toc_session_get_tracks(sessions[adr_num-1], &num_tracks); 01685 if(tracks==NULL || num_tracks<=0) 01686 goto not_found; 01687 isoburn_get_track_lba(tracks[0], &(o->fabricated_msc1), 0); 01688 01689 } else if(adr_mode==2) { 01690 /* use adr_num as track index */ 01691 total_tracks= 0; 01692 for(i=0; i<num_sessions; i++) { 01693 tracks= isoburn_toc_session_get_tracks(sessions[i], &num_tracks); 01694 if(tracks==NULL) 01695 continue; 01696 for(j= 0; j<num_tracks; j++) { 01697 total_tracks++; 01698 if(total_tracks==adr_num) { 01699 isoburn_get_track_lba(tracks[j], &(o->fabricated_msc1), 0); 01700 ret= 1; goto ex; 01701 } 01702 } 01703 } 01704 goto not_found; 01705 01706 } else if(adr_mode==3) { 01707 o->fabricated_msc1= adr_num; 01708 if((flag & 1) && o->fabricated_msc1 >= 16) { 01709 /* adr_num is possibly 16 blocks too high */ 01710 ret= isoburn_read_iso_head(d, o->fabricated_msc1, &size,volid, 1|(1<<14)); 01711 if(ret==2) 01712 o->fabricated_msc1-= 16; 01713 } 01714 } else if(adr_mode==4) { 01715 /* search for volume id that is equal to adr_value */ 01716 if(flag & 4) { 01717 ret= regcomp(&re, adr_value, 0); 01718 if(ret != 0) 01719 flag&= ~4; 01720 else 01721 re_valid= 1; 01722 } 01723 best_lba= -1; 01724 for(i=0; i<num_sessions; i++) { 01725 tracks= isoburn_toc_session_get_tracks(sessions[i], &num_tracks); 01726 if(tracks==NULL) 01727 continue; 01728 for(j= 0; j<num_tracks; j++) { 01729 now= time(NULL); 01730 if(now - last_pacifier >= 5 && track_count > 0) { 01731 last_pacifier= now; 01732 sprintf(msg, 01733 "Scanned %d tracks for matching volid in %.f seconds", 01734 track_count, (double) (now - start_time)); 01735 isoburn_msgs_submit(o, 0x00060000, msg, 0, "UPDATE", 0); 01736 } 01737 track_count++; 01738 ret= isoburn_toc_track_get_emul(tracks[0], &lba, &size, volid, 0); 01739 if(ret < 0) 01740 continue; 01741 if(ret == 0) { 01742 isoburn_get_track_lba(tracks[0], &lba, 0); 01743 ret= isoburn_read_iso_head(d, lba, &size, volid, 1); 01744 if(ret<=0) 01745 continue; 01746 } 01747 if(flag & 4) { 01748 ret= regexec(&re, volid, 1, match, 0); 01749 if(ret != 0) 01750 continue; 01751 } else { 01752 if(strcmp(volid, adr_value)!=0) 01753 continue; 01754 } 01755 best_lba= lba; 01756 } 01757 } 01758 if(best_lba<0) 01759 goto not_found; 01760 o->fabricated_msc1= best_lba; 01761 01762 } else { 01763 unknown_mode:; 01764 sprintf(msg, "Program error: Unknown msc1 address mode %d", adr_mode); 01765 isoburn_msgs_submit(o, 0x00060000, msg, 0, "FATAL", 0); 01766 ret= 0; goto ex; 01767 } 01768 ret= 1; 01769 ex:; 01770 if(start_time != last_pacifier && track_count > 0) { 01771 now= time(NULL); 01772 sprintf(msg, 01773 "Scanned %d tracks for matching volid in %.f seconds", 01774 track_count, (double) (now - start_time)); 01775 isoburn_msgs_submit(o, 0x00060000, msg, 0, "UPDATE", 0); 01776 } 01777 if(disc!=NULL) 01778 isoburn_toc_disc_free(disc); 01779 if((flag & 4) && re_valid) 01780 regfree(&re); 01781 return(ret); 01782 }
int isoburn_set_msgs_submit | ( | int(*)(void *handle, int error_code, char msg_text[], int os_errno, char severity[], int flag) | msgs_submit, | |
void * | submit_handle, | |||
int | submit_flag, | |||
int | flag | |||
) |
Note: Above version numbers are also recorded in configure.ac because libtool wants them as parameters at build time.
For the library compatibility check, ISOBURN_*_VERSION in configure.ac are not decisive. Only the three numbers here do matter. Usage discussion:Some developers of the libburnia project have differing opinions how to ensure the compatibility of libaries and applications.
It is about whether to use at compile time and at runtime the version numbers isoburn_header_version_* provided here. Thomas Schmitt advises to use them. Vreixo Formoso advises to use other means.
At compile time:
Vreixo Formoso advises to leave proper version matching to properly programmed checks in the the application's build system, which will eventually refuse compilation.
Thomas Schmitt advises to use the macros defined here for comparison with the application's requirements of library revisions and to eventually break compilation.
Both advises are combinable. I.e. be master of your build system and have if checks in the source code of your application, nevertheless.
At runtime (via *_is_compatible()):
Vreixo Formoso advises to compare the application's requirements of library revisions with the runtime library. This is to allow runtime libraries which are young enough for the application but too old for the lib*.h files seen at compile time.
Thomas Schmitt advises to compare the header revisions defined here with the runtime library. This is to enforce a strictly monotonous chain of revisions from app to header to library, at the cost of excluding some older libraries.
These two advises are mutually exclusive.
-----------------------------------------------------
For an implementation of the Thomas Schmitt approach, see libisoburn/burn_wrap.c : isoburn_initialize() This connects libisoburn as "application" with libisofs as "library".
The compatible part of Vreixo Formoso's approach is implemented in configure.ac LIBBURN_REQUIRED, LIBISOFS_REQUIRED. In isoburn_initialize() it would rather test by iso_lib_is_compatible(isoburn_libisofs_req_major,... than by iso_lib_is_compatible(iso_lib_header_version_major,... and would leave out the ugly compile time traps. Announce to the library an application provided method for immediate delivery of messages. It is used when no drive is affected directly or if the drive has no own msgs_submit() method attached by isoburn_drive_set_msgs_submit. If no method is preset or if the method is set to NULL then libisoburn delivers its messages through the message queue of libburn.
msgs_submit | The function call which implements the method | |
submit_handle | Handle to be used as first argument of msgs_submit | |
submit_flag | Flag to be used as last argument of msgs_submit | |
flag | Unused yet, submit 0 |
Definition at line 231 of file burn_wrap.c.
References libisoburn_default_msgs_submit, libisoburn_default_msgs_submit_flag, libisoburn_default_msgs_submit_handle, and isoburn::msgs_submit.
00235 { 00236 libisoburn_default_msgs_submit= msgs_submit; 00237 libisoburn_default_msgs_submit_handle= submit_handle; 00238 libisoburn_default_msgs_submit_flag= submit_flag; 00239 return(1); 00240 }
int isoburn_set_start_byte | ( | struct isoburn * | o, | |
off_t | value, | |||
int | flag | |||
) |
Set the start address for an emulated add-on session.
The value will be rounded up to the alignment necessary for the media. The aligned value will be divided by 2048 and then put into o->nwa .
o | The isoburn object to be programmed. | |
value | The start address in bytes | |
flag | unused yet |
Definition at line 847 of file burn_wrap.c.
References isoburn::drive, isoburn_msgs_submit(), Libisoburn_nwa_alignemenT, isoburn::min_start_byte, and isoburn::nwa.
Referenced by isoburn_start_emulation().
00848 { 00849 int ret; 00850 struct burn_drive *drive = o->drive; 00851 struct burn_multi_caps *caps= NULL; 00852 00853 ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); 00854 if(ret<=0) 00855 goto ex; 00856 if(!caps->start_adr) { 00857 isoburn_msgs_submit(o, 0x00060000, 00858 "Cannot set start byte address with this type of media", 00859 0, "FAILURE", 0); 00860 {ret= 0; goto ex;} 00861 } 00862 o->min_start_byte= value; 00863 if(value % caps->start_alignment) 00864 value+= caps->start_alignment - (value % caps->start_alignment); 00865 o->nwa= value/2048; 00866 /* If suitable for media alignment, round up to Libisoburn_nwa_alignemenT */ 00867 if((o->nwa % Libisoburn_nwa_alignemenT) && 00868 ((Libisoburn_nwa_alignemenT*2048) % caps->start_alignment)==0 ) 00869 o->nwa+= Libisoburn_nwa_alignemenT - (o->nwa % Libisoburn_nwa_alignemenT); 00870 ret= 1; 00871 ex: 00872 if(caps!=NULL) 00873 burn_disc_free_multi_caps(&caps); 00874 return(ret); 00875 }
int isoburn_toc_destroy_arrays | ( | struct isoburn_toc_disc * | o, | |
int | flag | |||
) |
Definition at line 1339 of file burn_wrap.c.
References isoburn_toc_disc::session_pointers, isoburn_toc_disc::sessions, isoburn_toc_disc::track_pointers, and isoburn_toc_disc::tracks.
Referenced by isoburn_toc_disc_free(), and isoburn_toc_new_arrays().
01340 { 01341 if(o->sessions!=NULL) 01342 free((char *) o->sessions); 01343 o->sessions= NULL; 01344 if(o->session_pointers!=NULL) 01345 free((char *) o->session_pointers); 01346 o->session_pointers= NULL; 01347 if(o->tracks!=NULL) 01348 free((char *) o->tracks); 01349 o->tracks= NULL; 01350 if(o->track_pointers!=NULL) 01351 free((char *) o->track_pointers); 01352 o->track_pointers= NULL; 01353 return(1); 01354 }
void isoburn_toc_disc_free | ( | struct isoburn_toc_disc * | disc | ) |
Release the memory associated with a master handle of media.
The handle is invalid afterwards and may not be used any more. Wrapper for: burn_disc_free()
disc | The master handle of the media |
Definition at line 1588 of file burn_wrap.c.
References isoburn_toc_disc::disc, and isoburn_toc_destroy_arrays().
Referenced by isoburn_set_msc1(), and isoburn_welcome_media().
01589 { 01590 if(d->disc!=NULL) 01591 burn_disc_free(d->disc); 01592 isoburn_toc_destroy_arrays(d, 0); 01593 free((char *) d); 01594 }
int isoburn_toc_disc_get_sectors | ( | struct isoburn_toc_disc * | disc | ) |
Tell the number of 2048 byte blocks covered by the table of content.
This number includes the eventual gaps between sessions and tracks. So this call is not really a wrapper for burn_disc_get_sectors().
disc | The master handle of the media |
Definition at line 1443 of file burn_wrap.c.
References isoburn_toc_disc::disc, isoburn_toc_entry::next, isoburn_toc_entry::start_lba, isoburn_toc_disc::toc, and isoburn_toc_entry::track_blocks.
01444 { 01445 struct isoburn_toc_entry *t; 01446 int ret= 0, num_sessions, num_tracks; 01447 struct burn_session **sessions; 01448 struct burn_track **tracks; 01449 struct burn_toc_entry entry; 01450 01451 if(disc==NULL) 01452 return(0); 01453 if(disc->toc!=NULL) { 01454 for(t= disc->toc; t!=NULL; t= t->next) 01455 ret= t->start_lba + t->track_blocks; 01456 } else if(disc->disc!=NULL) { 01457 sessions= burn_disc_get_sessions(disc->disc, &num_sessions); 01458 if(num_sessions > 0) { 01459 tracks = burn_session_get_tracks(sessions[num_sessions - 1], 01460 &num_tracks); 01461 if(num_tracks > 0) { 01462 burn_track_get_entry(tracks[num_tracks - 1], &entry); 01463 if(entry.extensions_valid & 1) 01464 ret= entry.start_lba + entry.track_blocks; 01465 } 01466 } 01467 /* 01468 ret= burn_disc_get_sectors(disc->disc); 01469 */ 01470 } 01471 return(ret); 01472 }
struct isoburn_toc_session** isoburn_toc_disc_get_sessions | ( | struct isoburn_toc_disc * | disc, | |
int * | num | |||
) | [read] |
Get the array of session handles from the table of content.
Wrapper for: burn_disc_get_sessions()
disc | The master handle of the media | |
num | returns the number of sessions in the array |
Definition at line 1475 of file burn_wrap.c.
References isoburn_toc_disc::session_count, and isoburn_toc_disc::session_pointers.
Referenced by isoburn_get_mount_params(), isoburn_set_msc1(), and isoburn_welcome_media().
01477 { 01478 *num= disc->session_count; 01479 return(disc->session_pointers); 01480 }
struct isoburn_toc_disc* isoburn_toc_drive_get_disc | ( | struct burn_drive * | d | ) | [read] |
Obtain a master handle for the table of content.
This handle governs allocated resources which have to be released by isoburn_toc_disc_free() when no longer needed. Wrapper for: burn_drive_get_disc()
d | The drive with the media to inspect |
Definition at line 1357 of file burn_wrap.c.
References isoburn_toc_disc::disc, isoburn_find_emulator(), isoburn_toc_new_arrays(), isoburn_toc_entry::next, isoburn_toc_session::session, isoburn_toc_disc::session_count, isoburn_toc_disc::session_pointers, isoburn_toc_disc::sessions, isoburn::toc, isoburn_toc_disc::toc, isoburn_toc_track::toc_entry, isoburn_toc_session::toc_entry, isoburn_toc_track::track, isoburn_toc_session::track_count, isoburn_toc_disc::track_count, isoburn_toc_session::track_pointers, isoburn_toc_disc::track_pointers, and isoburn_toc_disc::tracks.
Referenced by isoburn_get_mount_params(), isoburn_set_msc1(), and isoburn_welcome_media().
01358 { 01359 int ret, session_count= 0, track_count= 0, num_tracks= 0, i, j; 01360 struct isoburn *o; 01361 struct isoburn_toc_entry *t; 01362 struct isoburn_toc_disc *toc_disc= NULL; 01363 struct burn_session **s; 01364 struct burn_track **tracks; 01365 01366 toc_disc= calloc(1, sizeof(struct isoburn_toc_disc)); 01367 if(toc_disc==NULL) 01368 return(NULL); 01369 toc_disc->disc= NULL; 01370 toc_disc->sessions= NULL; 01371 toc_disc->session_pointers= NULL; 01372 toc_disc->tracks= NULL; 01373 toc_disc->track_pointers= NULL; 01374 toc_disc->session_count= 0; 01375 toc_disc->track_count= 0; 01376 toc_disc->toc= NULL; 01377 01378 /* is the media emulated multi-session ? */ 01379 ret= isoburn_find_emulator(&o, d, 0); 01380 if(ret<0) 01381 goto libburn; 01382 if(o->toc==NULL) 01383 goto libburn; 01384 01385 /* This is an emulated TOC */ 01386 toc_disc->toc= o->toc; 01387 for(t= toc_disc->toc; t!=NULL; t= t->next) 01388 session_count++; 01389 ret= isoburn_toc_new_arrays(toc_disc, session_count, session_count, 0); 01390 if(ret<=0) 01391 goto failure; 01392 t= toc_disc->toc; 01393 for(i= 0; i<session_count; i++) { 01394 toc_disc->sessions[i].track_pointers= toc_disc->track_pointers+i; 01395 toc_disc->sessions[i].track_count= 1; 01396 toc_disc->sessions[i].toc_entry= t; 01397 toc_disc->session_pointers[i]= toc_disc->sessions+i; 01398 toc_disc->tracks[i].toc_entry= t; 01399 toc_disc->track_pointers[i]= toc_disc->tracks+i; 01400 t= t->next; 01401 } 01402 toc_disc->session_count= session_count; 01403 toc_disc->track_count= session_count; 01404 return(toc_disc); 01405 01406 libburn:; 01407 /* This is a libburn provided TOC */ 01408 toc_disc->disc= burn_drive_get_disc(d); 01409 if(toc_disc->disc == NULL) { 01410 failure:; 01411 free((char *) toc_disc); 01412 return(NULL); 01413 } 01414 s= burn_disc_get_sessions(toc_disc->disc, &session_count); 01415 for(i= 0; i<session_count; i++) { 01416 tracks = burn_session_get_tracks(s[i], &num_tracks); 01417 track_count+= num_tracks; 01418 } 01419 if(session_count<=0 || track_count<=0) 01420 goto failure; 01421 ret= isoburn_toc_new_arrays(toc_disc, session_count, track_count, 0); 01422 if(ret<=0) 01423 goto failure; 01424 track_count= 0; 01425 for(i= 0; i<session_count; i++) { 01426 tracks = burn_session_get_tracks(s[i], &num_tracks); 01427 toc_disc->sessions[i].session= s[i]; 01428 toc_disc->sessions[i].track_pointers= toc_disc->track_pointers+track_count; 01429 toc_disc->sessions[i].track_count= num_tracks; 01430 toc_disc->session_pointers[i]= toc_disc->sessions+i; 01431 for(j= 0; j<num_tracks; j++) { 01432 toc_disc->tracks[track_count+j].track= tracks[j]; 01433 toc_disc->track_pointers[track_count+j]= toc_disc->tracks+(track_count+j); 01434 } 01435 track_count+= num_tracks; 01436 } 01437 toc_disc->session_count= session_count; 01438 toc_disc->track_count= track_count; 01439 return(toc_disc); 01440 }
int isoburn_toc_entry_finish | ( | struct burn_toc_entry * | entry, | |
int | session_no, | |||
int | track_no, | |||
int | flag | |||
) |
Definition at line 1502 of file burn_wrap.c.
Referenced by isoburn_toc_session_get_leadout_entry(), and isoburn_toc_track_get_entry().
01504 { 01505 int pmin, psec, pframe; 01506 01507 entry->extensions_valid= 1; 01508 entry->adr= 1; 01509 entry->control= 4; 01510 entry->session= session_no & 255; 01511 entry->session_msb= (session_no >> 8) & 255; 01512 entry->point= track_no & 255; 01513 entry->point_msb= (track_no >> 8) & 255; 01514 01515 burn_lba_to_msf(entry->start_lba, &pmin, &psec, &pframe); 01516 if(pmin<=255) 01517 entry->pmin= pmin; 01518 else 01519 entry->pmin= 255; 01520 entry->psec= psec; 01521 entry->pframe= pframe; 01522 return(1); 01523 }
int isoburn_toc_new_arrays | ( | struct isoburn_toc_disc * | o, | |
int | session_count, | |||
int | track_count, | |||
int | flag | |||
) |
Definition at line 1306 of file burn_wrap.c.
References isoburn_toc_destroy_arrays(), isoburn_toc_session::session, isoburn_toc_disc::session_pointers, isoburn_toc_disc::sessions, isoburn_toc_track::toc_entry, isoburn_toc_session::toc_entry, isoburn_toc_track::track, isoburn_toc_session::track_count, isoburn_toc_session::track_pointers, isoburn_toc_disc::track_pointers, and isoburn_toc_disc::tracks.
Referenced by isoburn_toc_drive_get_disc().
01308 { 01309 int i; 01310 int isoburn_toc_destroy_arrays(struct isoburn_toc_disc *o, int flag); 01311 01312 o->sessions= calloc(session_count, sizeof(struct isoburn_toc_session)); 01313 o->session_pointers= 01314 calloc(session_count, sizeof(struct isoburn_toc_session *)); 01315 o->tracks= calloc(track_count, sizeof(struct isoburn_toc_track)); 01316 o->track_pointers= calloc(track_count, sizeof(struct isoburn_toc_track *)); 01317 if(o->sessions!=NULL && o->session_pointers!=NULL && 01318 o->tracks!=NULL && o->track_pointers!=NULL) { 01319 for(i= 0; i<session_count; i++) { 01320 o->sessions[i].session= NULL; 01321 o->sessions[i].track_pointers= NULL; 01322 o->sessions[i].track_count= 0; 01323 o->sessions[i].toc_entry= NULL; 01324 o->session_pointers[i]= NULL; 01325 } 01326 for(i= 0; i<track_count; i++) { 01327 o->tracks[i].track= NULL; 01328 o->tracks[i].toc_entry= NULL; 01329 o->track_pointers[i]= NULL; 01330 } 01331 return(1); 01332 } 01333 /* failed */ 01334 isoburn_toc_destroy_arrays(o, 0); 01335 return(-1); 01336 }
void isoburn_toc_session_get_leadout_entry | ( | struct isoburn_toc_session * | s, | |
struct burn_toc_entry * | entry | |||
) |
Obtain a copy of the entry which describes the end of a particular session.
Wrapper for: burn_session_get_leadout_entry()
s | The session handle | |
entry | A pointer to memory provided by the caller. It will be filled with info according to struct burn_toc_entry as defined in libburn.h |
Definition at line 1526 of file burn_wrap.c.
References isoburn_toc_entry_finish(), isoburn_toc_entry::session, isoburn_toc_session::session, isoburn_toc_entry::start_lba, isoburn_toc_track::toc_entry, isoburn_toc_session::toc_entry, isoburn_toc_entry::track_blocks, isoburn_toc_session::track_count, isoburn_toc_entry::track_no, and isoburn_toc_session::track_pointers.
01528 { 01529 struct isoburn_toc_track *t; 01530 01531 if(s==NULL) 01532 return; 01533 if(s->session!=NULL && s->toc_entry==NULL) { 01534 burn_session_get_leadout_entry(s->session, entry); 01535 return; 01536 } 01537 if(s->track_count<=0 || s->track_pointers==NULL || s->toc_entry==NULL) 01538 return; 01539 t= s->track_pointers[s->track_count-1]; 01540 entry->start_lba= t->toc_entry->start_lba + t->toc_entry->track_blocks; 01541 entry->track_blocks= 0; 01542 isoburn_toc_entry_finish(entry, s->toc_entry->session, t->toc_entry->track_no, 01543 0); 01544 }
int isoburn_toc_session_get_sectors | ( | struct isoburn_toc_session * | s | ) |
Tell the number of 2048 byte blocks covered by a particular session.
Wrapper for: burn_session_get_sectors()
s | The session handle |
Definition at line 1483 of file burn_wrap.c.
References isoburn_toc_entry::next, isoburn_toc_session::session, isoburn_toc_session::toc_entry, isoburn_toc_entry::track_blocks, and isoburn_toc_session::track_count.
01484 { 01485 struct isoburn_toc_entry *t; 01486 int count= 0, i; 01487 01488 if(s==NULL) 01489 return(0); 01490 if(s->toc_entry!=NULL) { 01491 t= s->toc_entry; 01492 for(i= 0; i<s->track_count; i++) { 01493 count+= t->track_blocks; 01494 t= t->next; 01495 } 01496 } else if(s->session!=NULL) 01497 count= burn_session_get_sectors(s->session); 01498 return(count); 01499 }
struct isoburn_toc_track** isoburn_toc_session_get_tracks | ( | struct isoburn_toc_session * | s, | |
int * | num | |||
) | [read] |
Get the array of track handles from a particular session.
Wrapper for: burn_session_get_tracks()
s | The session handle | |
num | returns the number of tracks in the array |
Definition at line 1547 of file burn_wrap.c.
References isoburn_toc_session::track_count, and isoburn_toc_session::track_pointers.
Referenced by isoburn_get_mount_params(), isoburn_set_msc1(), and isoburn_welcome_media().
01549 { 01550 *num= s->track_count; 01551 return(s->track_pointers); 01552 }
int isoburn_toc_track_get_emul | ( | struct isoburn_toc_track * | t, | |
int * | start_lba, | |||
int * | image_blocks, | |||
char | volid[33], | |||
int | flag | |||
) |
Obtain eventual ISO image parameters of an emulated track.
This info was gained with much effort and thus gets cached in the track object. If this call returns 1 then one can save a call of isoburn_read_iso_head() with return mode 1 which could cause an expensive read operation.
t | The track handle | |
start_lba | Returns the start address of the ISO session | |
image_blocks | Returns the number of 2048 bytes blocks | |
volid | Caller provided memory for the volume id | |
flag | unused yet, submit 0 |
Definition at line 1573 of file burn_wrap.c.
References isoburn_toc_entry::start_lba, isoburn_toc_track::toc_entry, isoburn_toc_entry::track_blocks, and isoburn_toc_entry::volid.
Referenced by isoburn_set_msc1().
void isoburn_toc_track_get_entry | ( | struct isoburn_toc_track * | t, | |
struct burn_toc_entry * | entry | |||
) |
Obtain a copy of the entry which describes a particular track.
Wrapper for: burn_track_get_entry()
t | The track handle | |
entry | A pointer to memory provided by the caller. It will be filled with info according to struct burn_toc_entry as defined in libburn.h |
Definition at line 1555 of file burn_wrap.c.
References isoburn_toc_entry_finish(), isoburn_toc_entry::session, isoburn_toc_entry::start_lba, isoburn_toc_track::toc_entry, isoburn_toc_track::track, isoburn_toc_entry::track_blocks, and isoburn_toc_entry::track_no.
Referenced by isoburn_get_track_lba().
01557 { 01558 if(t==0) 01559 return; 01560 if(t->track!=NULL && t->toc_entry==NULL) { 01561 burn_track_get_entry(t->track, entry); 01562 return; 01563 } 01564 if(t->toc_entry==NULL) 01565 return; 01566 entry->start_lba= t->toc_entry->start_lba; 01567 entry->track_blocks= t->toc_entry->track_blocks; 01568 isoburn_toc_entry_finish(entry, t->toc_entry->session, t->toc_entry->track_no, 01569 0); 01570 }
static int isoburn_welcome_media | ( | struct isoburn ** | o, | |
struct burn_drive * | d, | |||
int | flag | |||
) | [static] |
Examines the media and sets appropriate emulation if needed.
flag | bit0= pretent blank on overwriteable media bit3= if the drive reports a -ROM profile then try to read table of content by scanning for ISO image headers. bit4= do not emulate TOC on overwriteable media bit5= ignore ACL from external filesystems bit6= ignore POSIX Extended Attributes from external filesystems bit7= pretend -ROM and scan for table of content |
Definition at line 272 of file burn_wrap.c.
References isoburn_toc_disc::disc, isoburn_emulate_toc(), isoburn_is_intermediate_dvd_rw(), isoburn_msgs_submit(), isoburn_new(), isoburn_start_emulation(), isoburn_toc_disc_free(), isoburn_toc_disc_get_sessions(), isoburn_toc_drive_get_disc(), isoburn_toc_session_get_tracks(), libisoburn_default_msgs_submit, libisoburn_default_msgs_submit_flag, libisoburn_default_msgs_submit_handle, isoburn_toc_entry::next, isoburn::nwa, and isoburn_toc_entry::start_lba.
Referenced by isoburn_drive_aquire(), and isoburn_drive_grab().
00274 { 00275 int ret, lba, nwa, profile, readonly= 0; 00276 struct burn_multi_caps *caps= NULL; 00277 struct isoburn_toc_entry *t; 00278 char profile_name[80]; 00279 struct isoburn_toc_disc *disc= NULL; 00280 struct isoburn_toc_session **sessions; 00281 struct isoburn_toc_track **tracks; 00282 int num_sessions= 0, num_tracks= 0, track_count= 0, session_no= 0; 00283 char msg[80]; 00284 00285 profile_name[0]= 0; 00286 ret= burn_disc_get_profile(d, &profile, profile_name); 00287 if(ret<=0) 00288 profile= 0x00; 00289 ret= burn_disc_get_multi_caps(d, BURN_WRITE_NONE, &caps, 0); 00290 if(ret<0) /* == 0 is read-only media, but it is too early to reject it here */ 00291 goto ex; 00292 if(ret==0 || (flag & 128)) 00293 readonly= 1; 00294 if(flag & 128) 00295 flag = (flag & ~ 16) | 8; 00296 00297 ret= isoburn_new(o, 0); 00298 if(ret<=0) 00299 goto ex; 00300 (*o)->drive= d; 00301 (*o)->msgs_submit= libisoburn_default_msgs_submit; 00302 (*o)->msgs_submit_handle= libisoburn_default_msgs_submit_handle; 00303 (*o)->msgs_submit_flag= libisoburn_default_msgs_submit_flag; 00304 iso_image_set_ignore_aclea((*o)->image, (flag >> 5 ) & 3); 00305 00306 #ifdef Hardcoded_cd_rW 00307 /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ 00308 caps->start_adr= 0; 00309 (*o)->fabricated_disc_status= BURN_DISC_APPENDABLE; 00310 #endif 00311 00312 if(caps->start_adr) 00313 (*o)->emulation_mode= 1; 00314 if(caps->start_adr && !readonly) { /* set emulation to overwriteable */ 00315 ret= isoburn_is_intermediate_dvd_rw(d, 0); 00316 if(ret>0) { 00317 (*o)->min_start_byte= 0; 00318 (*o)->nwa= 0; 00319 (*o)->zero_nwa= 0; 00320 } 00321 if(flag&1) { 00322 (*o)->nwa= (*o)->zero_nwa; 00323 (*o)->fabricated_disc_status= BURN_DISC_BLANK; 00324 } else { 00325 ret= isoburn_start_emulation(*o, 0); 00326 if(ret<=0) { 00327 (*o)->emulation_mode= -1; 00328 goto ex; 00329 } 00330 /* try to read emulated toc */ 00331 ret= isoburn_emulate_toc(d, flag & 16); 00332 if(ret<0) { 00333 (*o)->emulation_mode= -1; 00334 goto ex; 00335 } 00336 } 00337 } else { 00338 00339 /* >>> recognize unsuitable media (but allow read-only media) */; 00340 00341 if(readonly) { 00342 (*o)->fabricated_disc_status= BURN_DISC_FULL; 00343 /* This might be overwriteable media in a -ROM drive. 00344 Pitfall: 00345 Multi-session media which bear a xorriso image for overwriteables 00346 in their first session would get a TOC of that first image rather 00347 than of the media. 00348 It is not possible to distinguish a BD-RE from a single session 00349 BD-R with an image for overwriteables. But as soon as the media 00350 bears 2 logical tracks it cannot be overwriteable. 00351 So count the number of tracks first. 00352 */ 00353 disc= isoburn_toc_drive_get_disc(d); 00354 if(disc != NULL) { 00355 sessions= isoburn_toc_disc_get_sessions(disc, &num_sessions); 00356 for(session_no= 0; session_no < num_sessions; session_no++) { 00357 tracks= isoburn_toc_session_get_tracks(sessions[session_no], 00358 &num_tracks); 00359 track_count+= num_tracks; 00360 } 00361 isoburn_toc_disc_free(disc); 00362 } 00363 00364 sprintf(msg, "ROM media has libburn track count = %d", track_count); 00365 isoburn_msgs_submit(*o, 0x00060000, msg, 0, "DEBUG", 0); 00366 00367 if((flag & 16) || track_count >= 2) { 00368 ret= 0; /* toc emulation off, or not overwriteable */ 00369 } else { 00370 ret= isoburn_emulate_toc(d, 1); 00371 if(ret<0) 00372 goto ex; 00373 else if(ret > 0) 00374 (*o)->emulation_mode= 1; 00375 } 00376 if(ret == 0 && (profile != 0x08 || (flag & 128)) && (flag & 8)) { 00377 /* This might also be multi-session media which do not 00378 get shown with a decent TOC. 00379 CD-R TOC (profile 0x08) can be trusted. Others not. 00380 Do a scan search of ISO headers. 00381 */ 00382 ret= isoburn_emulate_toc(d, 1|2); 00383 if(ret<0) 00384 goto ex; 00385 if(ret>0) { /* point msc1 to last session */ 00386 if((*o)->toc!=NULL) { 00387 for(t= (*o)->toc; t->next!=NULL; t= t->next); 00388 (*o)->fabricated_msc1= t->start_lba; 00389 } 00390 } 00391 } 00392 } 00393 #ifdef Hardcoded_cd_rW 00394 (*o)->nwa= Hardcoded_cd_rw_nwA; 00395 #else 00396 ret= burn_disc_track_lba_nwa(d, NULL, 0, &lba, &nwa); 00397 if(ret>0) 00398 (*o)->nwa= nwa; 00399 #endif 00400 00401 } 00402 00403 ret= 1; 00404 ex: 00405 if(caps!=NULL) 00406 burn_disc_free_multi_caps(&caps); 00407 return(ret); 00408 }
struct isoburn* isoburn_list_start |
int(* libisoburn_default_msgs_submit)(void *handle, int error_code, char msg_text[], int os_errno, char severity[], int flag) |
Referenced by isoburn_msgs_submit(), isoburn_set_msgs_submit(), and isoburn_welcome_media().
Definition at line 48 of file isoburn.c.
Referenced by isoburn_msgs_submit(), isoburn_set_msgs_submit(), and isoburn_welcome_media().
Definition at line 47 of file isoburn.c.
Referenced by isoburn_msgs_submit(), isoburn_set_msgs_submit(), and isoburn_welcome_media().