New command -concat
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user