The functions were renamed and re-organized to be more consistent with the project practices.
This changeset focused on getting the number-only changes done within the time allowed.
This adds a new function for converting the f_file_mode into a mode_t for the libc chmod compatibility.
}
#endif // _di_f_file_access_
-#ifndef _di_f_file_change_mode_
- f_return_status f_file_change_mode(const f_string path, const mode_t mode) {
- #ifndef _di_level_0_parameter_checking_
- if (path == 0) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- return private_f_file_change_mode(path, mode);
- }
-#endif // _di_f_file_change_mode_
-
-#ifndef _di_f_file_change_mode_at_
- f_return_status f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode) {
- #ifndef _di_level_0_parameter_checking_
- if (path == 0) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- return private_f_file_change_mode_at(at_id, path, mode);
- }
-#endif // _di_f_file_change_mode_at_
-
-#ifndef _di_f_file_change_role_
- f_return_status f_file_change_role(const f_string path, const uid_t uid, const gid_t gid, const bool dereference) {
- #ifndef _di_level_0_parameter_checking_
- if (path == 0) return F_status_set_error(F_parameter);
- if (uid < 0 && gid < 0) return F_status_set_error(F_parameter);
- if (uid < -1 || gid < -1) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- return private_f_file_change_role(path, uid, gid, dereference);
- }
-#endif // _di_f_file_change_role_
-
-#ifndef _di_f_file_change_role_at_
- f_return_status f_file_change_role_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag) {
- #ifndef _di_level_0_parameter_checking_
- if (path == 0) return F_status_set_error(F_parameter);
- if (uid < 0 && gid < 0) return F_status_set_error(F_parameter);
- if (uid < -1 || gid < -1) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- return private_f_file_change_role_at(at_id, path, uid, gid, flag);
- }
-#endif // _di_f_file_change_role_at_
-
#ifndef _di_f_file_clone_
f_return_status f_file_clone(const f_string source, const f_string destination, const bool role, const f_number_unsigned size_block, const bool exclusive) {
#ifndef _di_level_0_parameter_checking_
if (F_status_is_error(status)) return status;
if (!exclusive) {
- status = private_f_file_change_mode(destination, source_stat.st_mode);
+ status = private_f_file_mode_set(destination, source_stat.st_mode);
if (F_status_is_error(status)) return status;
}
if (role) {
- status = private_f_file_change_role(destination, source_stat.st_uid, source_stat.st_gid, F_false);
+ status = private_f_file_role_change(destination, source_stat.st_uid, source_stat.st_gid, F_false);
if (F_status_is_error(status)) return status;
}
return status;
}
- status = private_f_file_change_mode(destination, source_stat.st_mode);
+ status = private_f_file_mode_set(destination, source_stat.st_mode);
if (F_status_is_error(status)) return status;
if (role) {
- status = private_f_file_change_role(destination, source_stat.st_uid, source_stat.st_gid, F_false);
+ status = private_f_file_role_change(destination, source_stat.st_uid, source_stat.st_gid, F_false);
if (F_status_is_error(status)) return status;
}
if (F_status_is_error(status)) return status;
if (!exclusive) {
- status = private_f_file_change_mode(destination, (~f_file_type_mask) & mode.regular);
+ status = private_f_file_mode_set(destination, (~f_file_type_mask) & mode.regular);
if (F_status_is_error(status)) return status;
}
}
}
- status = private_f_file_change_mode(destination, (~f_file_type_mask) & mode.directory);
+ status = private_f_file_mode_set(destination, (~f_file_type_mask) & mode.directory);
if (F_status_is_error(status)) return status;
return F_none;
}
}
- status = private_f_file_change_mode(destination, (~f_file_type_mask) & mode.fifo);
+ status = private_f_file_mode_set(destination, (~f_file_type_mask) & mode.fifo);
if (F_status_is_error(status)) return status;
return F_none;
}
}
- status = private_f_file_change_mode(destination, (~f_file_type_mask) & mode.socket);
+ status = private_f_file_mode_set(destination, (~f_file_type_mask) & mode.socket);
if (F_status_is_error(status)) return status;
return F_none;
}
}
- status = private_f_file_change_mode(destination, (~f_file_type_mask) & mode.block);
+ status = private_f_file_mode_set(destination, (~f_file_type_mask) & mode.block);
if (F_status_is_error(status)) return status;
return F_none;
}
#endif // _di_f_file_link_read_at_
+#ifndef _di_f_file_mode_determine_
+ f_return_status f_file_mode_determine(const mode_t mode_file, const f_file_mode mode_change, const uint8_t mode_replace, const bool directory_is, const mode_t umask, mode_t *mode) {
+ #ifndef _di_level_0_parameter_checking_
+ if (mode == 0) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ f_file_mode change = mode_change & f_file_mode_block_special;
+
+ *mode = 0;
+
+ if (mode_replace & f_file_mode_replace_special) {
+ if (change & f_file_mode_mask_bit_set_owner & f_file_mode_mask_how_add) {
+ *mode = f_file_mode_special_set_user;
+ }
+
+ if (change & f_file_mode_mask_bit_set_group & f_file_mode_mask_how_add) {
+ *mode |= f_file_mode_special_set_group;
+ }
+
+ if (change & f_file_mode_mask_bit_sticky & f_file_mode_mask_how_add) {
+ *mode |= f_file_mode_special_sticky;
+ }
+ }
+ else {
+ *mode = mode_file & f_file_mode_special_all;
+
+ if (mode_change & f_file_mode_block_special) {
+ if (change & f_file_mode_mask_bit_set_owner & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_special_set_user) {
+ *mode -= f_file_mode_special_set_user;
+ }
+ }
+ else if (change & f_file_mode_mask_bit_set_owner & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_special_set_user)) {
+ *mode |= f_file_mode_special_set_user;
+ }
+ }
+
+ if (change & f_file_mode_mask_bit_set_group & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_special_set_group) {
+ *mode -= f_file_mode_special_set_group;
+ }
+ }
+ else if (change & f_file_mode_mask_bit_set_group & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_special_set_group)) {
+ *mode |= f_file_mode_special_set_group;
+ }
+ }
+
+ if (change & f_file_mode_mask_bit_sticky & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_special_sticky) {
+ *mode -= f_file_mode_special_sticky;
+ }
+ }
+ else if (change & f_file_mode_mask_bit_sticky & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_special_sticky)) {
+ *mode |= f_file_mode_special_sticky;
+ }
+ }
+ }
+ }
+
+ change = mode_change & f_file_mode_block_owner;
+
+ if (mode_replace & f_file_mode_replace_owner) {
+ if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_add) {
+ *mode |= f_file_mode_owner_r;
+ }
+
+ if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_add) {
+ *mode |= f_file_mode_owner_w;
+ }
+
+ if (change & f_file_mode_mask_bit_execute & f_file_mode_mask_how_add) {
+ *mode |= f_file_mode_owner_x;
+ }
+ else if (change & f_file_mode_mask_bit_execute_only & f_file_mode_mask_how_add) {
+ if (directory_is || (mode_file & f_file_mode_owner_x)) {
+ *mode |= f_file_mode_owner_x;
+ }
+ }
+ }
+ else {
+ *mode |= mode_file & f_file_mode_owner_rwx;
+
+ if (mode_change & f_file_mode_block_owner) {
+ if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_owner_r) {
+ *mode -= f_file_mode_owner_r;
+ }
+ }
+ else if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_owner_r)) {
+ *mode |= f_file_mode_owner_r;
+ }
+ }
+
+ if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_owner_w) {
+ *mode -= f_file_mode_owner_w;
+ }
+ }
+ else if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_owner_w)) {
+ *mode |= f_file_mode_owner_w;
+ }
+ }
+
+ if (change & f_file_mode_mask_bit_execute) {
+ change &= f_file_mode_mask_bit_execute;
+
+ if (change & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_owner_x) {
+ *mode -= f_file_mode_owner_x;
+ }
+ }
+ else if (change & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_owner_x)) {
+ *mode |= f_file_mode_owner_x;
+ }
+ }
+ }
+ else if (change & f_file_mode_mask_bit_execute_only) {
+ change &= f_file_mode_mask_bit_execute_only;
+
+ if (directory_is || (mode_file & f_file_mode_owner_x)) {
+ if (change & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_owner_x) {
+ *mode -= f_file_mode_owner_x;
+ }
+ }
+ else if (change & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_owner_x)) {
+ *mode |= f_file_mode_owner_x;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ change = mode_change & f_file_mode_block_group;
+
+ if (mode_replace & f_file_mode_replace_group) {
+ if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_add) {
+ *mode |= f_file_mode_group_r;
+ }
+
+ if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_add) {
+ *mode |= f_file_mode_group_w;
+ }
+
+ if (change & f_file_mode_mask_bit_execute & f_file_mode_mask_how_add) {
+ *mode |= f_file_mode_group_x;
+ }
+ else if (change & f_file_mode_mask_bit_execute_only & f_file_mode_mask_how_add) {
+ if (directory_is || (mode_file & f_file_mode_group_x)) {
+ *mode |= f_file_mode_group_x;
+ }
+ }
+ }
+ else {
+ *mode |= mode_file & f_file_mode_group_rwx;
+
+ if (mode_change & f_file_mode_block_group) {
+
+ if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_group_r) {
+ *mode -= f_file_mode_group_r;
+ }
+ }
+ else if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_group_r)) {
+ *mode |= f_file_mode_group_r;
+ }
+ }
+
+ if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_group_w) {
+ *mode -= f_file_mode_group_w;
+ }
+ }
+ else if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_group_w)) {
+ *mode |= f_file_mode_group_w;
+ }
+ }
+
+ if (change & f_file_mode_mask_bit_execute) {
+ change &= f_file_mode_mask_bit_execute;
+
+ if (change & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_group_x) {
+ *mode -= f_file_mode_group_x;
+ }
+ }
+ else if (change & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_group_x)) {
+ *mode |= f_file_mode_group_x;
+ }
+ }
+ }
+ else if (change & f_file_mode_mask_bit_execute_only) {
+ change &= f_file_mode_mask_bit_execute_only;
+
+ if (directory_is || (mode_file & f_file_mode_group_x)) {
+ if (change & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_group_x) {
+ *mode -= f_file_mode_group_x;
+ }
+ }
+ else if (change & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_group_x)) {
+ *mode |= f_file_mode_group_x;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ change = mode_change & f_file_mode_block_world;
+
+ if (mode_replace & f_file_mode_replace_world) {
+
+ if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_add) {
+ *mode |= f_file_mode_world_r;
+ }
+
+ if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_add) {
+ *mode |= f_file_mode_world_w;
+ }
+
+ if (change & f_file_mode_mask_bit_execute & f_file_mode_mask_how_add) {
+ *mode |= f_file_mode_world_x;
+ }
+ else if (change & f_file_mode_mask_bit_execute_only & f_file_mode_mask_how_add) {
+ if (directory_is || (mode_file & f_file_mode_world_x)) {
+ *mode |= f_file_mode_world_x;
+ }
+ }
+ }
+ else {
+ *mode |= mode_file & f_file_mode_world_rwx;
+
+ if (mode_change & f_file_mode_block_world) {
+
+ if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_world_r) {
+ *mode -= f_file_mode_world_r;
+ }
+ }
+ else if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_world_r)) {
+ *mode |= f_file_mode_world_r;
+ }
+ }
+
+ if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_world_w) {
+ *mode -= f_file_mode_world_w;
+ }
+ }
+ else if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_world_w)) {
+ *mode |= f_file_mode_world_w;
+ }
+ }
+
+ if (change & f_file_mode_mask_bit_execute) {
+ change &= f_file_mode_mask_bit_execute;
+
+ if (change & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_world_x) {
+ *mode -= f_file_mode_world_x;
+ }
+ }
+ else if (change & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_world_x)) {
+ *mode |= f_file_mode_world_x;
+ }
+ }
+ }
+ else if (change & f_file_mode_mask_bit_execute_only) {
+ change &= f_file_mode_mask_bit_execute_only;
+
+ if (directory_is || (mode_file & f_file_mode_world_x)) {
+ if (change & f_file_mode_mask_how_subtract) {
+ if (*mode & f_file_mode_world_x) {
+ *mode -= f_file_mode_world_x;
+ }
+ }
+ else if (change & f_file_mode_mask_how_add) {
+ if (!(*mode & f_file_mode_world_x)) {
+ *mode |= f_file_mode_world_x;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (mode_replace & f_file_mode_replace_umask) {
+ *mode -= *mode & umask;
+ }
+
+ return F_none;
+ }
+#endif // _di_f_file_mode_determine_
+
#ifndef _di_f_file_mode_from_string_
f_return_status f_file_mode_from_string(const f_string string, f_file_mode *mode, uint8_t *replace) {
#ifndef _di_level_0_parameter_checking_
*replace = 0;
switch (string[0]) {
-
case '+':
case '-':
case '=':
switch (string[1]) {
-
case 'r':
case 'w':
case 'x':
return F_status_set_error(F_syntax);
}
- syntax = 1;
break;
case 'u':
if (syntax == 1) {
uint8_t on = 0; // 1 = user, 2 = group, 4 = world/sticky, 7 = all.
- uint8_t how = 0; // 1 = add, 2 = replace, 3 = subtract, 4 = umask add, 5 = umask replace, 6 = umask subtract.
+ uint8_t how = 0; // 1 = add, 2 = replace, 3 = subtract.
bool active = F_false;
- f_file_mode mask = 0;
+ f_file_mode mask = f_file_mode_block_special;
f_file_mode what = 0;
+ // @todo: this needs to record all of the possible combinations of add, subtract, and assignment (=).
for (f_string_length i = 0; syntax && i < string[i]; i++) {
switch (string[i]) {
}
on = 7;
- mask = f_file_mode_block_owner | f_file_mode_block_group | f_file_mode_block_world;
+ mask = f_file_mode_block_all;
break;
case '+':
// only the parts designated by the mask should be replaced.
*mode -= (*mode) & mask;
+
+ if (mask == f_file_mode_block_all) {
+ *replace = f_file_mode_replace_all;
+ }
+ else if (mask & f_file_mode_block_world) {
+ *replace |= f_file_mode_block_special & f_file_mode_block_world;
+ }
+ else if (mask & f_file_mode_block_group) {
+ *replace |= f_file_mode_block_special & f_file_mode_block_group;
+ }
+ else if (mask & f_file_mode_block_owner) {
+ *replace |= f_file_mode_block_special & f_file_mode_block_owner;
+ }
}
if (!on) {
on = 7;
- mask = f_file_mode_block_owner | f_file_mode_block_group | f_file_mode_block_world;
+ mask = f_file_mode_block_all;
}
for (i++; i < string[i]; i++) {
active = F_false;
on = 0;
how = 0;
- mask = 0;
+ mask = f_file_mode_block_special;
break;
}
else if (string[i] == '+' || string[i] == '-' || string[i] == '=') {
*mode |= what & mask & f_file_mode_mask_how_subtract;
}
else if (how == 4 || how == 5) {
- *mode |= what & mask & f_file_mode_mask_how_umask_add;
+ *mode |= what & mask & f_file_mode_mask_how_add;
+ *replace |= f_file_mode_replace_umask;
}
else if (how == 6) {
- *mode |= what & mask & f_file_mode_mask_how_umask_subtract;
+ *mode |= what & mask & f_file_mode_mask_how_subtract;
+ *replace |= f_file_mode_replace_umask;
}
} // for
} // for
}
else if (syntax == 2) {
- // 1 = add, 2 = replace, 3 = subtract, 4 = umask add, 5 = umask replace, 6 = umask subtract.
+ // 1 = add, 2 = replace, 3 = subtract.
uint8_t how = 0;
- mode_t classic = 0;
-
f_string_length i = 0;
+ *replace = 0;
+
if (string[0] == '+') {
how = 1;
i = 1;
how = 3;
i = 1;
}
- else if (string[0] == '=' || string[0] == '0') {
+ else if (string[0] == '=') {
how = 2;
i = 1;
+
+ *replace = f_file_mode_replace_standard;
}
else {
- how = 5;
+ how = 2;
+
+ *replace = f_file_mode_replace_standard | f_file_mode_replace_directory;
}
- for (; string[i] == '0'; i++) {
- // seek past leading '0's.
- } // for
+ if (string[i] == '0') {
+ for (; string[i] == '0'; i++) {
+ // seek past leading '0's.
+ } // for
+ }
if (string[i]) {
f_string_length j = 0;
for (; string[i + j] && j < 4; j++) {
if (j) {
- classic <<= 3;
+ *mode <<= 8;
}
switch (string[i]) {
case '6':
case '7':
// this assumes ASCII/UTF-8.
- classic |= string[i] - 0x30;
+ if (how == 3) {
+ *mode |= (string[i + j] - 0x30) << 4;
+ }
+ else {
+ *mode |= string[i + j] - 0x30;
+ }
break;
default:
+ // designate that this is invalid.
j = 4;
break;
}
if (j == 4) {
syntax = 0;
}
-
- // @fixme: classic is a different structure than mode masks, properly expand. (maybe just use f_file_mode instead of classic and shift by 6 instead of 3.)
- if (syntax) {
- if (how == 1) {
- *mode = classic & f_file_mode_mask_how_add;
- }
- else if (how == 2) {
- *mode = classic & f_file_mode_mask_how_add;
- *replace = f_file_mode_replace_all;
- }
- else if (how == 3) {
- *mode = classic & f_file_mode_mask_how_subtract;
- }
- else if (how == 5) {
- *mode = classic & f_file_mode_mask_how_add;
- *replace = f_file_mode_replace_umask_all;
+ else if (how == 2) {
+ // if there are only '0's then the setuid/setgid/sticky bits are to be replaced.
+ if (*mode == 0) {
+ *replace = f_file_mode_replace_standard;
}
}
}
- else {
- *replace = f_file_mode_replace_all;
- }
}
if (syntax) {
}
#endif // _di_f_file_mode_from_string_
-// @todo: needs f_file_mode_to_mode_t() to convert f_file_mode to a mode_t (requires f_file_mode, a source mode_t, and a destination mode_t).
+#ifndef _di_f_file_mode_set_
+ f_return_status f_file_mode_set(const f_string path, const mode_t mode) {
+ #ifndef _di_level_0_parameter_checking_
+ if (path == 0) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ return private_f_file_mode_set(path, mode);
+ }
+#endif // _di_f_file_mode_set_
+
+#ifndef _di_f_file_mode_set_at_
+ f_return_status f_file_mode_set_at(const int at_id, const f_string path, const mode_t mode) {
+ #ifndef _di_level_0_parameter_checking_
+ if (path == 0) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ return private_f_file_mode_set_at(at_id, path, mode);
+ }
+#endif // _di_f_file_mode_set_at_
#ifndef _di_f_file_name_base_
f_return_status f_file_name_base(const f_string path, const f_string_length length, f_string_dynamic *name_base) {
}
#endif // _di_f_file_remove_at_
+#ifndef _di_f_file_role_change_
+ f_return_status f_file_role_change(const f_string path, const uid_t uid, const gid_t gid, const bool dereference) {
+ #ifndef _di_level_0_parameter_checking_
+ if (path == 0) return F_status_set_error(F_parameter);
+ if (uid < 0 && gid < 0) return F_status_set_error(F_parameter);
+ if (uid < -1 || gid < -1) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ return private_f_file_role_change(path, uid, gid, dereference);
+ }
+#endif // _di_f_file_role_change_
+
+#ifndef _di_f_file_role_change_at_
+ f_return_status f_file_role_change_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag) {
+ #ifndef _di_level_0_parameter_checking_
+ if (path == 0) return F_status_set_error(F_parameter);
+ if (uid < 0 && gid < 0) return F_status_set_error(F_parameter);
+ if (uid < -1 || gid < -1) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ return private_f_file_role_change_at(at_id, path, uid, gid, flag);
+ }
+#endif // _di_f_file_role_change_at_
+
#ifndef _di_f_file_seek_
f_return_status f_file_seek(const int id, const int whence, const f_string_length offset, f_string_length *seeked) {
#ifndef _di_level_0_parameter_checking_
* 'S' = set user bit (setuid).
* 's' = set group bit (setgid).
* 't' = sticky bit.
+ *
+ * The mode replace codes are meant to be used for the user, group, and world modes.
+ * Generally "special" bits are preserved unless explicitly changed so there is also a "special" mode replace code as well.
+ * The "umask" equivalent specifies that the mask should allow for umask influence.
*/
#ifndef _di_f_file_mode_
typedef uint32_t f_file_mode;
+ // 0000 0000 0000 0111 0000 0101 0000 0101
#define f_file_mode_block_special 0x77000000 // 0111 0111 0000 0000 0000 0000 0000 0000
#define f_file_mode_block_owner 0x00ff0000 // 0000 0000 1111 1111 0000 0000 0000 0000
#define f_file_mode_block_group 0x0000ff00 // 0000 0000 0000 0000 1111 1111 0000 0000
#define f_file_mode_block_world 0x000000ff // 0000 0000 0000 0000 0000 0000 1111 1111
#define f_file_mode_block_all 0x77ffffff // 0111 0111 1111 1111 1111 1111 1111 1111
- #define f_file_mode_mask_how_add 0x070f0f0f // 0000 0111 0000 1111 0000 1111 0000 1111
- #define f_file_mode_mask_how_subtract 0x70f0f0f0 // 0111 0000 1111 0000 1111 0000 1111 0000
- #define f_file_mode_mask_how_umask_add 0x0f0f0f0f // 0000 1111 0000 1111 0000 1111 0000 1111
- #define f_file_mode_mask_how_umask_subtract 0x78f0f0f0 // 0111 1000 1111 0000 1111 0000 1111 0000
+ #define f_file_mode_mask_how_add 0x070f0f0f // 0000 0111 0000 1111 0000 1111 0000 1111
+ #define f_file_mode_mask_how_subtract 0x70f0f0f0 // 0111 0000 1111 0000 1111 0000 1111 0000
#define f_file_mode_mask_bit_execute 0x00111111 // 0000 0000 0001 0001 0001 0001 0001 0001
#define f_file_mode_mask_bit_execute_only 0x00888888 // 0000 0000 1000 1000 1000 1000 1000 1000
#define f_file_mode_mask_bit_sticky 0x11000000 // 0001 0001 0000 0000 0000 0000 0000 0000
#define f_file_mode_mask_bit_write 0x00222222 // 0000 0000 0010 0010 0010 0010 0010 0010
- #define f_file_mode_replace_owner 0x1 // 0000 0001
- #define f_file_mode_replace_group 0x2 // 0000 0010
- #define f_file_mode_replace_world 0x4 // 0000 0100
- #define f_file_mode_replace_umask_owner 0x8 // 0000 1000
- #define f_file_mode_replace_umask_group 0x10 // 0001 0000
- #define f_file_mode_replace_umask_world 0x20 // 0010 0000
+ #define f_file_mode_replace_owner 0x1 // 0000 0001
+ #define f_file_mode_replace_group 0x2 // 0000 0010
+ #define f_file_mode_replace_world 0x4 // 0000 0100
+ #define f_file_mode_replace_special 0x7 // 0000 1000
+ #define f_file_mode_replace_umask 0x10 // 0001 0000
+ #define f_file_mode_replace_directory 0x20 // 0010 0000
- #define f_file_mode_replace_all 0x7 // 0000 0111
- #define f_file_mode_replace_umask_all 0x38 // 0011 1000
+ #define f_file_mode_replace_all 0x3f // 0011 1111
+ #define f_file_mode_replace_other 0x38 // 0011 1000
+ #define f_file_mode_replace_standard 0x7 // 0000 0111
// file permission modes.
#define f_file_mode_owner_rwx S_IRWXU
#define f_file_mode_all_w (f_file_mode_owner_w | f_file_mode_group_w | f_file_mode_world_w)
#define f_file_mode_all_x (f_file_mode_owner_x | f_file_mode_group_x | f_file_mode_world_x)
- // file mode sticky-bits and all bits.
- #define f_file_mode_special_user S_ISUID
- #define f_file_mode_special_group S_ISGID
- #define f_file_mode_special_world S_ISVTX
- #define f_file_mode_special_all (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
+ // file mode set-uid/set-gid/sticky-bits and all bits.
+ #define f_file_mode_special_set_user S_ISUID
+ #define f_file_mode_special_set_group S_ISGID
+ #define f_file_mode_special_sticky S_ISVTX
+ #define f_file_mode_special_all (S_ISUID | S_ISGID | S_ISVTX)
+
+ // all permissions modes and special modes.
+ #define f_file_mode_all (f_file_mode_special_all | f_file_mode_all_rwx)
// special file mode combinations.
#define f_file_mode_user_access (f_file_mode_owner_rwx | f_file_mode_group_rwx | f_file_mode_world_x)
#endif // _di_f_file_access_
/**
- * Change mode of a given file at the specified path.
- *
- * This does not set mode based on umask(), be sure to apply umask if so desired.
- * (such as: mode & ~mask).
- *
- * @param path
- * The path file name.
- * @param mode
- * The new mode to use.
- *
- * @return
- * F_none on success.
- * F_access_denied (with error bit) on access denied.
- * F_access_mode (with error bit) if the current user does not have access to assign the file mode.
- * F_directory (with error bit) on invalid directory.
- * F_file_found_not (with error bit) if file at path was not found.
- * F_input_output (with error bit) on I/O error.
- * F_loop (with error bit) on loop error.
- * F_memory_out (with error bit) if out of memory.
- * F_name (with error bit) on path name error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_read_only (with error bit) if file is read-only.
- * F_failure (with error bit) for any other error.
- *
- * @see chmod()
- */
-#ifndef _di_f_file_change_mode_
- extern f_return_status f_file_change_mode(const f_string path, const mode_t mode);
-#endif // _di_f_file_change_mode_
-
-/**
- * Change mode of a given file at the specified path.
- *
- * This does not set mode based on umask(), be sure to apply umask if so desired.
- * (such as: mode & ~mask).
- *
- * @param at_id
- * The parent directory, as an open directory file descriptor, in which path is relative to.
- * @param path
- * The path file name.
- * @param mode
- * The new mode to use.
- *
- * @return
- * F_none on success.
- * F_access_denied (with error bit) on access denied.
- * F_access_mode (with error bit) if the current user does not have access to assign the file mode.
- * F_file_found_not (with error bit) if file at path was not found.
- * F_directory (with error bit) on invalid directory.
- * F_input_output (with error bit) on I/O error.
- * F_loop (with error bit) on loop error.
- * F_memory_out (with error bit) if out of memory.
- * F_name (with error bit) on path name error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_read_only (with error bit) if file is read-only.
- * F_failure (with error bit) for any other error.
- *
- * @see fchmodat()
- */
-#ifndef _di_f_file_change_mode_at_
- extern f_return_status f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode);
-#endif // _di_f_file_change_mode_at_
-
-/**
- * Change owner and/or group of a given file at the specified path.
- *
- * At least one of uid or gid must not be -1.
- *
- * @param path
- * The path file name.
- * @param uid
- * The new user id to use.
- * Set to -1 to not change.
- * @param gid
- * The new group id to use.
- * Set to -1 to not change.
- * @param dereference
- * Set to TRUE to dereferenc symlinks (often is what is desired).
- * Set to FALSE to operate on the symlink itself.
- *
- * @return
- * F_none on success.
- * F_access_denied (with error bit) on access denied.
- * F_access_group (with error bit) if the current user does not have access to assign the specified group.
- * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
- * F_buffer (with error bit) if the buffer is invalid.
- * F_directory (with error bit) on invalid directory.
- * F_file_found_not (with error bit) if file at path was not found.
- * F_input_output (with error bit) on I/O error.
- * F_loop (with error bit) on loop error.
- * F_memory_out (with error bit) if out of memory.
- * F_name (with error bit) on path name error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_read_only (with error bit) if file is read-only.
- * F_failure (with error bit) for any other error.
- *
- * @see chown()
- * @see lchown()
- */
-#ifndef _di_f_file_change_role_
- extern f_return_status f_file_change_role(const f_string path, const uid_t uid, const gid_t gid, const bool dereference);
-#endif // _di_f_file_change_role_
-
-/**
- * Change owner and/or group of a given file at the specified path.
- *
- * At least one of uid or gid must not be -1.
- *
- * @param at_id
- * The parent directory, as an open directory file descriptor, in which path is relative to.
- * @param path
- * The path file name.
- * @param uid
- * The new user id to use.
- * Set to -1 to not change.
- * @param gid
- * The new group id to use.
- * Set to -1 to not change.
- * @param flag
- * Any valid flag, such as f_file_at_path_empty, f_file_at_automount_no, or f_file_at_symlink_follow_no.
- *
- * @return
- * F_none on success.
- * F_access_denied (with error bit) on access denied.
- * F_access_group (with error bit) if the current user does not have access to assign the specified group.
- * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
- * F_buffer (with error bit) if the buffer is invalid.
- * F_directory (with error bit) on invalid directory.
- * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
- * F_file_found_not (with error bit) if file at path was not found.
- * F_input_output (with error bit) on I/O error.
- * F_loop (with error bit) on loop error.
- * F_memory_out (with error bit) if out of memory.
- * F_name (with error bit) on path name error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_read_only (with error bit) if file is read-only.
- * F_failure (with error bit) for any other error.
- *
- * @see fchownat()
- */
-#ifndef _di_f_file_change_role_at_
- extern f_return_status f_file_change_role_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag);
-#endif // _di_f_file_change_role_at_
-
-/**
* Copy a file, as well as its file mode and possibly the owner and group.
*
* The paths must not contain NULL except for the terminating NULL.
#endif // _di_f_file_link_read_at_
/**
+ * Determine how the mode should be applied based on different file properties and the given mode properties.
+ *
+ * @param mode_file
+ * The mode_t value representing the file's current mode.
+ * This is expected to be populated from (struct stat).st_mode.
+ * @param mode_change
+ * The file mode values to change.
+ * @param mode_replace
+ * The mode modes that should be replaced instead of simply changed.
+ * @param directory_is
+ * Set to TRUE if the file is a directory, FALSE otherwise.
+ * @param umask
+ * The current umask, which will be used if necessary.
+ * @param mode
+ * The determined mode.
+ *
+ * @return
+ * F_none on success.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see f_file_mode_from_string()
+ */
+#ifndef _di_f_file_mode_determine_
+ extern f_return_status f_file_mode_determine(const mode_t mode_file, const f_file_mode mode_change, const uint8_t mode_replace, const bool directory_is, const mode_t umask, mode_t *mode);
+#endif // _di_f_file_mode_determine_
+
+/**
* Get the file mode id from a string syntax.
*
* The string syntax is defined as follows:
- * '([ugoa]*[-+=]{0,1}([rwxXst]|[ugo])+([,][ugoa]*[-+=]{0,1}([rwxXst]|[ugo])+)*)|([-+=]0*[0-7]{1,4})'.
+ * '([ugoa]*[-+=]{0,1}([rwxXst]|[ugo])+([,][ugoa]*[-+=]{0,1}([rwxXst]|[ugo])+)*)|([-+=]{0,1}0*[0-7]{1,4})'.
*
* Such that:
* 'u' = apply to user.
* 'r' = read mode.
* 'w' = write mode.
* 'x' = execute mode.
- * 'X' = execute mode, only if already executable.
+ * 'X' = execute mode, only if already executable directory or is file with owner already has executable bit.
* 's' = set-gid/set-uid mode.
* 't' = sticky-bit mode.
* '0' = no mode.
* '7' = sticky-bit, set-uid, and set-gid mode.
*
* When using digits, each set of 0-7 represents the following:
- * [1-7] = apply to other/world.
- * [1-7][0-7] = first ([1-7]) to group and second ([0-7]) to other/world.
- * [1-7][0-7][0-7] = first ([1-7]) to owner, second ([0-7]) to group, and third ([0-7]) to other/world.
- * [1-7][0-7][0-7][0-7] = first ([1-7]) to stick/set-uid/set-gid, second ([0-7]) to owner, third ([0-7]) to owner, and fourth ([0-7]) to other/world.
+ * [0]+ = set all bits to 0.
+ * [0-7] = apply to other/world.
+ * [0-7][0-7] = first ([1-7]) to group and second ([0-7]) to other/world.
+ * [0-7][0-7][0-7] = first ([1-7]) to owner, second ([0-7]) to group, and third ([0-7]) to other/world.
+ * [0-7][0-7][0-7][0-7] = first ([1-7]) to stick/set-uid/set-gid, second ([0-7]) to owner, third ([0-7]) to owner, and fourth ([0-7]) to other/world.
*
- * When there is a leading 0 when using digits, then this mask will ignore the current umask settings.
- * Otherwise, the current umask is intended to be respected.
+ * When using digits, the umask is always ignored.
+ * When there is a leading '0' or '=' when using digits, then the special bits should be replaced.
+ * Otherwise, the current special bits are intended to be respected (designated by f_file_mode_replace_directory).
*
- * When '+', '-', or '=' are specified without a leading 'a', 'u', 'g', or 'o', then the mode operations should be performed against the current umask.
+ * When using non-digits and '+', '-', or '=' are specified without a leading 'a', 'u', 'g', or 'o', then the mode operations should be performed against the current umask.
* These are designated with the umask hows, such as f_file_mode_how_umask_replace.
*
+ * There are problems with the chmod documentation (as of GNU coreutils 8.30):
+ * 1) "The operator + causes the selected file mode bits to be added to the existing file mode bits of each file; - causes them to be removed; and = causes them to be added and causes unmentioned bits to be re‐moved except that a directory's unmentioned set user and group ID bits are not affected."
+ * - This means that "chmod =1 some_directory" would not change the setuid/setgid/sticky bits, however, in practice it does change it!
+ * 2) "For directories chmod preserves set-user-ID and set-group-ID bits unless you explicitly specify other‐wise. You can set or clear the bits with symbolic modes like u+s and g-s. To clear these bits for directories with a numeric mode requires an additional leading zero, or leading = like 00755, or =755"
+ * - This directly contradicts quote "1" above, which effectively states "=755" would preserve the bits while quote "2" states that it clears the bits.
+ * - This means that "chmod 1 some_directory" would not change the setuid/setgid/sticky bits, however, in practice it does change it!
+ *
+ * Considering the behavior, assume that when "=" or a leading "0" is provided, this will change the setuid/setgid/sticky bits, otherwise it preserves those bits for directories.
+ *
* @param string
* A NULL terminated string designating the desired mode, following the above string syntax.
* @param mode
* F_syntax (with error bit) if the string fails to follow the syntax rules.
*
* The parameters how, mode_normal, and mode_executable are all set to 0 on error.
+ *
+ * @see private_f_file_mode_determine()
*/
#ifndef _di_f_file_mode_from_string_
extern f_return_status f_file_mode_from_string(const f_string string, f_file_mode *mode, uint8_t *replace);
#endif // _di_f_file_mode_from_string_
/**
+ * Change mode of a given file at the specified path.
+ *
+ * This does not set mode based on umask(), be sure to apply umask if so desired.
+ * (such as: mode & ~mask).
+ *
+ * @param path
+ * The path file name.
+ * @param mode
+ * The new mode to use.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_access_mode (with error bit) if the current user does not have access to assign the file mode.
+ * F_directory (with error bit) on invalid directory.
+ * F_file_found_not (with error bit) if file at path was not found.
+ * F_input_output (with error bit) on I/O error.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see chmod()
+ */
+#ifndef _di_f_file_mode_set_
+ extern f_return_status f_file_mode_set(const f_string path, const mode_t mode);
+#endif // _di_f_file_mode_set_
+
+/**
+ * Change mode of a given file at the specified path.
+ *
+ * This does not set mode based on umask(), be sure to apply umask if so desired.
+ * (such as: mode & ~mask).
+ *
+ * @param at_id
+ * The parent directory, as an open directory file descriptor, in which path is relative to.
+ * @param path
+ * The path file name.
+ * @param mode
+ * The new mode to use.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_access_mode (with error bit) if the current user does not have access to assign the file mode.
+ * F_file_found_not (with error bit) if file at path was not found.
+ * F_directory (with error bit) on invalid directory.
+ * F_input_output (with error bit) on I/O error.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see fchmodat()
+ */
+#ifndef _di_f_file_mode_set_at_
+ extern f_return_status f_file_mode_set_at(const int at_id, const f_string path, const mode_t mode);
+#endif // _di_f_file_mode_set_at_
+
+/**
* Get the base name of a file path.
*
* @param path
#endif // _di_f_file_remove_at_
/**
+ * Change owner and/or group of a given file at the specified path.
+ *
+ * At least one of uid or gid must not be -1.
+ *
+ * @param path
+ * The path file name.
+ * @param uid
+ * The new user id to use.
+ * Set to -1 to not change.
+ * @param gid
+ * The new group id to use.
+ * Set to -1 to not change.
+ * @param dereference
+ * Set to TRUE to dereferenc symlinks (often is what is desired).
+ * Set to FALSE to operate on the symlink itself.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_access_group (with error bit) if the current user does not have access to assign the specified group.
+ * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_directory (with error bit) on invalid directory.
+ * F_file_found_not (with error bit) if file at path was not found.
+ * F_input_output (with error bit) on I/O error.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see chown()
+ * @see lchown()
+ */
+#ifndef _di_f_file_role_change_
+ extern f_return_status f_file_role_change(const f_string path, const uid_t uid, const gid_t gid, const bool dereference);
+#endif // _di_f_file_role_change_
+
+/**
+ * Change owner and/or group of a given file at the specified path.
+ *
+ * At least one of uid or gid must not be -1.
+ *
+ * @param at_id
+ * The parent directory, as an open directory file descriptor, in which path is relative to.
+ * @param path
+ * The path file name.
+ * @param uid
+ * The new user id to use.
+ * Set to -1 to not change.
+ * @param gid
+ * The new group id to use.
+ * Set to -1 to not change.
+ * @param flag
+ * Any valid flag, such as f_file_at_path_empty, f_file_at_automount_no, or f_file_at_symlink_follow_no.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_access_group (with error bit) if the current user does not have access to assign the specified group.
+ * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_directory (with error bit) on invalid directory.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
+ * F_file_found_not (with error bit) if file at path was not found.
+ * F_input_output (with error bit) on I/O error.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see fchownat()
+ */
+#ifndef _di_f_file_role_change_at_
+ extern f_return_status f_file_role_change_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag);
+#endif // _di_f_file_role_change_at_
+
+/**
* Given an open file descriptor, seek to a given location.
*
* @param id
extern "C" {
#endif
-#if !defined(_di_f_file_change_mode_) || !defined(_di_f_file_copy_)
- f_return_status private_f_file_change_mode(const f_string path, const mode_t mode) {
-
- if (chmod(path, mode) < 0) {
- if (errno == EACCES) return F_status_set_error(F_access_denied);
- if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == ELOOP) return F_status_set_error(F_loop);
- if (errno == ENOENT) return F_status_set_error(F_file_found_not);
- if (errno == ENOMEM) return F_status_set_error(F_memory_out);
- if (errno == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == EPERM) return F_status_set_error(F_access_mode);
- if (errno == EROFS) return F_status_set_error(F_read_only);
- if (errno == EIO) return F_status_set_error(F_input_output);
-
- return F_status_set_error(F_failure);
- }
-
- return F_none;
- }
-#endif // !defined(_di_f_file_change_mode_) || !defined(_di_f_file_copy_)
-
-#if !defined(_di_f_file_change_mode_at_) || !defined(_di_f_file_copy_at_)
- f_return_status private_f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode) {
-
- if (fchmodat(at_id, path, mode, 0) < 0) {
- if (errno == EACCES) return F_status_set_error(F_access_denied);
- if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == ELOOP) return F_status_set_error(F_loop);
- if (errno == ENOENT) return F_status_set_error(F_file_found_not);
- if (errno == ENOMEM) return F_status_set_error(F_memory_out);
- if (errno == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
- if (errno == EPERM) return F_status_set_error(F_access_mode);
- if (errno == EROFS) return F_status_set_error(F_read_only);
- if (errno == EIO) return F_status_set_error(F_input_output);
-
- return F_status_set_error(F_failure);
- }
-
- return F_none;
- }
-#endif // !defined(_di_f_file_change_mode_at_) || !defined(_di_f_file_copy_at_)
-
-#if !defined(_di_f_file_change_role_) || !defined(_di_f_file_copy_)
- f_return_status private_f_file_change_role(const f_string path, const uid_t uid, const gid_t gid, const bool dereference) {
- int result = 0;
-
- if (dereference) {
- if (uid != -1) {
- result = chown(path, uid, -1);
-
- if (result < 0 && errno == EPERM) return F_status_set_error(F_access_owner);
- }
-
- if (result == 0 && gid != -1) {
- result = chown(path, -1, gid);
-
- if (result < 0 && errno == EPERM) return F_status_set_error(F_access_group);
- }
- }
- else {
- if (uid != -1) {
- result = lchown(path, uid, -1);
-
- if (result < 0 && errno == EPERM) return F_status_set_error(F_access_owner);
- }
-
- if (gid != -1) {
- result = lchown(path, -1, gid);
-
- if (result < 0 && errno == EPERM) return F_status_set_error(F_access_group);
- }
- }
-
- if (result < 0) {
- if (errno == EACCES) return F_status_set_error(F_access_denied);
- if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == ELOOP) return F_status_set_error(F_loop);
- if (errno == ENOENT) return F_status_set_error(F_file_found_not);
- if (errno == ENOMEM) return F_status_set_error(F_memory_out);
- if (errno == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == EROFS) return F_status_set_error(F_read_only);
- if (errno == EIO) return F_status_set_error(F_input_output);
-
- return F_status_set_error(F_failure);
- }
-
- return F_none;
- }
-#endif // !defined(_di_f_file_change_role_) || !defined(_di_f_file_copy_)
-
-#if !defined(_di_f_file_change_role_at_) || !defined(_di_f_file_copy_at_)
- f_return_status private_f_file_change_role_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag) {
- int result = 0;
-
- if (uid != -1) {
- result = fchownat(at_id, path, uid, -1, flag);
-
- if (result < 0 && errno == EPERM) return F_status_set_error(F_access_owner);
- }
-
- if (gid != -1) {
- result = fchownat(at_id, path, -1, gid, flag);
-
- if (result < 0 && errno == EPERM) return F_status_set_error(F_access_group);
- }
-
- if (result < 0) {
- if (errno == EACCES) return F_status_set_error(F_access_denied);
- if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == ELOOP) return F_status_set_error(F_loop);
- if (errno == ENOENT) return F_status_set_error(F_file_found_not);
- if (errno == ENOMEM) return F_status_set_error(F_memory_out);
- if (errno == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
- if (errno == EROFS) return F_status_set_error(F_read_only);
- if (errno == EIO) return F_status_set_error(F_input_output);
-
- return F_status_set_error(F_failure);
- }
-
- return F_none;
- }
-#endif // !defined(_di_f_file_change_role_at_) || !defined(_di_f_file_copy_at_)
-
#if !defined(_di_f_file_close_) || !defined(_di_f_file_copy_)
f_return_status private_f_file_close(int *id) {
if (F_status_is_error(private_f_file_flush(*id))) return F_status_set_error(F_file_synchronize);
}
#endif // !defined(_di_f_file_link_read_at_) || !defined(_di_f_file_copy_at_)
+#if !defined(_di_f_file_mode_set_) || !defined(_di_f_file_copy_)
+ f_return_status private_f_file_mode_set(const f_string path, const mode_t mode) {
+
+ if (chmod(path, mode) < 0) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_out);
+ if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == EPERM) return F_status_set_error(F_access_mode);
+ if (errno == EROFS) return F_status_set_error(F_read_only);
+ if (errno == EIO) return F_status_set_error(F_input_output);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // !defined(_di_f_file_mode_set_) || !defined(_di_f_file_copy_)
+
+#if !defined(_di_f_file_mode_set_at_) || !defined(_di_f_file_copy_at_)
+ f_return_status private_f_file_mode_set_at(const int at_id, const f_string path, const mode_t mode) {
+
+ if (fchmodat(at_id, path, mode, 0) < 0) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_out);
+ if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
+ if (errno == EPERM) return F_status_set_error(F_access_mode);
+ if (errno == EROFS) return F_status_set_error(F_read_only);
+ if (errno == EIO) return F_status_set_error(F_input_output);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // !defined(_di_f_file_mode_set_at_) || !defined(_di_f_file_copy_at_)
+
#if !defined(_di_f_file_open_) || !defined(_di_f_file_copy_)
f_return_status private_f_file_open(const f_string path, const mode_t mode, f_file *file) {
if (mode == 0) {
}
#endif // !defined(_di_f_file_open_at_) || !defined(_di_f_file_copy_at_)
+#if !defined(_di_f_file_role_change_) || !defined(_di_f_file_copy_)
+ f_return_status private_f_file_role_change(const f_string path, const uid_t uid, const gid_t gid, const bool dereference) {
+ int result = 0;
+
+ if (dereference) {
+ if (uid != -1) {
+ result = chown(path, uid, -1);
+
+ if (result < 0 && errno == EPERM) return F_status_set_error(F_access_owner);
+ }
+
+ if (result == 0 && gid != -1) {
+ result = chown(path, -1, gid);
+
+ if (result < 0 && errno == EPERM) return F_status_set_error(F_access_group);
+ }
+ }
+ else {
+ if (uid != -1) {
+ result = lchown(path, uid, -1);
+
+ if (result < 0 && errno == EPERM) return F_status_set_error(F_access_owner);
+ }
+
+ if (gid != -1) {
+ result = lchown(path, -1, gid);
+
+ if (result < 0 && errno == EPERM) return F_status_set_error(F_access_group);
+ }
+ }
+
+ if (result < 0) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_out);
+ if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == EROFS) return F_status_set_error(F_read_only);
+ if (errno == EIO) return F_status_set_error(F_input_output);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // !defined(_di_f_file_role_change_) || !defined(_di_f_file_copy_)
+
+#if !defined(_di_f_file_role_change_at_) || !defined(_di_f_file_copy_at_)
+ f_return_status private_f_file_role_change_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag) {
+ int result = 0;
+
+ if (uid != -1) {
+ result = fchownat(at_id, path, uid, -1, flag);
+
+ if (result < 0 && errno == EPERM) return F_status_set_error(F_access_owner);
+ }
+
+ if (gid != -1) {
+ result = fchownat(at_id, path, -1, gid, flag);
+
+ if (result < 0 && errno == EPERM) return F_status_set_error(F_access_group);
+ }
+
+ if (result < 0) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_out);
+ if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
+ if (errno == EROFS) return F_status_set_error(F_read_only);
+ if (errno == EIO) return F_status_set_error(F_input_output);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // !defined(_di_f_file_role_change_at_) || !defined(_di_f_file_copy_at_)
+
#if !defined(_di_f_file_stat_) || !defined(_di_f_file_copy_)
f_return_status private_f_file_stat(const f_string path, const bool dereference, struct stat *file_stat) {
#endif
/**
- * Private implementation of f_file_change_mode().
- *
- * Intended to be shared to each of the different implementation variations.
- *
- * @param path
- * The path file name.
- * @param mode
- * The new mode to use.
- *
- * @return
- * F_none on success.
- * F_access_denied (with error bit) on access denied.
- * F_access_mode (with error bit) if the current user does not have access to assign the file mode.
- * F_directory (with error bit) on invalid directory.
- * F_file_found_not (with error bit) if file at path was not found.
- * F_input_output (with error bit) on I/O error.
- * F_loop (with error bit) on loop error.
- * F_memory_out (with error bit) if out of memory.
- * F_name (with error bit) on path name error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_read_only (with error bit) if file is read-only.
- * F_failure (with error bit) for any other error.
- *
- * @see f_file_change_mode()
- * @see f_file_copy()
- */
-#if !defined(_di_f_file_change_mode_) || !defined(_di_f_file_copy_)
- extern f_return_status private_f_file_change_mode(const f_string path, const mode_t mode) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_f_file_change_mode_) || !defined(_di_f_file_copy_)
-
-/**
- * Private implementation of f_file_change_mode_at().
- *
- * Intended to be shared to each of the different implementation variations.
- *
- * @param at_id
- * The parent directory, as an open directory file descriptor, in which path is relative to.
- * @param path
- * The path file name.
- * @param mode
- * The new mode to use.
- *
- * @return
- * F_none on success.
- * F_access_denied (with error bit) on access denied.
- * F_access_mode (with error bit) if the current user does not have access to assign the file mode.
- * F_file_found_not (with error bit) if file at path was not found.
- * F_directory (with error bit) on invalid directory.
- * F_input_output (with error bit) on I/O error.
- * F_loop (with error bit) on loop error.
- * F_memory_out (with error bit) if out of memory.
- * F_name (with error bit) on path name error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_read_only (with error bit) if file is read-only.
- * F_failure (with error bit) for any other error.
- *
- * @see f_file_change_mode_at()
- */
-#if !defined(_di_f_file_change_mode_at_)
- extern f_return_status private_f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_f_file_change_mode_at_)
-
-/**
- * Private implementation of f_file_change_role().
- *
- * Intended to be shared to each of the different implementation variations.
- *
- * @param path
- * The path file name.
- * @param uid
- * The new user id to use.
- * @param gid
- * The new group id to use.
- * @param dereference
- * Set to TRUE to dereference symlinks (often is what is desired).
- * Set to FALSE to operate on the symlink itself.
- *
- * @return
- * F_none on success.
- * F_access_denied (with error bit) on access denied.
- * F_access_group (with error bit) if the current user does not have access to assign the specified group.
- * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
- * F_buffer (with error bit) if the buffer is invalid.
- * F_directory (with error bit) on invalid directory.
- * F_file_found_not (with error bit) if file at path was not found.
- * F_input_output (with error bit) on I/O error.
- * F_loop (with error bit) on loop error.
- * F_memory_out (with error bit) if out of memory.
- * F_name (with error bit) on path name error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_read_only (with error bit) if file is read-only.
- * F_failure (with error bit) for any other error.
- *
- * @see f_file_change_role()
- * @see f_file_copy()
- */
-#if !defined(_di_f_file_change_role_) || !defined(_di_f_file_copy_)
- extern f_return_status private_f_file_change_role(const f_string path, const uid_t uid, const gid_t gid, const bool dereference) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_f_file_change_role_) || !defined(_di_f_file_copy_)
-
-/**
- * Private implementation of f_file_change_role_at().
- *
- * Intended to be shared to each of the different implementation variations.
- *
- * @param at_id
- * The parent directory, as an open directory file descriptor, in which path is relative to.
- * @param path
- * The path file name.
- * @param uid
- * The new user id to use.
- * @param gid
- * The new group id to use.
- * @param flag
- * Any valid flag, such as f_file_at_path_empty, f_file_at_automount_no, or f_file_at_symlink_follow_no.
- *
- * @return
- * F_none on success.
- * F_access_denied (with error bit) on access denied.
- * F_access_group (with error bit) if the current user does not have access to assign the specified group.
- * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
- * F_buffer (with error bit) if the buffer is invalid.
- * F_directory (with error bit) on invalid directory.
- * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
- * F_file_found_not (with error bit) if file at path was not found.
- * F_input_output (with error bit) on I/O error.
- * F_loop (with error bit) on loop error.
- * F_memory_out (with error bit) if out of memory.
- * F_name (with error bit) on path name error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_read_only (with error bit) if file is read-only.
- * F_failure (with error bit) for any other error.
- *
- * @see f_file_change_role_at()
- */
-#if !defined(_di_f_file_change_role_at_)
- extern f_return_status private_f_file_change_role_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_f_file_change_role_at_)
-
-/**
* Private implementation of f_file_close().
*
* Intended to be shared to each of the different implementation variations.
#endif // !defined(_di_f_file_copy_at_)
/**
- * Create a fifo based on the given path and file mode.
+ * Private implementation of private_f_file_create_fifo().
+ *
+ * Intended to be shared to each of the different implementation variations.
*
* @param path
* The path file name.
#endif // !defined(_di_f_file_create_fifo_) || !defined(_di_f_file_copy_)
/**
- * Create a fifo based on the given path and file mode.
+ * Private implementation of private_f_file_create_fifo_at().
+ *
+ * Intended to be shared to each of the different implementation variations.
*
* @param at_id
* The parent directory, as an open directory file descriptor, in which path is relative to.
#endif // !defined(_di_f_file_link_read_at_) || !defined(_di_f_file_copy_at_)
/**
+ * Private implementation of f_file_mode_set().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param path
+ * The path file name.
+ * @param mode
+ * The new mode to use.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_access_mode (with error bit) if the current user does not have access to assign the file mode.
+ * F_directory (with error bit) on invalid directory.
+ * F_file_found_not (with error bit) if file at path was not found.
+ * F_input_output (with error bit) on I/O error.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see f_file_mode_set()
+ * @see f_file_copy()
+ */
+#if !defined(_di_f_file_mode_set_) || !defined(_di_f_file_copy_)
+ extern f_return_status private_f_file_mode_set(const f_string path, const mode_t mode) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_file_mode_set_) || !defined(_di_f_file_copy_)
+
+/**
+ * Private implementation of f_file_mode_set_at().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param at_id
+ * The parent directory, as an open directory file descriptor, in which path is relative to.
+ * @param path
+ * The path file name.
+ * @param mode
+ * The new mode to use.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_access_mode (with error bit) if the current user does not have access to assign the file mode.
+ * F_file_found_not (with error bit) if file at path was not found.
+ * F_directory (with error bit) on invalid directory.
+ * F_input_output (with error bit) on I/O error.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see f_file_mode_set_at()
+ */
+#if !defined(_di_f_file_mode_set_at_)
+ extern f_return_status private_f_file_mode_set_at(const int at_id, const f_string path, const mode_t mode) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_file_mode_set_at_)
+
+/**
* Private implementation of f_file_open().
*
* Intended to be shared to each of the different implementation variations.
#endif // !defined(_di_f_file_open_at_)
/**
+ * Private implementation of f_file_role_change().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param path
+ * The path file name.
+ * @param uid
+ * The new user id to use.
+ * @param gid
+ * The new group id to use.
+ * @param dereference
+ * Set to TRUE to dereference symlinks (often is what is desired).
+ * Set to FALSE to operate on the symlink itself.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_access_group (with error bit) if the current user does not have access to assign the specified group.
+ * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_directory (with error bit) on invalid directory.
+ * F_file_found_not (with error bit) if file at path was not found.
+ * F_input_output (with error bit) on I/O error.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see f_file_role_change()
+ * @see f_file_copy()
+ */
+#if !defined(_di_f_file_role_change_) || !defined(_di_f_file_copy_)
+ extern f_return_status private_f_file_role_change(const f_string path, const uid_t uid, const gid_t gid, const bool dereference) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_file_role_change_) || !defined(_di_f_file_copy_)
+
+/**
+ * Private implementation of f_file_role_change_at().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param at_id
+ * The parent directory, as an open directory file descriptor, in which path is relative to.
+ * @param path
+ * The path file name.
+ * @param uid
+ * The new user id to use.
+ * @param gid
+ * The new group id to use.
+ * @param flag
+ * Any valid flag, such as f_file_at_path_empty, f_file_at_automount_no, or f_file_at_symlink_follow_no.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_access_group (with error bit) if the current user does not have access to assign the specified group.
+ * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_directory (with error bit) on invalid directory.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
+ * F_file_found_not (with error bit) if file at path was not found.
+ * F_input_output (with error bit) on I/O error.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see f_file_role_change_at()
+ */
+#if !defined(_di_f_file_role_change_at_)
+ extern f_return_status private_f_file_role_change_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_file_role_change_at_)
+
+/**
* Private implementation of f_file_stat().
*
* Intended to be shared to each of the different implementation variations.
return F_status_set_error(F_directory_found);
}
- status = f_file_change_mode(destination, source_stat.st_mode);
+ status = f_file_mode_set(destination, source_stat.st_mode);
if (F_status_is_error(status)) return status;
}
else {
}
if (role) {
- status = f_file_change_role(destination, source_stat.st_uid, source_stat.st_gid, F_true);
+ status = f_file_role_change(destination, source_stat.st_uid, source_stat.st_gid, F_true);
if (F_status_is_error(status)) return status;
}
return F_status_set_error(F_directory_found);
}
- status = f_file_change_mode(destination, mode.directory);
+ status = f_file_mode_set(destination, mode.directory);
if (F_status_is_error(status)) return status;
}
else {
*
* Errors from (with error bit): f_directory_create().
* Errors from (with error bit): f_directory_exists().
- * Errors from (with error bit): f_file_change_mode().
- * Errors from (with error bit): f_file_change_role().
+ * Errors from (with error bit): f_file_mode_set().
+ * Errors from (with error bit): f_file_role_change().
* Errors from (with error bit): f_file_stat().
*
* @see f_file_clone()
*
* Errors from (with error bit): f_directory_create().
* Errors from (with error bit): f_directory_exists().
- * Errors from (with error bit): f_file_change_mode().
- * Errors from (with error bit): f_file_change_role().
+ * Errors from (with error bit): f_file_mode_set().
+ * Errors from (with error bit): f_file_role_change().
* Errors from (with error bit): f_file_stat().
*
* @see f_file_copy()
break;
}
- status = f_file_change_mode(destination_sub.string, source_stat.st_mode);
+ status = f_file_mode_set(destination_sub.string, source_stat.st_mode);
if (F_status_is_error(status)) break;
}
else {
}
if (role) {
- status = f_file_change_role(destination_sub.string, source_stat.st_uid, source_stat.st_gid, F_true);
+ status = f_file_role_change(destination_sub.string, source_stat.st_uid, source_stat.st_gid, F_true);
if (F_status_is_error(status)) break;
}
}
break;
}
- status = f_file_change_mode(destination_sub.string, mode.directory);
+ status = f_file_mode_set(destination_sub.string, mode.directory);
if (F_status_is_error(status)) break;
}
else {
if (F_status_is_error(*status)) return;
for (f_array_length i = 1; i < arguments.used; i++) {
- *status = f_file_change_role(arguments.array[i].string, -1, id, F_false);
+ *status = f_file_role_change(arguments.array[i].string, -1, id, F_false);
if (F_status_is_error(*status)) {
- fake_print_error_file(data, *status, "f_file_change_role", arguments.array[i].string, "change group of", F_true, F_true);
+ fake_print_error_file(data, *status, "f_file_role_change", arguments.array[i].string, "change group of", F_true, F_true);
}
} // for
for (f_array_length i = 1; i < arguments.used; i++) {
// @todo: recursive.
- *status = f_file_change_role(arguments.array[i].string, -1, id, F_false);
+ *status = f_file_role_change(arguments.array[i].string, -1, id, F_false);
if (F_status_is_error(*status)) {
- fake_print_error_file(data, *status, "f_file_change_role", arguments.array[i].string, "change group of", F_true, F_true);
+ fake_print_error_file(data, *status, "f_file_role_change", arguments.array[i].string, "change group of", F_true, F_true);
}
} // for
mode_t mode = 0;
+ struct stat stat_file;
+
for (f_array_length i = 1; i < arguments.used; i++) {
- // @todo: get the file mode.
+ mode = 0;
+ memset(&stat_file, 0, sizeof(struct stat));
- if (replace) {
- // @todo when replace is specified, then determine what is to be replaced when converting to mode_t.
+ *status = f_file_stat(arguments.array[i].string, F_true, &stat_file);
+ if (F_status_is_error(*status)) {
+ fake_print_error_file(data, *status, "f_file_stat", arguments.array[i].string, "change mode of", F_true, F_true);
+ break;
}
- // @todo: check the zeroing logic, read each file's mode, and updat accordingly.
- //*status = f_file_change_mode(arguments.array[i].string, mode);
- //if (F_status_is_error(*status)) {
- // fake_print_error_file(data, *status, "f_file_change_mode", arguments.array[i].string, "change mode of", F_true, F_true);
- //}
+ *status = f_file_mode_determine(stat_file.st_mode, mode_rule, replace, f_macro_file_type_is_directory(stat_file.st_mode), data.umask, &mode);
+ if (F_status_is_error(*status)) {
+ fake_print_error_file(data, *status, "f_file_mode_determine", arguments.array[i].string, "change mode of", F_true, F_true);
+ break;
+ }
+
+ *status = f_file_mode_set(arguments.array[i].string, mode);
+ if (F_status_is_error(*status)) {
+ fake_print_error_file(data, *status, "f_file_mode_set", arguments.array[i].string, "change mode of", F_true, F_true);
+ break;
+ }
} // for
return;
if (F_status_is_error(*status)) return;
for (f_array_length i = 1; i < arguments.used; i++) {
- *status = f_file_change_role(arguments.array[i].string, id, -1, F_false);
+ *status = f_file_role_change(arguments.array[i].string, id, -1, F_false);
if (F_status_is_error(*status)) {
- fake_print_error_file(data, *status, "f_file_change_role", arguments.array[i].string, "change owner of", F_true, F_true);
+ fake_print_error_file(data, *status, "f_file_role_change", arguments.array[i].string, "change owner of", F_true, F_true);
}
} // for
for (f_array_length i = 1; i < arguments.used; i++) {
// @todo recursive.
- *status = f_file_change_role(arguments.array[i].string, id, -1, F_false);
+ *status = f_file_role_change(arguments.array[i].string, id, -1, F_false);
if (F_status_is_error(*status)) {
- fake_print_error_file(data, *status, "f_file_change_role", arguments.array[i].string, "change owner of", F_true, F_true);
+ fake_print_error_file(data, *status, "f_file_role_change", arguments.array[i].string, "change owner of", F_true, F_true);
}
} // for
}
}
else if (operation == fake_make_operation_type_group || operation == fake_make_operation_type_groups || operation == fake_make_operation_type_mode || operation == fake_make_operation_type_modes || operation == fake_make_operation_type_owner || operation == fake_make_operation_type_owners) {
- printf("DEBUG: arguments.used = %llu\n");
if (arguments.used > 1) {
f_status status_file = F_none;
for (f_array_length i = 1; i < arguments.used; i++) {
status_file = f_file_is(arguments.array[i].string, f_file_type_regular);
- printf("DEBUG: at %llu, looking at '%s', %llu\n", i, arguments.array[i].string, F_status_set_fine(status_file));
-
if (status_file == F_file_found_not) {
printf("%c", f_string_eol[0]);
fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Failed to find file '");
main:
#build
- owner a b
+ touch file b
+ mode =755 b