From a2104bc9d1ae079ca1feac8c67acb984f64bfa9d Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Mon, 15 Oct 2007 15:27:51 +0000 Subject: [PATCH] Implemented -dev, -add, -commit --- test/xorriso.c | 129 +++++++++------ test/xorriso.h | 1 + test/xorriso_private.h | 7 + test/xorriso_timestamp.h | 2 +- test/xorrisoburn.c | 334 ++++++++++++++++++++++++++++++++++++++- test/xorrisoburn.h | 14 ++ 6 files changed, 438 insertions(+), 49 deletions(-) diff --git a/test/xorriso.c b/test/xorriso.c index c6521be4..3703ef7c 100644 --- a/test/xorriso.c +++ b/test/xorriso.c @@ -1692,7 +1692,11 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->do_reassure= 0; m->global_gid= 0; m->indev[0]= 0; + m->in_drive_handle= NULL; + m->in_volset_handle= NULL; + m->volset_change_pending= 0; m->outdev[0]= 0; + m->out_drive_handle= NULL; m->ban_stdio_write= 0; m->do_dummy= 0; m->do_close= 0; @@ -1784,33 +1788,6 @@ int Xorriso_destroy(struct XorrisO **xorriso, int flag) } -int Xorriso_clone_options(struct XorrisO *target, struct XorrisO *source, - int flag) -{ - int ret; - - target->dialog= source->dialog; - target->search_mode= source->search_mode; - target->use_stdin= source->use_stdin; - target->result_page_length= source->result_page_length; - target->result_page_width= source->result_page_width; - strcpy(target->mark_text,source->mark_text); - target->packet_output= source->packet_output; - target->status_history_max= source->status_history_max; - ret= Xorriso_prepare_regex(target,source->reg_expr,0); - if(ret<=0) - return(ret); - target->is_dialog= source->is_dialog; - target->bar_is_fresh= source->bar_is_fresh; - target->request_to_abort= source->request_to_abort; - target->error_count= source->error_count; - target->insert_count= source->insert_count; - target->insert_bytes= source->insert_bytes; - target->prepended_wd= source->prepended_wd; - return(1); -} - - int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize, int flag) /* @@ -2911,17 +2888,37 @@ int Xorriso_option_abort_on(struct XorrisO *xorriso, char *severity, int flag) int Xorriso_option_add(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) { - int i, end_idx; + int i, end_idx, ret; + char *target, *source, *ept, *path= NULL; end_idx= Xorriso__end_idx(argc, argv, *idx, 0); - fprintf(stderr, ">>> LIBISOFS : -add "); - for(i= *idx; iallow_graft_points) { + if(Sregex_string(&path,argv[i],0)<=0) { + + /* >>> out of memory */; + + {ret= -1; goto ex;} + } + ret= Fileliste__target_source_limit(path, '=', &ept, 0); + if(ret>0) { + *ept= 0; + source= ept+1; + } + } + ret= Xorriso_graft_in(xorriso, source, target, 0); + if(path!=NULL) + Sregex_string(&path,NULL,0); + path= NULL; + if(ret<=0) + goto ex; + } + ret= 1; +ex:; (*idx)= end_idx; - return(1); + return(ret); } @@ -3115,12 +3112,31 @@ int Xorriso_option_close(struct XorrisO *xorriso, char *mode, int flag) /* Option -commit */ +/* @param flag bit0= do not aquire outdrive as new indrive */ int Xorriso_option_commit(struct XorrisO *xorriso, int flag) { + int ret; + char newdev[SfileadrL]; - fprintf(stderr, ">>> LIBISOBURN : -commit\n"); + if(!xorriso->volset_change_pending) { + /* >>> */ + fprintf(stderr, "--- No image modifications pending on -commit\n"); - return(1); + return(2); + } + + /* >>> care for modifying */ + + ret= Xorriso_write_growing(xorriso, 0); + if(ret<=0) + return(ret); + xorriso->volset_change_pending= 0; + + if(flag&1) + return(1); + strcpy(newdev, xorriso->outdev); + ret= Xorriso_option_dev(xorriso, newdev, 3); + return(ret); } @@ -3163,22 +3179,25 @@ int Xorriso_option_dev(struct XorrisO *xorriso, char *adr, int flag) { int ret; - if(xorriso->indev[0]==0 && xorriso->outdev==0) { - ret= Xorriso_startup_libraries(xorriso, 0); - if(ret<=0) - return(ret); - } if((flag&3)==0) flag|= 3; - else { + if((flag&3)!=3) { /* <<< for now only -dev */; fprintf(stderr, ">>> XORRISO : would execute -%sdev %s\n", ((flag&3)==1 ? "in" : ((flag&3)==2 ? "out" : "")), adr); } - - fprintf(stderr, ">>> XORRISO : would execute -dev %s\n", adr); + if(xorriso->volset_change_pending) { + ret= Xorriso_option_commit(xorriso, 1); + if(ret<=0) + return(ret); + } + ret= Xorriso_aquire_drive(xorriso, adr, flag&3); + if(ret<=0) + return(ret); + strcpy(xorriso->indev, adr); + strcpy(xorriso->outdev, adr); return(1); } @@ -3210,6 +3229,7 @@ int Xorriso_option_dummy(struct XorrisO *xorriso, char *mode, int flag) /* Option -eject */ int Xorriso_option_eject(struct XorrisO *xorriso, char *which, int flag) { + /* <<< should become handles */ char *drive1="", *drive2=""; if(strncmp(which,"in",2)==0) @@ -3220,8 +3240,17 @@ int Xorriso_option_eject(struct XorrisO *xorriso, char *which, int flag) drive1= xorriso->indev; drive2= xorriso->outdev; } + if(drive1== xorriso->indev && xorriso->volset_change_pending) { + + /* >>> */ + fprintf(stderr, "--- Image changes pending. -commit or -rollback first\n"); + + return(0); + } + fprintf(stderr, ">>> LIBBURN : eject media in drive%s %s %s\n", (drive2[0]!=0 ? "s" : ""), drive1, drive2); + return(1); } @@ -3229,9 +3258,13 @@ int Xorriso_option_eject(struct XorrisO *xorriso, char *which, int flag) /* Option -end */ int Xorriso_option_end(struct XorrisO *xorriso, int flag) { + int ret; - fprintf(stderr, ">>> XORRISO : -end\n"); - + if(xorriso->volset_change_pending) { + ret= Xorriso_option_commit(xorriso, 1); + if(ret<=0) + return(ret); + } return(1); } @@ -4663,6 +4696,10 @@ int main(int argc, char **argv) if(ret<0) exit(5); + ret= Xorriso_startup_libraries(xorriso, 0); + if(ret<=0) + exit(4); + /* Interpret startup file */ if(!xorriso->no_rc) { ret= Xorriso_read_rc(xorriso, 0); diff --git a/test/xorriso.h b/test/xorriso.h index cbe2409d..513c83b7 100644 --- a/test/xorriso.h +++ b/test/xorriso.h @@ -59,6 +59,7 @@ int Xorriso_option_chowni(struct XorrisO *xorriso, char *uid, char *path, int Xorriso_option_close(struct XorrisO *xorriso, char *mode, int flag); /* Option -commit */ +/* @param flag bit0= do not aquire outdrive as new indrive */ int Xorriso_option_commit(struct XorrisO *xorriso, int flag); /* Option -cp_r alias -cp_ri */ diff --git a/test/xorriso_private.h b/test/xorriso_private.h index 68a5b663..08625d96 100644 --- a/test/xorriso_private.h +++ b/test/xorriso_private.h @@ -77,7 +77,14 @@ struct XorrisO { /* the global context of xorriso */ /* >>> put libburn/isoburn aspects here */ char indev[SfileadrL]; + void *in_drive_handle; /* interpreted only by xorrisoburn.c */ + void *in_volset_handle; /* interpreted only by xorrisoburn.c */ + + int volset_change_pending; /* whether -commit would make sense */ + char outdev[SfileadrL]; + void *out_drive_handle; /* interpreted only by xorrisoburn.c */ + int ban_stdio_write; int do_dummy; int do_close; diff --git a/test/xorriso_timestamp.h b/test/xorriso_timestamp.h index 96db10c1..e5f119c6 100644 --- a/test/xorriso_timestamp.h +++ b/test/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2007.10.14.122456" +#define Xorriso_timestamP "2007.10.15.152705" diff --git a/test/xorrisoburn.c b/test/xorrisoburn.c index 07c6b0f3..6cfd94d6 100644 --- a/test/xorrisoburn.c +++ b/test/xorrisoburn.c @@ -16,6 +16,7 @@ #include #include #include +#include /* ------------------------------------------------------------------------ */ @@ -47,7 +48,7 @@ int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag) char *handler_prefix= NULL; /* >>> rather send this to msg system of xorriso */; - fprintf(stderr, "starting up libraries ...\n"); + fprintf(stderr, "Starting up libraries ...\n"); handler_prefix= calloc(strlen(xorriso->progname)+3+1, 1); if(handler_prefix==NULL) { @@ -70,7 +71,7 @@ int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag) iso_msgs_set_severities("NEVER", "DEBUG", "libisofs : "); burn_msgs_set_severities("NEVER", "DEBUG", "libburn : "); sprintf(handler_prefix, "%s : ", xorriso->progname); - burn_set_signal_handling("%s : ", NULL, 0); + burn_set_signal_handling(handler_prefix, NULL, 0); fprintf(stderr,"Library startup done.\n"); free(handler_prefix); @@ -78,4 +79,333 @@ int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag) } +/* @param flag bit0=aquire as isoburn input drive + bit1=aquire as libburn output drive (as isoburn drive if bit0) +*/ +int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) +{ + int ret; + struct burn_drive_info *dinfo= NULL; + struct burn_drive *drive; + enum burn_disc_status state; + struct iso_volset *volset; + struct isoburn_read_opts ropts; + + + if((flag&3)!=3) { + fprintf(stderr,">>> XORRISOBURN: Xorriso_aquire_drive bit0+bit1 not set\n"); + return(0); + } + ret= Xorriso_give_up_drive(xorriso, flag&3); + if(ret<=0) + return(ret); + + ret= isoburn_drive_scan_and_grab(&dinfo, adr, 1); + if(ret<=0) { + fprintf(stderr,"--- Cannot aquire drive '%s'\n", adr); + return(0); + } + if(flag&2) + xorriso->out_drive_handle= dinfo; + if(flag&1) + xorriso->in_drive_handle= dinfo; + else + return(1); + + drive= dinfo[0].drive; + + /* check for invalid state */ + state= isoburn_disc_get_status(drive); + + /* >>> show drive and media status */; + + if(state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) { + + /* >>> rather send this to msg system of xorriso */; + fprintf(stderr, "Unsuitable disc status\n"); + + ret= 0; goto ex; + } + /* fill read opts */ + ropts.norock= 0; + ropts.nojoliet= 0; + ropts.preferjoliet= 0; + ropts.uid= 0; + ropts.gid= 0; + ropts.mode= 0555; + + if(isoburn_read_volset(drive, &ropts, &volset) <= 0) { + + /* >>> rather send this to msg system of xorriso */; + fprintf(stderr, "Can't read volset\n"); + + ret= 0; goto ex; + } + xorriso->in_volset_handle= volset; + ret= 1; +ex: + if(ret<=0) { + + /* >>> ??? give up not-so-suitable drive ? */; + + } + return(ret); +} + + +/* @param flag bit0=input drive + bit1=output drive +*/ +int Xorriso_give_up_drive(struct XorrisO *xorriso, int flag) +{ + int in_is_out_too; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + + in_is_out_too= (xorriso->in_drive_handle == xorriso->out_drive_handle); + + if((flag&1) && xorriso->in_drive_handle != NULL) { + dinfo= (struct burn_drive_info *) xorriso->in_drive_handle; + drive= dinfo[0].drive; + isoburn_drive_release(drive,0); + + /* >>> this should be an official reference for this pointer which was + handed out by isoburn_read_volset() and attached to invisible + struct isoburn. Then to be processed by: iso_volset_free(volset); + */ + xorriso->in_volset_handle= NULL; /* destroyed by isoburn_drive_release() */ + + burn_drive_info_free(dinfo); + xorriso->in_drive_handle= NULL; + if(in_is_out_too) + xorriso->out_drive_handle= NULL; + } + if((flag&2) && xorriso->out_drive_handle!=NULL) { + dinfo= (struct burn_drive_info *) xorriso->out_drive_handle; + drive= dinfo[0].drive; + isoburn_drive_release(drive,0); + burn_drive_info_free(dinfo); + xorriso->out_drive_handle= NULL; + + } + return(1); +} + +int Xorriso_write_growing(struct XorrisO *xorriso, int flag) +{ + int ret; + struct isoburn_source_opts sopts; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + struct burn_disc *disc; + struct burn_write_opts *burn_options; + + dinfo= (struct burn_drive_info *) xorriso->in_drive_handle; + if(dinfo==NULL) { + + /* >>> */ + fprintf(stderr, "--- No drive aquired\n"); + + return(0); + } + drive= dinfo[0].drive; + + sopts.level= 2; + sopts.flags= ECMA119_ROCKRIDGE; + if(xorriso->do_joliet) + sopts.flags|= ECMA119_ROCKRIDGE; + sopts.relaxed_constraints= 0; + sopts.copy_eltorito= 1; + sopts.no_cache_inodes= 0; + sopts.sort_files= 1; + sopts.default_mode= 0; + sopts.replace_dir_mode= 0; + sopts.dir_mode= 0555; + sopts.replace_file_mode= 0; + sopts.file_mode= 0444; + sopts.replace_uid= (xorriso->do_global_uid); + sopts.uid= xorriso->global_uid; + sopts.replace_gid= (xorriso->do_global_gid); + sopts.gid= xorriso->global_gid; + sopts.input_charset= NULL; + sopts.ouput_charset= NULL; + + /* >>> -fs : isoburn_prepare_disc() needs fifo parameters */ + + if (isoburn_prepare_disc(drive, &disc, &sopts) <= 0) { + + /* >>> */ + fprintf(stderr, "--- Cannot prepare disc\n"); + + return(0); + } + + burn_options= burn_write_opts_new(drive); + if(burn_options==NULL) { + + /* >>> */ + fprintf(stderr, "--- Cannot allocate option set\n"); + + return(0); + } + burn_write_opts_set_simulate(burn_options, !!xorriso->do_dummy); + burn_write_opts_set_multi(burn_options, !xorriso->do_close); + burn_drive_set_speed(drive, xorriso->speed, xorriso->speed); + burn_write_opts_set_underrun_proof(burn_options, 1); + + isoburn_disc_write(burn_options, disc); + burn_write_opts_free(burn_options); + + ret= Xorriso_pacifier_loop(xorriso, drive, 0); + if(ret<=0) + return(ret); + + ret= isoburn_activate_session(drive); + if(ret<=0) { + fprintf(stderr, "--- Could not write new set olf volume descriptors\n"); + return(ret); + } + + /* >>> cleanup disc ? */ + + return(1); +} + + +int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive, + int flag) +{ + int ret, size, free_bytes, i; + struct burn_progress progress; + char *status_text; + + + while(burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) + usleep(100002); + + while(burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) { + + /* >>> make this output go into xorriso info channel */; + + printf("Writing: sector %d of %d", + progress.sector, progress.sectors); + ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text); + if(ret>0 ) + printf(" [fifo %s, %2d%% fill]", status_text, + (int) (100.0-100.0*((double) free_bytes)/(double) size)); + printf("\n"); + + for(i= 0; i<10; i++) { + + /* >>> check message system of libburn */; + + usleep(100000); + } + } + return(1); +} + + +int Xorriso_graft_in(struct XorrisO *xorriso, char *disk_path, char *img_path, + int flag) +{ + struct iso_volume *volume; + struct iso_tree_radd_dir_behavior behav= {NULL, 0, 0}; + char path[SfileadrL], *apt, *npt; + struct iso_tree_node_dir *dir; + struct iso_tree_node *node; + int done= 0, is_dir= 0; + struct stat stbuf; + + strncpy(path, img_path, sizeof(path)-1); + path[sizeof(path)-1]= 0; + apt= npt= path; + volume= iso_volset_get_volume( + (struct iso_volset *) xorriso->in_volset_handle, 0); + + if(lstat(disk_path, &stbuf) == -1) { + + /* >>> */ + fprintf(stderr, "--- Cannot determine attributes of '%s' : %s (%d)\n", + disk_path, (errno > 0 ? strerror(errno) : "unknown error"), errno); + + return(0); + } + if(S_ISDIR(stbuf.st_mode)) + is_dir= 1; + else if(!(S_ISREG(stbuf.st_mode) || S_ISLNK(stbuf.st_mode))) { + + /* >>> */ + fprintf(stderr, "--- File object '%s' is of non-supported file type\n", + disk_path); + + return(0); + } + + dir= iso_volume_get_root(volume); + if(dir==NULL) { + + /* >>> */ + fprintf(stderr, "--- While grafting '%s' : no root node available\n", + img_path); + + return(0); + } + for(npt= apt; !done; apt= npt+1) { + npt= strchr(apt, '/'); + if(npt==NULL) { + npt= apt+strlen(apt); + done= 1; + } else + *npt= 0; + if(*apt==0) { + *apt= '/'; + apt++; + continue; + } + node= iso_tree_volume_path_to_node(volume,path); + if(node!=NULL) { + if(iso_tree_node_get_type(node)!=LIBISO_NODE_DIR) { + + /* >>> */ + fprintf(stderr, "--- While grafting '%s' : '%s' is not a directory\n", + img_path, path); + + return(0); + } + dir= (struct iso_tree_node_dir *) node; + } else { + dir= iso_tree_add_dir(dir, apt); + if(dir==NULL) { + + /* >>> */ + fprintf(stderr, "--- While grafting '%s' : could not insert '%s'\n", + img_path, path); + + return(0); + } + } + if(done) { + if(is_dir) { + iso_tree_radd_dir(dir, disk_path, &behav); + } else { + node= iso_tree_add_node(dir, disk_path); + if(node == NULL) { + + /* >>> */ + fprintf(stderr, "While grafting '%s'='%s' : libisofs_errno = %d\n", + img_path, disk_path, libisofs_errno); + + return(0); + } + } + } else + *npt= '/'; + } + fprintf(stderr, "NOTE: added %s '%s'='%s'\n", (is_dir ? "directory" : "node"), + img_path, disk_path); + xorriso->volset_change_pending= 1; + return(1); +} + diff --git a/test/xorrisoburn.h b/test/xorrisoburn.h index 0064cf50..4859ca8f 100644 --- a/test/xorrisoburn.h +++ b/test/xorrisoburn.h @@ -15,9 +15,23 @@ #define Xorrisoburn_includeD yes struct XorrisO; +struct burn_drive; int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag); +int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag); + +int Xorriso_give_up_drive(struct XorrisO *xorriso, int flag); + +int Xorriso_write_growing(struct XorrisO *xorriso, int flag); + +int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive, + int flag); + +int Xorriso_graft_in(struct XorrisO *xorriso, char *disk_path, char *img_path, + int flag); + + #endif /* Xorrisoburn_includeD */