Got rid of call system() in Xorriso_mount(), new option -session_string

This commit is contained in:
Thomas Schmitt 2008-12-07 12:25:07 +00:00
parent b3089477fd
commit df1d2a2652
5 changed files with 245 additions and 67 deletions

View File

@ -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 "Dec 05, 2008"
.TH XORRISO 1 "Dec 07, 2008"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -59,6 +59,8 @@ Can perform multi-session tasks as emulation of mkisofs and cdrecord.
.br
Can restore files from ISO image to disk filesystem (see osirrox).
.br
Can issue commands to mount older sessions on Linux or FreeBSD.
.br
Can check media for damages and copy readable blocks to disk.
.br
Scans for optical drives, blanks re-useable optical media.
@ -1792,25 +1794,32 @@ 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
\fB\-mount_cmd\fR drive entity id path
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.
ISO session which is depicted by drive, entity and id. See option -mount
for direct execution of this command.
.br
drive can be "indev", "outdev" or the address of a not yet aquired drive.
Prefix "stdio:" for non MMC drives is not mandatory.
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.
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 a dummy text with "auto". See also option -load.
.br
If shell:command is given, then xorriso will substitute in the command text
the following parameter names:
path will be used as mount point and has already to exist as directory.
.br
xorriso determines on which kind of system it runs. Supported are Linux and
FreeBSD.
.TP
\fB\-session_string\fR drive entity id format
Print to the result channel a text which gets composed according to
format and the parameters of the addressed session.
.br
Formats "linux:"path or "freebsd:"path produce the output of -mount_cmd
for the given operating systems.
.br
In other texts xorriso will substitute the following parameter names.
An optional prefix "string:" will be removed.
.br
"%device%" will be substituted by the mountable device path of the drive
address.
@ -2197,13 +2206,12 @@ 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
\fB\-mount\fR drive entity id path
Produce the same line as -mount_cmd and then execute it as external program run
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.
superuser. For safety reasons the mount program is only executed if it is
reachable as /bin/mount or /sbin/mount.
.TP
.B Command compatibility emulations:
.PP
@ -2853,7 +2861,9 @@ the newly written session (here for mount point /mnt):
-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.
older sessions in the table-of-content. E.g. as superuser:
.br
\fB$\fR osirrox -mount /dev/sr0 "volid" '*2008_12_05*' /mnt
.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

View File

