2010-05-15 18:48:10 +00:00
|
|
|
|
|
|
|
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
|
|
|
|
|
2011-02-01 18:58:27 +00:00
|
|
|
Copyright 2007-2011 Thomas Schmitt, <scdbackup@gmx.net>
|
2010-05-15 18:48:10 +00:00
|
|
|
|
|
|
|
Provided under GPL version 2 or later.
|
|
|
|
|
|
|
|
This file contains functions which manipulate the libisofs tree model.
|
|
|
|
*/
|
|
|
|
|
2010-05-16 09:32:14 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "../config.h"
|
|
|
|
#endif
|
|
|
|
|
2010-05-15 18:48:10 +00:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include "xorriso.h"
|
|
|
|
#include "xorriso_private.h"
|
|
|
|
#include "xorrisoburn.h"
|
|
|
|
|
|
|
|
#include "lib_mgt.h"
|
|
|
|
#include "iso_img.h"
|
|
|
|
#include "iso_tree.h"
|
|
|
|
#include "iso_manip.h"
|
|
|
|
#include "sort_cmp.h"
|
2010-09-04 10:08:55 +00:00
|
|
|
#include "parse_exec.h"
|
2010-05-15 18:48:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= give directory x-permission where is r-permission
|
|
|
|
bit1= do not transfer ACL or xattr
|
|
|
|
bit2= record dev,inode (only if enabled by xorriso)
|
|
|
|
bit5= transfer ACL or xattr from eventual link target
|
|
|
|
*/
|
|
|
|
int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf,
|
|
|
|
char *disk_path, IsoNode *node, int flag)
|
|
|
|
{
|
|
|
|
mode_t mode;
|
|
|
|
int ret= 1;
|
|
|
|
size_t num_attrs= 0, *value_lengths= NULL;
|
|
|
|
char **names= NULL, **values= NULL;
|
|
|
|
|
|
|
|
mode= stbuf->st_mode;
|
|
|
|
|
|
|
|
if((!(flag & 2)) && !(xorriso->do_aaip & 1))
|
|
|
|
/* Will drop ACL. Update mode S_IRWXG by eventual group:: ACL entry */
|
|
|
|
iso_local_get_perms_wo_acl(disk_path, &mode, flag & 32);
|
|
|
|
|
|
|
|
if((flag&1) && S_ISDIR(mode)) {
|
|
|
|
if(mode&S_IRUSR)
|
|
|
|
mode|= S_IXUSR;
|
|
|
|
if(mode&S_IRGRP)
|
|
|
|
mode|= S_IXGRP;
|
|
|
|
if(mode&S_IROTH)
|
|
|
|
mode|= S_IXOTH;
|
|
|
|
}
|
|
|
|
iso_node_set_permissions(node, mode & 07777);
|
|
|
|
iso_node_set_uid(node, stbuf->st_uid);
|
|
|
|
iso_node_set_gid(node, stbuf->st_gid);
|
|
|
|
iso_node_set_atime(node, stbuf->st_atime);
|
|
|
|
iso_node_set_mtime(node, stbuf->st_mtime);
|
|
|
|
iso_node_set_ctime(node, stbuf->st_ctime);
|
|
|
|
|
|
|
|
if((xorriso->do_aaip & 5) && !(flag & 2)) {
|
|
|
|
ret= iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths,
|
|
|
|
&values, ((xorriso->do_aaip & 1) && !(flag & 2))
|
|
|
|
| ((!(xorriso->do_aaip & 4)) << 2)
|
|
|
|
| (flag & 32));
|
|
|
|
if(ret < 0) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
Xorriso_report_iso_error(xorriso, disk_path, ret,
|
|
|
|
"Error when obtaining local ACL and xattr", 0,
|
|
|
|
"FAILURE", 1 | 2);
|
|
|
|
ret= 0; goto ex;
|
|
|
|
}
|
|
|
|
ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
|
|
|
|
1 | 8);
|
|
|
|
if(ret < 0) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
Xorriso_report_iso_error(xorriso, "", ret,
|
|
|
|
"Error when setting ACL and xattr to image node",
|
|
|
|
0, "FAILURE", 1);
|
|
|
|
ret= 0; goto ex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if((flag & 4) && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) {
|
|
|
|
ret= Xorriso_record_dev_inode(xorriso, disk_path, (dev_t) 0, (ino_t) 0,
|
|
|
|
(void *) node, "", flag & 32);
|
|
|
|
if(ret <= 0)
|
|
|
|
goto ex;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret= 1;
|
|
|
|
ex:;
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths,
|
|
|
|
&values, 1 << 15); /* free memory */
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Xorriso_graft_split(struct XorrisO *xorriso, IsoImage *volume,
|
|
|
|
IsoDir *dir, char *disk_path, char *img_name,
|
|
|
|
char *nominal_source, char *nominal_target,
|
|
|
|
off_t size, IsoNode **node, int flag)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
IsoDir *new_dir= NULL;
|
|
|
|
IsoNode *part_node;
|
|
|
|
int partno, total_parts;
|
|
|
|
off_t offset;
|
|
|
|
char part_name[SfileadrL], sfe[5*SfileadrL];
|
|
|
|
|
|
|
|
ret= iso_tree_add_new_dir(dir, img_name, &new_dir);
|
|
|
|
if(ret<0)
|
|
|
|
return(ret);
|
|
|
|
*node= (IsoNode *) new_dir;
|
|
|
|
total_parts= size / xorriso->split_size;
|
|
|
|
if(size % xorriso->split_size)
|
|
|
|
total_parts++;
|
|
|
|
for(partno= 1; partno<=total_parts; partno++) {
|
|
|
|
offset = xorriso->split_size * (off_t) (partno-1);
|
|
|
|
Splitpart__compose(part_name, partno, total_parts, offset,
|
|
|
|
xorriso->split_size, size, 0);
|
|
|
|
ret= Xorriso_tree_graft_node(xorriso, volume,
|
|
|
|
new_dir, disk_path, part_name,
|
|
|
|
nominal_source, nominal_target,
|
|
|
|
offset, xorriso->split_size,
|
|
|
|
&part_node, 8);
|
|
|
|
if(ret<=0)
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
sprintf(xorriso->info_text, "Split into %d parts: %s",
|
|
|
|
total_parts, Text_shellsafe(nominal_target, sfe, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@param flag bit3= cut_out_node: offset and size are valid
|
2010-09-04 10:08:55 +00:00
|
|
|
bit8= hide in iso_rr
|
|
|
|
bit9= hide in joliet
|
2010-05-15 18:48:10 +00:00
|
|
|
*/
|
|
|
|
int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume,
|
|
|
|
IsoDir *dir, char *disk_path, char *img_name,
|
|
|
|
char *nominal_source, char *nominal_target,
|
|
|
|
off_t offset, off_t cut_size,
|
|
|
|
IsoNode **node, int flag)
|
|
|
|
{
|
|
|
|
int ret, stbuf_valid= 0;
|
|
|
|
struct stat stbuf;
|
|
|
|
char sfe[5*SfileadrL];
|
|
|
|
off_t size= 0;
|
|
|
|
|
|
|
|
if(lstat(disk_path, &stbuf) != -1) {
|
|
|
|
stbuf_valid= 1;
|
|
|
|
if(S_ISREG(stbuf.st_mode))
|
|
|
|
size= stbuf.st_size;
|
|
|
|
}
|
|
|
|
if(flag&8) {
|
|
|
|
if(cut_size > xorriso->file_size_limit && xorriso->file_size_limit > 0) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"File piece exceeds size limit of %.f bytes: %.f from %s\n",
|
|
|
|
(double) xorriso->file_size_limit, (double) cut_size,
|
|
|
|
Text_shellsafe(disk_path, sfe, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
ret= iso_tree_add_new_cut_out_node(volume, dir, img_name, disk_path,
|
|
|
|
offset, cut_size, node);
|
|
|
|
if(ret<0)
|
|
|
|
goto ex;
|
|
|
|
} else {
|
|
|
|
if(xorriso->split_size > 0 && size > xorriso->split_size) {
|
|
|
|
ret= Xorriso_graft_split(xorriso, volume, dir, disk_path, img_name,
|
|
|
|
nominal_source, nominal_target, size,
|
|
|
|
node, 0);
|
|
|
|
if(ret<=0)
|
|
|
|
goto ex;
|
|
|
|
} else if(size > xorriso->file_size_limit && xorriso->file_size_limit > 0) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"File exceeds size limit of %.f bytes: %s\n",
|
|
|
|
(double) xorriso->file_size_limit,
|
|
|
|
Text_shellsafe(disk_path, sfe, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
return(0);
|
|
|
|
} else {
|
|
|
|
ret= iso_tree_add_new_node(volume, dir, img_name, disk_path, node);
|
|
|
|
if(ret<0)
|
|
|
|
goto ex;
|
|
|
|
}
|
|
|
|
}
|
2010-09-04 10:08:55 +00:00
|
|
|
if(flag & (256 | 512)) {
|
|
|
|
ret= Xorriso_set_hidden(xorriso, (void *) *node, "", (flag >> 8) & 3, 0);
|
|
|
|
if(ret <= 0)
|
|
|
|
goto ex;
|
|
|
|
}
|
2010-05-15 18:48:10 +00:00
|
|
|
if(stbuf_valid && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) {
|
|
|
|
ret= Xorriso_record_dev_inode(xorriso, disk_path,
|
|
|
|
stbuf.st_dev, stbuf.st_ino, (void *) *node, "", 1);
|
|
|
|
if(ret <= 0)
|
|
|
|
goto ex;
|
|
|
|
}
|
|
|
|
|
|
|
|
ex:;
|
|
|
|
if(ret<0) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
Xorriso_report_iso_error(xorriso, nominal_source, ret,
|
|
|
|
"Cannot add node to tree", 0, "FAILURE", 1|2);
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
if(LIBISO_ISREG(*node))
|
|
|
|
xorriso->pacifier_byte_count+= iso_file_get_size((IsoFile *) *node);
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= recursion is active
|
|
|
|
bit1= do not report added files
|
|
|
|
bit6= do not delete eventually existing node from di_array
|
|
|
|
bit7= no special handling of split file directories
|
2010-09-04 10:08:55 +00:00
|
|
|
bit8= hide in iso_rr
|
|
|
|
bit9= hide in joliet
|
2010-05-15 18:48:10 +00:00
|
|
|
*/
|
|
|
|
int Xorriso_add_tree(struct XorrisO *xorriso, IsoDir *dir,
|
|
|
|
char *img_dir_path, char *disk_dir_path,
|
|
|
|
struct LinkiteM *link_stack, int flag)
|
|
|
|
{
|
|
|
|
IsoImage *volume;
|
|
|
|
IsoNode *node;
|
|
|
|
int ret, target_is_dir, source_is_dir, source_is_link, fret, was_failure= 0;
|
2010-09-04 10:08:55 +00:00
|
|
|
int do_not_dive, target_is_split= 0, hide_attrs;
|
2010-05-15 18:48:10 +00:00
|
|
|
struct DirseQ *dirseq= NULL;
|
|
|
|
char *name, *img_name, *srcpt, *stbuf_src= "";
|
|
|
|
struct stat stbuf, hstbuf;
|
|
|
|
dev_t dir_dev;
|
|
|
|
struct LinkiteM *own_link_stack;
|
|
|
|
char *sfe= NULL, *sfe2= NULL;
|
|
|
|
char *disk_path= NULL, *img_path= NULL, *link_target= NULL;
|
|
|
|
|
|
|
|
/* Avoiding large local memory objects in order to save stack space */
|
|
|
|
sfe= malloc(5*SfileadrL);
|
|
|
|
sfe2= malloc(5*SfileadrL);
|
|
|
|
disk_path= malloc(2*SfileadrL);
|
|
|
|
img_path= malloc(2*SfileadrL);
|
|
|
|
link_target= calloc(SfileadrL, 1);
|
|
|
|
if(sfe==NULL || sfe2==NULL || disk_path==NULL || img_path==NULL ||
|
|
|
|
link_target==NULL) {
|
|
|
|
Xorriso_no_malloc_memory(xorriso, &sfe, 0);
|
|
|
|
{ret= -1; goto ex;}
|
|
|
|
}
|
|
|
|
|
|
|
|
own_link_stack= link_stack;
|
|
|
|
|
|
|
|
ret= Xorriso_get_volume(xorriso, &volume, 0);
|
|
|
|
if(ret<=0)
|
|
|
|
goto ex;
|
|
|
|
|
|
|
|
stbuf_src= disk_dir_path;
|
|
|
|
if(lstat(disk_dir_path, &stbuf)==-1)
|
|
|
|
goto cannot_open_dir;
|
|
|
|
dir_dev= stbuf.st_dev;
|
|
|
|
if(S_ISLNK(stbuf.st_mode)) {
|
|
|
|
if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1))))
|
|
|
|
{ret= 2; goto ex;}
|
|
|
|
stbuf_src= disk_dir_path;
|
|
|
|
if(stat(disk_dir_path, &stbuf)==-1)
|
|
|
|
goto cannot_open_dir;
|
|
|
|
if(dir_dev != stbuf.st_dev &&
|
|
|
|
!(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1))))
|
|
|
|
{ret= 2; goto ex;}
|
|
|
|
}
|
|
|
|
ret= Dirseq_new(&dirseq, disk_dir_path, 1);
|
|
|
|
if(ret<0) {
|
|
|
|
sprintf(xorriso->info_text,"Failed to create source filesystem iterator");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
|
|
|
|
{ret= -1; goto ex;}
|
|
|
|
}
|
|
|
|
if(ret==0) {
|
|
|
|
cannot_open_dir:;
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0);
|
|
|
|
sprintf(xorriso->info_text,"Cannot open as source directory: %s",
|
|
|
|
Text_shellsafe(disk_dir_path, sfe, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Sfile_str(disk_path, disk_dir_path,0)<=0)
|
|
|
|
{ret= -1; goto ex;}
|
|
|
|
if(disk_path[0]==0 || disk_path[strlen(disk_path)-1]!='/')
|
|
|
|
strcat(disk_path,"/");
|
|
|
|
name= disk_path+strlen(disk_path);
|
|
|
|
if(Sfile_str(img_path, img_dir_path, 0)<=0)
|
|
|
|
{ret= -1; goto ex;}
|
2010-10-05 18:00:52 +00:00
|
|
|
if(img_path[0] == 0)
|
|
|
|
strcat(img_path, "/");
|
|
|
|
else if(img_path[strlen(img_path) - 1] != '/')
|
|
|
|
strcat(img_path, "/");
|
2010-05-15 18:48:10 +00:00
|
|
|
img_name= img_path+strlen(img_path);
|
|
|
|
|
|
|
|
while(1) { /* loop over directory content */
|
|
|
|
stbuf_src= "";
|
|
|
|
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
|
|
|
|
srcpt= disk_path;
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
ret= Dirseq_next_adr(dirseq,name,0); /* name is a pointer into disk_path */
|
|
|
|
if(ret==0)
|
|
|
|
break;
|
|
|
|
if(ret<0) {
|
|
|
|
sprintf(xorriso->info_text,"Failed to obtain next directory entry");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
|
|
|
|
{ret= -1; goto ex;}
|
|
|
|
}
|
|
|
|
|
2010-09-04 10:08:55 +00:00
|
|
|
/* Compare exclusions against disk_path resp. name */
|
2010-05-15 18:48:10 +00:00
|
|
|
ret= Xorriso_path_is_excluded(xorriso, disk_path, 0); /* (is never param) */
|
|
|
|
if(ret<0)
|
|
|
|
{ret= -1; goto ex;}
|
|
|
|
if(ret>0)
|
|
|
|
continue;
|
2010-09-04 10:08:55 +00:00
|
|
|
/* Check for mkisofs-style hidings */
|
|
|
|
hide_attrs= (flag >> 8) & 3;
|
|
|
|
if(hide_attrs != 3) {
|
|
|
|
ret= Xorriso_path_is_hidden(xorriso, disk_path, 0);
|
|
|
|
if(ret<0)
|
|
|
|
return(ret);
|
|
|
|
if(ret>=0)
|
|
|
|
hide_attrs|= ret;
|
|
|
|
}
|
2010-05-15 18:48:10 +00:00
|
|
|
|
|
|
|
strcpy(img_name, name);
|
|
|
|
if(Xorriso_much_too_long(xorriso, strlen(img_path), 0)<=0)
|
|
|
|
{ret= 0; goto was_problem;}
|
|
|
|
if(Xorriso_much_too_long(xorriso, strlen(srcpt), 0)<=0)
|
|
|
|
{ret= 0; goto was_problem;}
|
|
|
|
stbuf_src= srcpt;
|
|
|
|
if(lstat(srcpt, &stbuf)==-1) {
|
|
|
|
cannot_lstat:;
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, srcpt, 0, "ERRFILE", 0);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Cannot determine attributes of source file %s",
|
|
|
|
Text_shellsafe(srcpt, sfe, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
|
|
|
|
ret= 0; goto was_problem;
|
|
|
|
}
|
|
|
|
source_is_dir= 0;
|
|
|
|
source_is_link= S_ISLNK(stbuf.st_mode);
|
|
|
|
if(xorriso->do_follow_links && source_is_link) {
|
|
|
|
/* Xorriso_hop_link checks for wide link loops */
|
|
|
|
ret= Xorriso_hop_link(xorriso, srcpt, &own_link_stack, &hstbuf, 0);
|
|
|
|
if(ret<0)
|
|
|
|
goto was_problem;
|
|
|
|
if(ret==1) {
|
|
|
|
ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0);
|
|
|
|
if(ret<=0)
|
|
|
|
goto was_problem;
|
|
|
|
srcpt= link_target;
|
|
|
|
stbuf_src= srcpt;
|
|
|
|
if(lstat(srcpt, &stbuf)==-1)
|
|
|
|
goto cannot_lstat;
|
|
|
|
} else {
|
|
|
|
if(Xorriso_eval_problem_status(xorriso, 0, 1|2)<0)
|
|
|
|
{ret= 0; goto was_problem;}
|
|
|
|
ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1);
|
|
|
|
if(ret<=0)
|
|
|
|
goto was_problem;
|
|
|
|
}
|
|
|
|
} else if (S_ISLNK(stbuf.st_mode)) {
|
|
|
|
ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1);
|
|
|
|
if(ret<=0)
|
|
|
|
goto was_problem;
|
|
|
|
}
|
|
|
|
do_not_dive= 0;
|
|
|
|
if(S_ISDIR(stbuf.st_mode)) {
|
|
|
|
source_is_dir= 1;
|
|
|
|
if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount)
|
|
|
|
do_not_dive= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* does a node exist with this name ? */
|
|
|
|
node= NULL;
|
|
|
|
ret= Xorriso_node_from_path(xorriso, volume, img_path, &node, 1);
|
|
|
|
if(ret>0) {
|
|
|
|
target_is_dir= LIBISO_ISDIR(node);
|
|
|
|
target_is_split= 0;
|
|
|
|
if(target_is_dir && !(flag & 128))
|
|
|
|
target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2);
|
|
|
|
|
|
|
|
if(!((target_is_dir && !target_is_split) && source_is_dir)) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
|
|
|
|
/* handle overwrite situation */;
|
|
|
|
if(xorriso->do_overwrite==1 ||
|
|
|
|
(xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) {
|
|
|
|
ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, img_path,
|
|
|
|
1 | 8 | (flag & 64));
|
|
|
|
if(ret<=0)
|
|
|
|
goto was_problem;
|
|
|
|
if(ret==3) {
|
|
|
|
sprintf(xorriso->info_text, "User revoked adding of: %s",
|
|
|
|
Text_shellsafe(img_path, sfe, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
ret= 0; goto was_problem;
|
|
|
|
}
|
|
|
|
node= NULL;
|
|
|
|
} else {
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, srcpt, 0, "ERRFILE", 0);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"While grafting %s : file object exists and may not be overwritten by %s",
|
|
|
|
Text_shellsafe(img_path,sfe,0), Text_shellsafe(stbuf_src,sfe2,0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
ret= 0; goto was_problem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(node==NULL) {
|
|
|
|
ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name,
|
|
|
|
"", img_path, (off_t) 0, (off_t) 0,
|
2010-09-04 10:08:55 +00:00
|
|
|
&node, (hide_attrs << 8));
|
2010-05-15 18:48:10 +00:00
|
|
|
}
|
|
|
|
if(node==NULL) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, stbuf_src, 0, "ERRFILE", 0);
|
|
|
|
sprintf(xorriso->info_text, "Grafting failed: %s = %s",
|
|
|
|
Text_shellsafe(img_path,sfe,0), Text_shellsafe(stbuf_src,sfe2,0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
ret= 0; goto was_problem;
|
|
|
|
}
|
|
|
|
|
|
|
|
xorriso->pacifier_count++;
|
|
|
|
if((xorriso->pacifier_count%100)==0)
|
|
|
|
Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count,
|
|
|
|
xorriso->pacifier_total, "", 0);
|
|
|
|
|
|
|
|
Xorriso_set_change_pending(xorriso, 0);
|
|
|
|
if(source_is_dir) {
|
|
|
|
if(do_not_dive) {
|
|
|
|
sprintf(xorriso->info_text, "Did not follow mount point : %s",
|
|
|
|
Text_shellsafe(disk_path, sfe, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
} else {
|
|
|
|
ret= Xorriso_add_tree(xorriso, (IsoDir *) node,
|
|
|
|
img_path, disk_path, own_link_stack,
|
|
|
|
1 | (flag & (2 | 64 | 128)));
|
|
|
|
}
|
|
|
|
if(ret<=0)
|
|
|
|
goto was_problem;
|
|
|
|
}
|
|
|
|
|
|
|
|
continue; /* regular bottom of loop */
|
|
|
|
was_problem:;
|
|
|
|
was_failure= 1;
|
|
|
|
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
|
|
|
|
if(fret<0)
|
|
|
|
goto ex;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret= 1;
|
|
|
|
ex:
|
|
|
|
if(sfe!=NULL)
|
|
|
|
free(sfe);
|
|
|
|
if(sfe2!=NULL)
|
|
|
|
free(sfe2);
|
|
|
|
if(disk_path!=NULL)
|
|
|
|
free(disk_path);
|
|
|
|
if(img_path!=NULL)
|
|
|
|
free(img_path);
|
|
|
|
if(link_target!=NULL)
|
|
|
|
free(link_target);
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
|
|
|
|
Dirseq_destroy(&dirseq, 0);
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
return(!was_failure);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= cut_out mode : base on leaf parent directory
|
2010-09-04 10:08:55 +00:00
|
|
|
bit1= do not check and perform hidings
|
2010-05-15 18:48:10 +00:00
|
|
|
*/
|
|
|
|
int Xorriso_copy_implicit_properties(struct XorrisO *xorriso, IsoDir *dir,
|
|
|
|
char *full_img_path, char *img_path, char *full_disk_path, int flag)
|
|
|
|
{
|
2010-09-04 10:08:55 +00:00
|
|
|
int ret, nfic, nic, nfdc, d, i, hide_attrs;
|
2010-05-15 18:48:10 +00:00
|
|
|
char nfi[SfileadrL], ni[SfileadrL], nfd[SfileadrL], *cpt;
|
|
|
|
char sfe[5*SfileadrL];
|
|
|
|
struct stat stbuf;
|
|
|
|
|
|
|
|
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, full_img_path, nfi,
|
|
|
|
1|2);
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, img_path, ni, 1|2);
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd,
|
|
|
|
1|2|4);
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
nfic= Sfile_count_components(nfi, 0);
|
|
|
|
nic= Sfile_count_components(ni, 0);
|
|
|
|
nfdc= Sfile_count_components(nfd, 0);
|
|
|
|
d= nfic-(flag&1)-nic;
|
|
|
|
if(d<0)
|
|
|
|
return(-1);
|
|
|
|
if(d>nfdc)
|
|
|
|
return(0);
|
|
|
|
for(i= 0; i<d; i++) {
|
|
|
|
cpt= strrchr(nfd, '/');
|
|
|
|
if(cpt==NULL)
|
|
|
|
return(-1); /* should not happen */
|
|
|
|
*cpt= 0;
|
|
|
|
}
|
|
|
|
if(nfd[0]==0)
|
|
|
|
strcpy(nfd, "/");
|
|
|
|
if(stat(nfd, &stbuf)==-1)
|
|
|
|
return(0);
|
|
|
|
Xorriso_transfer_properties(xorriso, &stbuf, nfd, (IsoNode *) dir,
|
|
|
|
((flag&1) && d==0) | 4 | 32);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Copied properties for %s", Text_shellsafe(ni, sfe, 0));
|
|
|
|
sprintf(xorriso->info_text+strlen(xorriso->info_text),
|
|
|
|
" from %s", Text_shellsafe(nfd, sfe, 0));
|
|
|
|
if(!((flag&1) && d==0))
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
|
2010-09-04 10:08:55 +00:00
|
|
|
|
|
|
|
if(!(flag & 2)) {
|
|
|
|
/* Check for mkisofs-style hidings */
|
|
|
|
hide_attrs= 0;
|
|
|
|
ret= Xorriso_path_is_hidden(xorriso, nfd, 0);
|
|
|
|
if(ret<0)
|
|
|
|
return(ret);
|
|
|
|
if(ret>=0) {
|
|
|
|
/* Hide dir */
|
|
|
|
ret= Xorriso_set_hidden(xorriso, (void *) dir, "", ret, 0);
|
|
|
|
if(ret <= 0)
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
}
|
2010-05-15 18:48:10 +00:00
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @param bit0= copy link target properties rather than link properties
|
|
|
|
bit1= give directory x-permission where is r-permission
|
|
|
|
bit2= record dev,inode (only if enabled by xorriso)
|
|
|
|
*/
|
|
|
|
int Xorriso_copy_properties(struct XorrisO *xorriso,
|
|
|
|
char *disk_path, char *img_path, int flag)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
IsoNode *node;
|
|
|
|
struct stat stbuf;
|
|
|
|
|
|
|
|
ret= Xorriso_get_node_by_path(xorriso, img_path, NULL, &node, 0);
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
if(flag & 1) {
|
|
|
|
if(stat(disk_path, &stbuf)==-1)
|
|
|
|
return(0);
|
|
|
|
} else {
|
|
|
|
if(lstat(disk_path, &stbuf)==-1)
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
Xorriso_transfer_properties(xorriso, &stbuf, disk_path, node,
|
|
|
|
((flag & 2) >> 1) | ((flag & 1) << 5) | (flag & 4));
|
|
|
|
Xorriso_set_change_pending(xorriso, 0);
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
|
|
|
|
Set to NULL if calling this function from outside ISO world
|
|
|
|
@param flag bit0= mkdir: graft in as empty directory, not as copy from disk
|
|
|
|
bit1= do not report added files
|
|
|
|
bit2= -follow, -not_*: this is not a command parameter
|
|
|
|
bit3= use offset and cut_size for cut_out_node
|
|
|
|
bit4= return 3 on rejection by exclusion or user
|
|
|
|
bit5= if directory then do not add sub tree
|
|
|
|
bit6= do not delete eventually existing node from di_array
|
|
|
|
bit7= no special handling of split file directories
|
2010-09-04 10:08:55 +00:00
|
|
|
bit8= hide in iso_rr
|
|
|
|
bit9= hide in joliet
|
2010-05-15 18:48:10 +00:00
|
|
|
@return <=0 = error , 1 = added simple node , 2 = added directory ,
|
|
|
|
3 = rejected
|
|
|
|
*/
|
|
|
|
int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter,
|
|
|
|
char *disk_path, char *img_path,
|
|
|
|
off_t offset, off_t cut_size, int flag)
|
|
|
|
{
|
|
|
|
IsoImage *volume;
|
|
|
|
char path[SfileadrL], *apt, *npt, *cpt, sfe[5*SfileadrL], sfe2[5*SfileadrL];
|
|
|
|
char *disk_path_pt, resolved_disk_path[SfileadrL];
|
|
|
|
IsoDir *dir, *hdir;
|
|
|
|
IsoNode *node;
|
|
|
|
int done= 0, is_dir= 0, l, ret, target_is_dir, source_is_dir, resolve_link= 0;
|
2010-09-04 10:08:55 +00:00
|
|
|
int target_is_split, hide_attrs;
|
2010-05-15 18:48:10 +00:00
|
|
|
struct stat stbuf;
|
|
|
|
|
2011-02-07 18:43:06 +00:00
|
|
|
hide_attrs= (flag >> 8) & 3;
|
2011-01-31 14:05:58 +00:00
|
|
|
if (disk_path == NULL && !(flag & 1)) {
|
|
|
|
Xorriso_msgs_submit(xorriso, 0,
|
|
|
|
"Program error: Xorriso_graft_in(): disk_path == NULL && !(flag & 1)",
|
|
|
|
0, "ABORT", 0);
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
if (disk_path == NULL) {
|
|
|
|
disk_path= "";
|
|
|
|
} else {
|
|
|
|
ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4));
|
2010-09-04 10:08:55 +00:00
|
|
|
if(ret<0)
|
|
|
|
return(ret);
|
2011-01-31 14:05:58 +00:00
|
|
|
if(ret>0)
|
|
|
|
return(3*!!(flag&16));
|
|
|
|
|
|
|
|
/* Check for mkisofs-style hidings */
|
|
|
|
if(hide_attrs != 3) {
|
|
|
|
ret= Xorriso_path_is_hidden(xorriso, disk_path, 0);
|
|
|
|
if(ret<0)
|
|
|
|
return(ret);
|
|
|
|
if(ret>=0)
|
|
|
|
hide_attrs|= ret;
|
|
|
|
}
|
2010-09-04 10:08:55 +00:00
|
|
|
}
|
|
|
|
|
2010-05-15 18:48:10 +00:00
|
|
|
for(cpt= img_path; 1; cpt++) {
|
|
|
|
cpt= strstr(cpt,"/.");
|
|
|
|
if(cpt==NULL)
|
|
|
|
break;
|
|
|
|
if(cpt[2]=='.') {
|
|
|
|
if(cpt[3]=='/' || cpt[3]==0)
|
|
|
|
break;
|
|
|
|
} else if(cpt[2]=='/' || cpt[2]==0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(cpt!=NULL) {
|
2011-01-31 14:05:58 +00:00
|
|
|
if(disk_path[0])
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
|
2010-05-15 18:48:10 +00:00
|
|
|
sprintf(xorriso->info_text,
|
2011-01-31 14:05:58 +00:00
|
|
|
"Unsupported relative addressing in iso_rr_path %s",
|
|
|
|
Text_shellsafe(img_path, sfe, 0));
|
|
|
|
if(disk_path[0])
|
|
|
|
sprintf(xorriso->info_text + strlen(xorriso->info_text),
|
|
|
|
" (disk: %s)", Text_shellsafe(disk_path, sfe, 0));
|
2010-05-15 18:48:10 +00:00
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret= Xorriso_get_volume(xorriso, &volume, 0);
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
|
|
|
|
strncpy(path, img_path, sizeof(path)-1);
|
|
|
|
path[sizeof(path)-1]= 0;
|
|
|
|
apt= npt= path;
|
|
|
|
|
|
|
|
if(!(flag&1)) {
|
|
|
|
ret= lstat(disk_path, &stbuf);
|
|
|
|
if(ret!=-1) {
|
|
|
|
if(S_ISDIR(stbuf.st_mode))
|
|
|
|
is_dir= 1;
|
|
|
|
else if((stbuf.st_mode&S_IFMT)==S_IFLNK &&
|
|
|
|
(xorriso->do_follow_links ||
|
|
|
|
(xorriso->do_follow_param && !(flag&4)))) {
|
|
|
|
resolve_link= 1;
|
|
|
|
ret= stat(disk_path, &stbuf);
|
|
|
|
if(ret!=-1) {
|
|
|
|
if(S_ISDIR(stbuf.st_mode))
|
|
|
|
is_dir= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(ret == -1) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Cannot determine attributes of source file %s",
|
|
|
|
Text_shellsafe(disk_path, sfe, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
if(S_ISDIR(stbuf.st_mode)) {
|
|
|
|
is_dir= 1;
|
|
|
|
} else {
|
|
|
|
l= strlen(img_path);
|
|
|
|
if(l>0)
|
|
|
|
if(img_path[l-1]=='/')
|
|
|
|
l= 0;
|
|
|
|
if(l==0) {
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Source %s is not a directory. Target %s would be.",
|
|
|
|
Text_shellsafe(disk_path, sfe, 0), Text_shellsafe(img_path, sfe2, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dir= iso_image_get_root(volume);
|
|
|
|
if(dir==NULL) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"While grafting '%s' : no root node available", img_path);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
|
|
|
|
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++;
|
|
|
|
if(done)
|
|
|
|
goto attach_source;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
source_is_dir= (is_dir || (flag&1) || !done);
|
|
|
|
ret= Xorriso_node_from_path(xorriso, volume, path, &node, 1);
|
|
|
|
if(ret>0) {
|
|
|
|
target_is_dir= LIBISO_ISDIR(node);
|
|
|
|
|
|
|
|
target_is_split= 0;
|
|
|
|
if(target_is_dir && !(flag & 128))
|
|
|
|
target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2);
|
|
|
|
|
|
|
|
if(!((target_is_dir && !target_is_split) && source_is_dir)) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
|
|
|
|
/* handle overwrite situation */;
|
|
|
|
if(xorriso->do_overwrite==1 ||
|
|
|
|
(xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) {
|
|
|
|
ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, path,
|
|
|
|
1 | 8 | (flag & 64));
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
if(ret==3) {
|
|
|
|
sprintf(xorriso->info_text, "User revoked adding of: %s",
|
2011-01-31 14:05:58 +00:00
|
|
|
disk_path[0] ? Text_shellsafe(disk_path, sfe, 0)
|
|
|
|
: Text_shellsafe(img_path, sfe, 0));
|
2010-05-15 18:48:10 +00:00
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
return(3*!!(flag&16));
|
|
|
|
}
|
|
|
|
node= NULL;
|
|
|
|
goto handle_path_node;
|
|
|
|
}
|
|
|
|
|
2011-01-31 14:05:58 +00:00
|
|
|
if (disk_path[0])
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
|
2010-05-15 18:48:10 +00:00
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"While grafting '%s' : '%s' exists and may not be overwritten",
|
|
|
|
img_path, path);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
dir= (IsoDir *) node;
|
|
|
|
}
|
|
|
|
|
|
|
|
handle_path_node:;
|
|
|
|
if(node==NULL && source_is_dir) { /* make a directory */
|
|
|
|
ret= iso_tree_add_new_dir(dir, apt, &hdir);
|
|
|
|
if(ret<0) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
2011-01-31 14:05:58 +00:00
|
|
|
if(disk_path[0])
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
|
2010-05-15 18:48:10 +00:00
|
|
|
Xorriso_report_iso_error(xorriso, img_path, ret,
|
|
|
|
"Cannot create directory", 0, "FAILURE", 1);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"While grafting '%s' : could not insert '%s'", img_path, path);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
dir= hdir;
|
|
|
|
Xorriso_set_change_pending(xorriso, 0);
|
|
|
|
iso_node_set_ctime((IsoNode *) dir, time(NULL));
|
|
|
|
iso_node_set_uid((IsoNode *) dir, geteuid());
|
|
|
|
iso_node_set_gid((IsoNode *) dir, getegid());
|
|
|
|
|
2011-01-31 14:05:58 +00:00
|
|
|
if(disk_path[0] && !done)
|
2010-09-04 10:08:55 +00:00
|
|
|
/* This not only copies disk directory properties
|
|
|
|
but also sets eventual hide_attrs */
|
2010-05-15 18:48:10 +00:00
|
|
|
Xorriso_copy_implicit_properties(xorriso, dir, img_path, path, disk_path,
|
|
|
|
!!(flag&8));
|
|
|
|
}
|
|
|
|
if(done) {
|
|
|
|
attach_source:;
|
|
|
|
if(flag&1) {
|
|
|
|
/* directory node was created above */;
|
|
|
|
|
|
|
|
} else if(is_dir) {
|
|
|
|
Xorriso_transfer_properties(xorriso, &stbuf, disk_path,
|
|
|
|
(IsoNode *) dir, 4 | 32);
|
|
|
|
if(!(flag&32)) {
|
|
|
|
ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL,
|
|
|
|
flag & (2 | 64 | 128));
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(resolve_link) {
|
|
|
|
ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
disk_path_pt= resolved_disk_path;
|
|
|
|
} else
|
|
|
|
disk_path_pt= disk_path;
|
|
|
|
|
|
|
|
ret= Xorriso_tree_graft_node(xorriso, volume, dir, disk_path_pt, apt,
|
2010-09-04 10:08:55 +00:00
|
|
|
disk_path, img_path, offset, cut_size,
|
|
|
|
&node, (flag&8) | (hide_attrs << 8));
|
2010-05-15 18:48:10 +00:00
|
|
|
if(ret<=0) {
|
|
|
|
sprintf(xorriso->info_text, "Grafting failed: %s = %s",
|
|
|
|
Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
Xorriso_set_change_pending(xorriso, 0);
|
|
|
|
iso_node_set_name(node, apt);
|
|
|
|
|
|
|
|
xorriso->pacifier_count++;
|
|
|
|
if(xorriso->pacifier_count%100 && !(flag&2))
|
|
|
|
Xorriso_pacifier_callback(xorriso, "files added",
|
|
|
|
xorriso->pacifier_count,
|
|
|
|
xorriso->pacifier_total, "", 0);
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
*npt= '/';
|
|
|
|
}
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
return(1+!!is_dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= -follow: disk_path is not a command parameter
|
|
|
|
*/
|
|
|
|
int Xorriso_cut_out(struct XorrisO *xorriso, char *disk_path,
|
|
|
|
off_t startbyte, off_t bytecount, char *iso_rr_path, int flag)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
char eff_source[SfileadrL], eff_dest[SfileadrL], sfe[SfileadrL*5];
|
|
|
|
struct stat stbuf;
|
|
|
|
|
|
|
|
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_source,
|
|
|
|
2|4);
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1));
|
|
|
|
if(ret!=0)
|
|
|
|
return(0);
|
|
|
|
|
|
|
|
if(lstat(eff_source, &stbuf)==-1) {
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
|
|
|
|
sprintf(xorriso->info_text, "-cut_out: Cannot determine type of %s",
|
|
|
|
Text_shellsafe(eff_source, sfe, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if((stbuf.st_mode&S_IFMT) == S_IFLNK) {
|
|
|
|
if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1))))
|
|
|
|
goto unsupported_type;
|
|
|
|
if(stat(eff_source, &stbuf)==-1) {
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"-cut_out: Cannot determine link target type of %s",
|
|
|
|
Text_shellsafe(eff_source, sfe, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(S_ISREG(stbuf.st_mode)) {
|
|
|
|
if(stbuf.st_size<startbyte) {
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"-cut_out: Byte offset %.f larger than file size %.f",
|
|
|
|
(double) startbyte, (double) stbuf.st_size);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
unsupported_type:;
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
|
|
|
|
sprintf(xorriso->info_text, "-cut_out: Unsupported file type (%s) with %s",
|
|
|
|
Ftypetxt(stbuf.st_mode, 0), Text_shellsafe(eff_source, sfe, 0));
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path, eff_dest,
|
|
|
|
2);
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
|
|
|
|
ret= Xorriso_graft_in(xorriso, NULL, eff_source, eff_dest,
|
|
|
|
startbyte, bytecount, 8);
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= do not produce info message on success
|
2011-02-04 19:19:24 +00:00
|
|
|
bit1= do not raise protest if directory already exists
|
2010-05-15 18:48:10 +00:00
|
|
|
@return 1=success,
|
|
|
|
0=was already directory, -1=was other type, -2=other error
|
|
|
|
*/
|
|
|
|
int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
char eff_path[SfileadrL], sfe[5*SfileadrL];
|
|
|
|
|
|
|
|
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1);
|
|
|
|
if(ret<0)
|
|
|
|
return(-2);
|
|
|
|
if(ret>0) {
|
2011-02-04 19:19:24 +00:00
|
|
|
if(ret == 2 && (flag & 2))
|
|
|
|
return(0);
|
2010-05-15 18:48:10 +00:00
|
|
|
sprintf(xorriso->info_text,"-mkdir: Address already existing %s",
|
2011-02-04 19:19:24 +00:00
|
|
|
Text_shellsafe(eff_path, sfe, 0));
|
2010-05-15 18:48:10 +00:00
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
|
|
|
|
(ret==2 ? "WARNING" : "FAILURE"), 0);
|
|
|
|
return(-1+(ret==2));
|
|
|
|
}
|
|
|
|
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2);
|
|
|
|
if(ret<0)
|
|
|
|
return(-2);
|
|
|
|
ret= Xorriso_graft_in(xorriso, NULL, NULL, eff_path, (off_t) 0, (off_t) 0, 1);
|
|
|
|
if(ret<=0)
|
|
|
|
return(-2);
|
|
|
|
if(!(flag&1)) {
|
|
|
|
sprintf(xorriso->info_text, "Created directory in ISO image: %s\n",
|
|
|
|
Text_shellsafe(eff_path,sfe,0));
|
|
|
|
Xorriso_info(xorriso, 0);
|
|
|
|
}
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @param boss_iter If not NULL then this is an iterator suitable for
|
|
|
|
iso_dir_iter_remove() which is then to be used instead
|
|
|
|
of iso_node_remove().
|
|
|
|
@param flag bit0= remove whole sub tree: rm -r
|
|
|
|
bit1= remove empty directory: rmdir
|
|
|
|
bit2= recursion: do not reassure in mode 2 "tree"
|
|
|
|
bit3= this is for overwriting and not for plain removal
|
|
|
|
bit4= count deleted files in xorriso->pacifier_count
|
|
|
|
bit5= with bit0 only remove directory content, not the directory
|
|
|
|
bit6= do not delete eventually existing node from di_array
|
|
|
|
@return <=0 = error
|
|
|
|
1 = removed simple node
|
|
|
|
2 = removed directory or tree
|
|
|
|
3 = did not remove on user revocation
|
|
|
|
*/
|
|
|
|
int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, off_t boss_mem,
|
|
|
|
char *path, int flag)
|
|
|
|
{
|
|
|
|
int ret, is_dir= 0, pl, not_removed= 0, fret;
|
|
|
|
IsoNode *victim_node, *node;
|
|
|
|
IsoDir *boss_node, *root_dir;
|
|
|
|
IsoDirIter *iter= NULL;
|
|
|
|
IsoImage *volume;
|
|
|
|
char *sub_name, *name;
|
|
|
|
char *sfe= NULL, *sub_path= NULL;
|
|
|
|
off_t mem;
|
|
|
|
IsoNode **node_array= NULL;
|
|
|
|
int node_count= 0, node_idx;
|
|
|
|
|
|
|
|
/* Avoiding large local memory objects in order to save stack space */
|
|
|
|
sfe= malloc(5*SfileadrL);
|
|
|
|
sub_path= malloc(2*SfileadrL);
|
|
|
|
if(sfe==NULL || sub_path==NULL) {
|
|
|
|
Xorriso_no_malloc_memory(xorriso, &sfe, 0);
|
|
|
|
{ret= -1; goto ex;}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef Libisofs_iso_dir_iter_sufficienT
|
|
|
|
/* Ticket 127: A80301 - A80302
|
|
|
|
I do not not deem IsoDirIter safe for node list manipulations.
|
|
|
|
The parameter boss_iter once was intended to allow such but
|
|
|
|
has now been downgraded to a mere check for eventual programming bugs.
|
|
|
|
*/
|
|
|
|
if(boss_iter!=NULL) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Program error: Xorriso_rmi() was requested to delete iterated node %s",
|
|
|
|
Text_shellsafe(path, sfe, 0));
|
|
|