diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index c69229eb..7bae4013 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -2,7 +2,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 "Jan 25, 2008" +.TH XORRISO 1 "Jan 28, 2008" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -938,17 +938,17 @@ existing ACLs. If acl_text is empty, or contains the text "clear" or the text "--remove-all", then the existing ACLs will be removed and no new ones will be attached. Any other content of acl_text will be interpreted as a list of -ACL entries. It may be in the long format as put out by -getfacl but may also -be abbreviated as follows: +ACL entries. It may be in the long multi-line format as put out by -getfacl +but may also be abbreviated as follows: .br ACL entries are separated by comma or newline. If an entry is empty text or -begins with "#" then it will be gracefully ignored. A valid entry has to begin +begins with "#" then it will be ignored. A valid entry has to begin by a letter out of {ugom} for "user", "group", "other", "mask". It has to -contain two colons ":". A non-empty text between those two gives a user id -resp. group id. After the second ":" there may be letters out of {rwx-}. -Letter "-" is ignored. The other three give read, write resp. -execute permission. -Letter "X" or any other letters are not supported. Examples: +contain two colons ":". A non-empty text between those ":" gives a user id +resp. group id. After the second ":" there may be letters out of {rwx- #}. +The first three give read, write resp. execute permission. +Letters "-", " " and TAB are ignored. "#" causes the rest of the entry to +be ignored. Letter "X" or any other letters are not supported. Examples: .br g:toolies:rw,u:lisa:rw,u:1001:rw,u::wr,g::r,o::r,m::rw .br @@ -956,11 +956,21 @@ Letter "X" or any other letters are not supported. Examples: .br A valid entry may be prefixed by "d", some following characters and ":". This indicates that the entry goes to the "default" ACL rather than to the -"access" ACL. +"access" ACL. Example: +.br + u::rwx,g::rx,o::,d:u::rwx,d:g::rx,d:o::,d:u:lisa:rwx,d:m::rwx .TP \fB\-setfacl_r\fR acl_text iso_rr_path [***] Like -setfacl but affecting all files below eventual directories. .TP +\fB\-setfacl_list\fR disk_path +Read the output of -getfacl_r or shell command getfacl -R and apply it to the +iso_rr_paths as given in lines beginning with "# file:". This will change +ownership, group and ACL of the given files. +.br +Since -getfacl and getfacl strip leading "/" from file paths, the setting of +-cd does always matter. +.TP \fB\-alter_date\fR type timestring iso_rr_path [***] Alter the date entries of a file in the ISO image. type is one of "a", "m", "b" for access time, modification time, @@ -1449,7 +1459,7 @@ permissible. .B Settings for result writing: .TP Rock Ridge info will be generated by the program unconditionally. -ACL will be written according to the setting of option -acl. +ACLs will be written according to the setting of option -acl. .TP \fB\-joliet\fR "on"|"off" If enabled by "on", generate Joliet info additional to Rock Ridge info. diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 1932ef8c..4f30a095 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -10758,6 +10758,216 @@ ex: } +/* Normalize ACL and sort apart "access" ACL from "default" ACL. + */ +int Xorriso_normalize_acl_text(struct XorrisO *xorriso, char *in_text, + char **access_acl_text, char **default_acl_text, int flag) +{ + int ret, access_count= 0, default_count= 0, pass, is_default, line_len; + int was_error= 0, line_count= 0, perms; + char *acl_text= NULL, *cpt, *npt, *access_wpt= NULL, *default_wpt= NULL; + char *dpt, *ddpt, **wpt, *ppt; + + if(in_text[0] == 0 || strcmp(in_text, "clear") == 0 || + strcmp(in_text, "--remove-all") == 0) { + *access_acl_text= *default_acl_text= NULL; + return(1); + } else if (strcmp(in_text, "--remove-default") == 0) { + + /* >>> protect Access-ACL and delete Default-ACL */; + + /* <<< */ + return(0); + + } + + acl_text= strdup(in_text); + if(acl_text == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + {ret= -1; goto ex;} + } + + /* From comma to newline */ + for(cpt= strchr(acl_text, ','); cpt != NULL; cpt= strchr(cpt + 1, ',')) + *cpt= '\n'; + + /* Normalize to long text form + and sort apart "access" ACL from "default" ACL */; + for(pass= 0; pass < 2; pass++) { + line_count= 0; + for(cpt= acl_text; cpt != NULL; cpt= npt) { + line_count++; + npt= strchr(cpt, '\n'); + if(npt != NULL) + npt++; + if(*cpt == '#' || *cpt == '\n' || *cpt == 0) + continue; + + is_default= 0; + wpt= &access_wpt; + if(*cpt == 'd') { + is_default= 1; + if(pass == 1) + wpt= &default_wpt; + cpt= strchr(cpt, ':'); + if(cpt == NULL) { + was_error= line_count; + continue; + } + cpt++; + } + + line_len= 0; + dpt= strchr(cpt, ':'); + if(dpt != NULL) + ddpt= strchr(dpt + 1, ':'); + if(dpt == NULL || ddpt == NULL) { + was_error= line_count; + continue; + } + if(*cpt == 'u') { + if(pass == 0) { + line_len+= 5; + line_len+= ddpt - dpt; + } else { + strcpy(*wpt, "user:"); + strncpy(*wpt + 5, dpt + 1, ddpt - dpt); + (*wpt)+= 5 + (ddpt - dpt); + } + } else if(*cpt == 'g') { + if(pass == 0) { + line_len+= 6 + (ddpt - dpt); + } else { + strcpy(*wpt, "group:"); + strncpy(*wpt + 6, dpt + 1, ddpt - dpt); + (*wpt)+= 6 + (ddpt - dpt); + } + } else if(*cpt == 'o') { + if(pass == 0) { + if(ddpt - dpt > 1) { + was_error= line_count; + continue; + } + line_len+= 6 + (ddpt - dpt); + } else { + strcpy(*wpt, "other:"); + strncpy(*wpt + 6, dpt + 1, ddpt - dpt); + (*wpt)+= 6 + (ddpt - dpt); + } + } else if(*cpt == 'm') { + if(pass == 0) { + if(ddpt - dpt > 1) { + was_error= line_count; + continue; + } + line_len+= 5 + (ddpt - dpt); + } else { + strcpy(*wpt, "mask:"); + strncpy(*wpt + 5, dpt + 1, ddpt - dpt); + (*wpt)+= 5 + (ddpt - dpt); + } + + } else { + /* Unknown tag type */ + was_error= line_count; + continue; + } + + /* Examine permissions at ddpt + 1 */; + perms= 0; + for(ppt= ddpt + 1; *ppt != 0 && *ppt != '\n'; ppt++) { + if(*ppt == 'r') + perms|= 4; + else if(*ppt == 'w') + perms|= 2; + else if(*ppt == 'x') + perms|= 1; + else if(*ppt == '-' || *ppt == ' ' || *ppt == '\t') + ; + else if(*ppt == '#') + break; + else { + was_error= line_count; + break; + } + } + if(pass == 0) { + line_len+= 4; + } else { + sprintf(*wpt, "%c%c%c\n", + perms & 4 ? 'r' : '-', perms & 2 ? 'w' : '-', perms & 1 ? 'x' : '-'); + (*wpt)+= 4; + } + + if(pass == 0) { + if(is_default) + default_count+= line_len; + else + access_count+= line_len; + } + } + + if(pass == 0) { + *access_acl_text= calloc(access_count + 1, 1); + *default_acl_text= calloc(default_count + 1, 1); + if(access_acl_text == NULL || *default_acl_text == NULL) { + Xorriso_no_malloc_memory(xorriso, access_acl_text, 0); + {ret= -1; goto ex;} + } + access_wpt= *access_acl_text; + default_wpt= *default_acl_text; + } else { + *access_wpt= 0; + *default_wpt= 0; + } + } + + ret= 1; +ex:; + if(acl_text != NULL) + free(acl_text); + if(was_error) { + sprintf(xorriso->info_text, + "Malformed ACL entries encountered. Last one in line number %d.", + was_error); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(ret); +} + + +int Xorriso_perform_acl_from_list(struct XorrisO *xorriso, char *file_path, + char *uid, char *gid, char *acl, int flag) +{ + int ret, zero= 0; + uid_t uid_number; + gid_t gid_number; + + /* Set group and owner */ + if(gid[0]) { + ret= Xorriso_convert_gidstring(xorriso, gid, &gid_number, 0); + if(ret<=0) + return(ret); + ret= Xorriso_set_gid(xorriso, file_path, gid_number, 0); + if(ret<=0) + return(ret); + } + if(uid[0]) { + ret= Xorriso_convert_uidstring(xorriso, uid, &uid_number, 0); + if(ret<=0) + return(ret); + ret= Xorriso_set_uid(xorriso, file_path, uid_number, 0); + if(ret<=0) + return(ret); + } + ret= Xorriso_option_setfacli(xorriso, acl, 1, &file_path, &zero, 0); + if(ret <= 0) + return(ret); + return(1); +} + + /* ---------------------------- Options API ------------------------ */ @@ -13338,6 +13548,9 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " in the ISO image by the ACL which is defined by acl_text.", " -setfacl_r acl_text iso_rr_path [***]", " Like -setfacl but affecting all files below directories.", +" -setfacl_list disk_path", +" Read output of getfacl from file disk_path. Set owner,", +" group and ACL of the iso_rr_path given by line \"# file:\".", " -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:", @@ -15224,195 +15437,125 @@ int Xorriso_option_session_log(struct XorrisO *xorriso, char *path, int flag) } -/* Normalize ACL and sort apart "access" ACL from "default" ACL. - */ -int Xorriso_normalize_acl_text(struct XorrisO *xorriso, char *in_text, - char **access_acl_text, char **default_acl_text, int flag) +/* Option -setfacl_list alias -setfacl_listi */ +int Xorriso_option_setfacl_listi(struct XorrisO *xorriso, char *path, int flag) { - int ret, access_count= 0, default_count= 0, pass, is_default, line_len; - int was_error= 0, line_count= 0, perms; - char *acl_text= NULL, *cpt, *npt, *access_wpt= NULL, *default_wpt= NULL; - char *dpt, *ddpt, **wpt, *ppt; + int ret, eaten; + size_t buf_size= 0, buf_add= 64 * 1024, l, linecount= 0; + char line[SfileadrL * 4], *buf= NULL, *wpt, *new_buf, limit_text[80]; + char file_path[SfileadrL], uid[161], gid[161]; + FILE *fp= NULL; - if(in_text[0] == 0 || strcmp(in_text, "clear") == 0 || - strcmp(in_text, "--remove-all") == 0) { - *access_acl_text= *default_acl_text= NULL; - return(1); - } else if (strcmp(in_text, "--remove-default") == 0) { - - /* >>> protect Access-ACL and delete Default-ACL */; - - /* <<< */ - return(0); - - } - - acl_text= strdup(in_text); - if(acl_text == NULL) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - {ret= -1; goto ex;} - } - - /* From comma to newline */ - for(cpt= strchr(acl_text, ','); cpt != NULL; cpt= strchr(cpt + 1, ',')) - *cpt= '\n'; - - /* Normalize to long text form - and sort apart "access" ACL from "default" ACL */; - for(pass= 0; pass < 2; pass++) { - for(cpt= acl_text; cpt != NULL; cpt= npt) { - if(pass == 0) - line_count++; - npt= strchr(cpt, '\n'); - if(npt != NULL) - npt++; - if(*cpt == '#' || *cpt == '\n' || *cpt == 0) - continue; - - is_default= 0; - wpt= &access_wpt; - if(*cpt == 'd') { - is_default= 1; - if(pass == 1) - wpt= &default_wpt; - cpt= strchr(cpt, ':'); - if(cpt == NULL) { - was_error= line_count; - continue; - } - } - - line_len= 0; - dpt= strchr(cpt, ':'); - if(dpt != NULL) - ddpt= strchr(dpt + 1, ':'); - if(dpt == NULL || ddpt == NULL) { - was_error= line_count; - continue; - } - if(*cpt == 'u') { - if(pass == 0) { - line_len+= 5; - line_len+= ddpt - dpt; - } else { - strcpy(*wpt, "user:"); - strncpy(*wpt + 5, dpt + 1, ddpt - dpt); - (*wpt)+= 5 + (ddpt - dpt); - } - } else if(*cpt == 'g') { - if(pass == 0) { - line_len+= 6 + (ddpt - dpt); - } else { - strcpy(*wpt, "group:"); - strncpy(*wpt + 6, dpt + 1, ddpt - dpt); - (*wpt)+= 6 + (ddpt - dpt); - } - } else if(*cpt == 'o') { - if(pass == 0) { - if(ddpt - dpt > 1) { - was_error= line_count; - continue; - } - line_len+= 6 + (ddpt - dpt); - } else { - strcpy(*wpt, "other:"); - strncpy(*wpt + 6, dpt + 1, ddpt - dpt); - (*wpt)+= 6 + (ddpt - dpt); - } - } else if(*cpt == 'm') { - if(pass == 0) { - if(ddpt - dpt > 1) { - was_error= line_count; - continue; - } - line_len+= 5 + (ddpt - dpt); - } else { - strcpy(*wpt, "mask:"); - strncpy(*wpt + 5, dpt + 1, ddpt - dpt); - (*wpt)+= 5 + (ddpt - dpt); - } - - } else { - /* Unknown tag type */ - was_error= line_count; - continue; - } - - /* Examine permissions at ddpt + 1 */; - perms= 0; - for(ppt= ddpt + 1; *ppt != 0 && *ppt != '\n'; ppt++) { - if(*ppt == 'r') - perms|= 4; - else if(*ppt == 'w') - perms|= 2; - else if(*ppt == 'x') - perms|= 1; - else if(*ppt == '-') - ; - else { - was_error= line_count; - continue; - } - } - if(pass == 0) { - line_len+= 4; - } else { - sprintf(*wpt, "%c%c%c\n", - perms & 4 ? 'r' : '-', perms & 2 ? 'w' : '-', perms & 1 ? 'x' : '-'); - (*wpt)+= 4; - } - - if(pass == 0) { - if(is_default) - default_count+= line_len; - else - access_count+= line_len; - } - } - - if(pass == 0) { - *access_acl_text= calloc(access_count + 1, 1); - *default_acl_text= calloc(default_count + 1, 1); - if(access_acl_text == NULL || *default_acl_text == NULL) { - Xorriso_no_malloc_memory(xorriso, access_acl_text, 0); - {ret= -1; goto ex;} - } - access_wpt= *access_acl_text; - default_wpt= *default_acl_text; - } else { - *access_wpt= 0; - *default_wpt= 0; - } - } - - ret= 1; -ex:; - if(acl_text != NULL) - free(acl_text); - if(was_error) { - sprintf(xorriso->info_text, - "Malformed ACL entries encountered. Last one in line number %d.", - was_error); + Xorriso_pacifier_reset(xorriso, 0); + if(path[0]==0) { + sprintf(xorriso->info_text, "Empty file name given with -setfacl_list"); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); return(0); } + ret= Xorriso_afile_fopen(xorriso, path, "rb", &fp, 0); + if(ret <= 0) + return(0); + + buf_size= buf_add; + buf= calloc(buf_size, 1); + if(buf == NULL) + goto out_of_mem; + wpt= buf; + uid[0]= gid[0]= 0; + + while(1) { + if(Sfile_fgets_n(line, sizeof(line), fp, 0) == NULL) + break; + linecount++; + if(strncmp(line, "# file: ", 8) ==0) { + if(wpt != buf && file_path[0]) { + /* Commit previous list */ + ret= Xorriso_perform_acl_from_list(xorriso, file_path, + uid, gid, buf, 0); + if(ret<=0) + goto ex; + wpt= buf; + file_path[0]= uid[0]= gid[0]= 0; + } + /* Unescape line and register as file path */ + Sfile_bsl_interpreter(line + 8, strlen(line + 8), &eaten, 0); + if(strlen(line + 8) >= SfileadrL) { + sprintf(xorriso->info_text, "-setfacl_list: Oversized file path"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + strcpy(file_path, line + 8); + continue; + } else if(strncmp(line, "# owner: ", 9) == 0) { + if(strlen(line + 9) > 160) { + sprintf(xorriso->info_text, "-setfacl_list: Oversized owner id"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + strcpy(uid, line + 9); + continue; + } else if(strncmp(line, "# group: ", 9) == 0) { + if(strlen(line + 9) > 160) { + sprintf(xorriso->info_text, "-setfacl_list: Oversized group id"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + strcpy(gid, line + 9); + continue; + } else if(line[0] == '#' || line[0] == 0) { + continue; + } + + /* Register ACL entry */ + l= strlen(line); + if(wpt + l + 2 - buf > buf_size) { + if(buf_size + buf_add > xorriso->temp_mem_limit) { + Sfile_scale((double) xorriso->temp_mem_limit, limit_text,5,1e4,1); + sprintf(xorriso->info_text, + "-setfacl_list: List entry for a single file exceeds -temp_mem_limit %s", + limit_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + buf_size+= buf_add; + new_buf= realloc(buf, buf_size); + if(new_buf == NULL) + goto out_of_mem; + buf= new_buf; + } + memcpy(wpt, line, l); + *(wpt + l)= '\n'; + wpt+= l + 1; + *wpt= 0; + } + if(wpt != buf && file_path[0]) { + /* Commit last list */ + ret= Xorriso_perform_acl_from_list(xorriso, file_path, uid, gid, buf, 0); + if(ret<=0) + goto ex; + } else { + sprintf(xorriso->info_text, "-setfacl_list: Unexpected end of file "); + Text_shellsafe(path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } + ret= 1; +ex:; + if(buf != NULL) + free(buf); + if(fp!=NULL) + fclose(fp); + if(ret <= 0) { + sprintf(xorriso->info_text, "-setfacl_list "); + Text_shellsafe(path, xorriso->info_text, 1); + sprintf(xorriso->info_text + strlen(xorriso->info_text), + " aborted in line %.f\n", (double) linecount); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } return(ret); -} - - -/* Options -setfacl_list alias -setfacl_listi */ -int Xorriso_option_setfacl_listi(struct XorrisO *xorriso, char *path, int flag) -{ - - /* >>> Open path */; - /* >>> Loop over lines */; - /* >>> if(strncmp(line, */; - /* >>> */; - /* >>> */; - /* >>> */; - /* >>> */; - - return(1); +out_of_mem:; + Xorriso_no_malloc_memory(xorriso, &buf, 0); + ret= -1; + goto ex; } diff --git a/xorriso/xorriso.h b/xorriso/xorriso.h index bcc349a9..d54fa5e8 100644 --- a/xorriso/xorriso.h +++ b/xorriso/xorriso.h @@ -670,6 +670,10 @@ int Xorriso_option_rom_toc_scan(struct XorrisO *xorriso, char *mode, /* Option -session_log */ int Xorriso_option_session_log(struct XorrisO *xorriso, char *path, int flag); +/* Option -setfacl_list alias -setfacl_listi */ +int Xorriso_option_setfacl_listi(struct XorrisO *xorriso, char *disk_path, + int flag); + /* Option -setfacl alias -setfacli , -setfacl_r alias -setfacl_ri */ /* @param flag bit0=recursive -setfacl_r */ diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 93d18b7a..e2020d0b 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.01.28.190140" +#define Xorriso_timestamP "2009.01.29.165339"