From ef05d1c9005c712116d0c686efbf5f6b56bf73a5 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Wed, 2 Sep 2020 22:28:56 -0500 Subject: [PATCH] Update: add/update functions and refactor f_file_mode to f_file_mode_t and related. Add functions f_environment_exists(), f_file_group_read(), and f_file_owner_read(). Update function f_file_mode_to_mode(), implementing it. Refactor f_file_mode to f_file_mode_t and related. This appears to have been missed in a previous refactor. --- level_0/f_environment/c/environment.c | 18 ++ level_0/f_environment/c/environment.h | 26 +++ level_0/f_file/c/file.c | 332 ++++++++++++++++++++++------------ level_0/f_file/c/file.h | 157 +++++++++++----- 4 files changed, 364 insertions(+), 169 deletions(-) diff --git a/level_0/f_environment/c/environment.c b/level_0/f_environment/c/environment.c index 2a62111..c710075 100644 --- a/level_0/f_environment/c/environment.c +++ b/level_0/f_environment/c/environment.c @@ -15,8 +15,26 @@ extern "C" { } #endif // _di_f_environment_clear_ +#ifndef _di_f_environment_exists_ + f_return_status f_environment_exists(const f_string_t name) { + #ifndef _di_level_0_parameter_checking_ + if (!name) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (getenv(name)) { + return F_true; + } + + return F_false; + } +#endif // _di_f_environment_exists_ + #ifndef _di_f_environment_get_ f_return_status f_environment_get(const f_string_t name, f_string_dynamic_t *value) { + #ifndef _di_level_0_parameter_checking_ + if (!name) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + return private_f_environment_get(name, value); } #endif // _di_f_environment_get_ diff --git a/level_0/f_environment/c/environment.h b/level_0/f_environment/c/environment.h index ff104d2..597f2e3 100644 --- a/level_0/f_environment/c/environment.h +++ b/level_0/f_environment/c/environment.h @@ -59,9 +59,35 @@ extern "C" { * The value will be appended (set value->used to 0 to replace). * * @return + * F_true on success and environment variable exists. + * F_false on success and environment variable does not exist. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see getenv() + */ +#ifndef _di_f_environment_exists_ + extern f_return_status f_environment_exists(const f_string_t name); +#endif // _di_f_environment_exists_ + +/** + * Get a single environment variable. + * + * The variable is copied into a new dynamically allocated string and is safe to alter. + * + * @param name + * The name of the environment variable to get. + * The name string must not contain the '=' character. + * The name must be NULL terminated. + * @param value + * The value associated with name. + * The value will not be null terminated. + * The value will be appended (set value->used to 0 to replace). + * + * @return * F_none on success. * F_exist_not if name does not exist. * F_memory_reallocation (with error bit) on memory reallocation error. + * F_parameter (with error bit) if a parameter is invalid. * F_string_too_large (with error bit) if appended string length is too large to store in the buffer. * * @see getenv() diff --git a/level_0/f_file/c/file.c b/level_0/f_file/c/file.c index f61e07d..924e27a 100644 --- a/level_0/f_file/c/file.c +++ b/level_0/f_file/c/file.c @@ -355,6 +355,28 @@ extern "C" { } #endif // _di_f_file_flush_ +#ifndef _di_f_file_group_read_ + f_return_status f_file_group_read(const f_string_t path, gid_t *group) { + #ifndef _di_level_0_parameter_checking_ + if (path == 0) return F_status_set_error(F_parameter); + if (group == 0) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + struct stat stat_file; + + memset(&stat_file, 0, sizeof(struct stat)); + + f_status_t status = private_f_file_stat(path, F_true, &stat_file); + if (F_status_is_error(status)) { + return status; + } + + *group = stat_file.st_gid; + + return F_none; + } +#endif // _di_f_file_group_read_ + #ifndef _di_f_file_is_ f_return_status f_file_is(const f_string_t path, const int type) { #ifndef _di_level_0_parameter_checking_ @@ -525,60 +547,60 @@ extern "C" { #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, mode_t *mode) { + f_return_status f_file_mode_determine(const mode_t mode_file, const f_file_mode_t mode_change, const uint8_t mode_replace, const bool directory_is, 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; + f_file_mode_t change = mode_change & f_file_mode_t_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) { + if (mode_replace & f_file_mode_t_replace_special) { + if (change & f_file_mode_t_mask_bit_set_owner & f_file_mode_t_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) { + if (change & f_file_mode_t_mask_bit_set_group & f_file_mode_t_mask_how_add) { *mode |= f_file_mode_special_set_group; } - if (change & f_file_mode_mask_bit_sticky & f_file_mode_mask_how_add) { + if (change & f_file_mode_t_mask_bit_sticky & f_file_mode_t_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_change & f_file_mode_t_block_special) { + if (change & f_file_mode_t_mask_bit_set_owner & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_set_owner & f_file_mode_t_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 (change & f_file_mode_t_mask_bit_set_group & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_set_group & f_file_mode_t_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 (change & f_file_mode_t_mask_bit_sticky & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_sticky & f_file_mode_t_mask_how_add) { if (!(*mode & f_file_mode_special_sticky)) { *mode |= f_file_mode_special_sticky; } @@ -586,21 +608,21 @@ extern "C" { } } - change = mode_change & f_file_mode_block_owner; + change = mode_change & f_file_mode_t_block_owner; - if (mode_replace & f_file_mode_replace_owner) { - if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_add) { + if (mode_replace & f_file_mode_t_replace_owner) { + if (change & f_file_mode_t_mask_bit_read & f_file_mode_t_mask_how_add) { *mode |= f_file_mode_owner_r; } - if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_add) { + if (change & f_file_mode_t_mask_bit_write & f_file_mode_t_mask_how_add) { *mode |= f_file_mode_owner_w; } - if (change & f_file_mode_mask_bit_execute & f_file_mode_mask_how_add) { + if (change & f_file_mode_t_mask_bit_execute & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_execute_only & f_file_mode_t_mask_how_add) { if (directory_is || (mode_file & f_file_mode_owner_x)) { *mode |= f_file_mode_owner_x; } @@ -609,53 +631,53 @@ extern "C" { 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_change & f_file_mode_t_block_owner) { + if (change & f_file_mode_t_mask_bit_read & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_read & f_file_mode_t_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 (change & f_file_mode_t_mask_bit_write & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_write & f_file_mode_t_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_t_mask_bit_execute) { + change &= f_file_mode_t_mask_bit_execute; - if (change & f_file_mode_mask_how_subtract) { + if (change & f_file_mode_t_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) { + else if (change & f_file_mode_t_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; + else if (change & f_file_mode_t_mask_bit_execute_only) { + change &= f_file_mode_t_mask_bit_execute_only; if (directory_is || (mode_file & f_file_mode_owner_x)) { - if (change & f_file_mode_mask_how_subtract) { + if (change & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_how_add) { if (!(*mode & f_file_mode_owner_x)) { *mode |= f_file_mode_owner_x; } @@ -665,21 +687,21 @@ extern "C" { } } - change = mode_change & f_file_mode_block_group; + change = mode_change & f_file_mode_t_block_group; - if (mode_replace & f_file_mode_replace_group) { - if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_add) { + if (mode_replace & f_file_mode_t_replace_group) { + if (change & f_file_mode_t_mask_bit_read & f_file_mode_t_mask_how_add) { *mode |= f_file_mode_group_r; } - if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_add) { + if (change & f_file_mode_t_mask_bit_write & f_file_mode_t_mask_how_add) { *mode |= f_file_mode_group_w; } - if (change & f_file_mode_mask_bit_execute & f_file_mode_mask_how_add) { + if (change & f_file_mode_t_mask_bit_execute & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_execute_only & f_file_mode_t_mask_how_add) { if (directory_is || (mode_file & f_file_mode_group_x)) { *mode |= f_file_mode_group_x; } @@ -688,54 +710,54 @@ extern "C" { else { *mode |= mode_file & f_file_mode_group_rwx; - if (mode_change & f_file_mode_block_group) { + if (mode_change & f_file_mode_t_block_group) { - if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_subtract) { + if (change & f_file_mode_t_mask_bit_read & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_read & f_file_mode_t_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 (change & f_file_mode_t_mask_bit_write & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_write & f_file_mode_t_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_t_mask_bit_execute) { + change &= f_file_mode_t_mask_bit_execute; - if (change & f_file_mode_mask_how_subtract) { + if (change & f_file_mode_t_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) { + else if (change & f_file_mode_t_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; + else if (change & f_file_mode_t_mask_bit_execute_only) { + change &= f_file_mode_t_mask_bit_execute_only; if (directory_is || (mode_file & f_file_mode_group_x)) { - if (change & f_file_mode_mask_how_subtract) { + if (change & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_how_add) { if (!(*mode & f_file_mode_group_x)) { *mode |= f_file_mode_group_x; } @@ -745,22 +767,22 @@ extern "C" { } } - change = mode_change & f_file_mode_block_world; + change = mode_change & f_file_mode_t_block_world; - if (mode_replace & f_file_mode_replace_world) { + if (mode_replace & f_file_mode_t_replace_world) { - if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_add) { + if (change & f_file_mode_t_mask_bit_read & f_file_mode_t_mask_how_add) { *mode |= f_file_mode_world_r; } - if (change & f_file_mode_mask_bit_write & f_file_mode_mask_how_add) { + if (change & f_file_mode_t_mask_bit_write & f_file_mode_t_mask_how_add) { *mode |= f_file_mode_world_w; } - if (change & f_file_mode_mask_bit_execute & f_file_mode_mask_how_add) { + if (change & f_file_mode_t_mask_bit_execute & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_execute_only & f_file_mode_t_mask_how_add) { if (directory_is || (mode_file & f_file_mode_world_x)) { *mode |= f_file_mode_world_x; } @@ -769,54 +791,54 @@ extern "C" { else { *mode |= mode_file & f_file_mode_world_rwx; - if (mode_change & f_file_mode_block_world) { + if (mode_change & f_file_mode_t_block_world) { - if (change & f_file_mode_mask_bit_read & f_file_mode_mask_how_subtract) { + if (change & f_file_mode_t_mask_bit_read & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_read & f_file_mode_t_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 (change & f_file_mode_t_mask_bit_write & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_bit_write & f_file_mode_t_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_t_mask_bit_execute) { + change &= f_file_mode_t_mask_bit_execute; - if (change & f_file_mode_mask_how_subtract) { + if (change & f_file_mode_t_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) { + else if (change & f_file_mode_t_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; + else if (change & f_file_mode_t_mask_bit_execute_only) { + change &= f_file_mode_t_mask_bit_execute_only; if (directory_is || (mode_file & f_file_mode_world_x)) { - if (change & f_file_mode_mask_how_subtract) { + if (change & f_file_mode_t_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) { + else if (change & f_file_mode_t_mask_how_add) { if (!(*mode & f_file_mode_world_x)) { *mode |= f_file_mode_world_x; } @@ -831,7 +853,7 @@ extern "C" { #endif // _di_f_file_mode_determine_ #ifndef _di_f_file_mode_from_string_ - f_return_status f_file_mode_from_string(const f_string_t string, const mode_t umask, f_file_mode *mode, uint8_t *replace) { + f_return_status f_file_mode_from_string(const f_string_t string, const mode_t umask, f_file_mode_t *mode, uint8_t *replace) { #ifndef _di_level_0_parameter_checking_ if (string == 0) return F_status_set_error(F_parameter); if (string[0] == 0) return F_status_set_error(F_parameter); @@ -901,57 +923,57 @@ extern "C" { uint8_t on = 0; // 1 = user, 2 = group, 4 = world/sticky, 7 = all. uint8_t how = 0; // 1 = add, 2 = replace, 3 = subtract. - f_file_mode mode_mask = 0; - f_file_mode mode_umask = 0; - f_file_mode what = 0; + f_file_mode_t mode_mask = 0; + f_file_mode_t mode_umask = 0; + f_file_mode_t what = 0; - // translate the umask into an f_file_mode umask equivalent. + // translate the umask into an f_file_mode_t umask equivalent. if (umask & f_file_mode_special_set_user) { - mode_umask = f_file_mode_block_special & f_file_mode_mask_bit_set_owner; + mode_umask = f_file_mode_t_block_special & f_file_mode_t_mask_bit_set_owner; } if (umask & f_file_mode_special_set_group) { - mode_umask |= f_file_mode_block_special & f_file_mode_mask_bit_set_group; + mode_umask |= f_file_mode_t_block_special & f_file_mode_t_mask_bit_set_group; } if (umask & f_file_mode_special_sticky) { - mode_umask |= f_file_mode_block_special & f_file_mode_mask_bit_sticky; + mode_umask |= f_file_mode_t_block_special & f_file_mode_t_mask_bit_sticky; } if (umask & f_file_mode_owner_r) { - mode_umask |= f_file_mode_block_owner & f_file_mode_mask_bit_read; + mode_umask |= f_file_mode_t_block_owner & f_file_mode_t_mask_bit_read; } if (umask & f_file_mode_owner_w) { - mode_umask |= f_file_mode_block_owner & f_file_mode_mask_bit_write; + mode_umask |= f_file_mode_t_block_owner & f_file_mode_t_mask_bit_write; } if (umask & f_file_mode_owner_x) { - mode_umask |= f_file_mode_block_owner & f_file_mode_mask_bit_execute; + mode_umask |= f_file_mode_t_block_owner & f_file_mode_t_mask_bit_execute; } if (umask & f_file_mode_group_r) { - mode_umask |= f_file_mode_block_group & f_file_mode_mask_bit_read; + mode_umask |= f_file_mode_t_block_group & f_file_mode_t_mask_bit_read; } if (umask & f_file_mode_group_w) { - mode_umask |= f_file_mode_block_group & f_file_mode_mask_bit_write; + mode_umask |= f_file_mode_t_block_group & f_file_mode_t_mask_bit_write; } if (umask & f_file_mode_group_x) { - mode_umask |= f_file_mode_block_group & f_file_mode_mask_bit_execute; + mode_umask |= f_file_mode_t_block_group & f_file_mode_t_mask_bit_execute; } if (umask & f_file_mode_world_r) { - mode_umask |= f_file_mode_block_world & f_file_mode_mask_bit_read; + mode_umask |= f_file_mode_t_block_world & f_file_mode_t_mask_bit_read; } if (umask & f_file_mode_world_w) { - mode_umask |= f_file_mode_block_world & f_file_mode_mask_bit_write; + mode_umask |= f_file_mode_t_block_world & f_file_mode_t_mask_bit_write; } if (umask & f_file_mode_world_x) { - mode_umask |= f_file_mode_block_world & f_file_mode_mask_bit_execute; + mode_umask |= f_file_mode_t_block_world & f_file_mode_t_mask_bit_execute; } for (f_string_length_t i = 0; syntax && string[i]; i++) { @@ -959,22 +981,22 @@ extern "C" { switch (string[i]) { case 'o': on |= 1; - mode_mask |= f_file_mode_block_world; + mode_mask |= f_file_mode_t_block_world; break; case 'g': on |= 2; - mode_mask |= f_file_mode_block_group; + mode_mask |= f_file_mode_t_block_group; break; case 'u': on |= 4; - mode_mask |= f_file_mode_block_owner; + mode_mask |= f_file_mode_t_block_owner; break; case 'a': on = 7; - mode_mask = f_file_mode_block_standard; + mode_mask = f_file_mode_t_block_standard; break; case '+': @@ -990,61 +1012,61 @@ extern "C" { how = on ? 2 : 5; // clear by mask to prepare for replacement, which includes clearing the special block. - mode_mask |= f_file_mode_block_special; + mode_mask |= f_file_mode_t_block_special; *mode -= (*mode) & mode_mask; - *replace |= f_file_mode_replace_special; + *replace |= f_file_mode_t_replace_special; - if (mode_mask & f_file_mode_block_owner) { - *replace |= f_file_mode_replace_owner; + if (mode_mask & f_file_mode_t_block_owner) { + *replace |= f_file_mode_t_replace_owner; } - if (mode_mask & f_file_mode_block_group) { - *replace |= f_file_mode_replace_group; + if (mode_mask & f_file_mode_t_block_group) { + *replace |= f_file_mode_t_replace_group; } - if (mode_mask & f_file_mode_block_world) { - *replace |= f_file_mode_replace_world; + if (mode_mask & f_file_mode_t_block_world) { + *replace |= f_file_mode_t_replace_world; } } if (!on) { on = 7; - mode_mask = f_file_mode_block_all; + mode_mask = f_file_mode_t_block_all; } for (i++; string[i]; i++) { if (string[i] == 'r') { - what = f_file_mode_mask_bit_read; + what = f_file_mode_t_mask_bit_read; } else if (string[i] == 'w') { - what = f_file_mode_mask_bit_write; + what = f_file_mode_t_mask_bit_write; } else if (string[i] == 'x') { - what = f_file_mode_mask_bit_execute; + what = f_file_mode_t_mask_bit_execute; } else if (string[i] == 'X') { - what = f_file_mode_mask_bit_execute_only; + what = f_file_mode_t_mask_bit_execute_only; } else if (string[i] == 's') { - mode_mask |= f_file_mode_block_special; + mode_mask |= f_file_mode_t_block_special; if (on & 4) { - what = f_file_mode_mask_bit_set_owner; + what = f_file_mode_t_mask_bit_set_owner; } else if (on & 2) { - what = f_file_mode_mask_bit_set_group; + what = f_file_mode_t_mask_bit_set_group; } else { what = 0; } } else if (string[i] == 't') { - mode_mask |= f_file_mode_block_special; + mode_mask |= f_file_mode_t_block_special; if (on & 1) { - what = f_file_mode_mask_bit_sticky; + what = f_file_mode_t_mask_bit_sticky; } else { what = 0; @@ -1066,10 +1088,10 @@ extern "C" { } if (how == 1 || how == 2 || how == 4 || how == 5) { - *mode |= what & mode_mask & f_file_mode_mask_how_add; + *mode |= what & mode_mask & f_file_mode_t_mask_how_add; } else if (how == 3 || how == 6) { - *mode |= what & mode_mask & f_file_mode_mask_how_subtract; + *mode |= what & mode_mask & f_file_mode_t_mask_how_subtract; } } // for @@ -1105,12 +1127,12 @@ extern "C" { how = 2; i = 1; - *replace = f_file_mode_replace_standard; + *replace = f_file_mode_t_replace_standard; } else { how = 2; - *replace = f_file_mode_replace_standard | f_file_mode_replace_directory; + *replace = f_file_mode_t_replace_standard | f_file_mode_t_replace_directory; } if (string[i] == '0') { @@ -1163,7 +1185,7 @@ extern "C" { else if (how == 2) { // if there are only '0's then the standard and setuid/setgid/sticky bits are to be replaced. if (*mode == 0) { - *replace = f_file_mode_replace_standard | f_file_mode_replace_special; + *replace = f_file_mode_t_replace_standard | f_file_mode_t_replace_special; } } } @@ -1244,17 +1266,67 @@ extern "C" { } #endif // _di_f_file_mode_set_at_ -#ifndef _di_f_file_mode_determine_ - f_return_status f_file_mode_to_mode(const f_file_mode mode_from, const uint8_t mode_replace, mode_t *mode_to) { +#ifndef _di_f_file_mode_to_mode_ + f_return_status f_file_mode_to_mode(const f_file_mode_t from, mode_t *to) { #ifndef _di_level_0_parameter_checking_ - if (mode_to == 0) return F_status_set_error(F_parameter); + if (to == 0) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - // @todo + const f_file_mode_t add = from & f_file_mode_t_mask_how_add; + + *to = 0; + + if (add & f_file_mode_t_mask_bit_set_owner) { + *to |= f_file_mode_special_set_user; + } + + if (add & f_file_mode_t_mask_bit_set_group) { + *to |= f_file_mode_special_set_group; + } + + if (add & f_file_mode_t_mask_bit_sticky) { + *to |= f_file_mode_special_sticky; + } + + if (add & f_file_mode_t_block_owner & f_file_mode_t_mask_bit_read) { + *to |= f_file_mode_owner_r; + } + + if (add & f_file_mode_t_block_group & f_file_mode_t_mask_bit_read) { + *to |= f_file_mode_group_r; + } + + if (add & f_file_mode_t_block_world & f_file_mode_t_mask_bit_write) { + *to |= f_file_mode_world_r; + } + + if (add & f_file_mode_t_block_owner & f_file_mode_t_mask_bit_write) { + *to |= f_file_mode_owner_w; + } + + if (add & f_file_mode_t_block_group & f_file_mode_t_mask_bit_write) { + *to |= f_file_mode_group_w; + } + + if (add & f_file_mode_t_block_world & f_file_mode_t_mask_bit_write) { + *to |= f_file_mode_world_w; + } + + if (add & f_file_mode_t_block_owner & (f_file_mode_t_mask_bit_execute | f_file_mode_t_mask_bit_execute_only)) { + *to |= f_file_mode_owner_x; + } + + if (add & f_file_mode_t_block_group & (f_file_mode_t_mask_bit_execute | f_file_mode_t_mask_bit_execute_only)) { + *to |= f_file_mode_group_x; + } + + if (add & f_file_mode_t_block_world & (f_file_mode_t_mask_bit_execute | f_file_mode_t_mask_bit_execute_only)) { + *to |= f_file_mode_world_x; + } return F_none; } -#endif // _di_f_file_mode_determine_ +#endif // _di_f_file_mode_to_mode_ #ifndef _di_f_file_name_base_ f_return_status f_file_name_base(const f_string_t path, const f_string_length_t length, f_string_dynamic_t *name_base) { @@ -1349,6 +1421,28 @@ extern "C" { } #endif // _di_f_file_open_at_ +#ifndef _di_f_file_owner_read_ + f_return_status f_file_owner_read(const f_string_t path, uid_t *owner) { + #ifndef _di_level_0_parameter_checking_ + if (path == 0) return F_status_set_error(F_parameter); + if (owner == 0) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + struct stat stat_file; + + memset(&stat_file, 0, sizeof(struct stat)); + + f_status_t status = private_f_file_stat(path, F_true, &stat_file); + if (F_status_is_error(status)) { + return status; + } + + *owner = stat_file.st_uid; + + return F_none; + } +#endif // _di_f_file_owner_read_ + #ifndef _di_f_file_read_ f_return_status f_file_read(const f_file_t file, f_string_dynamic_t *buffer) { #ifndef _di_level_0_parameter_checking_ diff --git a/level_0/f_file/c/file.h b/level_0/f_file/c/file.h index e764c50..58245ad 100644 --- a/level_0/f_file/c/file.h +++ b/level_0/f_file/c/file.h @@ -264,7 +264,11 @@ extern "C" { /** * File mode related functionality. * - * The f_file_mode type properties are 8-bit types with the following structure: + * There are two types of file modes the f_file_mode_t macros associate with. + * + * The first type is the traditional mode type, associated with mode_t. + * + * The second type is f_file_mode_t, which utilizes 8-bit types with the following structure: * * There should only be a single bit for each 'r', 'w', 'x', and 'X' bit (as well as 'S', 's', and 't'): * 'r' = read bit. @@ -274,40 +278,43 @@ extern "C" { * 'S' = set user bit (setuid). * 's' = set group bit (setgid). * 't' = sticky bit. + * + * The file mode macros with "f_file_mode_" prefix (has no "_t") refer to the first type (mode_t). + * The file mode macros with "f_file_mode_t" prefix refer to the second type (f_file_mode_t). */ #ifndef _di_f_file_mode_ - typedef uint32_t f_file_mode; - - #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_block_standard 0x00ffffff // 0000 0000 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_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_read 0x00444444 // 0000 0000 0100 0100 0100 0100 0100 0100 - #define f_file_mode_mask_bit_set_group 0x22000000 // 0010 0010 0000 0000 0000 0000 0000 0000 - #define f_file_mode_mask_bit_set_owner 0x44000000 // 0100 0100 0000 0000 0000 0000 0000 0000 - #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_special 0x8 // 0000 1000 - #define f_file_mode_replace_directory 0x10 // 0001 0000 - - #define f_file_mode_replace_all 0x1f // 0001 1111 - #define f_file_mode_replace_other 0x18 // 0001 1000 - #define f_file_mode_replace_standard 0x7 // 0000 0111 - - // file permission modes. + typedef uint32_t f_file_mode_t; + + #define f_file_mode_t_block_special 0x77000000 // 0111 0111 0000 0000 0000 0000 0000 0000 + #define f_file_mode_t_block_owner 0x00ff0000 // 0000 0000 1111 1111 0000 0000 0000 0000 + #define f_file_mode_t_block_group 0x0000ff00 // 0000 0000 0000 0000 1111 1111 0000 0000 + #define f_file_mode_t_block_world 0x000000ff // 0000 0000 0000 0000 0000 0000 1111 1111 + + #define f_file_mode_t_block_all 0x77ffffff // 0111 0111 1111 1111 1111 1111 1111 1111 + #define f_file_mode_t_block_standard 0x00ffffff // 0000 0000 1111 1111 1111 1111 1111 1111 + + #define f_file_mode_t_mask_how_add 0x070f0f0f // 0000 0111 0000 1111 0000 1111 0000 1111 + #define f_file_mode_t_mask_how_subtract 0x70f0f0f0 // 0111 0000 1111 0000 1111 0000 1111 0000 + + #define f_file_mode_t_mask_bit_execute 0x00111111 // 0000 0000 0001 0001 0001 0001 0001 0001 + #define f_file_mode_t_mask_bit_execute_only 0x00888888 // 0000 0000 1000 1000 1000 1000 1000 1000 + #define f_file_mode_t_mask_bit_read 0x00444444 // 0000 0000 0100 0100 0100 0100 0100 0100 + #define f_file_mode_t_mask_bit_set_group 0x22000000 // 0010 0010 0000 0000 0000 0000 0000 0000 + #define f_file_mode_t_mask_bit_set_owner 0x44000000 // 0100 0100 0000 0000 0000 0000 0000 0000 + #define f_file_mode_t_mask_bit_sticky 0x11000000 // 0001 0001 0000 0000 0000 0000 0000 0000 + #define f_file_mode_t_mask_bit_write 0x00222222 // 0000 0000 0010 0010 0010 0010 0010 0010 + + #define f_file_mode_t_replace_owner 0x1 // 0000 0001 + #define f_file_mode_t_replace_group 0x2 // 0000 0010 + #define f_file_mode_t_replace_world 0x4 // 0000 0100 + #define f_file_mode_t_replace_special 0x8 // 0000 1000 + #define f_file_mode_t_replace_directory 0x10 // 0001 0000 + + #define f_file_mode_t_replace_all 0x1f // 0001 1111 + #define f_file_mode_t_replace_other 0x18 // 0001 1000 + #define f_file_mode_t_replace_standard 0x7 // 0000 0111 + + // file permission modes (mode_t). #define f_file_mode_owner_rwx S_IRWXU #define f_file_mode_owner_r S_IRUSR #define f_file_mode_owner_w S_IWUSR @@ -338,16 +345,16 @@ extern "C" { #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 set-uid/set-gid/sticky-bits and all bits. + // file mode set-uid/set-gid/sticky-bits and all bits (mode_t). #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. + // all permissions modes and special modes (mode_t). #define f_file_mode_all (f_file_mode_special_all | f_file_mode_all_rwx) - // special file mode combinations. + // special file mode combinations (mode_t). #define f_file_mode_user_access (f_file_mode_owner_rwx | f_file_mode_group_rwx | f_file_mode_world_x) #define f_file_mode_user_directory (f_file_mode_owner_rwx | f_file_mode_group_rwx) #define f_file_mode_user_file (f_file_mode_owner_rw | f_file_mode_group_rw) @@ -875,6 +882,31 @@ extern "C" { #endif // _di_f_file_flush_ /** + * Get the current group of a file. + * + * @param path + * The path file name. + * @param group + * The id of the file's group. + * + * @return + * F_none on success. + * F_access_denied (with error bit) if access to the file was denied. + * F_directory (with error bit) on invalid directory. + * F_file_found_not (with error bit) if the file was not found. + * 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_number_overflow (with error bit) on overflow error. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see fstat() + */ +#ifndef _di_f_file_group_read_ + extern f_return_status f_file_group_read(const f_string_t path, uid_t *group); +#endif // _di_f_file_group_read_ + +/** * Identify whether or not a file exists at the given path and if that file is a specific type. * * This does not require access on the file itself. @@ -1182,7 +1214,7 @@ extern "C" { * @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, mode_t *mode); + extern f_return_status f_file_mode_determine(const mode_t mode_file, const f_file_mode_t mode_change, const uint8_t mode_replace, const bool directory_is, mode_t *mode); #endif // _di_f_file_mode_determine_ /** @@ -1232,7 +1264,7 @@ extern "C" { * * 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). + * Otherwise, the current special bits are intended to be respected (designated by f_file_mode_t_replace_directory). * * 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. @@ -1258,7 +1290,7 @@ extern "C" { * The determined mode. * This uses bitwise data. * @param replace - * The determined modes that are to be replaced, such as: f_file_mode_replace_owner. + * The determined modes that are to be replaced, such as: f_file_mode_t_replace_owner. * This uses bitwise data. * * @return @@ -1271,11 +1303,11 @@ extern "C" { * @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_t string, const mode_t umask, f_file_mode *mode, uint8_t *replace); + extern f_return_status f_file_mode_from_string(const f_string_t string, const mode_t umask, f_file_mode_t *mode, uint8_t *replace); #endif // _di_f_file_mode_from_string_ /** - * Get the current file mode as an f_file_mode. + * Get the current file mode as an f_file_mode_t. * * @param path * The path file name. @@ -1300,7 +1332,7 @@ extern "C" { #endif // _di_f_file_mode_read_ /** - * Get the current file mode as an f_file_mode. + * Get the current file mode as an f_file_mode_t. * * @param at_id * The parent directory, as an open directory file descriptor, in which path is relative to. @@ -1391,13 +1423,13 @@ extern "C" { #endif // _di_f_file_mode_set_at_ /** - * Convert an f_file_mode type to a mode_t type. + * Convert an f_file_mode_t type to a mode_t type. + * + * This essentially converts all "add" codes from an f_file_mode_t to a mode_t, ignoring the "subtract" codes. * - * @param mode_from + * @param from * The file mode to convert from. - * @param mode_replace - * The modes designated to be replaced instead of simply changed. - * @param mode_to + * @param to * The determined mode. * * @return @@ -1406,9 +1438,9 @@ extern "C" { * * @see f_file_mode_from_string() */ -#ifndef _di_f_file_mode_determine_ - extern f_return_status f_file_mode_to_mode(const f_file_mode mode_from, const uint8_t mode_replace, mode_t *mode_to); -#endif // _di_f_file_mode_determine_ +#ifndef _di_f_file_mode_to_mode_ + extern f_return_status f_file_mode_to_mode(const f_file_mode_t from, mode_t *to); +#endif // _di_f_file_mode_to_mode_ /** * Get the base name of a file path. @@ -1515,6 +1547,31 @@ extern "C" { #endif // _di_f_file_open_at_ /** + * Get the current owner of a file. + * + * @param path + * The path file name. + * @param owner + * The id of the file's owner. + * + * @return + * F_none on success. + * F_access_denied (with error bit) if access to the file was denied. + * F_directory (with error bit) on invalid directory. + * F_file_found_not (with error bit) if the file was not found. + * 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_number_overflow (with error bit) on overflow error. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see fstat() + */ +#ifndef _di_f_file_owner_read_ + extern f_return_status f_file_owner_read(const f_string_t path, uid_t *owner); +#endif // _di_f_file_owner_read_ + +/** * Read until EOF is reached. * * To check how much was read into the buffer, record buffer->used before execution and compare to buffer->used after execution. -- 1.8.3.1