New commands -projid, -get_projid, -get_projid_r, -set_projid, -set_projid_r, -find test -has_projid, -find actions get_projid, set_projid, get_projid_minmax

This commit is contained in:
Thomas Schmitt 2024-11-03 20:04:54 +01:00
parent 923bfa0be9
commit 32bfa95973
25 changed files with 1168 additions and 214 deletions

View File

@ -380,6 +380,9 @@ isoburn_toc_track_get_emul_v2;
Xorriso_option_chattri;
Xorriso_option_for_backup;
Xorriso_option_genisoimage_completion;
Xorriso_option_get_projid;
Xorriso_option_lfa_flags;
Xorriso_option_projid;
Xorriso_option_set_projid;
} LIBISOBURN1;

View File

@ -159,6 +159,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->do_aaip= 0;
if(m->lfa_flags_setting & 1)
m->do_aaip|= m->lfa_flags_setting & (15 << 11);
m->projid_mapper= NULL;
m->do_md5= 64;
m->no_emul_toc= 0;
m->do_old_empty= 0;

View File

@ -295,6 +295,7 @@ ex:;
bit24= hardlink split
bit25= hardlink fusion
bit26= Linux file attribute mismatch
bit27= XFS-style project id mismatch
@param flag bit0= compare atime
bit1= compare ctime
bit2= check only existence of both file objects
@ -323,6 +324,7 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
int split_count= 0;
time_t stamp;
uint64_t lfa_flags1, lfa_flags2;
uint32_t projid1= 0, projid2= 0;
char *part_path= NULL, *part_name;
int partno, total_parts= 0;
@ -520,6 +522,25 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
}
}
/* XFS-style project id */
if(xorriso->do_aaip & (1 << 17)) {
ret= Xorriso_get_projid(xorriso, NULL, disk_adr, &projid1,
2 | ((flag & (1 << 28)) >> 23));
if(ret < 0)
goto ex;
ret= Xorriso_get_projid(xorriso, NULL, iso_adr, &projid2, 0);
if(ret < 0)
goto ex;
if(projid1 != projid2) {
(*result)|= (1 << 27);
sprintf(respt, "%s projid : %lu <> %lu",
a, (unsigned long int) projid1, (unsigned long int) projid2);
strcat(respt, "\n");
if(!(flag & (1u << 31)))
Xorriso_result(xorriso, 0);
}
}
if(s1.st_uid != s2.st_uid) {
sprintf(respt, "%s st_uid : %lu <> %lu\n", a,
(unsigned long) s1.st_uid, (unsigned long) s2.st_uid);

View File

@ -372,6 +372,24 @@ else
echo "disabled Linux chattr(1) flags"
fi
dnl ts C41009
AH_TEMPLATE([Libisofs_with_aaip_projiD],
[Define to use XFS-style project id capabilities])
PROJID_DEF=
AC_ARG_ENABLE(projid,
[ --enable-projid Enable processing of XFS-style project id, default=yes],
, enable_projid=yes)
if test x"$enable_projid" = xyes; then
AC_CHECK_HEADER(linux/fs.h, PROJID_DEF="-DLibisofs_with_aaip_projiD",
PROJID_DEF=)
fi
if test x"$PROJID_DEF" = x; then
echo "disabled XFS-style project id"
else
AC_DEFINE([Libisofs_with_aaip_projiD], [])
echo "enabled XFS-style project id"
fi
AH_TEMPLATE([Libisofs_with_zliB], [Define to use compression via zlib])
AH_TEMPLATE([LIBJTE_WITH_ZLIB], [Allow libjte to use zlib])
AC_ARG_ENABLE(zlib,

View File

@ -1162,6 +1162,7 @@ int Xorriso_findx_action(struct XorrisO *xorriso, struct FindjoB *job,
time_t date= 0;
mode_t mode_or= 0, mode_and= ~1;
uint64_t chattr_flags, lfa_flags;
uint32_t projid;
char *target, *text_2, *wdi_mem= NULL, *disk_prefix, *iso_path= NULL;
char *basename, *lfa_text= NULL, *acl_text= NULL, *attrlist= NULL;
char *leafname= NULL;
@ -1323,7 +1324,21 @@ int Xorriso_findx_action(struct XorrisO *xorriso, struct FindjoB *job,
ret= 1;
}
} else {
} else if(action == 63) { /* get_projid */
ret= Xorriso_get_projid(xorriso, NULL, show_path, &projid, 2);
if(ret > 0)
Xorriso_show_projid(xorriso, show_path, projid, 0);
} else if(action == 65) { /* get_projid_minmax */
ret= Xorriso_get_projid(xorriso, NULL, show_path, &projid, 2);
if(ret > 0) {
if((off_t) projid < job->projid_low || job->projid_low == -1)
job->projid_low= projid;
if((off_t) projid > job->projid_high || job->projid_high == -1)
job->projid_high= projid;
}
} else { /* all other actions default to echo */
Xorriso_esc_filepath(xorriso,show_path, xorriso->result_line, 0);
strcat(xorriso->result_line, "\n");
Xorriso_result(xorriso, 0);

View File

@ -182,7 +182,14 @@ static int Xorriso_grasp_loaded_aaip(struct XorrisO *xorriso, IsoImage *volset,
if(!(xorriso->do_aaip & (1 << 11))) {
/* lfa_flags not enabled for "read" */
ret= Xorriso_remove_all_lfa_flags(xorriso, 0);
ret= Xorriso_tree_remove_isofs_var(xorriso, "isofs.fa", 0);
if(ret <= 0)
goto ex;
}
if(!(xorriso->do_aaip & (1 << 17))) {
/* projid not enabled */
ret= Xorriso_tree_remove_isofs_var(xorriso, "isofs.pi", 0);
if(ret <= 0)
goto ex;
}
@ -276,7 +283,7 @@ int Xorriso_make_read_options(struct XorrisO *xorriso,
if(xorriso->read_fs & 2)
ext|= isoburn_ropt_nojoliet;
if((xorriso->ino_behavior & (1 | 2)) &&
!(xorriso->do_aaip & (1 | 4 | 32 | (1 << 11)))
!(xorriso->do_aaip & (1 | 4 | 32 | (1 << 11) | (1 << 17)))
&& !(xorriso->do_md5 & 1) && !(xorriso->do_hfsplus))
ext|= isoburn_ropt_noaaip;
if(!(xorriso->do_aaip & 1))
@ -285,6 +292,8 @@ int Xorriso_make_read_options(struct XorrisO *xorriso,
ext|= isoburn_ropt_noea;
if(xorriso->do_aaip & (1 << 11))
ext|= isoburn_ropt_lfa_flags;
if(xorriso->do_aaip & (1 << 17))
ext|= isoburn_ropt_projid;
if(xorriso->do_aaip & (1 << 15))
ext|= isoburn_ropt_lfa_only_settable;
if(xorriso->ino_behavior & 1)
@ -479,6 +488,8 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, char *show_adr,
}
if(xorriso->do_aaip & (1 << 11))
aquire_flag|= 1 << 11;
if(xorriso->do_aaip & (1 << 17))
aquire_flag|= 1 << 12;
if(xorriso->do_aaip & (1 << 15))
aquire_flag|= 1 << 15;
if(flag & 128)

View File

@ -372,20 +372,26 @@ int Findjob_new(struct FindjoB **o, char *start_path, int flag)
m->text_2= NULL; /* a mere pointer, not managed memory */
m->user= 0;
m->group= 0;
m->mode_and= ~0;
m->mode_or= 0;
m->type= 0;
m->date= 0;
m->start_path= strdup(start_path);
if(m->start_path==NULL)
goto failed;
m->found_path= NULL;
m->estim_upper_size= 0;
m->estim_lower_size= 0;
m->subjob= NULL;
m->last_data_file_block= 0;
m->lfa_flags= 0;
m->projid_low= -1;
m->projid_high= -1;
m->errmsg[0]= 0;
m->errn= 0;
m->match_count= 0;
m->depth= 0;
m->start_path= strdup(start_path);
if(m->start_path==NULL)
goto failed;
ret= Exprnode_new(&(m->test_tree), m, NULL, "-find", (m->use_shortcuts)<<1);
if(ret<=0)
goto failed;

View File

@ -59,6 +59,7 @@ struct ExprtesT {
-2=smaller_or_equal , 2=larger_or_equal)
28= -has_lfa_flags uint64_t *arg1 (Linux file attribute flag bits)
29= -has_some_lfa_flags_of uint64_t *arg1
30= -has_projid uint64_t *arg1
*/
int test_type;
@ -193,6 +194,9 @@ struct FindjoB {
61= chattr mode
62= internal: like 27 "setfattr name value" but with permission for all
name spaces including "isofs."
63= get_projid
64= set_projid projid
65= get_projid_minmax
*/
int action;
int prune;
@ -213,6 +217,8 @@ struct FindjoB {
struct FindjoB *subjob;
uint32_t last_data_file_block;
uint64_t lfa_flags;
off_t projid_low;
off_t projid_high;
/* Errors */
char errmsg[4096];

View File

@ -51,6 +51,8 @@ int Xorriso_set_ignore_aclea(struct XorrisO *xorriso, int flag)
hflag|= 8;
if(xorriso->do_aaip & 2048)
hflag|= 4;
if(xorriso->do_aaip & (1 << 17))
hflag|= 64;
if(xorriso->do_aaip & (1 << 15))
hflag|= 32;
iso_image_set_ignore_aclea(volume, hflag);

View File

@ -40,7 +40,7 @@
/* @param flag bit0= give directory x-permission where is r-permission
bit1= do not transfer ACL, xattr, file attribute flags
bit1= do not transfer ACL, xattr, lfa_flags, projid
bit2= record dev,inode (only if enabled by xorriso)
bit3= with bit0: pretend to have indeed a directory
bit5= transfer ACL or xattr from eventual link target
@ -50,7 +50,8 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf,
{
mode_t mode;
int ret= 1, max_bit, os_errno;
uint64_t lfa_flags;
uint64_t lfa_flags= 0;
uint32_t projid= 0;
size_t num_attrs= 0, *value_lengths= NULL;
char **names= NULL, **values= NULL;
@ -75,7 +76,7 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf,
iso_node_set_mtime(node, stbuf->st_mtime);
iso_node_set_ctime(node, stbuf->st_ctime);
if((xorriso->do_aaip & (1 | 4 | 2048)) && !(flag & 2)) {
if((xorriso->do_aaip & (1 | 4 | 2048 | (1 << 17))) && !(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)
@ -104,11 +105,13 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf,
if((xorriso->do_aaip & (1 << 15)) && ret >= 0 && lfa_flags == 0)
ret= 4;
if(ret < 0) {
Xorriso_process_msg_queues(xorriso, 0);
Xorriso_report_iso_error(xorriso, disk_path, ret,
"Error when obtaining file attribute flags",
os_errno, "FAILURE", 1 | 2);
ret= 0; goto ex;
if(ret != (int) ISO_LFA_NOT_ENABLED) {
Xorriso_process_msg_queues(xorriso, 0);
Xorriso_report_iso_error(xorriso, disk_path, ret,
"Error when obtaining file attribute flags",
os_errno, "FAILURE", 1 | 2);
ret= 0; goto ex;
}
} else if(ret == 1 || ret == 2) {
ret= iso_node_set_lfa_flags(node, lfa_flags, 0);
if(ret < 0) {
@ -120,6 +123,15 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf,
}
}
}
if(xorriso->do_aaip & (1 << 17)) {
ret= Xorriso_get_projid(xorriso, NULL, disk_path, &projid,
(flag & 32) | 2);
if(ret <= 0)
goto ex;
ret= Xorriso_set_projid(xorriso, node, NULL, projid, 0);
if(ret <= 0)
goto ex;
}
}
if((flag & 4) && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) {
@ -2712,6 +2724,7 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job,
uint64_t lfa_flags, chattr_flags;
int max_bit;
char *lfa_text= NULL;
uint32_t projid;
action= Findjob_get_action_parms(job, &target, &text_2, &user, &group,
&mode_and, &mode_or, &type, &date, &subjob,
@ -3044,6 +3057,23 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job,
ret= Xorriso_set_lfa_flags(xorriso, node, show_path, "",
chattr_flags, type, 1 | 4);
} else if(action == 63) { /* get_projid */
ret= Xorriso_get_projid(xorriso, node, NULL, &projid, 0);
if(ret > 0)
Xorriso_show_projid(xorriso, show_path, projid, 0);
} else if(action == 64) { /* set_projid */
ret= Xorriso_set_projid(xorriso, node, NULL, (uint32_t) chattr_flags, 0);
} else if(action == 65) { /* get_projid_minmax */
ret= Xorriso_get_projid(xorriso, node, NULL, &projid, 0);
if(ret > 0) {
if((off_t) projid < job->projid_low || job->projid_low == -1)
job->projid_low= projid;
if((off_t) projid > job->projid_high || job->projid_high == -1)
job->projid_high= projid;
}
} else { /* includes : 15 in_iso */
Xorriso_esc_filepath(xorriso, show_path, xorriso->result_line, 0);
strcat(xorriso->result_line, "\n");
@ -3117,6 +3147,7 @@ return:
off_t range_lba, end_lba, *file_end_lbas= NULL, *file_start_lbas= NULL;
off_t start_lba;
uint64_t lfa_flags, node_flags;
uint32_t projid;
void *arg1, *arg2;
char ft, *decision, md5[16], bless_code[17], *acl_text= NULL;
regmatch_t name_match;
@ -3456,6 +3487,21 @@ test_name:;
value= !!(node_flags & lfa_flags);
}
break; case 30: /* -has_projid uint64_t projid (in ->lfa_flags) */
lfa_flags= *((uint64_t *) ftest->arg1);
if(node == NULL) {
hflag= 2;
ret= Xorriso_get_projid(xorriso, NULL, path, &projid, hflag);
} else {
ret= Xorriso_get_projid(xorriso, node, path, &projid, 0);
}
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso, 0);
value= 0;
goto ex;
}
value= (lfa_flags == (uint64_t) projid);
break; default:
/* >>> complain about unknown test type */;
@ -4846,18 +4892,29 @@ int Xorriso_set_lfa_flags(struct XorrisO *xorriso, void *in_node, char *path,
}
int Xorriso_remove_all_lfa_flags(struct XorrisO *xorriso, int flag)
int Xorriso_tree_remove_isofs_var(struct XorrisO *xorriso, char *isofs_name,
int flag)
{
int ret;
struct FindjoB *job= NULL;
struct stat dir_stbuf;
char name[40];
if(strlen(isofs_name) > 38 || strncmp(isofs_name, "isofs.", 6) != 0) {
Xorriso_msgs_submit(xorriso, 0,
"Program error: Bad name for Xorriso_tree_remove_isofs_var",
0, "FATAL", 0);
Xorriso_msgs_submit(xorriso, 0, isofs_name, 0, "FATAL", 0);
return(-1);
}
sprintf(name, "-%s", isofs_name);
ret= Findjob_new(&job, "/", 0);
if(ret<=0) {
Xorriso_no_findjob(xorriso, "xorriso", 0);
return(-1);
}
Findjob_set_action_text_2(job, 62, "-isofs.fa", "", 0);
Findjob_set_action_text_2(job, 62, name, "", 0);
ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/",
&dir_stbuf, 0, 0);
@ -4867,3 +4924,34 @@ int Xorriso_remove_all_lfa_flags(struct XorrisO *xorriso, int flag)
return(1);
}
/* @param in_node if not NULL: the node to manipulate
@path if in_node is NULL: path to node
in any case: path to report with errors
*/
int Xorriso_set_projid(struct XorrisO *xorriso, void *in_node, char *path,
uint32_t projid, int flag)
{
int ret;
IsoNode *node;
if(in_node != NULL) {
node= (IsoNode *) in_node;
} else {
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
if(ret <= 0)
return(ret);
}
ret= iso_node_set_projid(node, projid, 0);
if(ret < 0) {
Xorriso_process_msg_queues(xorriso, 0);
Xorriso_report_iso_error(xorriso, path, ret,
"Error when setting XFS-style project id of ISO node",
0, "SORRY", 1);
return(-1);
}
Xorriso_set_change_pending(xorriso, 0);
return(1);
}

View File

@ -2973,14 +2973,66 @@ from_disk:;
ret= iso_local_get_lfa_flags(path, lfa_flags, max_bit, &os_errno,
flag & ((1 << 5) | (1 << 7)));
if(ret < 0) {
Xorriso_process_msg_queues(xorriso, 0);
Xorriso_report_iso_error(xorriso, path, ret,
"Error when obtaining lsattr flags of disk file",
os_errno, "WARNING", 1);
return(-1);
if(ret != (int) ISO_LFA_NOT_ENABLED) {
Xorriso_process_msg_queues(xorriso, 0);
Xorriso_report_iso_error(xorriso, path, ret,
"Error when obtaining lsattr flags of disk file",
os_errno, "WARNING", 1);
return(-1);
}
}
if(ret == 1 || ret == 2)
return(1);
return(0);
}
/*
@param in_node if not NULL and not flag bit1: omit path resolution
@param flag bit1= path is disk_path
bit5= in case of symbolic link on disk: inquire link target
@return >0 = ok , *projid is valid
<0 = libisofs error
*/
int Xorriso_get_projid(struct XorrisO *xorriso, void *in_node, char *path,
uint32_t *projid, int flag)
{
int ret, os_errno;
IsoNode *node;
*projid= 0;
if(flag & 2)
goto from_disk;
node= (IsoNode *) in_node;
if(node == NULL) {
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
if(ret <= 0)
return(ret);
}
ret= iso_node_get_projid(node, projid, 0);
if(ret < 0) {
Xorriso_process_msg_queues(xorriso, 0);
Xorriso_report_iso_error(xorriso, path, ret,
"Error when obtaining XFS-style project id of ISO node",
0, "WARNING", 1);
return(-1);
}
return(1);
from_disk:;
ret= iso_local_get_projid(path, projid, &os_errno, flag & (1 << 5));
if(ret < 0) {
if(ret != (int) ISO_PROJID_NOT_ENABLED) {
Xorriso_process_msg_queues(xorriso, 0);
Xorriso_report_iso_error(xorriso, path, ret,
"Error when obtaining XFS-style project id of disk file",
os_errno, "WARNING", 1);
return(-1);
}
}
return(1);
}

View File

@ -930,6 +930,8 @@ int Xorriso_list_extras(struct XorrisO *xorriso, char *mode, int flag)
Xorriso_result(xorriso, 0);
sprintf(xorriso->result_line, "Local chattr : -lfa_flags\n");
Xorriso_result(xorriso, 0);
sprintf(xorriso->result_line, "Local projid : -projid\n");
Xorriso_result(xorriso, 0);
sprintf(xorriso->result_line, "Jigdo files : -jigdo\n");
Xorriso_result(xorriso, 0);
sprintf(xorriso->result_line, "zisofs : -zisofs\n");
@ -946,13 +948,15 @@ int Xorriso_list_extras(struct XorrisO *xorriso, char *mode, int flag)
"List of xorriso extra features. yes = enabled , no = disabled\n");
Xorriso_list_extras_result(xorriso, mode, "list_extras", 0);
ret= iso_local_attr_support(7);
ret= iso_local_attr_support(15);
sprintf(xorriso->result_line, "Local ACL : %s\n", ret & 1 ? "yes" : "no");
Xorriso_list_extras_result(xorriso, mode, "acl", 0);
sprintf(xorriso->result_line, "Local xattr : %s\n", ret & 2 ? "yes" : "no");
Xorriso_list_extras_result(xorriso, mode, "xattr", 0);
sprintf(xorriso->result_line, "Local chattr : %s\n", ret & 4 ? "yes" : "no");
Xorriso_list_extras_result(xorriso, mode, "lfa_flags", 0);
sprintf(xorriso->result_line, "Local projid : %s\n", ret & 8 ? "yes" : "no");
Xorriso_list_extras_result(xorriso, mode, "lfa_flags", 0);
sprintf(xorriso->result_line, "Jigdo files : %s\n",
#ifdef Xorriso_with_libjtE

View File

@ -958,6 +958,22 @@ off_t_overflow:;
Findjob_set_uint64_filter(job,
28 + (strcmp(argv[i - 1], "-has_some_lfa_flags_of") == 0),
lfa_flags, 0);
} else if(strcmp(argv[i], "-has_projid") == 0) {
if(i + 1 >= end_idx)
goto not_enough_arguments;
i++;
ret= Sfile_text_to_off_t(argv[i - 1], &start_lba, 0);
if(ret <= 0) {
bad_projid:;
sprintf(xorriso->info_text,
"-has_projid: project id number too large or too small");
goto sorry_ex;
}
if(start_lba < 0 || start_lba > (off_t) 0xffffffff)
goto bad_projid;
Findjob_set_uint64_filter(job, 30, (uint64_t) start_lba, 0);
} else if(strcmp(argv[i], "-has_filter")==0) {
Findjob_set_filter_filter(job, 1, 0);
} else if(strcmp(argv[i], "-has_no_filter")==0) {
@ -1494,6 +1510,25 @@ not_enough_exec_arguments:;
if(ret <= 0)
goto sorry_ex;
Findjob_set_action_chattr(job, 61, lfa_flags, operator, 0);
} else if(strcmp(cpt, "get_projid") == 0) {
Findjob_set_action_target(job, 63, NULL, 0);
} else if(strcmp(cpt, "set_projid") == 0) {
if(i + 1 >= end_idx)
goto not_enough_exec_arguments;
i++;
ret= Sfile_text_to_off_t(argv[i], &start_lba, 0);
if(ret <= 0) {
bad_set_projid:;
sprintf(xorriso->info_text,
"set_projid: project id number too large or too small");
goto sorry_ex;
}
if(start_lba < 0 || start_lba > (off_t) 0xffffffff)
goto bad_set_projid;
operator= 0;
Findjob_set_action_chattr(job, 64, start_lba, operator, 0);
} else if(strcmp(cpt, "get_projid_minmax") == 0) {
Findjob_set_action_target(job, 65, NULL, 0);
} else {
sprintf(xorriso->info_text, "-find -exec: unknown action ");
Text_shellsafe(argv[i], xorriso->info_text, 1);
@ -1564,6 +1599,17 @@ ex:;
!!(first_job->estim_upper_size % 2048)));
Xorriso_result(xorriso,0);
}
if(first_job != NULL && first_job->action == 65) {
if(first_job->projid_low >= 0 && first_job->projid_high >= 0) {
sprintf(xorriso->result_line, "projid minmax: %lu %lu\n",
(unsigned long) first_job->projid_low,
(unsigned long) first_job->projid_high);
} else {
sprintf(xorriso->result_line, "projid minmax: -1 -1\n");
}
Xorriso_result(xorriso,0);
}
if(access_acl_text != NULL)
free(access_acl_text);
if(default_acl_text != NULL)
@ -1671,6 +1717,7 @@ int Xorriso_option_for_backup(struct XorrisO *xorriso, int flag)
if(xorriso->lfa_flags_default & 8)
Xorriso_option_lfa_flags(xorriso,
"default:on:import_only_settable:restore_mask=aAcdDijmPsStTux", 0);
Xorriso_option_projid(xorriso, "on", 0);
return(1);
}
@ -1713,6 +1760,61 @@ int Xorriso_option_genisoimage_completion(struct XorrisO *xorriso,
}
/* Commands -get_projid alias get_projidi
-get_projid_r alias -get_projid_ri */
/* @param flag bit0=recursive -get_projid_r
*/
int Xorriso_option_get_projid(struct XorrisO *xorriso,
int argc, char **argv, int *idx, int flag)
{
int i, ret, was_failure= 0, end_idx, fret;
int optc= 0;
uint32_t projid= 0;
char **optv= NULL;
struct FindjoB *job= NULL;
struct stat dir_stbuf;
ret= Xorriso_opt_args(xorriso, "-get_projid", argc, argv, *idx,
&end_idx, &optc, &optv, 0);
if(ret <= 0)
goto ex;
for(i= 0; i < optc; i++) {
if(flag & 1) {
ret= Findjob_new(&job, optv[i], 0);
if(ret <= 0) {
Xorriso_no_findjob(xorriso, "-get_projid_r", 0);
{ret= -1; goto ex;}
}
Findjob_set_action_target(job, 63, NULL, 0);
ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0,
NULL, optv[i], &dir_stbuf, 0, 0);
Findjob_destroy(&job, 0);
} else {
ret= Xorriso_get_projid(xorriso, NULL, optv[i], &projid, 0);
if(ret > 0)
Xorriso_show_projid(xorriso, optv[i], projid, 0);
}
if(ret > 0 && !xorriso->request_to_abort)
continue; /* regular bottom of loop */
was_failure= 1;
fret= Xorriso_eval_problem_status(xorriso, ret, 1 | 2);
if(fret>=0)
continue;
ret= 0; goto ex;
}
ret= 1;
ex:;
(*idx)= end_idx;
Xorriso_opt_args(xorriso, "-get_projid", argc, argv, *idx, &end_idx,
&optc, &optv, 256);
Findjob_destroy(&job, 0);
if(ret<=0)
return(ret);
return(!was_failure);
}
/* Commands -getfacl alias -getfacli, -getfacl_r alias -getfacl_ri
-getfattr alias getfattri
*/
@ -1978,10 +2080,14 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" -lfa_flags mode[:mode ...]",
" Enable or disable reading and restoring of Linux chattr",
" flags.",
" -projid \"on\"|\"off\"|\"restore_0\"|\"map+\"low,high=low,high",
" Enable or disable reading and restoring of XFS-style",
" project ids. Define mapping of ids at restore time.",
" -md5 \"on\"|\"all\"|\"off\"",
" Enable or disable processing of MD5 checksums.",
" -for_backup",
" Shortcut for: -hardlinks on -acl on -xattr any -md5 on",
" -projid on",
" possibly: -lfa_flags default:on:restore_mask=aAcCdDijmPsStTux",
" -ecma119_map \"unmapped\"|\"stripped\"|\"uppercase\"|\"lowercase\"",
" Choose conversion of file names if neither Rock Ridge",
@ -2254,6 +2360,12 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" xattr of the iso_rr_path given by line \"# file:\".",
" -chattr \"+\"|\"-\"|\"=\"|\".\"mode iso_rr_path [***]",
" Set or unset Linux chattr flags of the given files.",
" -chattr_r \"+\"|\"-\"|\"=\"|\".\"mode iso_rr_path [***]",
" Like -chattr but affecting all files below directories.",
" -set_projid number iso_rr_path [***]",
" Set XFS-style project id number of the given files.",
" -set_projid_r number iso_rr_path [***]",
" Like -set_projid but affecting all files below directories.",
" -alter_date type timestring iso_rr_path [***]",
" Alter the date entries of a file in the ISO image. type is",
" one of \"a\", \"m\", \"b\" for:",
@ -2273,6 +2385,7 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" -lba_range start count, -damaged, -has_acl, -has_xattr,",
" -has_aaip, -has_filter, -has_md5, -has_any_xattr,",
" -has_lfa_flags letters, -has_some_lfa_flags_of letters,",
" -has_projid number,",
" -has_hfs_crtp, -has_hfs_bless, -bad_outname,",
" -name_limit_blocker, -maxdepth, -mindepth, -size,",
" -prune, -decision yes|no, -true, -false",
@ -2286,9 +2399,10 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" list_extattr, get_md5, check_md5, make_md5,",
" set_hfs_crtp, get_hfs_crtp, set_hfs_bless, get_hfs_bless,",
" set_filter, show_stream, show_stream_id, mkisofs_r,",
" hide, print_outname, estimate_size, in_iso, not_in_iso",
" add_missing, empty_iso_dir, is_full_in_iso, sort_weight",
" update_merge, rm_merge, clear_merge, lsattrd, chattr, find",
" hide, print_outname, estimate_size, in_iso, not_in_iso,",
" add_missing, empty_iso_dir, is_full_in_iso, sort_weight,",
" update_merge, rm_merge, clear_merge, lsattrd, chattr,",
" get_projid, set_projid, get_projid_minmax, find",
" params are their parameters except iso_rr_path.",
" -mkdir iso_rr_path [...]",
" Create empty directories if they do not exist yet.",
@ -2442,12 +2556,14 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" -lsdx pattern [***] like -lsx but listing directories as single items.",
" -lslx pattern [***] like -lsx but also telling some file attributes.",
" -lsdlx pattern [***] like -lsdx but also telling some file attributes.",
" -lsattr pattern [***] lists Linux chattr flags of the given files.",
" -lsattrd pattern [***] like -lsattr but listing directories as single items.",
" -getfacl pattern [***] list eventual ACLs of the given files.",
" -getfacl_r pattern [***] like -getfacl but listing whole file trees.",
" -getfattr pattern [***] list eventual xattr of the given files.",
" -getfxattr_r pattern [***] like -getfxattr but listing whole file trees.",
" -getfattr_r pattern [***] like -getfattr but listing whole file trees.",
" -lsattr pattern [***] lists Linux chattr flags of the given files.",
" -lsattrd pattern [***] like -lsattr but listing directories as single items.",
" -get_projid pattern [***] lists XFS-style project ids of the given files.",
" -get_projid_r pattern [***] like -get_projid but listing whole file trees.",
"",
" -du pattern [***] recursively lists sizes of files or directories in the",
" ISO image which match one of the shell parser patterns.",

