Setting chattr "C" and "i" at their proper times during restoring to disk
This commit is contained in:
parent
ce66b6a7e4
commit
c0ec40c5d2
@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
#include "xorriso.h"
|
#include "xorriso.h"
|
||||||
#include "xorriso_private.h"
|
#include "xorriso_private.h"
|
||||||
|
#include "xorrisoburn.h"
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------- SplitparT ------------------------- */
|
/* ---------------------------- SplitparT ------------------------- */
|
||||||
@ -939,10 +940,16 @@ int Linkitem_get_link_count(struct LinkiteM *item, int flag)
|
|||||||
struct PermiteM {
|
struct PermiteM {
|
||||||
char *disk_path;
|
char *disk_path;
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
|
int immutable; /* bit0= set chattr immutable bit
|
||||||
|
bit1= only set immutable bit
|
||||||
|
*/
|
||||||
struct PermiteM *next;
|
struct PermiteM *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= Linux chattr immutable bit is set
|
||||||
|
bit1= when popping only set immutable bit
|
||||||
|
*/
|
||||||
int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf,
|
int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
@ -953,6 +960,7 @@ int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf,
|
|||||||
return(-1);
|
return(-1);
|
||||||
m->disk_path= NULL;
|
m->disk_path= NULL;
|
||||||
memcpy(&(m->stbuf), stbuf, sizeof(struct stat));
|
memcpy(&(m->stbuf), stbuf, sizeof(struct stat));
|
||||||
|
m->immutable= flag & 3;
|
||||||
m->next= *o;
|
m->next= *o;
|
||||||
|
|
||||||
m->disk_path= strdup(disk_path);
|
m->disk_path= strdup(disk_path);
|
||||||
@ -971,6 +979,7 @@ failed:;
|
|||||||
|
|
||||||
/* @param flag bit0= minimal transfer: access permissions only
|
/* @param flag bit0= minimal transfer: access permissions only
|
||||||
bit1= do not set timestamps
|
bit1= do not set timestamps
|
||||||
|
bit2= do not set chattr flag i "immutable"
|
||||||
*/
|
*/
|
||||||
int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
|
int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
|
||||||
struct XorrisO *xorriso, int flag)
|
struct XorrisO *xorriso, int flag)
|
||||||
@ -992,6 +1001,7 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(m= *o; m!=stopper; m= m_next) {
|
for(m= *o; m!=stopper; m= m_next) {
|
||||||
|
if(!(m->immutable & 2)) {
|
||||||
ret= chmod(m->disk_path, m->stbuf.st_mode);
|
ret= chmod(m->disk_path, m->stbuf.st_mode);
|
||||||
if(ret==-1) {
|
if(ret==-1) {
|
||||||
if(xorriso!=NULL) {
|
if(xorriso!=NULL) {
|
||||||
@ -1003,7 +1013,9 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
|
|||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!(flag&1)) {
|
}
|
||||||
|
|
||||||
|
if(!((flag & 1) || (m->immutable & 2))) {
|
||||||
ret= chown(m->disk_path, m->stbuf.st_uid, m->stbuf.st_gid);
|
ret= chown(m->disk_path, m->stbuf.st_uid, m->stbuf.st_gid);
|
||||||
/* don't complain if it fails */
|
/* don't complain if it fails */
|
||||||
if(!(flag&2)) {
|
if(!(flag&2)) {
|
||||||
@ -1019,6 +1031,10 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((m->immutable & 1) && !(flag & 4))
|
||||||
|
Xorriso_set_local_chattr_i(xorriso, m->disk_path, 0);
|
||||||
|
|
||||||
m_next= m->next;
|
m_next= m->next;
|
||||||
free(m->disk_path);
|
free(m->disk_path);
|
||||||
free((char *) m);
|
free((char *) m);
|
||||||
|
@ -107,7 +107,7 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf,
|
|||||||
"Error when obtaining file attribute flags",
|
"Error when obtaining file attribute flags",
|
||||||
os_errno, "FAILURE", 1 | 2);
|
os_errno, "FAILURE", 1 | 2);
|
||||||
ret= 0; goto ex;
|
ret= 0; goto ex;
|
||||||
} else if(ret > 0) {
|
} else if(ret == 1 || ret == 2) {
|
||||||
ret= iso_node_set_lfa_flags(node, lfa_flags, 0);
|
ret= iso_node_set_lfa_flags(node, lfa_flags, 0);
|
||||||
if(ret < 0) {
|
if(ret < 0) {
|
||||||
Xorriso_process_msg_queues(xorriso, 0);
|
Xorriso_process_msg_queues(xorriso, 0);
|
||||||
|
@ -2919,7 +2919,9 @@ int Xorriso_warn_if_not_bootcat(struct XorrisO *xorriso, char *prefix,
|
|||||||
@param in_node if not NULL and not flag bit1: omit path resolution
|
@param in_node if not NULL and not flag bit1: omit path resolution
|
||||||
@param flag bit1= path is disk_path
|
@param flag bit1= path is disk_path
|
||||||
bit5= in case of symbolic link on disk: inquire link target
|
bit5= in case of symbolic link on disk: inquire link target
|
||||||
@return <0 = ok , 0= no lfa_flags at node , <0 = libisofs error
|
@return >0 = ok ,
|
||||||
|
0 = no lfa_flags at node or disk file,
|
||||||
|
<0 = libisofs error
|
||||||
*/
|
*/
|
||||||
int Xorriso_get_lfa_flags(struct XorrisO *xorriso, void *in_node, char *path,
|
int Xorriso_get_lfa_flags(struct XorrisO *xorriso, void *in_node, char *path,
|
||||||
uint64_t *lfa_flags, int *max_bit, int flag)
|
uint64_t *lfa_flags, int *max_bit, int flag)
|
||||||
@ -2959,6 +2961,8 @@ from_disk:;
|
|||||||
os_errno, "WARNING", 1);
|
os_errno, "WARNING", 1);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
if(ret == 1 || ret == 2)
|
||||||
return(1);
|
return(1);
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,6 +448,8 @@ int Xorriso_report_iso_error(struct XorrisO *xorriso, char *victim,
|
|||||||
|
|
||||||
Xorriso_alloc_meM(sfe, char, 6 * SfileadrL);
|
Xorriso_alloc_meM(sfe, char, 6 * SfileadrL);
|
||||||
|
|
||||||
|
Xorriso_process_msg_queues(xorriso, 0);
|
||||||
|
|
||||||
if(sorry_sev<0)
|
if(sorry_sev<0)
|
||||||
Xorriso__text_to_sev("SORRY", &sorry_sev, 0);
|
Xorriso__text_to_sev("SORRY", &sorry_sev, 0);
|
||||||
|
|
||||||
|
@ -303,6 +303,105 @@ ex:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Xorriso_report_chattr_outcome(struct XorrisO *xorriso, char *disk_path,
|
||||||
|
uint64_t lfa_flags, uint64_t lfa_mask,
|
||||||
|
int iso_ret, int os_errno, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char msg[101], *lfa_text= NULL;
|
||||||
|
|
||||||
|
if(iso_ret == 1)
|
||||||
|
{ret= 1; goto ex;}
|
||||||
|
|
||||||
|
ret= iso_util_encode_lfa_flags(lfa_flags & lfa_mask, &lfa_text, 0);
|
||||||
|
if(lfa_text == NULL)
|
||||||
|
lfa_text= strdup("-unknown-attributes-");
|
||||||
|
if(iso_ret < 0) {
|
||||||
|
strcpy(msg, "Could not set chattr '");
|
||||||
|
if(lfa_text != NULL)
|
||||||
|
strcat(msg, lfa_text);
|
||||||
|
strcat(msg, "'");
|
||||||
|
Xorriso_report_iso_error(xorriso, disk_path, iso_ret, msg, os_errno,
|
||||||
|
"FAILURE", 2);
|
||||||
|
ret= 0; goto ex;
|
||||||
|
} else if(iso_ret == 2) {
|
||||||
|
sprintf(xorriso->info_text,
|
||||||
|
"Could not map all of chattr '%s' to local file attributes of ",
|
||||||
|
lfa_text);
|
||||||
|
} else if(iso_ret == 3) {
|
||||||
|
sprintf(xorriso->info_text, "Will not apply chattr '%s' to symbolic link ",
|
||||||
|
lfa_text);
|
||||||
|
} else {
|
||||||
|
sprintf(xorriso->info_text,
|
||||||
|
"Unknown return value %d from iso_local_set_lfa_flags() with chattr '%s' to ",
|
||||||
|
iso_ret, lfa_text);
|
||||||
|
}
|
||||||
|
Text_shellsafe(disk_path, xorriso->info_text, 1);
|
||||||
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
|
||||||
|
ret= 0;
|
||||||
|
ex:;
|
||||||
|
if(lfa_text != NULL)
|
||||||
|
free(lfa_text);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint64_t Xorriso__lfa_bits(char *lfa_text)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint64_t lfa_bits;
|
||||||
|
|
||||||
|
ret= iso_util_decode_lfa_flags(lfa_text, &lfa_bits, 0);
|
||||||
|
if(ret < 0)
|
||||||
|
lfa_bits= 0;
|
||||||
|
return(lfa_bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Xorriso_set_local_chattr_i(struct XorrisO *xorriso, char *disk_path,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int ret, max_bit= 31, os_errno;
|
||||||
|
static uint64_t lfa_i= 0xffffffff;
|
||||||
|
|
||||||
|
if(lfa_i == 0xffffffff)
|
||||||
|
lfa_i= Xorriso__lfa_bits("i");
|
||||||
|
|
||||||
|
ret= iso_local_set_lfa_flags(disk_path, lfa_i, max_bit, lfa_i, &os_errno, 0);
|
||||||
|
ret= Xorriso_report_chattr_outcome(xorriso, disk_path, lfa_i, lfa_i,
|
||||||
|
ret, os_errno, 0);
|
||||||
|
if(ret <= 0)
|
||||||
|
return(ret);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If present and enabled: restore chattr i */
|
||||||
|
int Xorriso_restore_chattr_i(struct XorrisO *xorriso, IsoNode *node,
|
||||||
|
char *disk_path, int flag)
|
||||||
|
{
|
||||||
|
int ret, max_bit;
|
||||||
|
uint64_t lfa_flags;
|
||||||
|
static uint64_t lfa_i= 0xffffffff;
|
||||||
|
|
||||||
|
if(lfa_i == 0xffffffff)
|
||||||
|
lfa_i= Xorriso__lfa_bits("i");
|
||||||
|
|
||||||
|
if((xorriso->do_aaip & (1 << 12)) && !(xorriso->do_aaip & (1 << 13))) {
|
||||||
|
ret= iso_node_get_lfa_flags(node, &lfa_flags, &max_bit, 0);
|
||||||
|
if(ret > 0) {
|
||||||
|
if(lfa_flags & lfa_i & xorriso->lfa_restore_mask) {
|
||||||
|
ret= Xorriso_set_local_chattr_i(xorriso, disk_path, 0);
|
||||||
|
if(ret <= 0)
|
||||||
|
return(ret);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* @param flag bit0= minimal transfer: access permissions only
|
/* @param flag bit0= minimal transfer: access permissions only
|
||||||
bit1= keep directory open: keep owner, allow rwx for owner
|
bit1= keep directory open: keep owner, allow rwx for owner
|
||||||
and push directory onto xorriso->perm_stack
|
and push directory onto xorriso->perm_stack
|
||||||
@ -319,8 +418,14 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path,
|
|||||||
size_t num_attrs= 0, *value_lengths= NULL;
|
size_t num_attrs= 0, *value_lengths= NULL;
|
||||||
char **names= NULL, **values= NULL;
|
char **names= NULL, **values= NULL;
|
||||||
int *errnos= NULL;
|
int *errnos= NULL;
|
||||||
uint64_t lfa_flags;
|
uint64_t lfa_flags, mask;
|
||||||
int max_bit, os_errno;
|
int max_bit, os_errno;
|
||||||
|
static uint64_t lfa_C= 0xffffffff, lfa_i= 0xffffffff;
|
||||||
|
|
||||||
|
if(lfa_C == 0xffffffff) {
|
||||||
|
lfa_C= Xorriso__lfa_bits("C");
|
||||||
|
lfa_i= Xorriso__lfa_bits("i");
|
||||||
|
}
|
||||||
|
|
||||||
ret= lstat(disk_path, &stbuf);
|
ret= lstat(disk_path, &stbuf);
|
||||||
if(ret==-1) {
|
if(ret==-1) {
|
||||||
@ -474,16 +579,25 @@ cannot_set_perm:;
|
|||||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
||||||
{ret= 0; goto ex;}
|
{ret= 0; goto ex;}
|
||||||
} else if(ret > 0) {
|
} else if(ret > 0) {
|
||||||
ret= iso_local_set_lfa_flags(disk_path, lfa_flags, max_bit,
|
/* Do not set lfa_flag 'C' here. It would be too late. */
|
||||||
xorriso->lfa_restore_mask, &os_errno,
|
mask= xorriso->lfa_restore_mask & ~lfa_C;
|
||||||
|
/* Do not set lfa_flag 'i' of a directory here. It would be too early. */
|
||||||
|
if(is_dir)
|
||||||
|
mask&= ~lfa_i;
|
||||||
|
if(mask != 0) {
|
||||||
|
ret= iso_local_set_lfa_flags(disk_path, lfa_flags, max_bit, mask,
|
||||||
|
&os_errno,
|
||||||
(!!(xorriso->do_aaip & (1 << 13))) |
|
(!!(xorriso->do_aaip & (1 << 13))) |
|
||||||
((!!(xorriso->do_aaip & (1 << 14))) << 1));
|
((!!(xorriso->do_aaip & (1 << 14))) << 1));
|
||||||
if(ret < 0) {
|
|
||||||
|
|
||||||
/* >>> Need adjustable graceful error handling */;
|
/* >>> Need adjustable graceful error handling */;
|
||||||
|
|
||||||
Xorriso_process_msg_queues(xorriso, 0);
|
ret= Xorriso_report_chattr_outcome(xorriso, disk_path,
|
||||||
{ret= 0; goto ex;}
|
lfa_flags,
|
||||||
|
xorriso->lfa_restore_mask & ~lfa_C,
|
||||||
|
ret, os_errno, 0);
|
||||||
|
if(ret <= 0)
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -850,7 +964,7 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
|
|||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
int ret= 0, write_fd= -1, wanted, wret, open_flags, l_errno= 0;
|
int ret= 0, write_fd= -1, wanted, wret, open_flags, l_errno= 0;
|
||||||
int target_deleted= 0, buf_size= 32 * 1024;
|
int target_deleted= 0, buf_size= 32 * 1024, new_empty= 0;
|
||||||
char *what= "[unknown filetype]";
|
char *what= "[unknown filetype]";
|
||||||
char *buf= NULL, type_text[5], *temp_path= NULL, *buf_pt, *reason;
|
char *buf= NULL, type_text[5], *temp_path= NULL, *buf_pt, *reason;
|
||||||
char *link_target, *open_path_pt= NULL;
|
char *link_target, *open_path_pt= NULL;
|
||||||
@ -867,12 +981,17 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
|
|||||||
off_t catsize, iso_node_size, wanted_size, cap;
|
off_t catsize, iso_node_size, wanted_size, cap;
|
||||||
char disk_md5[16], iso_md5[16];
|
char disk_md5[16], iso_md5[16];
|
||||||
void *ctx= NULL;
|
void *ctx= NULL;
|
||||||
int use_md5= 0, i, sparse_ret= 3;
|
int use_md5= 0, i, sparse_ret= 3, max_bit, os_errno;
|
||||||
struct Xorriso_sparse_statE *sparse_state= NULL;
|
struct Xorriso_sparse_statE *sparse_state= NULL;
|
||||||
|
uint64_t lfa_flags;
|
||||||
|
static uint64_t lfa_C= 0xffffffff;
|
||||||
|
|
||||||
Xorriso_alloc_meM(buf, char, buf_size);
|
Xorriso_alloc_meM(buf, char, buf_size);
|
||||||
Xorriso_alloc_meM(temp_path, char, SfileadrL);
|
Xorriso_alloc_meM(temp_path, char, SfileadrL);
|
||||||
|
|
||||||
|
if(lfa_C == 0xffffffff)
|
||||||
|
lfa_C= Xorriso__lfa_bits("C");
|
||||||
|
|
||||||
if(!(flag & 2))
|
if(!(flag & 2))
|
||||||
img_offset= bytes= 0;
|
img_offset= bytes= 0;
|
||||||
if(LIBISO_ISDIR(node)) {
|
if(LIBISO_ISDIR(node)) {
|
||||||
@ -911,8 +1030,11 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
|
|||||||
}
|
}
|
||||||
open_path_pt= disk_path;
|
open_path_pt= disk_path;
|
||||||
ret= stat(open_path_pt, &stbuf);
|
ret= stat(open_path_pt, &stbuf);
|
||||||
if(ret == -1 && errno == EACCES && (flag & 128))
|
if(ret == -1) {
|
||||||
|
if(errno == EACCES && (flag & 128))
|
||||||
{ret= 4; goto ex;}
|
{ret= 4; goto ex;}
|
||||||
|
new_empty= 1;
|
||||||
|
}
|
||||||
if(flag&2) {
|
if(flag&2) {
|
||||||
if(ret != -1) {
|
if(ret != -1) {
|
||||||
wanted_size= disk_offset + bytes;
|
wanted_size= disk_offset + bytes;
|
||||||
@ -959,6 +1081,7 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
|
|||||||
if(ret <= 0 || ret == 4)
|
if(ret <= 0 || ret == 4)
|
||||||
goto ex;
|
goto ex;
|
||||||
open_path_pt= temp_path;
|
open_path_pt= temp_path;
|
||||||
|
new_empty= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(write_fd==-1) {
|
if(write_fd==-1) {
|
||||||
@ -972,6 +1095,25 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
|
|||||||
if(write_fd==-1)
|
if(write_fd==-1)
|
||||||
goto cannot_restore;
|
goto cannot_restore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(new_empty) {
|
||||||
|
/* If chattr 'C' "no copy-on-write" is present on node and enabled for
|
||||||
|
restoring, then set it as long as the file is empty, because man chattr
|
||||||
|
says so for btrfs.
|
||||||
|
*/
|
||||||
|
ret= iso_node_get_lfa_flags(node, &lfa_flags, &max_bit, 0);
|
||||||
|
if(ret > 0) {
|
||||||
|
if(lfa_flags & lfa_C & xorriso->lfa_restore_mask) {
|
||||||
|
ret= iso_local_set_lfa_flags(open_path_pt, lfa_C, max_bit, lfa_C,
|
||||||
|
&os_errno, 0);
|
||||||
|
ret= Xorriso_report_chattr_outcome(xorriso, open_path_pt,
|
||||||
|
lfa_C, lfa_C, ret, os_errno, 0);
|
||||||
|
if(ret <= 0)
|
||||||
|
goto cannot_restore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(ISO_NODE_IS_BOOTCAT(node)) {
|
if(ISO_NODE_IS_BOOTCAT(node)) {
|
||||||
ret= Xorriso_get_volume(xorriso, &volume, 0);
|
ret= Xorriso_get_volume(xorriso, &volume, 0);
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
@ -1479,6 +1621,8 @@ int Xorriso_restore_disk_object(struct XorrisO *xorriso,
|
|||||||
goto restoring_failed;
|
goto restoring_failed;
|
||||||
if(ret == 4)
|
if(ret == 4)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
if(ret == 2)
|
||||||
|
{ret= 3; goto ex;}
|
||||||
}
|
}
|
||||||
if(first_part_node != NULL && !no_props)
|
if(first_part_node != NULL && !no_props)
|
||||||
Xorriso_restore_properties(xorriso, disk_path, first_part_node,
|
Xorriso_restore_properties(xorriso, disk_path, first_part_node,
|
||||||
@ -1526,6 +1670,8 @@ int Xorriso_restore_disk_object(struct XorrisO *xorriso,
|
|||||||
| (no_props << 3));
|
| (no_props << 3));
|
||||||
if(ret == 4)
|
if(ret == 4)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
if(ret == 2)
|
||||||
|
{ret= 3; goto ex;}
|
||||||
if(ret > 0 && (flag & 8) && !no_props)
|
if(ret > 0 && (flag & 8) && !no_props)
|
||||||
ret= Xorriso_restore_properties(xorriso, disk_path, node, 2 | !!(flag&64));
|
ret= Xorriso_restore_properties(xorriso, disk_path, node, 2 | !!(flag&64));
|
||||||
if(ret<=0) {
|
if(ret<=0) {
|
||||||
@ -1537,8 +1683,6 @@ restoring_failed:;
|
|||||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
|
||||||
{ret= 0; goto ex;}
|
{ret= 0; goto ex;}
|
||||||
}
|
}
|
||||||
if(ret==2)
|
|
||||||
{ret= 3; goto ex;}
|
|
||||||
if(record_hl_path) { /* Start of a disk hardlink family */
|
if(record_hl_path) { /* Start of a disk hardlink family */
|
||||||
ret= Xorriso_register_node_target(xorriso, node_idx, disk_path, 0);
|
ret= Xorriso_register_node_target(xorriso, node_idx, disk_path, 0);
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
@ -1659,7 +1803,7 @@ int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir,
|
|||||||
IsoDirIter *iter= NULL;
|
IsoDirIter *iter= NULL;
|
||||||
IsoNode **node_array= NULL;
|
IsoNode **node_array= NULL;
|
||||||
int node_count= 0, node_idx;
|
int node_count= 0, node_idx;
|
||||||
int ret, source_is_dir, fret, was_failure= 0;
|
int ret, source_is_dir, fret, was_failure= 0, sret;
|
||||||
int do_not_dive, source_is_split= 0, len_dp, len_ip, stbuf_ret, hflag, hret;
|
int do_not_dive, source_is_split= 0, len_dp, len_ip, stbuf_ret, hflag, hret;
|
||||||
char *name, *disk_name, *leaf_name, *srcpt, *stbuf_src= "";
|
char *name, *disk_name, *leaf_name, *srcpt, *stbuf_src= "";
|
||||||
struct LinkiteM *own_link_stack;
|
struct LinkiteM *own_link_stack;
|
||||||
@ -1667,8 +1811,9 @@ int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir,
|
|||||||
char *disk_path= NULL, *img_path= NULL, *link_target= NULL;
|
char *disk_path= NULL, *img_path= NULL, *link_target= NULL;
|
||||||
off_t mem;
|
off_t mem;
|
||||||
struct PermiteM *perm_stack_mem;
|
struct PermiteM *perm_stack_mem;
|
||||||
struct stat stbuf;
|
struct stat stbuf, disk_stbuf;
|
||||||
int dir_create= 0, node_register= 0, do_node_count= 0, normal_mode= 0;
|
int dir_create= 0, node_register= 0, do_node_count= 0, normal_mode= 0;
|
||||||
|
int target_was_no_dir, dir_is_new;
|
||||||
|
|
||||||
perm_stack_mem= xorriso->perm_stack;
|
perm_stack_mem= xorriso->perm_stack;
|
||||||
switch((flag >> 7) & 3) {
|
switch((flag >> 7) & 3) {
|
||||||
@ -1759,6 +1904,8 @@ much_too_long:;
|
|||||||
|
|
||||||
while(1) { /* loop over ISO directory content */
|
while(1) { /* loop over ISO directory content */
|
||||||
stbuf_src= "";
|
stbuf_src= "";
|
||||||
|
target_was_no_dir= 0;
|
||||||
|
dir_is_new= 0;
|
||||||
|
|
||||||
#ifdef Osirrox_not_yeT
|
#ifdef Osirrox_not_yeT
|
||||||
|
|
||||||
@ -1862,26 +2009,49 @@ much_too_long:;
|
|||||||
} else if(node_register || do_node_count) {
|
} else if(node_register || do_node_count) {
|
||||||
ret= 1;
|
ret= 1;
|
||||||
} else {
|
} else {
|
||||||
|
if(source_is_dir) {
|
||||||
|
ret= lstat(disk_path, &disk_stbuf);
|
||||||
|
if(ret == -1) {
|
||||||
|
target_was_no_dir= 1;
|
||||||
|
} else {
|
||||||
|
if(!S_ISDIR(disk_stbuf.st_mode))
|
||||||
|
target_was_no_dir= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path,
|
ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path,
|
||||||
(off_t) 0, (off_t) 0, hflag);
|
(off_t) 0, (off_t) 0, hflag);
|
||||||
if(ret == 3) /* intentionally not restored */
|
if(ret == 3) /* intentionally not restored */
|
||||||
do_not_dive= 1;
|
do_not_dive= 1;
|
||||||
|
if(target_was_no_dir) {
|
||||||
|
sret= lstat(disk_path, &disk_stbuf);
|
||||||
|
if(sret != -1)
|
||||||
|
if(S_ISDIR(disk_stbuf.st_mode))
|
||||||
|
dir_is_new= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
goto was_problem;
|
goto was_problem;
|
||||||
}
|
}
|
||||||
|
ret= 1;
|
||||||
if(source_is_dir && !do_not_dive) {
|
if(source_is_dir && !do_not_dive) {
|
||||||
ret= Xorriso_restore_tree(xorriso, (IsoDir *) node,
|
ret= Xorriso_restore_tree(xorriso, (IsoDir *) node,
|
||||||
img_path, disk_path, mem,
|
img_path, disk_path, mem,
|
||||||
own_link_stack, 1 | (flag & (2 | (3 << 7))));
|
own_link_stack, 1 | (flag & (2 | (3 << 7))));
|
||||||
/* eventually restore exact access permissions of directory */
|
}
|
||||||
|
if(source_is_dir) {
|
||||||
|
/* Restore exact access permissions of directory */
|
||||||
hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
|
hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
|
||||||
!!(flag&64));
|
!!(flag&64));
|
||||||
if(hret<=0 && hret<ret)
|
if(hret<=0 && hret<ret)
|
||||||
ret= hret;
|
ret= hret;
|
||||||
if(ret<=0)
|
if(dir_is_new && !dir_create) {
|
||||||
goto was_problem;
|
hret= Xorriso_restore_chattr_i(xorriso, node, disk_path, 0);
|
||||||
|
if(hret <= 0 && hret < ret)
|
||||||
|
ret= hret;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if(ret <= 0)
|
||||||
|
goto was_problem;
|
||||||
|
|
||||||
continue; /* regular bottom of loop */
|
continue; /* regular bottom of loop */
|
||||||
was_problem:;
|
was_problem:;
|
||||||
@ -2115,7 +2285,8 @@ attach_source:;
|
|||||||
if(hret < 0)
|
if(hret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
if(new_dir_made && !(flag&64))
|
}
|
||||||
|
if(new_dir_made && !(flag&64)) {
|
||||||
/* set timestamps which Permstack_pop() will not set */
|
/* set timestamps which Permstack_pop() will not set */
|
||||||
Xorriso_restore_properties(xorriso, disk_path, node, 2);
|
Xorriso_restore_properties(xorriso, disk_path, node, 2);
|
||||||
}
|
}
|
||||||
@ -2137,9 +2308,27 @@ attach_source:;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
*npt= '/';
|
*npt= '/';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(new_dir_made && !dir_create) {
|
||||||
|
ret= 1;
|
||||||
|
/* Need to set any properties before possibly setting immutable bit.
|
||||||
|
So pop earlier than normal.
|
||||||
|
*/
|
||||||
|
hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
|
||||||
|
2 | !!(flag&64));
|
||||||
|
if(hret <= 0 && hret < ret)
|
||||||
|
ret= hret;
|
||||||
|
hret= Xorriso_restore_chattr_i(xorriso, node, disk_path, 0);
|
||||||
|
if(hret <= 0 && hret < ret)
|
||||||
|
ret= hret;
|
||||||
|
if(ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
Xorriso_process_msg_queues(xorriso,0);
|
Xorriso_process_msg_queues(xorriso,0);
|
||||||
ret= 1 + (is_dir && !leaf_is_split);
|
ret= 1 + (is_dir && !leaf_is_split);
|
||||||
ex:;
|
ex:;
|
||||||
@ -2419,6 +2608,8 @@ int Xorriso_extract_cut(struct XorrisO *xorriso,
|
|||||||
eff_disk_path, (off_t) 0, bytes, 2 | 8);
|
eff_disk_path, (off_t) 0, bytes, 2 | 8);
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
if(ret != 1)
|
||||||
|
{ret= 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret= Xorriso_restore_properties(xorriso, eff_disk_path, node, 0);
|
ret= Xorriso_restore_properties(xorriso, eff_disk_path, node, 0);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
.\" First parameter, NAME, should be all caps
|
.\" First parameter, NAME, should be all caps
|
||||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
.\" other parameters are allowed: see man(7), man(1)
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
.TH XORRISO 1 "Version 1.5.7, Jul 23, 2024"
|
.TH XORRISO 1 "Version 1.5.7, Aug 05, 2024"
|
||||||
.\" Please adjust this date whenever revising the manpage.
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
.\"
|
.\"
|
||||||
.\" Some roff macros, for reference:
|
.\" Some roff macros, for reference:
|
||||||
@ -1093,6 +1093,10 @@ changeable by the bearer of superuser capabilities. "no_restore_su" disables
|
|||||||
restoring of these attributes. "restore_su_auto" enables it only if the
|
restoring of these attributes. "restore_su_auto" enables it only if the
|
||||||
effective user id is 0.
|
effective user id is 0.
|
||||||
.br
|
.br
|
||||||
|
The attribute "i" (for "immutable") gets restored to directories only if they
|
||||||
|
have been created freshly by the same file restoring xorriso command.
|
||||||
|
A directory which already existed on disk will not be made immutable.
|
||||||
|
.br
|
||||||
Mode "restore_only_known" restricts restoring to the known settable attribute
|
Mode "restore_only_known" restricts restoring to the known settable attribute
|
||||||
flags "aAcCdDFijmPsStTux". "restore_unknown" enables the attempt to restore
|
flags "aAcCdDFijmPsStTux". "restore_unknown" enables the attempt to restore
|
||||||
unknown flags or even those which are known to be unchangeable, if they are
|
unknown flags or even those which are known to be unchangeable, if they are
|
||||||
@ -4805,11 +4809,14 @@ drive can be "indev" or "outdev" to indicate already acquired drives,
|
|||||||
or it can be the path of a not yet acquired drive.
|
or it can be the path of a not yet acquired drive.
|
||||||
Prefix "stdio:" for non\-MMC drives is not mandatory.
|
Prefix "stdio:" for non\-MMC drives is not mandatory.
|
||||||
.br
|
.br
|
||||||
For entity and id, see also command \-load. They must be either "sbsector" with
|
See command \fB\-load\fR for the meaning of entity and id.
|
||||||
the superblock sector address as id,
|
.br
|
||||||
or "track" with a track number as id, or "session" with a session number,
|
Entities are: "auto", "session", "track", "lba", "sbsector", "volid",
|
||||||
or "volid" with a search pattern for the volume id, or "auto" with which
|
"at_time", "before", "not_after", "after", and "not_before".
|
||||||
any text as id mounts the first track of the last session.
|
.br
|
||||||
|
Each is to be used with its appropriate kind of id string: "auto",
|
||||||
|
session number, track number, block number, search expression for volume id,
|
||||||
|
or time string.
|
||||||
.br
|
.br
|
||||||
path will be used as mount point and must already exist as a directory on disk.
|
path will be used as mount point and must already exist as a directory on disk.
|
||||||
.br
|
.br
|
||||||
@ -5916,6 +5923,9 @@ Code "codes" lists them. They share names with related commands
|
|||||||
.br
|
.br
|
||||||
"xattr" tells whether xorriso has an adapter for local filesystems EA.
|
"xattr" tells whether xorriso has an adapter for local filesystems EA.
|
||||||
.br
|
.br
|
||||||
|
"lfa_flags" tells whether xorriso has an adapter for local Linux file
|
||||||
|
attributes (see man 1 chattr).
|
||||||
|
.br
|
||||||
"jigdo" tells whether production of Jigdo files is possible.
|
"jigdo" tells whether production of Jigdo files is possible.
|
||||||
.br
|
.br
|
||||||
"zisofs" tells whether zisofs and built\-in gzip filters are enabled.
|
"zisofs" tells whether zisofs and built\-in gzip filters are enabled.
|
||||||
|
@ -978,6 +978,10 @@ activate them only after image loading.
|
|||||||
are only changeable by the bearer of superuser capabilities.
|
are only changeable by the bearer of superuser capabilities.
|
||||||
"no_restore_su" disables restoring of these attributes.
|
"no_restore_su" disables restoring of these attributes.
|
||||||
"restore_su_auto" enables it only if the effective user id is 0.
|
"restore_su_auto" enables it only if the effective user id is 0.
|
||||||
|
The attribute "i" (for "immutable") gets restored to directories
|
||||||
|
only if they have been created freshly by the same file restoring
|
||||||
|
xorriso command. A directory which already existed on disk will
|
||||||
|
not be made immutable.
|
||||||
Mode "restore_only_known" restricts restoring to the known settable
|
Mode "restore_only_known" restricts restoring to the known settable
|
||||||
attribute flags "aAcCdDFijmPsStTux". "restore_unknown" enables the
|
attribute flags "aAcCdDFijmPsStTux". "restore_unknown" enables the
|
||||||
attempt to restore unknown flags or even those which are known to
|
attempt to restore unknown flags or even those which are known to
|
||||||
@ -4030,11 +4034,13 @@ File: xorriso.info, Node: Inquiry, Next: Navigate, Prev: DialogCtl, Up: Comm
|
|||||||
drive can be "indev" or "outdev" to indicate already acquired
|
drive can be "indev" or "outdev" to indicate already acquired
|
||||||
drives, or it can be the path of a not yet acquired drive. Prefix
|
drives, or it can be the path of a not yet acquired drive. Prefix
|
||||||
"stdio:" for non-MMC drives is not mandatory.
|
"stdio:" for non-MMC drives is not mandatory.
|
||||||
For entity and id, see also command -load. They must be either
|
See command '-load' for the meaning of entity and id.
|
||||||
"sbsector" with the superblock sector address as id, or "track"
|
Entities are: "auto", "session", "track", "lba", "sbsector",
|
||||||
with a track number as id, or "session" with a session number, or
|
"volid", "at_time", "before", "not_after", "after", and
|
||||||
"volid" with a search pattern for the volume id, or "auto" with
|
"not_before".
|
||||||
which any text as id mounts the first track of the last session.
|
Each is to be used with its appropriate kind of id string: "auto",
|
||||||
|
session number, track number, block number, search expression for
|
||||||
|
volume id, or time string.
|
||||||
path will be used as mount point and must already exist as a
|
path will be used as mount point and must already exist as a
|
||||||
directory on disk.
|
directory on disk.
|
||||||
The command gets printed to the result channel. See command -mount
|
The command gets printed to the result channel. See command -mount
|
||||||
@ -4967,6 +4973,8 @@ File: xorriso.info, Node: Scripting, Next: Frontend, Prev: Emulation, Up: Co
|
|||||||
ACLs.
|
ACLs.
|
||||||
"xattr" tells whether xorriso has an adapter for local filesystems
|
"xattr" tells whether xorriso has an adapter for local filesystems
|
||||||
EA.
|
EA.
|
||||||
|
"lfa_flags" tells whether xorriso has an adapter for local Linux
|
||||||
|
file attributes (see man 1 chattr).
|
||||||
"jigdo" tells whether production of Jigdo files is possible.
|
"jigdo" tells whether production of Jigdo files is possible.
|
||||||
"zisofs" tells whether zisofs and built-in gzip filters are
|
"zisofs" tells whether zisofs and built-in gzip filters are
|
||||||
enabled.
|
enabled.
|
||||||
@ -5907,7 +5915,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
|
|||||||
|