New command -concat

master
Thomas Schmitt 9 years ago
parent 36029c0b23
commit 51c02ceba7
  1. 1
      libisoburn/libisoburn.ver
  2. 203
      xorriso/disk_ops.c
  3. 44
      xorriso/filters.c
  4. 3
      xorriso/iso_img.c
  5. 74
      xorriso/opts_a_c.c
  6. 7
      xorriso/opts_d_h.c
  7. 170
      xorriso/parse_exec.c
  8. 16
      xorriso/parse_exec.h
  9. 57
      xorriso/read_run.c
  10. 52
      xorriso/sfile.c
  11. 5
      xorriso/sfile.h
  12. 36
      xorriso/xorriso.1
  13. 5
      xorriso/xorriso.h
  14. 119
      xorriso/xorriso.info
  15. 38
      xorriso/xorriso.texi
  16. 2
      xorriso/xorriso_timestamp.h
  17. 9
      xorriso/xorrisoburn.h

@ -177,6 +177,7 @@ Xorriso_option_commit;
Xorriso_option_commit_eject;
Xorriso_option_compare;
Xorriso_option_compliance;
Xorriso_option_concat;
Xorriso_option_copyright_file;
Xorriso_option_cp_clone;
Xorriso_option_cpri;

@ -1506,19 +1506,30 @@ ex:;
/* @param flag bit0= path is a directory
bit2= recursion: do not reassure in mode 2 "tree"
bit3= this is for overwriting and not for plain removal
bit3-7= question text mode
0= plain removal
1= replacing file object
2= overwriting of content, keeping file object
3= appending of content, keeping file object
*/
int Xorriso_reassure_restore(struct XorrisO *xorriso, char *path, int flag)
{
int ret;
int ret, mode;
mode= (flag >> 3) & 31;
while((xorriso->do_reassure==1 || (xorriso->do_reassure==2 && !(flag&4)))
&& !xorriso->request_not_to_ask) {
/* ls -ld */
Xorriso_lsx_filev(xorriso, xorriso->wdx, 1, &path, (off_t) 0, 1|2|8);
if(flag&1) /* du -s */
Xorriso_lsx_filev(xorriso, xorriso->wdx, 1, &path, (off_t) 0, 2|4);
if(flag&8)
if(mode == 3)
sprintf(xorriso->info_text,
"File exists. Append content ? n= no, y= yes, x= abort, @= stop asking\n");
else if(mode == 2)
sprintf(xorriso->info_text,
"File exists. Overwrite content ? n= no, y= yes, x= abort, @= stop asking\n");
else if(mode == 1)
sprintf(xorriso->info_text,
"File exists. Remove ? n= keep old, y= remove, x= abort, @= stop asking\n");
else
@ -1530,7 +1541,7 @@ int Xorriso_reassure_restore(struct XorrisO *xorriso, char *path, int flag)
goto ex;
if(xorriso->request_to_abort) {
sprintf(xorriso->info_text,
"Removal operation aborted by user before file: ");
"File alteration operation aborted by user before file: ");
Text_shellsafe(path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
ret= 3; goto ex;
@ -1960,3 +1971,187 @@ int Xorriso_append_scdbackup_record(struct XorrisO *xorriso, int flag)
return(1);
}
/* @param flag bit0= for append rather than overwrite
*/
int Xorriso_is_concat_target(struct XorrisO *xorriso, char *target,
int *ftype, int *fd, int flag)
{
int ret;
char *why= "";
*ftype= 0;
*fd = -1;
if(strcmp(target, "-") == 0) {
*fd= 1;
*ftype= 8; /* character device */
return(1);
}
*ftype= Sfile_type(target, 1 | 8 | 16);
if(*ftype == -1)
return(2); /* not yet existing regular */
if(*ftype & 1024) {
*fd= Sfile_get_dev_fd_no(target, 0);
*ftype &= ~1024;
}
if(*ftype & 2048) {
why= "fstat(2) returned -1 on file descriptor number.";
goto not_usable;
}
if(*ftype == 3) {
/* >>>
if follow_links is enabled : obtain target type
*ftype= Sfile_type(target, 1 | 4 | 8);
else
*/
why= "May not follow symbolic link.";
goto not_usable;
}
if(*ftype == 2) {
why= "May not write data into a directory.";
goto not_usable;
}
if(*ftype == 0) {
why= "Cannot determine file type.";
goto not_usable;
}
if(*ftype == 7) {
/* >>> what to do with UNIX socket ? */;
why= "Cannot yet handle socket file as target.";
goto not_usable;
}
if(xorriso->do_overwrite != 1 && xorriso->do_overwrite != 2) {
why= "May not alter existing file.";
goto not_usable;
}
ret= Xorriso_reassure_restore(xorriso, target, (2 + (flag & 1)) << 3);
if(ret <= 0 || ret == 0) {
why= "User revoked alteration of existing file.";
goto not_usable;
}
if(*ftype == 1)
return(2); /* existing regular */
if(*ftype == 4 || *ftype == 6 || *ftype == 8)
return(1); /* named pipe, block device, character device */
not_usable:;
sprintf(xorriso->info_text,
"Unsuitable -concat target: ");
Text_shellsafe(target, xorriso->info_text, 1);
sprintf(xorriso->info_text + strlen(xorriso->info_text), ". %s", why);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
int Xorriso_concat(struct XorrisO *xorriso, char *mode, char *target,
int progc, char **progv,
int filec, char **filev, int flag)
{
int ret, i, fd= -1, target_is_regular= 0, fd_opened= 0, ftype, prog_forked= 0;
int status;
int open_mode= O_WRONLY | O_CREAT;
struct stat stbuf;
pid_t forked_pid;
for(i= 0; i < filec; i++) {
ret= Xorriso_iso_lstat(xorriso, filev[i], &stbuf, 4);
if(ret == -1)
goto ex;
if(!S_ISREG(stbuf.st_mode)) {
sprintf(xorriso->info_text,
"-concat: iso_rr_path is not a regular data file: ");
Text_shellsafe(filev[i], xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
if(strcmp(mode, "overwrite") == 0) {
ret= Xorriso_is_concat_target(xorriso, target, &ftype, &fd, 0);
if(ret <= 0)
goto ex;
if(ret == 2) {
target_is_regular= 1;
open_mode |= O_TRUNC;
}
if(fd == -1) {
fd= open(target, O_WRONLY | O_TRUNC | O_CREAT, 0666);
fd_opened= 1;
}
} else if(strcmp(mode, "append") == 0) {
ret= Xorriso_is_concat_target(xorriso, target, &ftype, &fd, 1);
if(ret <= 0)
goto ex;
target_is_regular= (ret == 2);
if(fd == -1) {
fd= open(target, O_WRONLY | O_CREAT, 0666);
fd_opened= 1;
if(fd != -1 && target_is_regular) {
ret= lseek(fd, (off_t) 0, SEEK_END);
if(ret == -1) {
sprintf(xorriso->info_text,
"-concat append: Cannot lseek(2) to file end of ");
Text_shellsafe(target, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
}
} else if(strcmp(mode, "pipe") == 0) {
ret= Xorriso_pipe_open(xorriso, "-concat pipe", progv[0], progc, progv,
"", &fd, &forked_pid, 2 | 8);
if(ret <= 0)
goto ex;
fd_opened= 1;
prog_forked= 1;
} else {
sprintf(xorriso->info_text, "-concat: Unknown mode ");
Text_shellsafe(mode, xorriso->info_text, 1);
strcat(xorriso->info_text, ". Known modes: overwrite, append, pipe");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(fd == -1) {
sprintf(xorriso->info_text,
"-concat: Cannot open file handle to ");
Text_shellsafe(target, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
for(i= 0; i < filec; i++) {
ret= Xorriso_iso_file_to_fd(xorriso, filev[i], fd, 0);
if(ret <= 0) {
if(i < filec - 1) {
ret= Xorriso_eval_problem_status(xorriso, ret, 1 | 2);
if(ret < 0) {
sprintf(xorriso->info_text,
"-concat: Aborted although %d files stay unprocessed.",
filec - i + 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
}
}
ret= 1;
ex:;
if(fd_opened && fd != -1)
close(fd);
if(prog_forked)
Xorriso_wait_child_end(xorriso, forked_pid, &status, 0);
return(ret);
}

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2011 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2014 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -436,22 +436,15 @@ ex:;
}
/* @param flag bit0= delete filter with the given name
*/
int Xorriso_external_filter(struct XorrisO *xorriso,
char *name, char *options, char *path,
int argc, char **argv, int flag)
int Xorriso_external_filter_banned(struct XorrisO *xorriso, char *purpose,
int flag)
{
int ret, delete= 0, behavior= 0, extf_flag= 0, is_banned= 0;
char *what, *what_next, *suffix= "";
struct Xorriso_lsT *lst;
struct Xorriso_extF *found_filter, *new_filter= NULL;
int is_banned= 0;
#ifndef Xorriso_allow_external_filterS
/* To be controlled by: configure --enable-external-filters */
sprintf(xorriso->info_text, "%s : Banned at compile time.",
flag & 1 ? "-unregister_filter" : "-external_filter");
sprintf(xorriso->info_text, "%s : Banned at compile time.", purpose);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
sprintf(xorriso->info_text,
"This may be changed at compile time by ./configure option --enable-external-filters");
@ -474,16 +467,31 @@ int Xorriso_external_filter(struct XorrisO *xorriso,
}
#endif /* ! Xorriso_allow_extf_suiD */
if(is_banned)
return(0);
if(xorriso->filter_list_closed) {
sprintf(xorriso->info_text,
"%s : Banned by previous command -close_filter_list",
flag & 1 ? "-unregister_filter" : "-external_filter");
"%s : Banned by previous command -close_filter_list", purpose);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
is_banned= 1;
}
return(is_banned);
}
/* @param flag bit0= delete filter with the given name
*/
int Xorriso_external_filter(struct XorrisO *xorriso,
char *name, char *options, char *path,
int argc, char **argv, int flag)
{
int ret, delete= 0, behavior= 0, extf_flag= 0, is_banned= 0;
char *what, *what_next, *suffix= "";
struct Xorriso_lsT *lst;
struct Xorriso_extF *found_filter, *new_filter= NULL;
is_banned= Xorriso_external_filter_banned( xorriso,
flag & 1 ? "-unregister_filter" : "-external_filter", 0);
if(is_banned)
return(0);
if((!(flag & 1)) && path[0] != '/') {
sprintf(xorriso->info_text,
"-external_filter : Given command path does not begin by '/' : ");

@ -1196,7 +1196,8 @@ int Xorriso_mount(struct XorrisO *xorriso, char *dev, int adr_mode,
sprintf(xorriso->result_line, "%s\n", mount_command);
Xorriso_result(xorriso,0);
} else {
ret= Xorriso_execv(xorriso, mount_command, "/bin:/sbin", &status, 1);
ret= Xorriso_execv(xorriso, mount_command, 0, NULL, "/bin:/sbin",
NULL, NULL, NULL, &status, 1);
if(WIFEXITED(status) && WEXITSTATUS(status) != 0) {
sprintf(xorriso->info_text,
"-mount : mount command failed with exit value %d",

@ -2177,6 +2177,80 @@ int Xorriso_option_compliance(struct XorrisO *xorriso, char *mode,
}
/* Command -concat */
int Xorriso_option_concat(struct XorrisO *xorriso,
int argc, char **argv, int *idx, int flag)
{
int ret, end_idx, optc= 0, progc= 0, iso_rr_start, prog_end_idx= -1;
char **optv= NULL, **progv= NULL, *delimiter_mem= NULL;
/* Must be done before any goto ex; */
end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1);
iso_rr_start= *idx + 2;
if(xorriso->allow_restore <= 0) {
sprintf(xorriso->info_text,
"-concat: image content copies are not enabled by option -osirrox");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(end_idx - *idx < 3) {
sprintf(xorriso->info_text,
"-concat: Not enough arguments. Need mode, target, iso_rr_path.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(strcmp(argv[*idx], "pipe") == 0) {
if(end_idx - *idx < 5) {
sprintf(xorriso->info_text,
"-concat pipe: Not enough arguments. Need delimiter, program path, delimiter, iso_rr_path.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
Xorriso_alloc_meM(delimiter_mem, char, strlen(xorriso->list_delimiter) + 1);
strcpy(delimiter_mem, xorriso->list_delimiter);
strcpy(xorriso->list_delimiter, argv[*idx + 1]);
ret= Xorriso_opt_args(xorriso, "-concat pipe", argc , argv, *idx + 2,
&prog_end_idx, &progc, &progv, 4 | 128);
strcpy(xorriso->list_delimiter, delimiter_mem);
if(ret <= 0)
goto ex;
if(progc <= 0) {
sprintf(xorriso->info_text, "-concat pipe: No program path given.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
iso_rr_start= prog_end_idx + 1;
}
ret= Xorriso_opt_args(xorriso, "-concat", argc , argv, iso_rr_start, &end_idx,
&optc, &optv, 128);
if(ret <= 0)
goto ex;
if(optc <= 0) {
sprintf(xorriso->info_text, "-concat: No iso_rr_paths given.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
ret= 0; goto ex;
}
ret= Xorriso_concat(xorriso, argv[*idx], argv[*idx + 1],
progc, progv, optc, optv, 0);
ex:;
if(progv != NULL) {
if(delimiter_mem != NULL)
strcpy(xorriso->list_delimiter, argv[*idx + 2]);
Xorriso_opt_args(xorriso, "-concat", argc, argv, *idx + 2, &prog_end_idx,
&progc, &progv, 256);
if(delimiter_mem != NULL)
strcpy(xorriso->list_delimiter, delimiter_mem);
}
Xorriso_opt_args(xorriso, "-concat", argc, argv, iso_rr_start, &end_idx,
&optc, &optv, 256);
Xorriso_free_meM(delimiter_mem);
*idx= end_idx;
return(ret);
}
/* Option -copyright_file */
int Xorriso_option_copyright_file(struct XorrisO *xorriso, char *name, int flag)
{

@ -2108,6 +2108,13 @@ 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.",
" -concat \"append\"|\"overwrite\" target iso_rr_path [***]",
" Write content of iso_rr_paths into disk file target. Target",
" may be a disk_path or \"-\" for writing to standard output.",
" -concat \"pipe\" lim prog [args [...]] lim iso_rr_path [***]",
" Start prog with given args and write content of iso_rr_paths",
" into its standard input. prog must at least contain one '/'.",
" lim may be any word that is not among prog and args.",
" -mount drive entity id path",
" Like -mount_cmd but actually performing that command if",
" not setuid or setgid is active.",

@ -96,7 +96,7 @@ int Xorriso_opt_args(struct XorrisO *xorriso, char *cmd,
else
do_expand= (xorriso->do_iso_rr_pattern==1 && !(flag&4)) || (flag & 512);
if(flag&256) {
if(*optv<argv || *optv>=argv+argc)
if(*optv < argv || (*optv >= argv + argc && argc > 0))
Sfile_destroy_argv(optc, optv, 0);
return(1);
}
@ -563,7 +563,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
"check_md5","check_md5_r","check_media","check_media_defaults",
"chgrp","chgrpi","chgrp_r","chgrp_ri","chmod","chmodi",
"chmod_r","chmod_ri","chown","chowni","chown_r","chown_ri",
"compare_l","cp_clone","cp_rax","cp_rx","cpr","cpri", "cpax","cpx",
"compare_l","concat","cp_clone","cp_rax","cp_rx","cpr","cpri","cpax","cpx",
"du","dui","dus","dusi","dux","dusx","external_filter","extract_l",
"file_size_limit","find","findi","finds","findx",
"getfacl","getfacli","getfacl_r","getfacl_ri",
@ -717,7 +717,7 @@ int Xorriso_cmd_sorting_rank(struct XorrisO *xorriso,
"* osirrox ISO-to-disk restore options:",
"osirrox", "extract", "extract_single", "extract_l", "extract_cut",
"cpx", "cpax", "cp_rx", "cp_rax", "paste_in",
"cpx", "cpax", "cp_rx", "cp_rax", "paste_in", "concat",
"mount",
"* Settings for result writing:",
@ -1164,6 +1164,9 @@ next_command:;
(*idx)++;
Xorriso_option_compliance(xorriso, arg1, 0);
} else if(strcmp(cmd,"concat") == 0) {
ret= Xorriso_option_concat(xorriso, argc, argv, idx, 0);
} else if(strcmp(cmd,"copyright_file")==0) {
(*idx)++;
Xorriso_option_copyright_file(xorriso, arg1, 0);
@ -2739,16 +2742,67 @@ int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, int flag)
}
int Xorriso_wait_child_end(struct XorrisO *xorriso, pid_t child_pid,
int *status, int flag)
{
int ret;
do {
/* try to read and print the reply */;
ret= waitpid(child_pid, status, WNOHANG);
if(ret == -1) {
if(errno != EINTR)
return(0);
} else if(ret == 0) {
continue;
} else {
break;
}
} while(1);
/* >>> interpret *status */;
return(1);
}
int Xorriso_make_argv_with_null(struct XorrisO *xorriso,
int in_argc, char **in_argv,
int *argc, char ***argv, int flag)
{
int i, ret= 0;
*argv= NULL;
Xorriso_alloc_meM(*argv, char *, in_argc + 1);
for(i= 0; i < in_argc; i++) {
Xorriso_alloc_meM((*argv)[i], char, strlen(in_argv[i]) + 1);
strcpy((*argv)[i], in_argv[i]);
*argc= i + 1;
}
(*argv)[in_argc]= NULL;
ret= 1;
ex:;
if(ret <= 0)
Sfile_destroy_argv(argc, argv, 0);
return(ret);
}
/*
@param flag bit0= use env_path to find the desired program
bit1= use in_argv rather than parsing cmd to words
bit2= -reserved-
bit3= demand absolute cmd path
return:
<=0 : error
1 : done
*/
int Xorriso_execv(struct XorrisO *xorriso, char *cmd, char *env_path,
int Xorriso_execv(struct XorrisO *xorriso, char *cmd,
int in_argc, char **in_argv, char *env_path,
int *stdin_pipe, int *stdout_pipe, pid_t *forked_pid,
int *status, int flag)
{
int ret, argc= 0;
int ret, argc= 0, has_slash;
char **argv= NULL, *pathlist= NULL, *cpt, *npt, *prog= NULL;
pid_t child_pid;
struct stat stbuf;
@ -2757,14 +2811,26 @@ int Xorriso_execv(struct XorrisO *xorriso, char *cmd, char *env_path,
wait3(NULL,WNOHANG,NULL); /* just to remove any old dead child */
ret= Sfile_make_argv("", cmd, &argc, &argv, 1|4|128);
if(flag & 2) {
ret= Xorriso_make_argv_with_null(xorriso, in_argc, in_argv,
&argc, &argv, 0);
} else {
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) {
has_slash= (strchr(argv[0], '/') != NULL);
if((flag & 8) && !has_slash) {
sprintf(xorriso->info_text, "External program path contains no '/': ");
Text_shellsafe(argv[0], xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if((flag & 1) && has_slash) {
if(env_path == NULL)
env_path= "/bin:/sbin";
else if(env_path[0] == 0)
@ -2801,9 +2867,21 @@ int Xorriso_execv(struct XorrisO *xorriso, char *cmd, char *env_path,
sprintf(xorriso->info_text, "Executing external program ");
Text_shellsafe(prog, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
Xorriso_destroy(&xorriso, 0); /* reduce memory foot print */
if(stdin_pipe != NULL) {
close(0);
if(dup2(stdin_pipe[0], 0) == -1)
{ perror("dup2(,0)"); exit(1); }
close(stdin_pipe[1]); /* unused */
}
if(stdout_pipe != NULL) {
close(1);
if(dup2(stdout_pipe[1], 1) == -1)
{ perror("dup2(,1)"); exit(1); }
close(stdout_pipe[0]); /* unused */
}
execv(prog, argv); /* should never come back */
fprintf(stderr,"--- execution of shell command failed:\n");
fprintf(stderr," %s\n",cmd);
@ -2812,33 +2890,22 @@ int Xorriso_execv(struct XorrisO *xorriso, char *cmd, char *env_path,
/* 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 */
if(stdin_pipe != NULL)
close(stdin_pipe[0]); /* unused */
if(stdout_pipe != NULL)
close(stdout_pipe[1]); /* unused */
if(stdin_pipe != NULL || stdout_pipe != NULL) {
/* Pipes need to be fed by the caller who later calls Xorriso_wait_child_end
with *forked_pid as child_pid.
*/
*forked_pid= child_pid;
{ret= 1; goto ex;}
}
continue;
} else {
break;
}
} while(1);
ret= Xorriso_wait_child_end(xorriso, child_pid, status, 0);
if(ret <= 0)
goto ex;
ret= 1;
ex:
Sfile_make_argv("", "", &argc, &argv, 2);
@ -2848,6 +2915,43 @@ ex:
}
/* @param flag bit0= use env_path to find the desired program
bit1= use in_argv rather than parsing cmd to words
bit2= "r" rather than "w"
bit3= demand absolute cmd path
bit4= override any restriction on external filters
*/
int Xorriso_pipe_open(struct XorrisO *xorriso, char *purpose, char *cmd,
int in_argc, char **in_argv, char *env_path,
int *fd, pid_t *forked_pid, int flag)
{
int fp_pipe[2], *stdin_pipe= NULL, *stdout_pipe= NULL, status, ret;
*fd= -1;
if(!(flag & 16)) {
ret= Xorriso_external_filter_banned(xorriso, purpose, 0);
if(ret)
return(0);
}
if(pipe(fp_pipe) != 0) {
sprintf(xorriso->info_text, "Cannot create pipe(2) object");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FATAL", 0);
return(0);
}
if(flag & 4) {
stdout_pipe= fp_pipe;
*fd= fp_pipe[0];
} else {
stdin_pipe= fp_pipe;
*fd= fp_pipe[1];
}
ret= Xorriso_execv(xorriso, cmd, in_argc, in_argv, env_path,
stdin_pipe, stdout_pipe, forked_pid, &status, flag & 11);
return(ret);
}
/* @param flag bit0= path is a command parameter
*/
int Xorriso_path_is_excluded(struct XorrisO *xorriso, char *path, int flag)

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2010 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2014 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -71,11 +71,19 @@ int Xorriso_convert_datestring(struct XorrisO *xorriso, char *cmd,
int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, 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 Xorriso_execv(struct XorrisO *xorriso, char *cmd,
int in_argc, char **in_argv, char *env_path,
int *stdin_pipe, int *stdout_pipe, pid_t *forked_pid,
int *status, int flag);
int Xorriso_pipe_open(struct XorrisO *xorriso, char *purpose, char *cmd,
int in_argc, char **in_argv, char *env_path,
int *fd, pid_t *forked_pid, int flag);
int Xorriso_wait_child_end(struct XorrisO *xorriso, int child_pid,
int *status, int flag);
int Xorriso_path_is_excluded(struct XorrisO *xorriso, char *path, int flag);
int Xorriso_path_is_hidden(struct XorrisO *xorriso, char *path, int flag);

@ -2,7 +2,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2012 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2014 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -55,6 +55,9 @@ int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource)
}
/* @param flag bit0= open IsoNode *node_pt rather than looking up pathname
bit1= dig out the most original stream for reading
*/
int Xorriso_iso_file_open(struct XorrisO *xorriso, char *pathname,
void *node_pt, void **stream, int flag)
{
@ -242,6 +245,58 @@ int Xorriso_restore_is_identical(struct XorrisO *xorriso, void *in_node,
}
int Xorriso_iso_file_to_fd(struct XorrisO *xorriso, char *path, int fd,
int flag)
{
int ret, rret, wret, to_write, wanted;
void *stream= NULL;
char *buffer= NULL, *wpt;
off_t todo;
static int buffer_size= 64 * 1024;
Xorriso_alloc_meM(buffer, char, buffer_size);
ret= Xorriso_iso_file_open(xorriso, path, NULL, &stream, 0);
if(ret <= 0)
goto ex;
todo= iso_stream_get_size((IsoStream *) stream);
while(todo > 0) {
if(todo < buffer_size)
wanted= todo;
else
wanted= buffer_size;
rret = Xorriso_iso_file_read(xorriso, stream, buffer, wanted, 0);
if(rret <= 0)
{ret= -1; goto ex;}
todo-= rret;
wpt= buffer;
for(to_write= rret; to_write > 0;) {
wret= write(fd, wpt, to_write);
if(wret <= 0) {
if(wret == 0)
sprintf(xorriso->info_text,
"Strange behavior of write(2): return == 0 with ");
else
sprintf(xorriso->info_text, "Write error with ");
Text_shellsafe(path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text,
wret == 0 ? 0 : errno, "FAILURE",0);
ret= 0; goto ex;
}
to_write-= wret;
wpt+= wret;
}
}
ret= 1;
ex:;
if(stream != NULL)
Xorriso_iso_file_close(xorriso, &stream, 0);
Xorriso_free_meM(buffer);
return(ret);
}
/* @param flag bit0= minimal transfer: access permissions only
bit1= keep directory open: keep owner, allow rwx for owner
and push directory onto xorriso->perm_stack

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2012 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2014 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -227,12 +227,30 @@ int Sfile_being_group_member(struct stat *stbuf, int flag)
}
int Sfile_get_dev_fd_no(char *filename, int flag)
{
int i, fd= -1;
if(strncmp(filename, "/dev/fd/", 8) != 0)
return(-1);
for(i = 8; filename[i]; i++)
if(filename[i] < '0' || filename[i] > '9')
break;
if(i > 8 && filename[i] == 0)
sscanf(filename + 8, "%d", &fd);
if(fd < 0)
fd = -1;
return(fd);
}
int Sfile_type(char *filename, int flag)
/*
bit0= return -1 if file is missing
bit1= return a hardlink with siblings as type 5
bit2= evaluate eventual link target rather than the link object itself
bit3= return a socket or a char device as types 7 or 8 rather than 0
bit4= interpret /dev/fd/#fd# as open file descriptor fd
*/
/*
return:
@ -245,10 +263,20 @@ int Sfile_type(char *filename, int flag)
6=block device
7=socket (with bit3)
8=character device (with bit3)
| 1024 if interpreted as /dev/fd/#fd#
| 2048 if interpreted as /dev/fd/#fd# and not fstatable
*/
{
struct stat stbuf;
if(flag&4) {
int fd= -1, was_dev_fd= 0, ret;
if(flag & 16)
fd= Sfile_get_dev_fd_no(filename, 0);
if(fd != -1) {
was_dev_fd= 1;
if(fstat(fd, &stbuf) == -1)
return(1024 | 2048);
} else if(flag&4) {
if(stat(filename,&stbuf)==-1) {
if(flag&1) return(-1);
else return(0);
@ -262,24 +290,26 @@ int Sfile_type(char *filename, int flag)
if(S_ISREG(stbuf.st_mode)) {
if(flag&2)
if(stbuf.st_nlink>1)
return(5);
return(1);
{ret= 5; goto ex;}
{ret= 1; goto ex;}
}
if(S_ISDIR(stbuf.st_mode))
return(2);
{ret= 2; goto ex;}
if((stbuf.st_mode&S_IFMT)==S_IFLNK)
return(3);
{ret= 3; goto ex;}
if(S_ISFIFO(stbuf.st_mode))
return(4);
{ret= 4; goto ex;}
if(S_ISBLK(stbuf.st_mode))
return(6);
{ret= 6; goto ex;}
if(flag&8)
if((stbuf.st_mode&S_IFMT)==S_IFSOCK)
return(7);
{ret= 7; goto ex;}
if(flag&8)
if(S_ISCHR(stbuf.st_mode))
return(8);
return(0);
{ret= 8; goto ex;}
ret = 0;
ex:;
return(ret | (was_dev_fd << 10));
}

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2012 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2014 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -68,6 +68,8 @@ int Sfile_count_components(char *path, int flag);
6=block device
7=socket (with bit3)
8=character device (with bit3)
| 1024 if interpreted as /dev/fd/#fd#
| 2048 if interpreted as /dev/fd/#fd# and not fstatable
*/
int Sfile_type(char *filename, int flag);
@ -135,6 +137,7 @@ int Sfile_prepend_path(char *prefix, char path[SfileadrL], int flag);
int Sfile_home_adr_s(char *filename, char *fileadr, int fa_size, int flag);
int Sfile_get_dev_fd_no(char *filename, int flag);
#endif /* ! Xorriso_pvt_sfile_includeD */

@ -9,7 +9,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 "Version 1.3.7, Apr 19, 2014"
.TH XORRISO 1 "Version 1.3.7, Apr 21, 2014"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -2177,9 +2177,10 @@ Remove an \-external_filter registration. This is only possible if the filter
is not applied to any file in the ISO image.
.TP
\fB\-close_filter_list\fR
Irrevocably ban commands \-external_filter and \-unregister_filter,
but not \-set_filter. Use this to prevent external filtering in general or
when all intended filters are registered.
Irrevocably ban commands \-concat "pipe", \-external_filter,
and \-unregister_filter, but not \-set_filter. Use this to prevent external
filtering in general or when all intended filters are registered and \-concat
mode "pipe" shall be disallowed.
External filters may also be banned totally at compile time of
\fBxorriso\fR.
By default they are banned if \fBxorriso\fR runs under setuid permission.
@ -4308,6 +4309,33 @@ 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 command \-cut_out.
.TP
\fB\-concat\fR mode [target | lim prog [args [...]] lim] iso_rr_path [***]
Copy the data content of one or more data files of the ISO image into a
disk file object, into a file descriptor, or start a program and copy the
data into its standard input.
The latter is subject to the security restrictions for external filters.
.br
Modes \fBoverwrite\fR and \fBappend\fR write into the target which is
given by the second parameter. This may be the path to a disk file object,
or "\-" which means standard output, or a text of the form /dev/fd/number,
where number is an open file descriptor (e.g. standard error is /dev/fd/2).
An existing target file is not removed before writing begins. If it is not
able to take content data, then this command fails.
Mode overwrite truncates regular data files to 0 size before writing into them.
Example:
\-concat append /home/me/accumulated_text /my/iso/text \-\-
.br
Mode \fBpipe\fR expects as second parameter a delimiter word which shall
mark the end of the program argument list. The third argument is the disk_path
to the program. It must contain at least one '/'. $PATH is not applied.
Further parameters up to the announced delimiter
word are used as arguments with the program start. Example:
.br
\-concat pipe + /usr/bin/wc + /my/iso/files* \-\-
.br
The further parameters in all modes are the iso_rr_paths of data files.
Their content gets concatenated in the copy.
.TP
\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. See also \-mount_opts.

@ -1389,6 +1389,11 @@ int Xorriso_option_compare(struct XorrisO *xorriso, char *disk_path,
/* Command -compliance */
int Xorriso_option_compliance(struct XorrisO *xorriso, char *mode, int flag);
/* Command -concat */
/* @since 1.3.8 */
int Xorriso_option_concat(struct XorrisO *xorriso,
int argc, char **argv, int *idx, int flag);
/* Command -copyright_file */
/* @since 0.6.0 */
int Xorriso_option_copyright_file(struct XorrisO *xorriso, char *name,

@ -1921,9 +1921,10 @@ there are many small files.
the filter is not applied to any file in the ISO image.
-close_filter_list
Irrevocably ban commands -external_filter and -unregister_filter,
but not -set_filter. Use this to prevent external filtering in
general or when all intended filters are registered. External
Irrevocably ban commands -concat "pipe", -external_filter, and
-unregister_filter, but not -set_filter. Use this to prevent
external filtering in general or when all intended filters are
registered and -concat mode "pipe" shall be disallowed. External
filters may also be banned totally at compile time of `xorriso'.
By default they are banned if `xorriso' runs under setuid
permission.
@ -3790,6 +3791,30 @@ The directory permissions on disk have to allow rwx.
on disk beginning at the byte_offset. Write at most byte_count
bytes. This is the inverse of command -cut_out.
-concat mode [target | lim prog [args [...]] lim] iso_rr_path [***]
Copy the data content of one or more data files of the ISO image
into a disk file object, into a file descriptor, or start a
program and copy the data into its standard input. The latter is
subject to the security restrictions for external filters.
Modes *overwrite* and *append* write into the target which is
given by the second parameter. This may be the path to a disk file
object, or "-" which means standard output, or a text of the form
/dev/fd/number, where number is an open file descriptor (e.g.
standard error is /dev/fd/2). An existing target file is not
removed before writing begins. If it is not able to take content
data, then this command fails. Mode overwrite truncates regular
data files to 0 size before writing into them. Example: -concat
append /home/me/accumulated_text /my/iso/text -
Mode *pipe* expects as second parameter a delimiter word which
shall mark the end of the program argument list. The third
argument is the disk_path to the program. It must contain at least
one '/'. $PATH is not applied. Further parameters up to the
announced delimiter word are used as arguments with the program
start. Example:
-concat pipe + /usr/bin/wc + /my/iso/files* -
The further parameters in all modes are the iso_rr_paths of data
files. Their content gets concatenated in the copy.
-mount 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. See also
@ -4998,6 +5023,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
* -compare_l reports ISO/disk differences: Navigate. (line 164)
* -compare_r reports ISO/disk differences: Navigate. (line 159)
* -compliance controls standard compliance: SetWrite. (line 58)
* -concat copies ISO file content: Restore. (line 129)
* -copyright_file sets copyright file name: SetWrite. (line 231)
* -cp_clone copies ISO directory tree: Insert. (line 193)
* -cp_rx copies file trees to disk: Restore. (line 111)
@ -5082,7 +5108,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
* -mark sets synchronizing message: Frontend. (line 25)
* -md5 controls handling of MD5 sums: Loading. (line 183)
* -mkdir creates ISO directory: Insert. (line 171)
* -mount issues mount command for ISO session: Restore. (line 129)
* -mount issues mount command for ISO session: Restore. (line 153)
* -mount_cmd composes mount command line: Inquiry. (line 52)
* -mount_cmd controls mount command: Inquiry. (line 68)
* -msg_op perform operations on program messages: Frontend. (line 30)
@ -5141,8 +5167,8 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
* -scsi_log reports SCSI commands: Scripting. (line 158)
* -session_log logs written sessions: Scripting. (line 149)
* -session_string composes session info line: Inquiry. (line 78)
* -set_filter applies filter to file: Filter. (line 60)
* -set_filter_r applies filter to file tree: Filter. (line 89)
* -set_filter applies filter to file: Filter. (line 61)
* -set_filter_r applies filter to file tree: Filter. (line 90)
* -setfacl sets ACL in ISO image: Manip. (line 80)
* -setfacl_list sets ACL in ISO image: Manip. (line 108)
* -setfacl_r sets ACL in ISO image: Manip. (line 105)
@ -5265,9 +5291,10 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top
* Emulation, pacifier form, -pacifier: Emulation. (line 165)
* Examples: Examples. (line 6)
* extattr, _definition: Extras. (line 65)
* File content, copy, -concat: Restore. (line 129)
* Filter, _definition: Filter. (line 6)
* Filter, apply to file tree, -set_filter_r: Filter. (line 89)
* Filter, apply to file, -set_filter: Filter. (line 60)
* Filter, apply to file tree, -set_filter_r: Filter. (line 90)
* Filter, apply to file, -set_filter: Filter. (line 61)
* Filter, ban registration, -close_filter_list: Filter. (line 52)
* Filter, register, -external_filter: Filter. (line 20)
* Filter, show chain, -show_stream: Navigate. (line 169)
@ -5430,7 +5457,7 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top
* Session, _definition: Model. (line 6)
* Session, altered start address, -displacement: Loading. (line 60)
* Session, info string, -session_string: Inquiry. (line 78)
* Session, issue mount command, -mount: Restore. (line 129)
* Session, issue mount command, -mount: Restore. (line 153)
* Session, log when written, -session_log: Scripting. (line 149)
* Session, mount command line, -mount_cmd: Inquiry. (line 52)
* Session, mount parameters, -mount_opts: Inquiry. (line 68)
@ -5502,42 +5529,42 @@ Node: SetInsert58213
Node: Manip66790
Node: CmdFind76570
Node: Filter93841
Node: Writing98397
Node: SetWrite108528
Node: Bootable129234
Node: Jigdo146601
Node: Charset150848
Node: Exception154163
Node: DialogCtl160283
Node: Inquiry162881
Node: Navigate170016
Node: Verify178314
Node: Restore188141
Node: Emulation195228
Node: Scripting205616
Node: Frontend213387
Node: Examples222994
Node: ExDevices224172
Node: ExCreate224838
Node: ExDialog226123
Node: ExGrowing227388
Node: ExModifying228193
Node: ExBootable228697
Node: ExCharset229249
Node: ExPseudo230141
Node: ExCdrecord231039
Node: ExMkisofs231356
Node: ExGrowisofs232696
Node: ExException233831
Node: ExTime234285
Node: ExIncBackup234744
Node: ExRestore238724
Node: ExRecovery239657
Node: Files240227
Node: Seealso241526
Node: Bugreport242249
Node: Legal242830
Node: CommandIdx243841
Node: ConceptIdx260576
Node: Writing98463
Node: SetWrite108594
Node: Bootable129300
Node: Jigdo146667
Node: Charset150914
Node: Exception154229
Node: DialogCtl160349
Node: Inquiry162947
Node: Navigate170082
Node: Verify178380
Node: Restore188207
Node: Emulation196780
Node: Scripting207168
Node: Frontend214939
Node: Examples224546
Node: ExDevices225724
Node: ExCreate226390
Node: ExDialog227675
Node: ExGrowing228940
Node: ExModifying229745
Node: ExBootable230249
Node: ExCharset230801
Node: ExPseudo231693
Node: ExCdrecord232591
Node: ExMkisofs232908
Node: ExGrowisofs234248
Node: ExException235383
Node: ExTime235837
Node: ExIncBackup236296
Node: ExRestore240276
Node: ExRecovery241209
Node: Files241779
Node: Seealso243078
Node: Bugreport243801
Node: Legal244382
Node: CommandIdx245393
Node: ConceptIdx262201

End Tag Table

@ -50,7 +50,7 @@
@c man .\" First parameter, NAME, should be all caps
@c man .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
@c man .\" other parameters are allowed: see man(7), man(1)
@c man .TH XORRISO 1 "Version 1.3.7, Apr 19, 2014"
@c man .TH XORRISO 1 "Version 1.3.7, Apr 21, 2014"
@c man .\" Please adjust this date whenever revising the manpage.
@c man .\"
@c man .\" Some roff macros, for reference:
@ -2590,9 +2590,10 @@ is not applied to any file in the ISO image.
@item -close_filter_list
@kindex -close_filter_list bans filter registration
@cindex Filter, ban registration, -close_filter_list
Irrevocably ban commands -external_filter and -unregister_filter,
but not -set_filter. Use this to prevent external filtering in general or
when all intended filters are registered.
Irrevocably ban commands -concat "pipe", -external_filter,
and -unregister_filter, but not -set_filter. Use this to prevent external
filtering in general or when all intended filters are registered and -concat
mode "pipe" shall be disallowed.
External filters may also be banned totally at compile time of
@command{xorriso}.
By default they are banned if @command{xorriso} runs under setuid permission.
@ -5024,6 +5025,35 @@ 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 command -cut_out.
@c man .TP
@item -concat mode [target | lim prog [args [...]] lim] iso_rr_path [***]
@kindex -concat copies ISO file content
@cindex File content, copy, -concat
Copy the data content of one or more data files of the ISO image into a
disk file object, into a file descriptor, or start a program and copy the
data into its standard input.
The latter is subject to the security restrictions for external filters.
@*
Modes @strong{overwrite} and @strong{append} write into the target which is
given by the second parameter. This may be the path to a disk file object,
or "-" which means standard output, or a text of the form /dev/fd/number,
where number is an open file descriptor (e.g. standard error is /dev/fd/2).
An existing target file is not removed before writing begins. If it is not
able to take content data, then this command fails.
Mode overwrite truncates regular data files to 0 size before writing into them.
Example:
-concat append /home/me/accumulated_text /my/iso/text --
@*
Mode @strong{pipe} expects as second parameter a delimiter word which shall
mark the end of the program argument list. The third argument is the disk_path
to the program. It must contain at least one '/'. $PATH is not applied.
Further parameters up to the announced delimiter
word are used as arguments with the program start. Example:
@*
-concat pipe + /usr/bin/wc + /my/iso/files* --
@*
The further parameters in all modes are the iso_rr_paths of data files.
Their content gets concatenated in the copy.
@c man .TP
@item -mount drive entity id path
@kindex -mount issues mount command for ISO session
@cindex Session, issue mount command, -mount

@ -1 +1 @@
#define Xorriso_timestamP "2014.04.19.115057"
#define Xorriso_timestamP "2014.04.21.131802"