View File

@ -401,6 +401,95 @@ int Xorriso_option_prog_help(struct XorrisO *xorriso, char *name, int flag)
}
/* Command -projid */
int Xorriso_option_projid(struct XorrisO *xorriso, char *mode, int flag)
{
int ret, l;
off_t from_low= 0, from_high= 0, to_low= 0, to_high= 0;
char *npt, *cpt, errmsg[80];
npt= cpt= mode;
for(; npt != NULL; cpt= npt + 1) {
npt= strchr(cpt, ':');
if(npt==NULL)
l= strlen(cpt);
else
l= npt-cpt;
if(l == 0)
continue;
if(l == 2 && strncmp(cpt, "on", l) == 0) {
xorriso->do_aaip|= (1 << 17);
} else if(l == 3 && strncmp(cpt, "off", l) == 0) {
xorriso->do_aaip&= ~(1 << 17);
} else if(l == 9 && strncmp(cpt, "restore_0", l) == 0) {
xorriso->do_aaip|= (1 << 18);
} else if(l == 9 && strncmp(cpt, "no_restore_0", l) == 0) {
xorriso->do_aaip&= ~(1 << 18);
} else if(l >= 4 && strncmp(cpt, "map+", 4) == 0) {
if(xorriso->projid_mapper == NULL) {
ret= Numbermapper_new(&(xorriso->projid_mapper),
(off_t) 0, (off_t) 0xffffffff, 0);
if(ret <= 0) {
sprintf(xorriso->info_text, "-projid: Cannot create mapper object");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
}
ret= Numbermapper_decode(xorriso->projid_mapper, cpt + 4,
&from_low, &from_high, &to_low, &to_high,
errmsg, 0);
if(ret <= 0) {
sprintf(xorriso->info_text, "-projid: map+ text unusable: %s", errmsg);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
{ret= 0; goto ex;}
}
ret= Numbermapper_add(xorriso->projid_mapper, from_low, from_high,
to_low, to_high, 0);
if(ret <= 0) {
sprintf(xorriso->info_text, "-projid: Cannot create mapper entry");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
} else if(l > 9 && strncmp(cpt, "map_test=", 9) == 0) {
strncpy(errmsg, cpt + 9, l - 9);
errmsg[l - 9]= 0;
ret= Sfile_text_to_off_t(errmsg, &from_low, 0);
if(ret <= 0) {
sprintf(xorriso->info_text,
"-projid: map= text cannot be converted to a number: %s",
errmsg);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
{ret= 0; goto ex;}
}
ret= Numbermapper_map(xorriso->projid_mapper, from_low, &to_low, 0);
if(ret < 0) {
sprintf(xorriso->info_text,
"-projid: map=%s yields unexpected error", errmsg);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
{ret= 0; goto ex;}
}
sprintf(xorriso->result_line, "projid mapped: %lu -> %lu\n",
from_low, to_low);
Xorriso_result(xorriso, 0);
} else if(l == 7 && strncmp(cpt, "default", l) == 0) {
xorriso->do_aaip&= ~(3 << 17);
Numbermapper_destroy(&(xorriso->projid_mapper), 0);
} else {
sprintf(xorriso->info_text,
"-projid: unknown or mistyped mode in '%s'", mode);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
}
ret= Xorriso_set_ignore_aclea(xorriso, 0);
if(ret <= 0)
goto ex;
ret= 1;
ex:
return(ret);
}
/* Option -prompt */
int Xorriso_option_prompt(struct XorrisO *xorriso, char *text, int flag)
{
@ -831,6 +920,71 @@ int Xorriso_option_session_log(struct XorrisO *xorriso, char *path, int flag)
}
/* Commands -set_projid alias -set_projidi
-set_projid_r alias -set_projid_ri */
/* @param flag bit0=recursive -set_projid_r
*/
int Xorriso_option_set_projid(struct XorrisO *xorriso, char *projid_text,
int argc, char **argv, int *idx, int flag)
{
int i, ret, was_failure= 0, end_idx, fret;
int optc= 0;
uint32_t projid= 0;
off_t num;
char **optv= NULL;
struct FindjoB *job= NULL;
struct stat dir_stbuf;
ret= Xorriso_opt_args(xorriso, "-set_projid", argc, argv, *idx,
&end_idx, &optc, &optv, 0);
if(ret <= 0)
goto ex;
ret= Sfile_text_to_off_t(projid_text, &num, 0);
if(ret <= 0) {
bad_set_projid:;
sprintf(xorriso->info_text,
"-set_projid: project id number too large or too small");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(num < 0 || num > (off_t) 0xffffffff)
goto bad_set_projid;
projid= num;
for(i= 0; i < optc; i++) {
if(flag & 1) {
ret= Findjob_new(&job, optv[i], 0);
if(ret <= 0) {
Xorriso_no_findjob(xorriso, "-set_projid_r", 0);
{ret= -1; goto ex;}
}
Findjob_set_action_chattr(job, 64, (uint64_t) projid, 0, 0);
ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0,
NULL, optv[i], &dir_stbuf, 0, 0);
Findjob_destroy(&job, 0);
} else {
ret= Xorriso_set_projid(xorriso, NULL, optv[i], projid, 0);
}
if(ret>0 && !xorriso->request_to_abort)
continue; /* regular bottom of loop */
was_failure= 1;
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
if(fret>=0)
continue;
ret= 0; goto ex;
}
ret= 1;
ex:;
(*idx)= end_idx;
Xorriso_opt_args(xorriso, "-set_projid", argc, argv, *idx, &end_idx,
&optc, &optv, 256);
Findjob_destroy(&job, 0);
if(ret<=0)
return(ret);
return(!was_failure);
}
/* Option -setfacl_list alias -setfacl_listi */
int Xorriso_option_setfacl_listi(struct XorrisO *xorriso, char *path, int flag)
{

View File

@ -599,7 +599,8 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
"options_from_file","osirrox","outdev","out_charset","overwrite",
"pacifier","padding","path_list","pathspecs","pkt_output",
"preparer_id","print","print_info","print_mark","prompt",
"prog","prog_help","publisher","quoted_not_list","quoted_path_list",
"prog","prog_help","projid","publisher",
"quoted_not_list","quoted_path_list",
"read_fs","read_speed","reassure","report_about",
"report_el_torito","report_system_area","rockridge",
"rom_toc_scan","rr_reloc_dir","scsi_dev_family","scsi_log",
@ -640,6 +641,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
"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",
"get_projid","get_projidi","get_projid_r","get_projid_ri",
"getfacl","getfacli","getfacl_r","getfacl_ri",
"getfattr","getfattri","getfattr_r","getfattr_ri","hide",
"launch_frontend","lsattr","lsattri","lsattrd","lsaddrdi",
@ -647,6 +649,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
"lsx","lslx","lsdx","lsdlx","map_l","mv","mvi","mkdir","mkdiri",
"not_paths","rm","rmi","rm_r","rm_ri","rmdir","rmdiri",
"update_l","update_li","update_lx","update_lxi",
"set_projid","set_projidi","set_projid_r","set_projid_ri",
"setfacl","setfacli","setfacl_list","setfacl_listi",
"setfacl_r","setfacl_ri","setfattr","setfattri",
"setfattr_r","setfattr_ri",
@ -746,7 +749,7 @@ int Xorriso_cmd_sorting_rank(struct XorrisO *xorriso,
"* Influencing the behavior of image loading:",
"read_speed", "load", "displacement", "read_fs",
"assert_volid", "in_charset", "auto_charset",
"for_backup", "hardlinks", "acl", "xattr", "md5", "lfa_flags",
"for_backup", "hardlinks", "acl", "xattr", "md5", "lfa_flags", "projid",
"ecma119_map", "joliet_map",
"disk_dev_ino", "rom_toc_scan", "calm_drive", "ban_stdio_write",
"data_cache_size",
@ -781,8 +784,8 @@ int Xorriso_cmd_sorting_rank(struct XorrisO *xorriso,
"* Navigation in ISO image and disk filesystem (2):",
"ls", "lsd", "lsl", "lsdl", "lsx", "lsdx", "lslx", "lsdlx",
"lsattr", "lsattri", "lsattrd", "lsaddrdi",
"getfacl", "getfacl_r", "getfattr", "getfattr_r", "du", "dus",
"lsattr", "lsattrd", "get_projid", "get_projid_r",
"dux", "dusx", "findx",
"compare", "compare_r", "compare_l", "show_stream", "show_stream_r",
@ -791,7 +794,8 @@ int Xorriso_cmd_sorting_rank(struct XorrisO *xorriso,
"rm", "rm_r", "rmdir", "move", "mv",
"chown", "chown_r", "chgrp", "chgrp_r", "chmod", "chmod_r", "setfacl",
"setfacl_r", "setfacl_list", "setfattr", "setfattr_r", "setfattr_list",
"chattr", "chattr_r", "alter_date", "alter_date_r", "hide",
"chattr", "chattr_r", "set_projid", "set_projid_r",
"alter_date", "alter_date_r", "hide",
"* Filters for data file content:",
"external_filter", "unregister_filter", "close_filter_list",
@ -1446,6 +1450,13 @@ next_command:;
(*idx)++;
ret= Xorriso_option_genisoimage_completion(xorriso, arg1, 0);
} else if(strcmp(cmd, "get_projid") == 0 || strcmp(cmd, "get_projidi") == 0) {
ret= Xorriso_option_get_projid(xorriso, argc, argv, idx, 0);
} else if(strcmp(cmd, "get_projid_r") == 0 ||
strcmp(cmd, "get_projid_ri") == 0) {
ret= Xorriso_option_get_projid(xorriso, argc, argv, idx, 1);
} else if(strcmp(cmd,"getfacl")==0 || strcmp(cmd,"getfacli")==0) {
ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 0);
@ -1752,6 +1763,10 @@ next_command:;
(*idx)++;
ret= Xorriso_option_prog(xorriso, arg1, 0);
} else if(strcmp(cmd,"projid") == 0) {
(*idx)++;
ret= Xorriso_option_projid(xorriso, arg1, 0);
} else if(strcmp(cmd,"publisher")==0) {
(*idx)++;
Xorriso_option_publisher(xorriso, arg1, 0);
@ -1866,6 +1881,15 @@ next_command:;
ret= Xorriso_option_mount(xorriso, arg1, arg2,
argv[(*idx)-2], argv[(*idx)-1], 2);
} else if(strcmp(cmd, "set_projid") == 0 || strcmp(cmd, "set_projidi") == 0) {
(*idx)++;
ret= Xorriso_option_set_projid(xorriso, arg1, argc, argv, idx, 0);
} else if(strcmp(cmd, "set_projid_r") == 0 ||
strcmp(cmd, "set_projid_ri") == 0) {
(*idx)++;
ret= Xorriso_option_set_projid(xorriso, arg1, argc, argv, idx, 1);
} else if(strcmp(cmd,"setfacl")==0 || strcmp(cmd,"setfacli")==0) {
(*idx)+= 1;
ret= Xorriso_option_setfacli(xorriso, arg1, argc, argv, idx, 0);

View File

@ -584,6 +584,8 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path,
int *errnos= NULL;
uint64_t lfa_flags= 0, mask= 0, push_mask= 0;
int max_bit, os_errno;
uint32_t projid;
off_t off_t_projid;
static uint64_t lfa_C= 0xffffffff, lfa_i= 0, lfa_a= 0, lfa_F= 0;
if(lfa_C == 0xffffffff) {
@ -770,6 +772,28 @@ cannot_set_perm:;
}
}
if(xorriso->do_aaip & (1 << 17)) {
ret= Xorriso_get_projid(xorriso, node, NULL, &projid, 0);
if(ret < 0)
goto ex;
ret= Numbermapper_map(xorriso->projid_mapper, (off_t) projid, &off_t_projid,
0);
if(ret < 0)
goto ex;
projid= off_t_projid;
if(projid != 0 || (xorriso->do_aaip & (1 << 18))) {
ret= iso_local_set_projid(disk_path, projid, &os_errno, 0);
if(ret < 0) {
Xorriso_process_msg_queues(xorriso, 0);
strcpy(xorriso->info_text,
"Error with setting XFS-style project id for ");
Text_shellsafe(disk_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
}
}
ret= 1 + !!lfa_ia_pushed;
ex:;
iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,1 << 15);

View File

@ -2775,7 +2775,7 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
-options_from_file:${resume_state_file}_pos
*/
{
int is_default, no_defaults, i, ret, adr_mode, do_single, behavior;
int is_default, no_defaults, i, ret, adr_mode, do_single, behavior, count;
int show_indev= 1, show_outdev= 1, show_dev= 0;
int do_drive_access, did_drive_access;
int part_table_implicit= 0;
@ -3862,6 +3862,31 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso, filter, fp, flag & 2);
count= Numbermapper_get_count(xorriso->projid_mapper, 0);
is_default= (count == 0 && !(xorriso->do_aaip & (1 << 17)));
strcpy(line, "-projid ");
if(xorriso->do_aaip & (1 << 17))
strcat(line, "on");
else
strcat(line, "off");
if(xorriso->do_aaip & (1 << 18))
strcat(line, ":restore_0");
else
strcat(line, ":no_restore_0");
strcat(line, "\n");
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso, filter, fp, flag & 2);
for(i= count - 1; i >= 0; i--) {
strcpy(line, "-projid map+");
ret= Numbermapper_encode(xorriso->projid_mapper, i, line + strlen(line),
1024, 0);
if(ret <= 0)
continue;
strcat(line, "\n");
Xorriso_status_result(xorriso, filter, fp, flag & 2);
}
is_default= ((xorriso->do_aaip & (16 | 32 | 64)) == 0);
sprintf(line,"-disk_dev_ino %s\n",
(xorriso->do_aaip & 16 ? (xorriso->do_aaip & 128 ? "ino_only" : "on" )
@ -4910,4 +4935,15 @@ int Xorriso_set_info_text(struct XorrisO *xorriso, char *text,
}
return(1);
}
int Xorriso_show_projid(struct XorrisO *xorriso, char *path, uint32_t projid,
int flag)
{
sprintf(xorriso->result_line, "%10lu ", (unsigned long int) projid);
Xorriso_esc_filepath(xorriso, path, xorriso->result_line, 1);
strcat(xorriso->result_line, "\n");
Xorriso_result(xorriso, 0);
return(1);
}

View File

@ -912,7 +912,7 @@ int Xorriso_make_iso_write_opts(struct XorrisO *xorriso, IsoImage *image,
((!!xorriso->do_iso1999) * isoburn_igopt_iso1999) |
(( !(xorriso->ino_behavior & 2)) * isoburn_igopt_hardlinks) |
(( (!(xorriso->ino_behavior & 2)) ||
(xorriso->do_aaip & (2 | 8 | 16 | 256 | (1 << 11))) ||
(xorriso->do_aaip & (2 | 8 | 16 | 256 | (1 << 11) | (1 << 17))) ||
(xorriso->do_md5 & (2 | 4)) ||
xorriso->do_hfsplus
) * isoburn_igopt_aaip) |

View File

@ -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.5.7, Oct 10, 2024"
.TH XORRISO 1 "Version 1.5.7, Nov 01, 2024"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -502,6 +502,19 @@ number grew over the years.
\fB\-lfa_flags\fR. Its command \-lsattr lists 22 flags the same way as the
program lsattr does. They can be set by xorriso command \-chattr and can be
enabled by \-lfa_flags for restoring when their files get restored to disk.
.PP
\fBXFS\-style project ids\fR are numbers which define the members of file
object groups, called projects. They can be set by programs chattr(1) and
xfs_quota(8) and reported by programs lsattr(1) and xfs_quota(8).
The files of a project can share quotas which limit their usage of filesystem
resources. This is possible in XFS and in specially prepared and mounted ext4
filesystems. Project id 0 means that the file is not member of any project.
.br
\fBxorriso\fR records non\-zero project ids of disk files if enabled by
command \fB\-projid\fR. Command \-get_projid lists the project ids of files.
They can be set by command \-set_projid and get restored to disk if enabled
by \-projid. Usually project id 0 is not set to restored disk files, so that
they may get the project id of their parent disk directory.
.SS
.B Command processing:
.br
@ -1145,6 +1158,51 @@ Mode "default" reinstates the default settings:
.br
Use "default:on" to get default settings with enabled processing.
.TP
\fB\-projid\fR mode[:mode...]
Enable, disable, or influence processing of XFS\-style project ids.
.br
Mode "on" enables recording and restoring of project ids.
.br
Mode "off" disables it.
.br
Mode "restore_0" enables restoring of project id 0 when files get extracted
to disk. Default is "no_restore_0" which leaves the decision about the project
id to the local filesystem, if the file has project id 0 in the ISO filesystem.
.br
Mode "map+" defines mappings of project id intervals in the ISO to project id
intervals on disk when files get restored. The form is:
.br
map+low_in_iso,high_in_iso=low_on_disk[,[high_on_disk]]
.br
"low_in_iso" and "high_in_iso" define the number interval from which the
mapping happens at restore time. "low_on_disk" is the mapping result of
"low_in_iso". Project id numbers up to "high_in_iso" get mapped to
.br
low_on_disk + (project_id \- low_in_iso)
.br