From 9737650fae8dfdf8b092d9671eef6a9659b2e9c8 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Tue, 4 Sep 2007 23:03:21 +0000 Subject: [PATCH] Implemented use of stdio-pseudo-drives --- libisoburn/burn_wrap.c | 140 ++++++++++++++++++++++++++++++----------- libisoburn/isoburn.c | 21 ++++++- libisoburn/isoburn.h | 18 ++++-- 3 files changed, 137 insertions(+), 42 deletions(-) diff --git a/libisoburn/burn_wrap.c b/libisoburn/burn_wrap.c index db88a956..19788789 100644 --- a/libisoburn/burn_wrap.c +++ b/libisoburn/burn_wrap.c @@ -1,6 +1,8 @@ /* - cc -g -c burn_wrap.c + cc -g -c \ + -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE \ + burn_wrap.c */ /* libburn wrappers for libisoburn @@ -15,6 +17,7 @@ #include #include #include +#include #include "../libburn/libburn.h" @@ -29,15 +32,13 @@ 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); + return(1); } @@ -84,13 +85,10 @@ int isoburn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], 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 */; - + ret= burn_drive_grab_dummy(drive_infos, adr); + if(ret<=0) + return(ret); + o->emulation_mode= 2; /* standard i/o */ } else { /* >>> unsuitable file type */; @@ -107,7 +105,7 @@ int isoburn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], 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); + ret= isoburn_welcome_media(&o, (*drive_infos)[0].drive, 0); if(ret<=0) goto ex; } @@ -128,7 +126,7 @@ int isoburn_drive_grab(struct burn_drive *drive, int load) ret= burn_drive_grab(drive, load); if(ret<=0) goto ex; - ret= isoburn_examine_media(&o, drive, 0); + ret= isoburn_welcome_media(&o, drive, 0); if(ret<=0) goto ex; @@ -187,16 +185,14 @@ void isoburn_disc_erase(struct burn_drive *drive, int fast) ret= isoburn_find_emulator(&o, drive, 0); if(ret>0) { if(o->emulation_mode==-1) { - - /* >>> influence wrote_well reply or have wrote_well wrapper ? */ - + /* 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); - - /* >>> influence wrote_well reply or have wrote_well wrapper ? */ - + if(ret<=0) + burn_drive_cancel(drive); return; } } @@ -239,29 +235,103 @@ int isoburn_disc_track_lba_nwa(struct burn_drive *d, } -int isoburn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc) +void 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); } +#ifdef NIX + +int isoburn_random_access_write(struct burn_drive *d, off_t byte_address, + char *data, off_t data_count, int flag) +{ + int ret, mode = O_RDWR | O_LARGEFILE | O_CREAT; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(0); + if(o->emulation_mode==2) { + if(flag&1) + mode|= O_SYNC; + o->stdio_fd= open(o->stdio_path, mode); + if(o->stdio_fd==-1) { + + /* >>> cannot open stdio_path */; + return(0); + } + if(lseek(o->stdio_fd, byte_address, SEEK_SET)==-1) { + + /* >>> cannot reach given byte_address */; + ret= 0; goto close_stdio; + } + if(write(o->stdio_fd, data, data_count) != data_count) { + + /* >>> cannot write desired number of bytes */; + ret= 0; goto close_stdio; + } + + ret= 1; +close_stdio:; + close(o->stdio_fd); o->stdio_fd= -1; + } else if(o->emulation_mode==-1) + ret= 0; + else + ret= burn_random_access_write(d, byte_address, data, data_count, flag); + return(ret); +} + + +int burn_read_data(struct burn_drive *d, off_t byte_address, + char data[], off_t data_size, off_t *data_count, int flag) +{ + int ret, mode = O_RDONLY | O_LARGEFILE; + off_t count, todo; + struct isoburn *o; + + ret= isoburn_find_emulator(&o, d, 0); + if(ret<0) + return(0); + if(o->emulation_mode==2) { + o->stdio_fd= open(o->stdio_path, mode); + if(o->stdio_fd==-1) { + + /* >>> cannot open stdio_path */; + return(0); + } + if(lseek(o->stdio_fd, byte_address, SEEK_SET)==-1) { + + /* >>> cannot reach given byte_address */; + ret= 0; goto close_stdio; + } + for(todo= data_size; todo>0; ) { + count= read(o->stdio_fd, data+(data_size-todo), todo); + if(count<=0) + break; + todo-= count; + } + if(todo>0) { + + /* >>> cannot read desired number of bytes */; + ret= 0; goto close_stdio; + } + ret= 1; +close_stdio:; + close(o->stdio_fd); o->stdio_fd= -1; + } else if(o->emulation_mode==-1) + ret= 0; + else + ret= burn_read_data(d, byte_address, data, data_size, data_count, flag); + return(ret); +} + +#endif /* NIX */ + + void isoburn_drive_release(struct burn_drive *drive, int eject) { - int ret, no_drive_release= 0; + int ret; struct isoburn *o; ret= isoburn_find_emulator(&o, drive, 0); diff --git a/libisoburn/isoburn.c b/libisoburn/isoburn.c index bee03576..f512955e 100644 --- a/libisoburn/isoburn.c +++ b/libisoburn/isoburn.c @@ -17,7 +17,10 @@ #include #include #include +#include +#include "../libisofs/libisofs.h" +#include "../libburn/libburn.h" #include "isoburn.h" @@ -46,6 +49,12 @@ int isoburn_new(struct isoburn **objpt, int flag) o->emulation_mode= 0; o->min_start_byte= 0; o->nwa= 0; + +#ifdef NIX + o->stdio_path= NULL; + o->stdio_fd= -1; +#endif /* NIX */ + o->target_ropts= NULL; o->new_wopts= NULL; for(i=0;i<65536;i++) @@ -84,6 +93,13 @@ int isoburn_destroy(struct isoburn **objpt, int flag) /* >>> end mutex */ +#ifdef NIX + if(o->stdio_path!=NULL) + free((char *) o->stdio_path); + if(o->stdio_fd!=-1) + close(o->stdio_fd); +#endif + if(o->drive!=NULL) burn_drive_release(o->drive, 0); isoburn_free_rwopts(o); @@ -120,7 +136,8 @@ int isoburn_get_emulation_mode(struct isoburn *o, int *pt, int flag) } -int isoburn_get_target_volset(struct isoburn *o, struct volset **pt, int flag) +int isoburn_get_target_volset(struct isoburn *o, struct iso_volset **pt, + int flag) { *pt= o->target_volset; return(1); @@ -150,7 +167,7 @@ int isoburn_link(struct isoburn *o, struct isoburn *link, int flag) /* >>> mutex */ if(isoburn_list_start==NULL || - isoburn_list_start==link && (flag&1)) + (isoburn_list_start==link && (flag&1))) isoburn_list_start= o; if(o->prev!=NULL) o->prev->next= o->next; diff --git a/libisoburn/isoburn.h b/libisoburn/isoburn.h index 8c5d143a..232a7a3a 100644 --- a/libisoburn/isoburn.h +++ b/libisoburn/isoburn.h @@ -10,8 +10,6 @@ #define Isoburn_includeD -/* <<< as long as no inclusion of libisofs.h */ -struct volset; /* for uint8_t */ #include @@ -32,7 +30,7 @@ struct isoburn { /* Although rarely used, libburn can operate on several */ /* drives simultaneously. */ - /* >>> I propose to design isoburn as chain link of a list with its + /* >>> I propose to design isoburn as chain link of a list with its */ /* >>> start stored globally. */ struct isoburn *prev; struct isoburn *next; @@ -46,6 +44,15 @@ struct isoburn { /* Aligned start address to be used for processing (counted in blocks) */ int nwa; +#ifdef NIX + + /* Path for eventual stdandard i/o (see .emulation_mode) */ + char *stdio_path; + + /* File descriptor for stdandard i/o. Points to stdio_path object if not -1 */ + int stdio_fd; + +#endif /* NIX */ /* --- Vreixo's part --- */ @@ -57,7 +64,7 @@ struct isoburn { uint8_t target_iso_head[65536]; /* The filesystem structure of the old image from media. */ - struct volset *target_volset; + struct iso_volset *target_volset; /* The output options of the current run of libisofs. */ /* Element .overwrite eventually points to a buffered new head */ @@ -77,7 +84,8 @@ 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, struct volset **pt, int flag); +int isoburn_get_target_volset(struct isoburn *o, struct iso_volset **pt, + int flag); /* List management */ int isoburn_get_prev(struct isoburn *o, struct isoburn **pt, int flag);