/* cc -g -c burn_wrap.c */ /* libburn wrappers for libisoburn Copyright 2007 Thomas Schmitt, */ #include #include #include #include #include #include #include #include "../libburn/libburn.h" #include "../libisofs/libisofs.h" #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) { int ret; if(!iso_init()) return(0); if(!burn_initialize()) return(0); isoburn_destroy_all(&isoburn_list_start, 0); /* isoburn_list_start= NULL */ reurn(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; struct burn_multi_caps *caps= NULL; ret= burn_disc_get_multi_caps(d, BURN_WRITE_NONE, &caps, 0); if(ret<=0) goto ex; if(caps->start_adr) { /* set emulation to overwriteable */ ret= isoburn_new(o, 0); if(ret<=0) goto ex; (*o)->emulation_mode= 1; (*o)->drive= d; ret= isoburn_start_emulation(*o, 0); if(ret<=0) goto ex; } 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; struct stat stbuf; char libburn_drive_adr[BURN_DRIVE_ADR_LEN]; struct isoburn *o= NULL; ret= burn_drive_convert_fs_adr(adr, libburn_drive_adr); if(ret<0) return(ret); if(ret==0) { if(stat(adr,&stbuf)!=-1) { if(S_ISREG(stbuf.st_mode) || S_ISBLK(stbuf.st_mode)) { return(0); /* >>> would be acceptable in future */; /* >>> create null-drive */; /* >>> set emulation to standard i/o */; } else { /* >>> unsuitable file type */; return(0); } } else { /* >>> file not found */; return(0); } } else { ret= burn_drive_scan_and_grab(drive_infos, adr, load); if(ret<=0) goto ex; ret= isoburn_examine_media(&o, (*drive_infos)[0].drive, 0); if(ret<=0) goto ex; } ret= 1; ex: if(ret<=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_examine_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. */ static 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(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); } 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) { /* >>> influence wrote_well reply or have wrote_well wrapper ? */ return; } if(o->emulation_mode>0) { ret= isoburn_invalidate_iso(o, 0); /* >>> influence wrote_well reply or have wrote_well wrapper ? */ return; } } burn_disc_erase(drive, fast); } int isoburn_disc_get_msc1(struct burn_drive *d, int *start_lba) { int ret; struct isoburn *o; if(isoburn_disc_get_status(d)!=BURN_DISC_APPENDABLE) return(0); ret= isoburn_find_emulator(&o, d, 0); if(ret<0) return(0); if(ret==0) return(burn_disc_get_msc1(d, start_lba)); *start_lba= 0; return(1); } 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; ret= isoburn_find_emulator(&o, d, 0); if(ret<0) return(0); if(ret==0) return(burn_disc_track_lba_nwa(d, opts, trackno, lba, nwa)); *lba= 0; *nwa= o->nwa; return(1); } int isoburn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc) { int ret; struct isoburn *o; struct burn_drive *drive; drive= burn_write_opts_get_drive(opts); ret= isoburn_find_emulator(&o, drive, 0); if(ret<0) return(0); if(o->emulation_mode==2) { return(0); /* >>> implement an asynchronous standard i/o writer */; } burn_disc_write(opts, disc); } void isoburn_drive_release(struct burn_drive *drive, int eject) { int ret, no_drive_release= 0; struct isoburn *o; ret= isoburn_find_emulator(&o, drive, 0); if(ret<0) return; if(o!=NULL) isoburn_destroy(&o, 0); burn_drive_release(drive, eject); } void isoburn_finish(void) { isoburn_destroy_all(&isoburn_list_start, 0); burn_finish(); iso_finish(); } int isoburn_needs_emulation(struct burn_drive *drive) { int ret; struct isoburn *o; enum burn_disc_status s; s= isoburn_disc_get_status(drive); if(s!=BURN_DISC_BLANK && s!=BURN_DISC_APPENDABLE) return(-1); ret= isoburn_find_emulator(&o, drive, 0); if(ret<0) return(-1); if(ret>0) if(o->emulation_mode>0) return(1); return(0); } void isoburn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value) { int ret; struct isoburn *o; struct burn_drive *drive; struct burn_multi_caps *caps= NULL; drive= burn_write_opts_get_drive(opts); ret= isoburn_find_emulator(&o, drive, 0); if(ret<=0) goto ex; ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); if(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; burn_write_opts_set_start_byte(opts, value); ex: if(caps!=NULL) burn_disc_free_multi_caps(&caps); }