@ -723,12 +723,12 @@ int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
bit2= abort with return(0) if incomplete quotes are found
bit3= eventually prepend missing '-' to first argument read from line
bit4= like bit2 but only check quote completeness, do not allocate memory
>>>
bit5+6= interpretation of backslashes:
0= no interpretation, leave unchanged
1= only inside double quotes
2= outside single quotes
3= everywhere
bit7= append a NULL element to argv
*/
{
int i,pass,maxl=0,l,argzaehl=0,bufl,line_start_argc, bsl_mode, ret= 0, eaten;
@ -848,8 +848,9 @@ int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
if(flag & 16)
{ret= 1; goto ex;}
*argc= argzaehl;
if(argzaehl>0) {
*argv= (char **) Smem_malloC(argzaehl*sizeof(char *));
if(argzaehl>0 || (flag & 128)) {
*argv= (char **) Smem_malloC((argzaehl + !!(flag & 128))
* sizeof(char *));
if(*argv==NULL)
{ret= -1; goto ex;}
}
@ -858,6 +859,8 @@ int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
if((*argv)[i]==NULL)
{ret= -1; goto ex;}
}
if(flag & 128)
(*argv)[*argc]= NULL;
}
}
ret= 1;
@ -10338,7 +10341,11 @@ int Xorriso_open_job_data_to(struct XorrisO *xorriso,
return(1);
}
/*
@param flag bit0= make absolute command paths with known systems
bit1= do not allow prefixes with cmd
bit2= interpret unprefixed cmd as shell:
*/
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)
@ -10352,22 +10359,24 @@ int Xorriso_make_mount_cmd(struct XorrisO *xorriso, char *cmd,
/*
too_long:;
*/
/* >>> complain about argument too long */;
Xorriso_msgs_submit(xorriso, 0, "Argument much too long", 0, "FAILURE", 0);
return(0);
}
ret= stat(devadr, &stbuf);
if(ret != -1)
if(S_ISREG(stbuf.st_mode))
reg_file= 1;
if(strncmp(cmd, "linux:", 6) == 0) {
if(strncmp(cmd, "linux:", 6) == 0 && !(flag & 2)) {
cpt= cmd + 6;
sys_code= 1;
} else if(strncmp(cmd, "freebsd:", 8) == 0) {
} else if(strncmp(cmd, "freebsd:", 8) == 0 && !(flag & 2)) {
cpt= cmd + 8;
sys_code= 2;
} else if(strncmp(cmd, "shell:", 6) == 0) {
cpt= cmd + 6;
} else if(strncmp(cmd, "string:", 7) == 0 && !(flag & 2)) {
cpt= cmd + 7;
strcpy(form, cpt);
} else if(flag & 4) {
cpt= cmd;
strcpy(form, cpt);
} else {
cpt= cmd;
@ -10391,22 +10400,23 @@ too_long:;
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));
"%smount -t iso9660 -o %snodev,noexec,nosuid,ro,sbsector=%%sbsector%% %%device%% %s",
(flag & 1 ? "/bin/" : ""), (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 <fbsd@opal.com>, 20 Nov 2008:
# mdconfig -a -t vnode -f xfburn.iso
/dev/md0
(Real CD drives look like /dev/cd0)
*/
if(reg_file) {
/* <<<
/* <<< Considered to create vnode as of
J.R. Oldroyd <fbsd@opal.com>, 20 Nov 2008
but for now refraining from creating that persistent file object
strcpy(form, "n=$(mdconfig -a -t vnode -f %device%)");
sprintf(form + strlen(form),
" && mount -t cd9660 -o noexec,nosuid -s %%sbsector%% /dev/\"$n\" %s",
Text_shellsafe(cmd+8, sfe, 0));
*/
Xorriso_msgs_submit(xorriso, 0,
"Detected regular file as mount device with FreeBSD style command.",
0, "FAILURE", 0);
@ -10416,8 +10426,8 @@ too_long:;
return(0);
} else
sprintf(form,
"mount -t cd9660 -o noexec,nosuid -s %%sbsector%% %%device%% %s",
Text_shellsafe(cmd+8, sfe, 0));
"%smount -t cd9660 -o noexec,nosuid -s %%sbsector%% %%device%% %s",
(flag & 1 ? "/sbin/" : ""), Text_shellsafe(cmd+8, sfe, 0));
is_safe= 1;
}
sprintf(session_text, "%d", session);
@ -10486,6 +10496,111 @@ int Xorriso_decode_load_adr(struct XorrisO *xorriso, char *cmd,
}
/*
@param flag bit0= use env_path to find the desired program
return:
<=0 : error
1 : done
*/
int Xorriso_execv(struct XorrisO *xorriso, char *cmd, char *env_path,
int *status, int flag)
{
int ret, argc= 0;
char **argv= NULL, *pathlist= NULL, *cpt, *npt, prog[SfileadrL];
char sfe[5*SfileadrL];
pid_t child_pid;
struct stat stbuf;
wait3(NULL,WNOHANG,NULL); /* just to remove any old dead child */
ret= Sfile_make_argv("", cmd, &argc, &argv, 1|4|128);
if(ret <= 0)
goto ex;
if(argc < 1)
{ret= 0; goto ex;}
strcpy(prog, argv[0]);
if((flag & 1) && strchr(argv[0], '/') == NULL) {
if(env_path == NULL)
env_path= "/bin:/sbin";
else if(env_path[0] == 0)
env_path= "/bin:/sbin";
if(Sregex_string(&pathlist, env_path, 0) <= 0)
{ret= -1; goto ex;}
for(cpt= npt= pathlist; npt != NULL; cpt= npt + 1) {
npt= strchr(cpt, ':');
if(npt != NULL)
*npt= 0;
if(strlen(cpt) + strlen(argv[0]) + 1 >= SfileadrL)
{ret= -1; goto ex;}
sprintf(prog, "%s/%s", cpt, argv[0]);
ret= stat(prog, &stbuf);
if(ret != -1)
break;
prog[0]= 0;
}
if(prog[0] == 0) {
sprintf(xorriso->info_text, "Cannot find external program %s",
Text_shellsafe(argv[0], sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
child_pid= fork();
if(child_pid==-1)
return(-1);
if(child_pid==0) {
/* this is the child process */
sprintf(xorriso->info_text, "Executing external program %s",
Text_shellsafe(prog, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
execv(prog, argv); /* should never come back */
fprintf(stderr,"--- execution of shell command failed:\n");
fprintf(stderr," %s\n",cmd);
exit(127);
}
/* this is the original process waiting for child to exit */
do {
/* try to read and print the reply */;
ret= waitpid(child_pid,status,WNOHANG);
if(ret==-1) {
if(errno!=EINTR)
ret= 0; goto ex;
} else if(ret==0) {
#ifdef NIX
/* >>> An interrupt key would be nice. */
if((flag&4)) {
ret= Asqueue_event_is_pending(agent->queue,0,0);
if(ret>0) {
Asagent_stderr(agent,"--- shell command interrupted",1);
kill(child_pid,SIGTERM);
ret= 2; goto ex;
}
}
#endif /* NIX */
continue;
} else {
break;
}
} while(1);
ret= 1;
ex:
Sfile_make_argv("", "", &argc, &argv, 2);
Sregex_string(&pathlist, NULL, 0);
return(ret);
}
/* ---------------------------- Options API ------------------------ */
@ -12785,9 +12900,11 @@ 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",
" -mount_cmd drive entity id path",
" Print to result channel a command suitable to mount the",
" depicted entity (see -load) at the given directory path.",
" -session_string drive entity id \"linux:\"path|\"freebsd:\"path|form",
" Print foreign OS command or custom line.",
"",
" -list_formats Show media specific list of format descriptors.",
"",
@ -13023,9 +13140,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",
" -mount drive entity id path",
" Like -mount_cmd but actually performing that command if it",
" is not from a shell:form and no setuid or setgid is active.",
" not setuid or setgid is active.",
"",
"Evaluation of readability:",
" -check_media [options] --",
@ -13751,17 +13868,21 @@ ex:;
}
/* Option -mount */
/* @param bit0= print mount command to result channel rather than performing it
/* Options -mount , -mount_mds , -session_string */
/* @param bit0= -mount_cmd: print mount command to result channel rather
than performing it
bit1= preform -session_string rather than -mount_cmd
*/
int Xorriso_option_mount(struct XorrisO *xorriso, char *dev, char *adr_mode,
char *adr, char *cmd, int flag)
{
int ret, entity_code= 0;
int ret, entity_code= 0, m_flag;
char entity_id[81], *mnt;
if(flag & 1)
mnt= "-mount_cmd";
else if(flag & 2)
mnt= "-session_string";
else {
mnt= "-mount";
if(!xorriso->allow_restore) {
@ -13781,7 +13902,11 @@ int Xorriso_option_mount(struct XorrisO *xorriso, char *dev, char *adr_mode,
&entity_code, entity_id, 0);
if(ret <= 0)
return(ret);
ret= Xorriso_mount(xorriso, dev, entity_code, entity_id, cmd, flag & 1);
if(flag & 2)
m_flag= 1 | 4;
else
m_flag= (flag & 1) | 2;
ret= Xorriso_mount(xorriso, dev, entity_code, entity_id, cmd, m_flag);
return(ret);
}
@ -15239,7 +15364,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
""
};
static char arg4_commands[][40]= {
"cut_out","extract_cut","mount","mount_cmd","paste_in",
"cut_out","extract_cut","mount","mount_cmd","paste_in","session_string",
""
};
static char argn_commands[][40]= {
@ -15670,7 +15795,8 @@ next_command:;
(*idx)+= 4;
if((*idx)>argc) {
sprintf(xorriso->info_text,
"-mount: Not enough arguments. Needed are: device entity id command");
"-%s: Not enough arguments. Needed are: device entity id command",
cmd);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0;
} else
@ -15847,6 +15973,18 @@ next_command:;
(*idx)++;
ret= Xorriso_option_session_log(xorriso, arg1, 0);
} else if(strcmp(cmd, "session_string") == 0) {
(*idx)+= 4;
if((*idx)>argc) {
sprintf(xorriso->info_text,
"-%s: Not enough arguments. Needed are: device entity id command",
cmd);
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], 2);
} else if(strcmp(cmd,"speed")==0) {
(*idx)++;
ret= Xorriso_option_speed(xorriso, arg1, 0);

View File

@ -598,6 +598,12 @@ int Xorriso_make_mount_cmd(struct XorrisO *xorriso, char *cmd,
char *devadr, char result[SfileadrL], int flag);
/* @param flag bit0= use env_path to find the desired program
*/
int Xorriso_execv(struct XorrisO *xorriso, char *cmd, char *env_path,
int *status, int flag);
int Sfile_str(char target[SfileadrL], char *source, int flag);
double Sfile_microtime(int flag);

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.12.06.140828"
#define Xorriso_timestamP "2008.12.07.122439"

View File

@ -8416,12 +8416,14 @@ int Xorriso_get_relax_text(struct XorrisO *xorriso, char mode[1024],
/**
@param flag bit0= print mount command to result channel rather than
performing it
bit1= do not allow prefixes with cmd
bit2= interpret unprefixed cmd as shell:
*/
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, mount_chardev= 0;
int give_up= 0, mount_chardev= 0, status;
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, *sysname= "";
@ -8436,7 +8438,9 @@ int Xorriso_mount(struct XorrisO *xorriso, char *dev, int adr_mode,
"on attempt to perform -mount \"indev\"", 0);
if(ret<=0)
goto ex;
devadr= xorriso->indev;
dev_path= devadr= xorriso->indev;
if(strncmp(dev_path, "stdio:", 6) == 0)
dev_path+= 6;
if(xorriso->in_drive_handle == xorriso->out_drive_handle)
give_up= 3;
else
@ -8447,7 +8451,9 @@ int Xorriso_mount(struct XorrisO *xorriso, char *dev, int adr_mode,
2);
if(ret<=0)
goto ex;
devadr= xorriso->outdev;
dev_path= devadr= xorriso->outdev;
if(strncmp(dev_path, "stdio:", 6) == 0)
dev_path+= 6;
if(xorriso->in_drive_handle == xorriso->out_drive_handle)
give_up= 3;
else
@ -8513,7 +8519,7 @@ int Xorriso_mount(struct XorrisO *xorriso, char *dev, int adr_mode,
if(strstr(devadr, "stdio:") == devadr)
devadr+= 6;
ret= Xorriso_make_mount_cmd(xorriso, cmd, lba, track, session, volid, devadr,
mount_command, 0);
mount_command, flag & (2 | 4));
if(ret <= 0)
goto ex;
if(ret == 2)
@ -8539,23 +8545,24 @@ int Xorriso_mount(struct XorrisO *xorriso, char *dev, int adr_mode,
} 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) {
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 {
#ifdef NIX
} else 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 {
/* >>> 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",
@ -8563,13 +8570,30 @@ int Xorriso_mount(struct XorrisO *xorriso, char *dev, int adr_mode,
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",
#else
} else {
ret= Xorriso_execv(xorriso, mount_command, "/bin:/sbin", &status, 1);
if(WIFEXITED(status) && WEXITSTATUS(status) != 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;
}
#endif
sprintf(xorriso->info_text, "\nMounted session %d of device %s",
session, Text_shellsafe(dev_path, sfe, 0));
dpt= strchr(cmd, ':');
if(dpt == NULL)
dpt= cmd ;
else
dpt++;
sprintf(xorriso->info_text + strlen(xorriso->info_text),
" as directory %s\n", Text_shellsafe(dpt + 1, sfe, 0));
" as directory %s\n", Text_shellsafe(dpt, sfe, 0));
Xorriso_info(xorriso, 0);
}
}