From dc2a8f1ab0b44afc9870a85fd28271c68f8a275c Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 10 Jan 2008 15:20:57 +0000 Subject: [PATCH] Begin of porting to next generation libisofs --- Makefile.am | 13 +- ng_src/burn_wrap.c | 453 +++++++++++++++++++++++++++++++++++++++ ng_src/data_source.c | 74 +++++++ ng_src/isoburn.c | 335 +++++++++++++++++++++++++++++ ng_src/isoburn.h | 134 ++++++++++++ ng_src/isofs_wrap.c | 314 +++++++++++++++++++++++++++ ng_src/libisoburn.h | 379 ++++++++++++++++++++++++++++++++ test/xorriso_timestamp.h | 2 +- 8 files changed, 1698 insertions(+), 6 deletions(-) create mode 100644 ng_src/burn_wrap.c create mode 100644 ng_src/data_source.c create mode 100644 ng_src/isoburn.c create mode 100644 ng_src/isoburn.h create mode 100644 ng_src/isofs_wrap.c create mode 100644 ng_src/libisoburn.h diff --git a/Makefile.am b/Makefile.am index 337dd026..c0432869 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,12 +25,15 @@ libinclude_HEADERS = \ ## ========================================================================= ## ## Build test applications -noinst_PROGRAMS = \ - test/test +noinst_PROGRAMS = -test_test_CPPFLAGS = -Ilibisofs -Ilibburn -Ilibisoburn -test_test_LDADD = $(src_libisoburn_la_OBJECTS) $(THREAD_LIBS) -lburn -lisofs -test_test_SOURCES = test/test.c +# ts A80110 : I am too lazy for now to apply the ng patch to test.c . +# noinst_PROGRAMS = +# test/test + +# test_test_CPPFLAGS = -Ilibisofs -Ilibburn -Ilibisoburn +# test_test_LDADD = $(src_libisoburn_la_OBJECTS) $(THREAD_LIBS) -lburn -lisofs +# test_test_SOURCES = test/test.c bin_PROGRAMS = diff --git a/ng_src/burn_wrap.c b/ng_src/burn_wrap.c new file mode 100644 index 00000000..cae78ba5 --- /dev/null +++ b/ng_src/burn_wrap.c @@ -0,0 +1,453 @@ + +/* + cc -g -c \ + -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE \ + burn_wrap.c +*/ +/* libburn wrappers for libisoburn + + Copyright 2007 Thomas Schmitt, +*/ + +/* <<< A70929 : hardcoded CD-RW with fabricated -msinfo +#define Hardcoded_cd_rW 1 +#define Hardcoded_cd_rw_c1 12999 +#define Hardcoded_cd_rw_nwA 152660 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +/* >>> NG */ +#include + +#include "libisoburn.h" +#include "isoburn.h" + + +/* The global list of isoburn objects. Usually there is only one. */ +extern struct isoburn *isoburn_list_start; /* in isoburn.c */ + + +int isoburn_initialize(void) +{ + if(!burn_initialize()) + return(0); + isoburn_destroy_all(&isoburn_list_start, 0); /* isoburn_list_start= NULL */ + + return(1); +} + + +/** Examine the media and sets appropriate emulation if needed. +*/ +static int isoburn_welcome_media(struct isoburn **o, struct burn_drive *d, + int flag) +{ + int ret, lba, nwa; + struct burn_multi_caps *caps= NULL; + + ret= burn_disc_get_multi_caps(d, BURN_WRITE_NONE, &caps, 0); + if(ret<0) /* == 0 is read-only media, but it is too early to reject it here */ + goto ex; + ret= isoburn_new(o, 0); + if(ret<=0) + goto ex; + (*o)->drive= d; + +#ifdef Hardcoded_cd_rW + /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ + caps->start_adr= 0; + (*o)->fabricated_disc_status= BURN_DISC_APPENDABLE; +#endif + + if(caps->start_adr) { /* set emulation to overwriteable */ + (*o)->emulation_mode= 1; + ret= isoburn_start_emulation(*o, 0); + if(ret<=0) { + (*o)->emulation_mode= -1; + goto ex; + } + } else { + + /* >>> recognize unsuitable media (but allow read-only media) */; + +#ifdef Hardcoded_cd_rW + (*o)->nwa= Hardcoded_cd_rw_nwA; +#else + ret= burn_disc_track_lba_nwa(d, NULL, 0, &lba, &nwa); + if(ret>0) + (*o)->nwa= nwa; +#endif + + } + ret= 1; +ex: + if(caps!=NULL) + burn_disc_free_multi_caps(&caps); + return(ret); +} + + +int isoburn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], + char *adr, int load) +{ + int ret, conv_ret, drive_grabbed= 0; + char libburn_drive_adr[BURN_DRIVE_ADR_LEN]; + struct isoburn *o= NULL; + char msg[BURN_MSGS_MESSAGE_LEN+4096]; + + conv_ret= burn_drive_convert_fs_adr(adr, libburn_drive_adr); + if(conv_ret<=0) { + sprintf(msg, "Unsuitable drive address: '%s'\n",adr); + msg[BURN_MSGS_MESSAGE_LEN-1]= 0; + burn_msgs_submit(0, msg, 0, "SORRY", NULL); + ret= 0; goto ex; + } + + ret= burn_drive_scan_and_grab(drive_infos, libburn_drive_adr, load); + if(ret<=0) + goto ex; + drive_grabbed= 1; + ret= isoburn_welcome_media(&o, (*drive_infos)[0].drive, 0); + if(ret<=0) + goto ex; + + ret= 1; +ex: + if(ret<=0) { + if(drive_grabbed) + burn_drive_release((*drive_infos)[0].drive, 0); + isoburn_destroy(&o, 0); + } + return(ret); +} + + +int isoburn_drive_grab(struct burn_drive *drive, int load) +{ + int ret; + struct isoburn *o= NULL; + + ret= burn_drive_grab(drive, load); + if(ret<=0) + goto ex; + ret= isoburn_welcome_media(&o, drive, 0); + if(ret<=0) + goto ex; + + ret= 1; +ex: + if(ret<=0) + isoburn_destroy(&o,0); + return(ret); +} + + +/** Retrieve media emulation and eventual isoburn emulator of drive. + @return -1 unsuitable media, 0 generic media, 1 emulated media. +*/ +int isoburn_find_emulator(struct isoburn **pt, + struct burn_drive *drive, int flag) +{ + int ret; + + ret= isoburn_find_by_drive(pt, drive, 0); + if(ret<=0) + return(0); + if((*pt)->emulation_mode==-1) + return(-1); + if((*pt)->emulation_mode==0) + return(0); + return(1); +} + + +enum burn_disc_status isoburn_disc_get_status(struct burn_drive *drive) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, drive, 0); + if(ret<0) + return(BURN_DISC_UNSUITABLE); + if(o!=NULL) + if(o->fabricated_disc_status!=BURN_DISC_UNREADY) + return(o->fabricated_disc_status); + if(ret==0) + return(burn_disc_get_status(drive)); + + /* emulated status */ + if(o->emulation_mode==-1) + return(BURN_DISC_UNSUITABLE); + if(o->nwa>0) + return(BURN_DISC_APPENDABLE); + return(BURN_DISC_BLANK); +} + + +int isoburn_disc_erasable(struct burn_drive *d) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret>0) + if(o->emulation_mode==1) + return(1); + return burn_disc_erasable(d); +} + + +void isoburn_disc_erase(struct burn_drive *drive, int fast) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, drive, 0); + if(ret>0) { + if(o->emulation_mode==-1) { + /* To cause a negative reply with burn_drive_wrote_well() */ + burn_drive_cancel(drive); + return; + } + if(o->emulation_mode>0) { + ret= isoburn_invalidate_iso(o, 0); + if(ret<=0) + burn_drive_cancel(drive); + return; + } + } + burn_disc_erase(drive, fast); +} + + +int isoburn_disc_get_msc1(struct burn_drive *d, int *start_lba) +{ + int ret; + struct isoburn *o; + +#ifdef Hardcoded_cd_rW + /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ + *start_lba= Hardcoded_cd_rw_c1; + return(1); +#endif + + if(isoburn_disc_get_status(d)!=BURN_DISC_APPENDABLE && + isoburn_disc_get_status(d)!=BURN_DISC_FULL) + return(0); + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(0); + if(ret>0) if(o->emulation_mode>0) { + *start_lba= 0; + return(1); + } + return(burn_disc_get_msc1(d, start_lba)); +} + + +int isoburn_disc_track_lba_nwa(struct burn_drive *d, + struct burn_write_opts *opts, + int trackno, int *lba, int *nwa) +{ + int ret; + struct isoburn *o; + +#ifdef Hardcoded_cd_rW + /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ + *lba= Hardcoded_cd_rw_c1; + *nwa= Hardcoded_cd_rw_nwA; + return(1); +#endif + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(0); + if(ret>0) if(o->emulation_mode>0) { + *lba= 0; + *nwa= o->nwa; + return(1); + } + return(burn_disc_track_lba_nwa(d, opts, trackno, lba, nwa)); +} + + +void isoburn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc) +{ + int ret; + struct isoburn *o; + struct burn_drive *drive; + char reasons[BURN_REASONS_LEN],msg[160+BURN_REASONS_LEN]; + enum burn_write_types write_type; + + drive= burn_write_opts_get_drive(opts); + ret= isoburn_find_emulator(&o, drive, 0); + if(ret<0) + return; + if(o!=NULL) { + o->wrote_well= -1; + if(o->emulation_mode!=0) { + burn_write_opts_set_multi(opts, 0); + if(o->emulation_mode>0 && o->nwa >= 0) + burn_write_opts_set_start_byte(opts, ((off_t) o->nwa) * (off_t) 2048); + } + } + + write_type= burn_write_opts_auto_write_type(opts, disc, reasons, 0); + if (write_type == BURN_WRITE_NONE) { + sprintf(msg, "Failed to find a suitable write mode:\n%s", reasons); + burn_msgs_submit(0, msg, 0, "SORRY", NULL); + if(o!=NULL) + o->wrote_well= 0; + /* To cause a negative reply with burn_drive_wrote_well() */ + burn_drive_cancel(drive); + return; + } + +/* + sprintf(reasons, "%d", (int) write_type); + fprintf(stderr, "isoburn_EXPERIMENTAL: write_type = %s\n", + (write_type == BURN_WRITE_SAO ? "SAO" : + (write_type == BURN_WRITE_TAO ? "TAO" : reasons))); +*/ + +#ifdef Hardcoded_cd_rW + /* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */ + fprintf(stderr, "Setting write address to LBA %d\n", Hardcoded_cd_rw_nwA); + burn_write_opts_set_start_byte(opts, + ((off_t) Hardcoded_cd_rw_nwA) * (off_t) 2048); +#endif + + burn_disc_write(opts, disc); +} + + +void isoburn_drive_release(struct burn_drive *drive, int eject) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, drive, 0); + if(ret<0) + return; + if(o!=NULL) { + isoburn_destroy(&o, 0); + } + burn_drive_release(drive, eject); +} + + +void isoburn_finish(void) +{ + isoburn_destroy_all(&isoburn_list_start, 0); + burn_finish(); +} + + +int isoburn_needs_emulation(struct burn_drive *drive) +{ + int ret; + struct isoburn *o; + enum burn_disc_status s; + + s= isoburn_disc_get_status(drive); + if(s!=BURN_DISC_BLANK && s!=BURN_DISC_APPENDABLE) + return(-1); + ret= isoburn_find_emulator(&o, drive, 0); + if(ret<0) + return(-1); + if(ret>0) + if(o->emulation_mode>0) + return(1); + return(0); +} + + +int isoburn_set_start_byte(struct isoburn *o, off_t value, int flag) +{ + int ret; + struct burn_drive *drive = o->drive; + struct burn_multi_caps *caps= NULL; + + ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); + if(ret<=0) + goto ex; + if(!caps->start_adr) + {ret= 0; goto ex;} + o->min_start_byte= value; + if(value % caps->start_alignment) + value+= caps->start_alignment - (value % caps->start_alignment); + o->nwa= value/2048; + /* If suitable for alignment, round up to full 16 sector addresses */ + if((o->nwa%16) && ((16*2048) % caps->start_alignment)==0 ) + o->nwa+= 16 - (o->nwa%16); + ret= 1; +ex: + if(caps!=NULL) + burn_disc_free_multi_caps(&caps); + return(ret); +} + + +int isoburn_get_min_start_byte(struct burn_drive *d, off_t *start_byte, + int flag) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(-1); + if(ret==0) + return(0); + *start_byte= o->min_start_byte; + if(o->min_start_byte<=0) + return(0); + return(1); +} + + +int isoburn_drive_wrote_well(struct burn_drive *d) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(-1); + if(o!=NULL) + if(o->wrote_well>=0) + return(o->wrote_well); + ret= burn_drive_wrote_well(d); + return ret; +} + + +int isoburn_get_fifo_status(struct burn_drive *d, int *size, int *free_bytes, + char **status_text) +{ + int ret; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(-1); + if(o==NULL) + return(0); + if(o->fifo==NULL) + return(0); + ret= burn_fifo_inquire_status(o->fifo, size, free_bytes, status_text); + return(ret); +} + + diff --git a/ng_src/data_source.c b/ng_src/data_source.c new file mode 100644 index 00000000..5fd18aed --- /dev/null +++ b/ng_src/data_source.c @@ -0,0 +1,74 @@ +/* + data source for libisoburn. + + Copyright 2007 Vreixo Formoso Lopes +*/ + +#include +#include + +#include + +/* >>> NG */ +#include + +#include "isoburn.h" + + +static int +ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer) +{ + int ret; + struct burn_drive *d; + off_t count; + + assert(src && buffer); + + d = (struct burn_drive*)src->data; + + ret = burn_read_data(d, (off_t) lba * (off_t) 2048, (char *) buffer, + 2048, &count, 0); + if (ret <= 0 ) + return -1; + + return 1; +} + +static int +ds_open(IsoDataSource *src) +{ + /* nothing to do, device is always grabbed */ + return 1; +} + +static int +ds_close(IsoDataSource *src) +{ + /* nothing to do, device is always grabbed */ + return 1; +} + +static void +ds_free_data(IsoDataSource *src) +{ + /* nothing to do */; +} + +IsoDataSource * +isoburn_data_source_new(struct burn_drive *d) +{ + IsoDataSource *ret; + if (d==NULL) + return NULL; + ret = malloc(sizeof(IsoDataSource)); + if (!ret) + return NULL; + ret->refcount = 1; + ret->read_block = ds_read_block; + ret->open = ds_open; + ret->close = ds_close; + ret->free_data = ds_free_data; + ret->data = d; + return ret; +} + diff --git a/ng_src/isoburn.c b/ng_src/isoburn.c new file mode 100644 index 00000000..e32ed9df --- /dev/null +++ b/ng_src/isoburn.c @@ -0,0 +1,335 @@ + +/* + cc -g -c isoburn.c +*/ + +/* + Class core of libisoburn. + + Copyright 2007 Vreixo Formoso Lopes + and Thomas Schmitt +*/ + +/* ( derived from stub generated by CgeN on Sat, 01 Sep 2007 12:04:36 GMT ) */ + +#include +#include +#include +#include +#include +#include + +#include + +/* >>> NG */ +#include + +#include "libisoburn.h" +#include "isoburn.h" + + + +/* -------------------------- isoburn ----------------------- */ + + +/* The global list of isoburn objects. Usually there is only one. + >>> we are not ready for multiple control threads yet. See >>> mutex . + Multiple burns under one control thread should work. +*/ +struct isoburn *isoburn_list_start= NULL; + + +int isoburn_new(struct isoburn **objpt, int flag) +{ + struct isoburn *o; + int i, ret; + + *objpt= o= (struct isoburn *) malloc(sizeof(struct isoburn)); + if(o==NULL) + return(-1); + + o->drive= NULL; + o->emulation_mode= 0; + o->min_start_byte= 0; + o->nwa= 0; + o->fifo= NULL; + o->wrote_well= -1; + o->fabricated_disc_status= BURN_DISC_UNREADY; + for(i=0;i<65536;i++) + o->target_iso_head[i]= 0; + o->image= NULL; + o->prev= NULL; + o->next= NULL; + ret= iso_image_new("NEW", &o->image); + if(ret<0) + goto failed; + isoburn_link(o, isoburn_list_start, 1); + return(1); +failed:; + isoburn_destroy(objpt, 0); + return(-1); +} + + +int isoburn_destroy(struct isoburn **objpt, int flag) +{ + struct isoburn *o; + + o= *objpt; + if(o==NULL) + return(0); + + /* >>> mutex */ + + if(o==isoburn_list_start) + isoburn_list_start= o->next; + if(o->prev!=NULL) + o->prev->next= o->next; + if(o->next!=NULL) + o->next->prev= o->prev; + + /* >>> end mutex */ + + if(o->image!=NULL) + iso_image_unref(o->image); + if(o->fifo!=NULL) + burn_source_free(o->fifo); + + free((char *) o); + *objpt= NULL; + return(1); +} + + +int isoburn_destroy_all(struct isoburn **objpt, int flag) +{ + struct isoburn *o,*n; + + o= *objpt; + if(o==NULL) + return(0); + for(;o->prev!=NULL;o= o->prev); + for(;o!=NULL;o= n) { + n= o->next; + isoburn_destroy(&o,0); + } + *objpt= NULL; + return(1); +} + + +int isoburn_get_target_image(struct isoburn *o, IsoImage **pt, int flag) +{ + *pt= o->image; + return(1); +} + + +int isoburn_get_prev(struct isoburn *o, struct isoburn **pt, int flag) +{ + *pt= o->prev; + return(1); +} + + +int isoburn_get_next(struct isoburn *o, struct isoburn **pt, int flag) +{ + *pt= o->next; + return(1); +} + + +int isoburn_link(struct isoburn *o, struct isoburn *link, int flag) +/* + bit0= insert as link->prev rather than as link->next +*/ +{ + + /* >>> mutex */ + + if(isoburn_list_start==NULL || + (isoburn_list_start==link && (flag&1))) + isoburn_list_start= o; + if(o->prev!=NULL) + o->prev->next= o->next; + if(o->next!=NULL) + o->next->prev= o->prev; + o->prev= o->next= NULL; + if(link==NULL) + return(1); + if(flag&1) { + o->next= link; + o->prev= link->prev; + if(o->prev!=NULL) + o->prev->next= o; + link->prev= o; + } else { + o->prev= link; + o->next= link->next; + if(o->next!=NULL) + o->next->prev= o; + link->next= o; + } + + /* >>> end mutex */ + + return(1); +} + + +int isoburn_count(struct isoburn *o, int flag) +/* flag: bit1= count from start of list */ +{ + int counter= 0; + + if(flag&2) + for(;o->prev!=NULL;o= o->prev); + for(;o!=NULL;o= o->next) + counter++; + return(counter); +} + + +int isoburn_by_idx(struct isoburn *o, int idx, struct isoburn **pt, int flag) +/* flag: bit0= fetch first (idx<0) or last (idx>0) item in list + bit1= address from start of list */ +{ + int i,abs_idx; + struct isoburn *npt; + + if(flag&2) + for(;o->prev!=NULL;o= o->prev); + abs_idx= (idx>0?idx:-idx); + *pt= o; + for(i= 0;(i0) + npt= o->next; + else + npt= o->prev; + if(npt==NULL && (flag&1)) + break; + *pt= npt; + } + return(*pt!=NULL); +} + + +int isoburn_find_by_drive(struct isoburn **pt, struct burn_drive *d, int flag) +{ + struct isoburn *o; + + *pt= NULL; + for(o= isoburn_list_start;o!=NULL;o= o->next) + if(o->drive==d) { + *pt= o; + return(1); + } + return(0); +} + +static +int isoburn_prepare_disc_aux(struct burn_drive *d, struct burn_disc **disc, + struct isoburn_source_opts *opts, int new_img) +{ + struct burn_source *wsrc; + struct burn_session *session; + struct burn_track *track; + struct isoburn *o; + Ecma119WriteOpts wopts; + enum burn_disc_status state; + int ret, chunks; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0 || o==NULL) + return -1; + o->wrote_well= 0; /* early end will be registered as failure */ + + + state = isoburn_disc_get_status(d); + if (state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE + && (state != BURN_DISC_FULL || ! new_img)) { + /* unsuitable status */ + return -2; + } + + wopts.level = opts->level; + wopts.rockridge = opts->rockridge; + wopts.joliet = opts->joliet; + wopts.omit_version_numbers = opts->omit_version_numbers; + wopts.allow_deep_paths = opts->allow_deep_paths; + wopts.joliet_longer_paths = opts->joliet_longer_paths; + /* wopts.copy_eltorito = opts->copy_eltorito; */ + wopts.sort_files = opts->sort_files; + wopts.replace_dir_mode = opts->replace_dir_mode; + wopts.replace_file_mode = opts->replace_file_mode; + wopts.replace_uid = opts->replace_uid; + wopts.replace_gid = opts->replace_gid; + wopts.dir_mode = opts->dir_mode; + wopts.file_mode = opts->file_mode; + wopts.gid = opts->gid; + wopts.uid = opts->uid; + wopts.output_charset = opts->ouput_charset; + + if (new_img) { + wopts.ms_block = 0; + wopts.appendable = 0; + wopts.overwrite = NULL; + } else { + int lba, nwa; + ret = isoburn_disc_track_lba_nwa(d, NULL, 0, &lba, &nwa); + if (ret != 1) + return -3; + if (nwa == 0 && state == BURN_DISC_APPENDABLE) { + /* invalid nwa */ + return -4; + } + + wopts.ms_block = nwa; + wopts.appendable = 1; + wopts.overwrite = o->target_iso_head; + } + + ret = iso_image_create_burn_source(o->image, &wopts, &wsrc); + if (ret < 0) + return -1; + + /* TODO check return values for failure. propertly clean-up on error */ + + chunks= 32; + if(opts->fifo_size >= 64*1024 && opts->fifo_size <= 1024.0 * 1024.0 * 1024.0){ + chunks= opts->fifo_size/2048; + if(chunks*2048 < opts->fifo_size) + chunks++; + } + o->fifo = burn_fifo_source_new(wsrc, 2048, chunks, 0); + burn_source_free(wsrc); + if (o->fifo == NULL) { + fprintf(stderr, "Cannot attach fifo\n"); + return -1; + } + *disc = burn_disc_create(); + session = burn_session_create(); + burn_disc_add_session(*disc, session, BURN_POS_END); + track = burn_track_create(); + burn_track_set_source(track, o->fifo); + burn_session_add_track(session, track, BURN_POS_END); + + /* give up local references */ + burn_track_free(track); + burn_session_free(session); + + o->wrote_well= -1; /* neutral */ + return 1; +} + +int isoburn_prepare_disc(struct burn_drive *d, struct burn_disc **disc, + struct isoburn_source_opts *opts) +{ + return isoburn_prepare_disc_aux(d, disc, opts, 0); +} + +int isoburn_prepare_new_image(struct burn_drive *d, struct burn_disc **disc, + struct isoburn_source_opts *opts) +{ + return isoburn_prepare_disc_aux(d, disc, opts, 1); +} diff --git a/ng_src/isoburn.h b/ng_src/isoburn.h new file mode 100644 index 00000000..e3afbe83 --- /dev/null +++ b/ng_src/isoburn.h @@ -0,0 +1,134 @@ + +/* + Class struct of libisoburn. + + Copyright 2007 Vreixo Formoso Lopes + and Thomas Schmitt +*/ + +#ifndef Isoburn_includeD +#define Isoburn_includeD + + + +/* for uint8_t */ +#include + + +struct isoburn { + + + /* The libburn drive to which this isoburn object is related + Most isoburn calls will use a burn_drive as object handle */ + struct burn_drive *drive; + + /* -1= inappropriate media state detected + 0= libburn multi-session media, resp. undecided yet + 1= random access media */ + int emulation_mode; + + /* Although rarely used, libburn can operate on several + drives simultaneously. */ + struct isoburn *prev; + struct isoburn *next; + + + /* --- My part --- */ + + /* Start address as given by image examination (bytes, not blocks) */ + off_t min_start_byte; + + /* Aligned start address to be used for processing (counted in blocks) */ + int nwa; + + /* Eventual freely fabricated isoburn_disc_get_status(). + BURN_DISC_UNREADY means that normally emulated status is in effect. + */ + enum burn_disc_status fabricated_disc_status; + + /* The fifo which is installed between track and libisofs burn_source + */ + struct burn_source *fifo; + + /* Indicator wether the most recent burn run worked : + -1 = undetermined, ask libburn , 0 = failure , 1 = success + To be inquired by isoburn_drive_wrote_well() + */ + int wrote_well; + + + /* --- Vreixo's part --- */ + + /* Buffered ISO head from media (should that become part of + ecma119_read_opts ?) */ + uint8_t target_iso_head[65536]; + + /* Libisofs image context */ + IsoImage *image; +}; + + +/* Creation and disposal function */ +int isoburn_new(struct isoburn **objpt, int flag); +int isoburn_destroy(struct isoburn **objpt, int flag); + +/* Eventual readers for public attributes */ +/* ( put into separate .h file then ) */ +int isoburn_get_emulation_mode(struct isoburn *o, int *pt, int flag); +int isoburn_get_target_volset(struct isoburn *o, IsoImage **pt, int flag); + +/* List management */ +int isoburn_get_prev(struct isoburn *o, struct isoburn **pt, int flag); +int isoburn_get_next(struct isoburn *o, struct isoburn **pt, int flag); +int isoburn_destroy_all(struct isoburn **objpt, int flag); +int isoburn_link(struct isoburn *o, struct isoburn *link, int flag); +int isoburn_count(struct isoburn *o, int flag); +int isoburn_by_idx(struct isoburn *o, int idx, struct isoburn **pt, int flag); +int isoburn_find_by_drive(struct isoburn **pt, struct burn_drive *d, int flag); + + +/* Non API inner interfaces */ + +/* Calls from burn_wrap.c into isofs_wrap.c */ + +int isoburn_start_emulation(struct isoburn *o, int flag); +int isoburn_invalidate_iso(struct isoburn *o, int flag); + + +/* Calls from isofs_wrap.c into burn_wrap.c */ + +/** Get an eventual isoburn object which is wrapped around the drive. + @param pt Eventually returns a pointer to the found object. + It is allowed to become NULL if return value is -1 or 0. + In this case, the drive is a genuine libburn drive + with no emulation activated by isoburn. + @param drive The drive to be searched for + @param flag unused yet + @return -1 unsuitable media, 0 generic media, 1 emulated media. +*/ +int isoburn_find_emulator(struct isoburn **pt, + struct burn_drive *drive, 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 . + @param o The isoburn object to be programmed. + @param value The start address in bytes + @param flag unused yet + @return <=0 is failure , >0 success +*/ +int isoburn_set_start_byte(struct isoburn *o, off_t value, int flag); + +/** Get a data source suitable for read from a drive using burn_read_data() + function. + @param d drive to read from. Must be grabbed. + @return the data source, NULL on error. Must be freed with libisofs + iso_data_source_unref() function. Note: this doesn't release + the drive. +*/ +IsoDataSource * +isoburn_data_source_new(struct burn_drive *d); + +#endif /* Isoburn_includeD */ + diff --git a/ng_src/isofs_wrap.c b/ng_src/isofs_wrap.c new file mode 100644 index 00000000..64a3d110 --- /dev/null +++ b/ng_src/isofs_wrap.c @@ -0,0 +1,314 @@ + +/* + cc -g -c isofs_wrap.c +*/ + +/* + libisofs related functions of libisoburn. + + Copyright 2007 Vreixo Formoso Lopes + Thomas Schmitt +*/ + +#include +#include +#include + +#include + +/* >>> NG */ +#include + +#include "isoburn.h" +#include "libisoburn.h" + +#define BP(a,b) [(b) - (a) + 1] + +struct ecma119_pri_vol_desc +{ + uint8_t vol_desc_type BP(1, 1); + uint8_t std_identifier BP(2, 6); + uint8_t vol_desc_version BP(7, 7); + uint8_t unused1 BP(8, 8); + uint8_t system_id BP(9, 40); + uint8_t volume_id BP(41, 72); + uint8_t unused2 BP(73, 80); + uint8_t vol_space_size BP(81, 88); + uint8_t unused3 BP(89, 120); + uint8_t vol_set_size BP(121, 124); + uint8_t vol_seq_number BP(125, 128); + uint8_t block_size BP(129, 132); + uint8_t path_table_size BP(133, 140); + uint8_t l_path_table_pos BP(141, 144); + uint8_t opt_l_path_table_pos BP(145, 148); + uint8_t m_path_table_pos BP(149, 152); + uint8_t opt_m_path_table_pos BP(153, 156); + uint8_t root_dir_record BP(157, 190); + uint8_t vol_set_id BP(191, 318); + uint8_t publisher_id BP(319, 446); + uint8_t data_prep_id BP(447, 574); + uint8_t application_id BP(575, 702); + uint8_t copyright_file_id BP(703, 739); + uint8_t abstract_file_id BP(740, 776); + uint8_t bibliographic_file_id BP(777, 813); + uint8_t vol_creation_time BP(814, 830); + uint8_t vol_modification_time BP(831, 847); + uint8_t vol_expiration_time BP(848, 864); + uint8_t vol_effective_time BP(865, 881); + uint8_t file_structure_version BP(882, 882); + uint8_t reserved1 BP(883, 883); + uint8_t app_use BP(884, 1395); + uint8_t reserved2 BP(1396, 2048); +}; + +static +uint32_t iso_read_lsb(const uint8_t *buf, int bytes) +{ + int i; + uint32_t ret = 0; + + for (i=0; iimage); + return o->image; +} + + +/* API function. See libisoburn.h +*/ +int isoburn_read_image(struct burn_drive *d, + struct isoburn_read_opts *read_opts, + IsoImage **image) +{ + int ret; + struct iso_read_opts ropts; + struct iso_read_image_features features; + enum burn_disc_status status= BURN_DISC_BLANK; + IsoDataSource *ds= NULL; + struct isoburn *o= NULL; + + if(read_opts==NULL) { + + /* >>> program error */; + + return(-1); + } + if(d != NULL) { + ret = isoburn_find_emulator(&o, d, 0); + if (ret < 0) + return 0; + + if (o == NULL) { + return -1; + } + status = isoburn_disc_get_status(d); + } + if (d == NULL || status == BURN_DISC_BLANK || read_opts->pretend_blank) { + + /* + * Blank disc, we create a new image without files. + */ + + if (d == NULL) { + if (image==NULL) + return -1; + /* create a new image */ + ret = iso_image_new("NEW", image); + if (ret < 0) + return ret; + } else { + /* use isoburn image */ + if (image) { + *image = o->image; + iso_image_ref(*image); /*protects object from premature free*/ + } + } + return 1; + } + + if (status != BURN_DISC_APPENDABLE && status != BURN_DISC_FULL) { + /* incorrect disc status */ + return -4; + } + + ret = isoburn_disc_get_msc1(d, (int*) &ropts.block); + if (ret < 0) + return -2; + + ropts.norock = read_opts->norock; + ropts.nojoliet = read_opts->nojoliet; + ropts.preferjoliet = read_opts->preferjoliet; + ropts.mode = read_opts->mode; + ropts.uid = read_opts->uid; + ropts.gid = read_opts->gid; + + /* create the data source */ + ds = isoburn_data_source_new(d); + ret = iso_image_import(o->image, ds, &ropts, &features); + iso_data_source_unref(ds); + if (ret < 0) + return ret; + + if (image) { + *image = o->image; + iso_image_ref(*image); /*protects object from premature free*/ + } + + read_opts->hasRR = features.hasRR; + read_opts->hasJoliet = features.hasJoliet; + read_opts->size = features.size; + return 1; +} + + +/* API function. See libisoburn.h +*/ +int isoburn_attach_image(struct burn_drive *d, IsoImage *image) +{ + int ret; + struct isoburn *o; + + if (image == NULL) + return -1; + ret = isoburn_find_emulator(&o, d, 0); + if (ret < 0) + return 0; + if (o == NULL) + return -1; + if(o->image != NULL) + iso_image_unref(o->image); + o->image = image; + return(1); +} + + +/* API function. See libisoburn.h +*/ +int isoburn_activate_session(struct burn_drive *drive) +{ + int ret; + struct isoburn *o; + + ret = isoburn_find_emulator(&o, drive, 0); + if (ret < 0) + return -1; + + if (o->emulation_mode != 1) + return 1; /* don't need to activate session */ + + if (o->fabricated_disc_status != BURN_DISC_APPENDABLE) + return 1; + + ret = burn_random_access_write(drive, 0, (char*)o->target_iso_head, + 32*2048, 1); + + return ret; +} + + +/** Initialize the emulation of multi-session on random access media. + The need for emulation is confirmed already. + @param o A freshly created isoburn object. isoburn_create_data_source() was + already called, nevertheless. + @return <=0 error , 1 = success +*/ +int isoburn_start_emulation(struct isoburn *o, int flag) +{ + int ret, i; + off_t data_count; + struct burn_drive *drive; + struct ecma119_pri_vol_desc *pvm; + + assert(o); + + drive= o->drive; + + /* we can assume 0 as start block for image */ + /* TODO what about ms? where we validate valid iso image in ms disc? */ + ret = burn_read_data(drive, (off_t) 0, (char*)o->target_iso_head, + sizeof(o->target_iso_head), &data_count, 1); + + /* an error means an empty disc */ + if (ret <= 0) { + o->fabricated_disc_status= BURN_DISC_BLANK; + return 1; + } + + /* check first 64K. If 0's, the disc is treated as a blank disc, and thus + overwritten without extra check. */ + i = sizeof(o->target_iso_head); + while (i && !o->target_iso_head[i-1]) + --i; + + if (!i) { + o->fabricated_disc_status= BURN_DISC_BLANK; + return 1; + } + + pvm = (struct ecma119_pri_vol_desc *)(o->target_iso_head + 16 * 2048); + + if (!strncmp((char*)pvm->std_identifier, "CD001", 5)) { + off_t size; + + /* sanity check */ + if (pvm->vol_desc_type[0] != 1 || pvm->vol_desc_version[0] != 1 + || pvm->file_structure_version[0] != 1 ) { + /* TODO for now I treat this as a full disc */ + o->fabricated_disc_status= BURN_DISC_FULL; + return 1; + } + + /* ok, PVM found, set size */ + size = (off_t) iso_read_lsb(pvm->vol_space_size, 4); + size *= (off_t) 2048; /* block size in bytes */ + isoburn_set_start_byte(o, size, 0); + o->fabricated_disc_status= BURN_DISC_APPENDABLE; + } else if (!strncmp((char*)pvm->std_identifier, "CDXX1", 5)) { + + /* empty image */ + isoburn_set_start_byte(o, (off_t) 0, 0); + o->fabricated_disc_status= BURN_DISC_BLANK; + } else { + /* treat any disc in an unknown format as full */ + o->fabricated_disc_status= BURN_DISC_FULL; + } + return 1; +} + + +/** Alters and writes the first 64 kB of a "media" to invalidate + an ISO image. (It shall stay restorable by skilled humans, though). + The result shall especially keep libisoburn from accepting the media + image as ISO filesystem. + @param o A fully activated isoburn object. isoburn_start_emulation() + was already called. + @return <=0 error , 1 = success +*/ +int isoburn_invalidate_iso(struct isoburn *o, int flag) +{ + /* + * replace CD001 with CDXX1 in PVM. + * I think this is enought for invalidating an iso image + */ + strncpy((char*)o->target_iso_head + 16 * 2048 + 1, "CDXX1", 5); + return isoburn_activate_session(o->drive); +} + diff --git a/ng_src/libisoburn.h b/ng_src/libisoburn.h new file mode 100644 index 00000000..87f45764 --- /dev/null +++ b/ng_src/libisoburn.h @@ -0,0 +1,379 @@ + +/* + API definition of libisoburn. + + Copyright 2007 Vreixo Formoso Lopes + and Thomas Schmitt +*/ + +/** + +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. + +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. + +>>> +>>> Take into respect Vreixo's (mandatory ?) shortcuts which are to come +>>> + +The usage model is like with libburn: the target is a "media" in a "drive". +The wrappers will transparently provide the necessary emulations which +are appropriate for particular target "drives". + +*/ + + + /* API functions */ + + +/** Initialize libisoburn, libisofs and libburn. + Wrapper for : iso_init() and burn_initialize() + @return 1 indicates success, 0 is failure +*/ +int isoburn_initialize(void); + + +/** Aquire a target drive by its filesystem path resp. libburn persistent + address. + Wrapper for: burn_drive_scan_and_grab() +*/ +int isoburn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], + char* adr, 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() +*/ +int isoburn_drive_grab(struct burn_drive *drive, int load); + + +/** 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() +*/ +enum burn_disc_status isoburn_disc_get_status(struct burn_drive *drive); + + +/** Tells whether the media can be treated by isoburn_disc_erase(). + Wrapper for: burn_disc_erasable() +*/ +int isoburn_disc_erasable(struct burn_drive *d); + + +/** 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() +*/ +void isoburn_disc_erase(struct burn_drive *drive, int fast); + +/** + * Options for image reading. + */ +struct isoburn_read_opts { + unsigned int norock:1; /*< Do not read Rock Ridge extensions */ + unsigned int nojoliet:1; /*< Do not read Joliet extensions */ + unsigned int preferjoliet:1; + /*< When both Joliet and RR extensions are present, the RR + * tree is used. If you prefer using Joliet, set this to 1. */ + uid_t uid; /**< Default uid when no RR */ + gid_t gid; /**< Default uid when no RR */ + mode_t mode; /**< Default mode when no RR (only permissions) */ + + /** + * Input charset for RR file names. NULL to use default locale charset. + */ + char *input_charset; + + /* modified by the function isoburn_read_image */ + unsigned int hasRR:1; /*< It will be set to 1 if RR extensions are present, + to 0 if not. */ + unsigned int hasJoliet:1; /*< It will be set to 1 if Joliet extensions are + present, to 0 if not. */ + uint32_t size; /**< Will be filled with the size (in 2048 byte block) of + * the image, as reported in the PVM. */ + unsigned int pretend_blank:1; /* always create empty image */ +}; + +/** + * Options for image generation by libisofs and image transport to libburn. + */ +struct isoburn_source_opts { + + /* Options for image generation */ + + int level; /**< ISO level to write at. */ + int flags; /**< Which extensions to support. */ + int relaxed_constraints; /**< see ecma119_relaxed_constraints_flag */ + + /** Which extensions to support. */ + unsigned int rockridge :1; + unsigned int joliet :1; + + /* relaxed constraints */ + unsigned int omit_version_numbers :1; + unsigned int allow_deep_paths :1; + unsigned int joliet_longer_paths :1; + + unsigned int sort_files:1; + /**< If files should be sorted based on their weight. */ + + unsigned int copy_eltorito:1; + /**< + * In multisession discs, select whether to copy el-torito catalog + * and boot image. Copy is needed for isolinux images, that need to + * be patched. However, it can lead to problems when the image is + * not present in the iso filesystem, because we can't figure out + * its size. In those cases, we only copy 1 block of data. + */ + + /** + * The following options set the default values for files and directory + * permissions, gid and uid. All these take one of three values: 0, 1 or 2. + * If 0, the corresponding attribute will be kept as set in the IsoNode. + * Unless you have changed it, it corresponds to the value on disc, so it + * is suitable for backup purposes. If set to 1, the corresponding attrib. + * will be changed by a default suitable value. Finally, if you set it to + * 2, the attrib. will be changed with the value specified in the options + * below. Note that for mode attributes, only the permissions are set, the + * file type remains unchanged. + */ + unsigned int replace_dir_mode :2; + unsigned int replace_file_mode :2; + unsigned int replace_uid :2; + unsigned int replace_gid :2; + + mode_t dir_mode; /** Mode to use on dirs when replace_dir_mode == 2. */ + mode_t file_mode; /** Mode to use on files when replace_file_mode == 2. */ + uid_t uid; /** uid to use when replace_uid == 2. */ + gid_t gid; /** gid to use when replace_gid == 2. */ + + char *ouput_charset; /**< NULL to use default charset */ + + + /* Options for image transport */ + + /** The number of bytes to be used for the fifo which decouples libisofs + and libburn for better throughput and for reducing the risk of + interrupting signals hitting the libburn thread which operates the + MMC drive. + The size will be rounded up to the next full 2048. + Minimum is 64kiB, maximum is 1 GiB (but that is too much anyway). + */ + int fifo_size; + +}; + +/** Get the image attached to a drive, if any. + @return A reference to attached image, or NULL if the drive has no image + attached. This reference needs to be released via iso_image_unref() + when it is not longer needed. +*/ +IsoImage *isoburn_get_attached_image(struct burn_drive *d); + +/** Load the ISO filesystem directory tree from the media in the given drive. + This will give libisoburn the base on which it can let libisofs perform + image growing or image modification. The loaded volset gets attached + to the drive object and handed out to the application. + Not a wrapper, but peculiar to libisoburn. + @param d The drive which holds an existing ISO filesystem or blank media. + d is allowed to be NULL which produces an empty ISO image. In + this case one has to call before writing isoburn_attach_volset() + with the volset from this call and with the intended output + drive. + @param read_opts The read options which can be chosen by the application + @param image the image read, if the disc is blank it will have no files. + This reference needs to be released via iso_image_unref() when + it is not longer needed. The drive, if not NULL, will hold an + own reference which it will release when it gets a new volset + or when it gets released via isoburn_drive_release(). + You can pass NULL if you already have a reference or you plan to + obtain it later with isoburn_get_attached_image(). Of course, if + you haven't specified a valid drive (i.e., if d == NULL), this + parameter can't be NULL. + @return <=0 error , 1 = success +*/ +int isoburn_read_image(struct burn_drive *d, + struct isoburn_read_opts *read_opts, + IsoImage **image); + + +/** Set the IsoImage to be used with a drive. This eventually releases + the reference to the old IsoImage attached to the drive. + Caution: Use with care. It hardly makes sense to replace an image that + reflects a valid ISO image on media. + This call is rather intended for writing a newly created and populated + image to blank media. The use case in xorriso is to let an image survive + the change or demise of the outdev target drive. + @param d The drive which shall be write target of the volset. + @param image The image that represents the image to be written. + This image pointer MUST already be a valid reference suitable + for iso_image_unref(). + It may have been obtained by appropriate libisofs calls or by + isoburn_read_image() with d==NULL. + @return <=0 error , 1 = success +*/ +int isoburn_attach_image(struct burn_drive *d, IsoImage *image); + + +/** Obtain the start block number of the most recent session on media. In + case of random access media this will always be 0. Succesfull 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. + Wrapper for: burn_disc_get_msc1() +*/ +int isoburn_disc_get_msc1(struct burn_drive *d, int *start_lba); + + +/** 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() +*/ +int isoburn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o, + int trackno, int *lba, int *nwa); + + +/** 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(). + @param drive The drive holding the media. + @param start_byte The reply value counted in bytes, not in sectors. + @param flag Unused yet. Submit 0. + @return 1=stat_byte is valid, 0=not an emulated appendable, -1=error +*/ +int isoburn_get_min_start_byte(struct burn_drive *d, off_t *start_byte, + int flag); + + +/** Create a disc object for writing the new session from the created or loaded + iso_volset which has been manipulated via libisofs, to the same media from + where the image was eventually loaded. This struct burn_disc is ready for + use by a subsequent call to isoburn_disc_write(). + After this asynchronous writing has ended and the drive is BURN_DRIVE_IDLE + again, the burn_disc object has to be disposed by burn_disc_free(). + @param drive The combined source and target drive, grabbed with + isoburn_drive_scan_and_grab(). . + @param disc Returns the newly created burn_disc object. + @return <=0 error , 1 = success +*/ +int isoburn_prepare_disc(struct burn_drive *d, struct burn_disc **disc, + struct isoburn_source_opts *opts); + + +/** Create a disc object for producing a new image from a previous image + plus the changes made by user. The generated burn_disc is suitable + to be written to any other libburn drive. You must not use the same drive + for writing as you are using here as source, because data will be + read from the source drive while the target drive gets written to. + The resulting burn_disc object has to be disposed when all its writing + is done and the drive is BURN_DRIVE_IDLE again after asynchronous + burn_disc_write(). + @param d The source drive, grabbed with isoburn_drive_scan_and_grab(). + @param disc Returns the newly created burn_disc object. + @return <=0 error , 1 = success +*/ +int isoburn_prepare_new_image(struct burn_drive *d, struct burn_disc **disc, + struct isoburn_source_opts *opts); + +/** 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() +*/ +void isoburn_disc_write(struct burn_write_opts *o, struct burn_disc *disc); + + +/** 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. + Hint: If only burn_write_opts and not burn_drive is known, then the drive + can be obtained by burn_write_opts_get_drive(). + @parm d The drive to which the track with the fifo gets burned. + @param size The total size of the fifo + @param free_bytes The current free capacity of the fifo + @param status_text Returns a pointer to a constant text, see below + @return <0 reply invalid, >=0 fifo status code: + bit0+1=input status, bit2=consumption status, i.e: + 0="standby" : data processing not started yet + 1="active" : input and consumption are active + 2="ending" : input has ended without error + 3="failing" : input had error and ended, + 4="unused" : ( consumption has ended before processing start ) + 5="abandoned" : consumption has ended prematurely + 6="ended" : consumption has ended without input error + 7="aborted" : consumption has ended after input error +*/ +int isoburn_get_fifo_status(struct burn_drive *d, int *size, int *free_bytes, + char **status_text); + + +/** Inquire whether the most recent write run was successful. + Wrapper for: burn_drive_wrote_well() +*/ +int isoburn_drive_wrote_well(struct burn_drive *d); + + +/** Call this after isoburn_disc_write has finished and burn_drive_wrote_well() + indicates success. It will eventually complete the emulation of + multi-session functionality, if needed at all. Let libisoburn decide. + Not a wrapper, but peculiar to libisoburn. +*/ +int isoburn_activate_session(struct burn_drive *drive); + + +/** Write a new session to a disc. + This is a synchronous call equivalent to isoburn_prepare_disc + + isoburn_disc_write + isoburn_activate_session + @param pacifier_func If not NULL: a function to produce appeasing messages. + See burn_abort_pacifier() in libburn.h for an example. +*/ +/* TODO implement this */ +int isoburn_perform_write(struct burn_write_opts *o, + int (*pacifier_func)(void *handle, int patience, + int elapsed)); + +/** Release an aquired drive. + Wrapper for: burn_drive_release() +*/ +void isoburn_drive_release(struct burn_drive *drive, int eject); + + +/** Shutdown all three libraries. + Wrapper for : iso_finish() and burn_finish(). +*/ +void isoburn_finish(void); + + +/* + The following two calls are for expert applications only. + An application should have a special reason to use them. +*/ + + +/** Inquire wether the media needs emulation or would be suitable for + generic multi-session via libburn. + @return 0 is generic multi-session + 1 is emulated multi-session + -1 is not suitable for isoburn +*/ +int isoburn_needs_emulation(struct burn_drive *drive); + + diff --git a/test/xorriso_timestamp.h b/test/xorriso_timestamp.h index 714096b3..5e8416fb 100644 --- a/test/xorriso_timestamp.h +++ b/test/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.01.10.114451" +#define Xorriso_timestamP "2008.01.10.151924"