From 8e131041a46d34100f03c5b371c5a87b99363367 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Fri, 5 Dec 2008 17:17:29 +0000 Subject: [PATCH] New options -mount and -mount_cmd --- xorriso/xorriso.1 | 75 ++++++++- xorriso/xorriso.c | 321 +++++++++++++++++++++++++++++++++++- xorriso/xorriso.h | 7 + xorriso/xorriso_private.h | 5 + xorriso/xorriso_timestamp.h | 2 +- xorriso/xorrisoburn.c | 168 ++++++++++++++++++- 6 files changed, 564 insertions(+), 14 deletions(-) diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index cb4a3f41..a3afec61 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "Nov 28, 2008" +.TH XORRISO 1 "Dec 05, 2008" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -547,7 +547,8 @@ address. The following entities are defined: .br "lba" or "sbsector" with a number as of a line "ISO ...", column "sbsector". .br -"volid" with a text as of a line "ISO ...", column "Volume Id". +"volid" with a search pattern for a text as of a line "ISO ...", +column "Volume Id". .br Adressing a non-existing entity or one which does not represent an ISO image will either abandon -indev or at least lead to a blank image. @@ -1791,6 +1792,34 @@ to be the most recent real session then. Some read-only drives and media show no usable session history at all. Eventually option -rom_toc_scan might help. .TP +\fB\-mount_cmd\fR drive entity id command_form +Print to the result channel an appropriate command line for mounting the +ISO session which is depicted by drive, entity and id. The id can be a block +address with entity "sbsector", a track number with "track", a session number +with "session", a volume id search pattern with "volid", or any text with +"auto". See also option -load. +.br +drive can be "indev", "outdev" or the address of a not yet aquired drive. +Prefix "stdio:" for non MMC drives is not mandatory. +.br +command_form is either "linux:"path , or "freebsd:"path, or "shell:"command, +or a path. +The path will be used as moint point and has already to exist as directory. +A command line with suitable options is then generated. +If no recognizable prefix is given then xorriso guesses on which kind of +system it runs and uses the whole command_form as path. +.br +If shell:command is given, then xorriso will substitute in the command text +the following parameter names: +.br +"%device%" will be substituted by the mountable device path of the drive +address. +.br +"%sbsector%" will be substituted by the session start sector. +.br +"%track%", "%session%", "%volid%" will be substituted by track number, +session number, resp. volume id of the depicted session. +.TP \fB\-print_size\fR Print the foreseeable consumption of 2048 byte blocks by next -commit. This can last a while as a -commit gets @@ -2168,6 +2197,14 @@ Read the content of a ISO data file and write it into a data file on disk beginning at the byte_offset. Write at most byte_count bytes. This is the inverse of option -cut_out. .TP +\fB\-mount\fR drive entity id command_form +Produce the same line as -mount_cmd and then execute it as shell command +after giving up the depicted drive. +This demands -osirrox to be enabled and normally will succeed only for the +superuser. For safety reasons it will refuse to execute the command line +if it stems from command_form shell:command or if setuid or setgid are in +effect. In these cases -mount will default to -mount_cmd and a SORRY event. +.TP .B Command compatibility emulations: .PP Writing of ISO 9660 on CD is traditionally done by program mkisofs @@ -2499,14 +2536,27 @@ which shall be able to use the drives with xorriso. 2 -dev '/dev/sr2' rwrw-- : 'PHILIPS ' 'SPD3300L' .SS .B Blank media and compose a new ISO image as batch run -Aquire drive /dev/sr2, blank media resp. invalidate existing ISO image. -Add the files from hard disk directories /home/me/sounds and /pictures. +Aquire drive /dev/sr2, make media ready for writing a new image, +fill the image with the files from hard disk directories /home/me/sounds +and /home/me/pictures. +.br +Because no -dialog "on" is given, the program will then end by writing the +session to media. +.br +\fB$\fR xorriso -outdev /dev/sr2 \\ +.br + -blank as_needed \\ +.br + -map /home/me/sounds /sounds \\ +.br + -map /home/me/pictures /pictures +.br + +.br +The ISO image may be shaped in a more elaborate way like the following: Omit some unwanted stuff by removing it from the image directory tree. Re-add some wanted stuff. .br -Because no -dialog "on" is given, the program will then end by committing the -session to media. -.br \fB$\fR cd /home/me .br \fB$\fR xorriso -outdev /dev/sr2 \\ @@ -2790,13 +2840,20 @@ This makes sense if the full backup leaves substantial remaining capacity on media and if the expected changes are much smaller than the full backup. An update run will probably save no time but last longer than a full backup. .br -With \fBmount\fR option -o \fB"sbsector="\fR on Linux resp. \fB-s\fR on FreeBSD +With \fBmount\fR option \fB-o "sbsector="\fR on Linux resp. \fB-s\fR on FreeBSD it is possible to access the session trees which represent the older backup versions. With CD media, Linux mount accepts session numbers directly by its option "session=". .br Multi-session media and most overwriteable media written by xorriso can tell the sbsectors of their sessions by xorriso option -toc. +Used after -commit the following option prints the matching mount command for +the newly written session (here for mount point /mnt): +.br + -mount_cmd "indev" "auto" "auto" /mnt +.br +Options -mount_cmd and -mount are also able to produce the mount commands for +older sessions in the table-of-content. .br Sessions on multi-session media are separated by several MB of unused blocks. So with small sessions the payload capacity can become substantially lower @@ -2821,7 +2878,7 @@ First check which backup sessions are on the media: Then load the desired session and copy the file trees to disk. Avoid to eventually create /home/thomas/restored without rwx-permission. .br -\fB$\fR xorriso -load volid PROJECTS_MAIL_2008_06_19_205956 \\ +\fB$\fR xorriso -load volid 'PROJECTS_MAIL_2008_06_19*' \\ .br -indev /dev/sr0 \\ .br diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 4302f478..af1e3351 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -1598,6 +1598,124 @@ int Sregex_string(char **handle, char *text, int flag) return(ret); } + +/* + vars[][0] points to the variable names, vars[][1] to their contents. + start marks the begin of variable names. It must be non-empty. esc before + start disables this meaning. start and esc may be equal but else they must + have disjoint character sets. + end marks the end of a variable name. It may be empty but if non-empty it + must not appear in vars[][0]. + @param flag bit0= Substitute unknown variables by empty text + (else copy start,name,end unaltered to result). + Parameter end must be non-empty for that. +*/ +int Sregex_resolve_var(char *form, char *vars[][2], int num_vars, + char *start, char *end, char *esc, + char *result, int result_size, int flag) +{ + int l_e, l_v, l_s, l_esc, i, start_equals_esc; + char *rpt, *wpt, *spt, *npt, *ept; + + if(start[0] == 0) /* It is not allowed to have no start marker */ + return(-1); + l_s= strlen(start); + l_e= strlen(end); + l_esc= strlen(esc); + start_equals_esc= !strcmp(start, esc); + rpt= form; + wpt= result; + wpt[0]= 0; + while(1) { + + /* look for start mark */ + spt= strstr(rpt, start); + if(spt == NULL) { + if((wpt - result) + strlen(rpt) >= result_size) + return(0); + strcpy(wpt, rpt); + wpt+= strlen(wpt); + break; + } + + /* copy cleartext part up to next variable */ + if((wpt - result) + (spt - rpt) >= result_size) + return(0); + strncpy(wpt, rpt, spt - rpt); + wpt+= spt - rpt; + *wpt= 0; + rpt= spt; + npt= spt + l_s; + + /* handle eventual escape */ + if(start_equals_esc) { + if(strncmp(spt + l_s, esc, l_esc) == 0) { + /* copy esc and start */ + if((wpt - result) + l_esc + l_s >= result_size) + return(0); + strncpy(wpt, spt, l_esc + l_s); + wpt+= l_esc + l_s; + rpt+= l_esc + l_s; + *wpt= 0; + continue; + } + } else { + /* escape would be already copied */ + if(l_esc > 0 && spt - form >= l_esc) { + if(strncmp(spt - l_esc, esc, l_esc) == 0) { + /* copy start */ + if((wpt - result) + l_s >= result_size) + return(0); + strncpy(wpt, spt, l_s); + wpt+= l_s; + rpt+= l_s; + *wpt= 0; + continue; + } + } + } + + /* Memorize eventual end mark for default handling */; + ept= NULL; + if(l_e > 0) + ept= strstr(npt, end); + + /* Look for defined variable name */ + for(i = 0; i < num_vars; i++) { + if(strncmp(npt, vars[i][0], strlen(vars[i][0])) == 0 + && (l_e == 0 || strncmp(npt + strlen(vars[i][0]), end, l_e) == 0)) + break; + } + if(i < num_vars) { + /* substitute found variable */ + l_v= strlen(vars[i][0]); + if((wpt - result) + strlen(vars[i][1]) >= result_size) + return(0); + strcpy(wpt, vars[i][1]); + rpt= npt + strlen(vars[i][0]) + l_e; + } else if((flag & 1) && ept != NULL) { + /* skip up to end mark */ + rpt= ept + l_e; + } else if(ept != NULL) { + /* copy start,name,end */ + if((wpt - result) + (ept - rpt) + l_e >= result_size) + return(0); + strncpy(wpt, rpt, (ept - rpt) + l_e); + rpt= ept + l_e; + } else { + /* copy start marker only */ + if((wpt - result) + l_s >= result_size) + return(0); + strncpy(wpt, rpt, l_s); + rpt= rpt + l_s; + } + wpt+= strlen(wpt); + *wpt= 0; + } + return(1); +} + + #endif /* Xorriso_sregex_externaL */ @@ -10195,6 +10313,133 @@ int Xorriso_open_job_data_to(struct XorrisO *xorriso, } +int Xorriso_make_mount_cmd(struct XorrisO *xorriso, char *cmd, + int lba, int track, int session, char *volid, + char *devadr, char result[SfileadrL], int flag) +{ + int ret, reg_file= 0, is_safe= 0, sys_code= 0; + char form[6*SfileadrL], session_text[12], track_text[12], lba_text[12]; + char *vars[5][2], sfe[5*SfileadrL], volid_sfe[5*80+1], *cpt; + struct stat stbuf; + + if(strlen(cmd) > SfileadrL) { +/* +too_long:; +*/ + /* >>> complain about argument too long */; + + return(0); + } + ret= stat(devadr, &stbuf); + if(ret != -1) + if(S_ISREG(stbuf.st_mode)) + reg_file= 1; + if(strncmp(cmd, "linux:", 6) == 0) { + cpt= cmd + 6; + sys_code= 1; + } else if(strncmp(cmd, "freebsd:", 8) == 0) { + cpt= cmd + 8; + sys_code= 2; + } else if(strncmp(cmd, "shell:", 6) == 0) { + cpt= cmd + 6; + strcpy(form, cpt); + } else { + cpt= cmd; +#ifdef __FreeBSD__ + sys_code= 2; +#else + sys_code= 1; +#endif + } + + if(sys_code == 1) { /* Linux */ + sprintf(form, + "mount -t iso9660 -o %snodev,noexec,nosuid,ro,sbsector=%%sbsector%% %%device%% %s", + (reg_file ? "loop," : ""), Text_shellsafe(cpt, sfe, 0)); + is_safe= 1; + } else if(sys_code == 2) { /* FreeBSD */ + /* eventually create vnode as of J.R. Oldroyd , 20 Nov 2008: + # mdconfig -a -t vnode -f xfburn.iso + /dev/md0 + (Real CD drives look like /dev/cd0) + */ + if(reg_file) { + strcpy(form, "n=$(mdconfig -a -t vnode -f %device%)"); + sprintf(form + strlen(form), + " && mount -t cd9660 -o noexec,nosuid -s %%sbsector%% \"$n\" %s", + Text_shellsafe(cmd+8, sfe, 0)); + } else + sprintf(form, + "mount -t cd9660 -o noexec,nosuid -s %%sbsector%% %%device%% %s", + Text_shellsafe(cmd+8, sfe, 0)); + is_safe= 1; + } + sprintf(session_text, "%d", session); + sprintf(track_text, "%d", track); + sprintf(lba_text, "%d", lba); + vars[0][0]= "sbsector"; + vars[0][1]= lba_text; + vars[1][0]= "track"; + vars[1][1]= track_text; + vars[2][0]= "session"; + vars[2][1]= session_text; + vars[3][0]= "volid"; + vars[3][1]= Text_shellsafe(volid, volid_sfe, 0); + vars[4][0]= "device"; + vars[4][1]= Text_shellsafe(devadr, sfe, 0); + ret= Sregex_resolve_var(form, vars, 5, "%", "%", "%", result, SfileadrL, 0); + if(ret <= 0) + return(ret); + return(1 + is_safe); +} + + +int Xorriso_decode_load_adr(struct XorrisO *xorriso, char *cmd, + char *adr_mode, char *adr_value, + int *entity_code, char entity_id[81], + int flag) +{ + double num; + int l; + + if(strcmp(adr_mode, "auto")==0) + *entity_code= 0; + else if(strcmp(adr_mode, "session")==0) + *entity_code= 1; + else if(strcmp(adr_mode, "track")==0) + *entity_code= 2; + else if(strcmp(adr_mode, "lba")==0 || strcmp(adr_mode, "sbsector")==0) + *entity_code= 3 | ((flag&1) << 16); + else if(strcmp(adr_mode, "volid")==0) + *entity_code= 4; + else { + sprintf(xorriso->info_text, "%s: unknown address mode '%s'", cmd, adr_mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + l= strlen(adr_value); + if(l==0) + *entity_code= 0; + + if(*entity_code>=1 && *entity_code<= 3) { + num= Scanf_io_size(adr_value, 0); + if(*entity_code==3 && + (adr_value[l-1]<'0' || adr_value[l-1]>'9')) + num/= 2048.0; + sprintf(entity_id, "%.f", num); + } else { + if(strlen(adr_value)>80) { + sprintf(xorriso->info_text, "%s: address value too long (80 < %d)", + cmd, (int) strlen(adr_value)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + strcpy(entity_id, adr_value); + } + return(1); +} + + /* ---------------------------- Options API ------------------------ */ @@ -12494,6 +12739,10 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) "", " -toc Show media specific table of content (sessions).", "", +" -mount_cmd drive entity id \"linux:\"path|\"freebsd:\"path|\"shell:\"form", +" Print to result channel a command suitable to mount the", +" depicted entity (see -load) at the given directory path.", +"", " -list_formats Show media specific list of format descriptors.", "", " -print_size Print the foreseeable consumption by next -commit.", @@ -12728,6 +12977,9 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " Like -cp_rx but trying to restore timestamps and ownership.", " -paste_in iso_rr_path disk_path byte_offset byte_count", " Copy ISO file content into a byte interval of a disk file.", +" -mount drive entity id \"linux:\"path|\"freebsd:\"path|\"shell:\"form", +" Like -mount_cmd but actually performing that command if it", +" is not from a shell:form and no setuid or setgid is active.", "", "Evaluation of readability:", " -check_media [options] --", @@ -12975,8 +13227,7 @@ int Xorriso_option_list_formats(struct XorrisO *xorriso, int flag) int Xorriso_option_load(struct XorrisO *xorriso, char *adr_mode, char *adr_value, int flag) { - double num; - int ret, l; + int ret; if(xorriso->volset_change_pending) { sprintf(xorriso->info_text, @@ -12987,6 +13238,20 @@ int Xorriso_option_load(struct XorrisO *xorriso, char *adr_mode, ret= Xorriso_reassure(xorriso, "-load", "loads an alternative image", 0); if(ret<=0) return(2); + +#ifndef NIX + + ret= Xorriso_decode_load_adr(xorriso, "-load", adr_mode, adr_value, + &(xorriso->image_start_mode), + xorriso->image_start_value, 0); + if(ret <= 0) + return(ret); + +#else + + double num; + int l; + if(strcmp(adr_mode, "auto")==0) xorriso->image_start_mode= 0; else if(strcmp(adr_mode, "session")==0) @@ -13021,6 +13286,9 @@ int Xorriso_option_load(struct XorrisO *xorriso, char *adr_mode, } strcpy(xorriso->image_start_value, adr_value); } + +#endif /* NIX */ + xorriso->image_start_mode|= (1<<30); /* enable non-default msc1 processing */ if(strlen(xorriso->indev)>0) { ret= Xorriso_option_rollback(xorriso, 1); /* Load image, no -reassure */ @@ -13437,6 +13705,41 @@ ex:; } +/* Option -mount */ +/* @param bit0= print mount command to result channel rather than performing it +*/ +int Xorriso_option_mount(struct XorrisO *xorriso, char *dev, char *adr_mode, + char *adr, char *cmd, int flag) +{ + int ret, entity_code= 0; + char entity_id[81], *mnt; + + if(flag & 1) + mnt= "-mount_cmd"; + else { + mnt= "-mount"; + if(!xorriso->allow_restore) { + sprintf(xorriso->info_text, + "-mount: image-to-disk features are not enabled by option -osirrox"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(xorriso->volset_change_pending) { + sprintf(xorriso->info_text, + "%s: Image changes pending. -commit or -rollback first", mnt); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + ret= Xorriso_decode_load_adr(xorriso, mnt, adr_mode, adr, + &entity_code, entity_id, 0); + if(ret <= 0) + return(ret); + ret= Xorriso_mount(xorriso, dev, entity_code, entity_id, cmd, flag & 1); + return(ret); +} + + /* Option -mv alias -mvi */ int Xorriso_option_mvi(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) @@ -14890,7 +15193,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, "" }; static char arg4_commands[][40]= { - "cut_out","extract_cut","paste_in", + "cut_out","extract_cut","mount","mount_cmd","paste_in", "" }; static char argn_commands[][40]= { @@ -15317,6 +15620,18 @@ next_command:; (*idx)++; ret= Xorriso_option_mark(xorriso, arg1, 0); + } else if(strcmp(cmd, "mount") == 0 || strcmp(cmd, "mount_cmd") == 0) { + (*idx)+= 4; + if((*idx)>argc) { + sprintf(xorriso->info_text, + "-mount: Not enough arguments. Needed are: device entity id command"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; + } else + ret= Xorriso_option_mount(xorriso, arg1, arg2, + argv[(*idx)-2], argv[(*idx)-1], + (strcmp(cmd, "mount_cmd") == 0)); + } else if(strcmp(cmd,"mv")==0 || strcmp(cmd,"mvi")==0) { ret= Xorriso_option_mvi(xorriso, argc, argv, idx, 0); diff --git a/xorriso/xorriso.h b/xorriso/xorriso.h index f21b179f..1afcd7e1 100644 --- a/xorriso/xorriso.h +++ b/xorriso/xorriso.h @@ -533,6 +533,13 @@ int Xorriso_option_mark(struct XorrisO *xorriso, char *mark, int flag); int Xorriso_option_mkdiri(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag); +/* Option -mount */ +/* @param bit0= print mount command to result channel rather than performing it +*/ +int Xorriso_option_mount(struct XorrisO *xorriso, char *dev, char *adr_mode, + char *adr, char *cmd, int flag); + + /* Option -mv alias -mvi */ int Xorriso_option_mvi(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag); diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index d301348a..d990e66b 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -593,6 +593,11 @@ int Xorriso_open_job_data_to(struct XorrisO *xorriso, int Xorriso_no_findjob(struct XorrisO *xorriso, char *cmd, int flag); +int Xorriso_make_mount_cmd(struct XorrisO *xorriso, char *cmd, + int lba, int track, int session, char *volid, + char *devadr, char result[SfileadrL], int flag); + + int Sfile_str(char target[SfileadrL], char *source, int flag); double Sfile_microtime(int flag); diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index eba99bc6..cfc49598 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.12.05.171005" +#define Xorriso_timestamP "2008.12.05.171700" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index fc2ee28e..aca77c45 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -20,6 +20,7 @@ #include #include #include +#include /* for -charset */ #include @@ -524,7 +525,7 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) dinfo= out_dinfo; } else if((flag&3)==2 && xorriso->in_drive_handle!=NULL) { ret= Xorriso_get_drive_handles(xorriso, &in_dinfo, &in_drive, - "on attempt to compare new indev with outdev", 0); + "on attempt to compare new outdev with indev", 0); if(ret<=0) goto ex; ret= burn_drive_equals_adr(in_drive, libburn_adr, 1); @@ -8412,3 +8413,168 @@ int Xorriso_get_relax_text(struct XorrisO *xorriso, char mode[1024], } +/** + @param flag bit0= print mount command to result channel rather than + performing it +*/ +int Xorriso_mount(struct XorrisO *xorriso, char *dev, int adr_mode, + char *adr_value, char *cmd, int flag) +{ + int ret, lba, track, session, params_flag= 0, is_safe= 0, is_extra_drive= 0; + int give_up= 0; + char volid[33], *devadr, mount_command[SfileadrL], adr_data[163], *adr_pt; + char *dev_path, libburn_adr[BURN_DRIVE_ADR_LEN + SfileadrL]; + char sfe[5 * SfileadrL], *dpt; + struct stat stbuf; + struct burn_drive_info *dinfo= NULL; + struct burn_drive *drive= NULL; + + devadr= dev; + adr_pt= adr_value; + if(strcmp(dev, "indev") == 0) { + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to perform -mount \"indev\"", 0); + if(ret<=0) + goto ex; + devadr= xorriso->indev; + if(xorriso->in_drive_handle == xorriso->out_drive_handle) + give_up= 3; + else + give_up= 1; + } else if(strcmp(dev, "outdev") == 0) { + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to perform -mount \"outdev\"", + 2); + if(ret<=0) + goto ex; + devadr= xorriso->outdev; + if(xorriso->in_drive_handle == xorriso->out_drive_handle) + give_up= 3; + else + give_up= 2; + } else { + is_extra_drive= 1; + dev_path= dev; + if(strncmp(dev_path, "stdio:", 6) == 0) + dev_path+= 6; + + /* do only accept regular files and block devices */ + ret= stat(dev_path, &stbuf); + if(ret == -1) { + sprintf(xorriso->info_text, "Cannot determine properties of file %s", + Text_shellsafe(dev_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(!(S_ISREG(stbuf.st_mode) || S_ISBLK(stbuf.st_mode))) { + sprintf(xorriso->info_text, + "File object is not suitable as mount device: %s", + Text_shellsafe(dev_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + /* Aquire drive as direct libburn address or via stdio: prefix */ + ret= burn_drive_convert_fs_adr(dev, libburn_adr); + Xorriso_process_msg_queues(xorriso,0); + if(ret < 0) + {ret= -1; goto ex;} + if(ret == 0 && strncmp(dev, "stdio:", 6) != 0) + sprintf(libburn_adr, "stdio:%s", dev); + ret= isoburn_drive_aquire(&dinfo, libburn_adr, 1); + Xorriso_process_msg_queues(xorriso,0); + if(ret <= 0) + {ret= 0; goto ex;} + drive= dinfo[0].drive; + } + + if(adr_mode == 4 && strlen(adr_pt) <= 80) { + ret= Xorriso__bourne_to_reg(adr_pt, adr_data, 0); + if(ret == 1) { + params_flag|= 4; + adr_pt= adr_data; + } + } + ret= isoburn_get_mount_params(drive, adr_mode, adr_pt, &lba, &track, + &session, volid, params_flag); + Xorriso_process_msg_queues(xorriso,0); + if(ret <= 0) + goto ex; + if(session <= 0 || track <= 0 || ret == 2) { + Xorriso_msgs_submit(xorriso, 0, + "-mount : Given address does not point to an ISO 9660 session", + 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(strstr(devadr, "stdio:") == devadr) + devadr+= 6; + ret= Xorriso_make_mount_cmd(xorriso, cmd, lba, track, session, volid, devadr, + mount_command, 0); + if(ret <= 0) + goto ex; + if(ret == 2) + is_safe= 1; + + if(is_extra_drive) { + isoburn_drive_release(drive, 0); + burn_drive_info_free(dinfo); + drive= NULL; + } else if(give_up > 0 && !(flag & 1)) { + Xorriso_give_up_drive(xorriso, give_up); + if(ret <= 0) + goto ex; + } + Xorriso_process_msg_queues(xorriso,0); + + sprintf(xorriso->info_text, "Volume id : %s\n", + Text_shellsafe(volid, sfe, 0)); + Xorriso_info(xorriso, 0); + if(flag & 1) { + sprintf(xorriso->result_line, "%s\n", mount_command); + Xorriso_result(xorriso,0); + } else { + sprintf(xorriso->info_text, "Mount command: %s\n", mount_command); + Xorriso_info(xorriso, 0); + if(geteuid() != getuid() || getgid() != getegid()) { + Xorriso_msgs_submit(xorriso, 0, + "-mount : Detected own setuid/gid identity. Will not perform mount command.", + 0, "SORRY", 0); + sprintf(xorriso->result_line, "%s\n", mount_command); + Xorriso_result(xorriso,0); + } else if(!is_safe) { + Xorriso_msgs_submit(xorriso, 0, + "-mount : Will not perform mount command which stems from command template.", + 0, "SORRY", 0); + sprintf(xorriso->result_line, "%s\n", mount_command); + Xorriso_result(xorriso,0); + } else { + + /* >>> find safer way to perform command */; + ret= system(mount_command); + + if(WIFEXITED(ret) && WEXITSTATUS(ret) != 0) { + sprintf(xorriso->info_text, + "-mount : mount command failed with exit value %d", + (int) WEXITSTATUS(ret)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + sprintf(xorriso->info_text, "Mounted session %d of device %s", + session, Text_shellsafe(dev_path, sfe, 0)); + dpt= strchr(cmd, ':'); + if(dpt == NULL) + dpt= cmd; + sprintf(xorriso->info_text + strlen(xorriso->info_text), + " as directory %s\n", Text_shellsafe(dpt + 1, sfe, 0)); + Xorriso_info(xorriso, 0); + } + } + ret= 1; +ex:; + if(is_extra_drive && drive != NULL) { + isoburn_drive_release(drive, 0); + burn_drive_info_free(dinfo); + Xorriso_process_msg_queues(xorriso,0); + } + return(ret); +}