Implement recursive change owner, change groups, and change modes functions.
These are implemented in the fll_file project.
Then utilize these for the recursive owners, groups, and modes section operations.
Fix specification where I forgot to rename "archiver" to "indexer".
In documentation it is "indexer" and not "index" for the indexer program whereas "index" is a section operation name.
Fix documentation where I forgot to rename "archive" to "index".
A bug in fl_directory_list() was discovered where the parameter check for path is incorrect.
build_language c
build_libraries -lc
build_libraries-level -lfll_1 -lfll_0
-build_sources_library execute.c private-execute.c file.c fss.c private-fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c fss_status.c path.c program.c status.c
+build_sources_library execute.c private-execute.c file.c private-file.c fss.c private-fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c fss_status.c path.c program.c status.c
build_sources_program
build_sources_headers execute.h file.h fss.h fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_status.h path.h program.h status.h
build_sources_script
build_language c
build_libraries -lc
build_libraries-monolithic
-build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/serialize.c level_0/private-serialize.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/path.c level_2/program.c level_2/status.c
+build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/serialize.c level_0/private-serialize.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/path.c level_2/program.c level_2/status.c
build_sources_program
build_sources_headers level_0/account.h level_0/color.h level_0/console.h level_0/conversion.h level_0/directory.h level_0/directory_type.h level_0/environment.h level_0/file.h level_0/fss.h level_0/fss-common.h level_0/fss-named.h level_0/fss-nest.h level_0/fss-quoted.h level_0/fss-set.h level_0/iki.h level_0/iki-common.h level_0/memory.h level_0/memory-structure.h level_0/path.h level_0/pipe.h level_0/print.h level_0/serialize.h level_0/socket.h level_0/status.h level_0/status_array.h level_0/string.h level_0/string_common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/path.h level_2/program.h level_2/status.h
build_sources_script
#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) {
+ f_return_status f_file_is(const f_string_t path, const int type, const bool dereference) {
#ifndef _di_level_0_parameter_checking_
if (path == 0) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
memset(&file_stat, 0, sizeof(struct stat));
- if (stat(path, &file_stat) < 0) {
- if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == ENOMEM) return F_status_set_error(F_memory_out);
- if (errno == EOVERFLOW) return F_status_set_error(F_number_overflow);
- if (errno == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == ENOENT) return F_file_found_not;
- if (errno == EACCES) return F_status_set_error(F_access_denied);
- if (errno == ELOOP) return F_status_set_error(F_loop);
-
- return F_status_set_error(F_file_stat);
- }
+ f_status_t status = private_f_file_stat(path, dereference, &file_stat);
+ if (F_status_is_error(status)) return status;
if (f_macro_file_type_get(file_stat.st_mode) == type) return F_true;
* The path file name.
* @param type
* The type of the file.
+ * @param dereference
+ * Set to TRUE to dereference symlinks (often is what is desired).
+ * Set to FALSE to operate on the symlink itself.
*
* @return
* F_true if path was found and path is type.
* @see stat()
*/
#ifndef _di_f_file_is_
- extern f_return_status f_file_is(const f_string_t path, const int type);
+ extern f_return_status f_file_is(const f_string_t path, const int type, const bool dereference);
#endif // _di_f_file_is_
/**
* @see f_file_exists()
* @see f_file_touch()
*/
-#if !defined(_di_f_file_stat_) || !defined(_di_f_file_copy_) || !defined(_di_f_file_exists_) || !defined(_di_f_file_touch_)
+#if !defined(_di_f_file_stat_) || !defined(_di_f_file_copy_) || !defined(_di_f_file_exists_) || !defined(_di_f_file_is_) || !defined(_di_f_file_touch_)
extern f_return_status private_f_file_stat(const f_string_t file_name, const bool dereference, struct stat *file_stat) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_f_file_stat_) || !defined(_di_f_file_copy_) || !defined(_di_f_file_exists_) || !defined(_di_f_file_touch_)
+#endif // !defined(_di_f_file_stat_) || !defined(_di_f_file_copy_) || !defined(_di_f_file_exists_) || !defined(_di_f_file_is_) || !defined(_di_f_file_touch_)
/**
* Private implementation of f_file_stat_at().
#ifndef _di_fl_directory_list_
f_return_status fl_directory_list(const f_string_t path, int (*filter)(const struct dirent *), int (*sort)(const struct dirent **, const struct dirent **), const bool dereference, f_directory_listing_t *listing) {
#ifndef _di_level_1_parameter_checking_
- if (path) return F_status_set_error(F_parameter);
- if (listing == 0) return F_status_set_error(F_parameter);
+ if (!path) return F_status_set_error(F_parameter);
+ if (!listing) return F_status_set_error(F_parameter);
#endif // _di_level_1_parameter_checking_
return private_fl_directory_list(path, filter, sort, dereference, listing);
#include "file.h"
+#include "private-file.h"
#ifdef __cplusplus
extern "C" {
}
#endif // _di_fll_file_error_print_
+#ifndef _di_fll_file_mode_set_all_
+ f_return_status fll_file_mode_set_all(const f_string_t path, const mode_t mode, const f_number_unsigned_t depth_max) {
+ #ifndef _di_level_0_parameter_checking_
+ if (path == 0) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ return private_fll_file_mode_set_all(path, mode, depth_max, 0);
+ }
+#endif // _di_fll_file_mode_set_all__
+
+#ifndef _di_fll_file_role_change_all_
+ f_return_status fll_file_role_change_all(const f_string_t path, const uid_t uid, const gid_t gid, const bool dereference, const f_number_unsigned_t depth_max) {
+ #ifndef _di_level_0_parameter_checking_
+ if (path == 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_fll_file_role_change_all(path, uid, gid, dereference, depth_max, 0);
+ }
+#endif // _di_fll_file_role_change_all_
+
#ifdef __cplusplus
} // extern "C"
#endif
#include <level_0/status.h>
#include <level_0/memory.h>
#include <level_0/string.h>
+#include <level_0/directory.h>
+#include <level_0/file.h>
// fll-1 includes
#include <level_1/color.h>
+#include <level_1/directory.h>
#ifdef __cplusplus
extern "C" {
extern f_return_status fll_file_error_print(FILE *file, const fl_color_context_t context, const f_string_t function_name, const f_string_t file_name, const f_status_t status);
#endif // _di_fll_file_error_print_
+/**
+ * Change mode of a given file or directory at the specified path.
+ *
+ * This does not set mode based on umask(), be sure to apply umask if so desired.
+ * (such as: mode & ~mask).
+ *
+ * If the file is a directory then recurse into that directory and apply mode to all files within.
+ *
+ * @param path
+ * The path file name.
+ * @param mode
+ * The new mode to use.
+ * @param depth_max
+ * The max recursion depth.
+ *
+ * @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_recurse (with error bit) if recursion failed, due to max depth reached.
+ * F_failure (with error bit) for any other error.
+ */
+#ifndef _di_fll_file_mode_set_all_
+ extern f_return_status fll_file_mode_set_all(const f_string_t path, const mode_t mode, const f_number_unsigned_t depth_max);
+#endif // _di_fll_file_mode_set_all_
+
+/**
+ * Change owner and/or group of a given file at the specified path.
+ *
+ * At least one of uid or gid must not be -1.
+ *
+ * If the file is a directory then recurse into that directory and apply mode to all files within.
+ *
+ * @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.
+ * @param depth_max
+ * The max recursion depth.
+ *
+ * @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_recurse (with error bit) if recursion failed, due to max depth reached.
+ * F_failure (with error bit) for any other error.
+ */
+#ifndef _di_fll_file_role_change_all_
+ extern f_return_status fll_file_role_change_all(const f_string_t path, const uid_t uid, const gid_t gid, const bool dereference, const f_number_unsigned_t depth_max);
+#endif // _di_fll_file_role_change_all_
+
#ifdef __cplusplus
} // extern "C"
#endif
--- /dev/null
+#include "file.h"
+#include "private-file.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_di_fll_file_mode_set_all_)
+ f_return_status private_fll_file_mode_set_all(const f_string_t path, const mode_t mode, const f_number_unsigned_t depth_max, const f_number_unsigned_t depth) {
+
+ if (depth >= depth_max) return F_status_set_error(F_recurse);
+
+ f_status_t status = F_none;
+
+ status = f_directory_is(path);
+ if (F_status_is_error(status)) return status;
+
+ if (status == F_false) {
+ return f_file_mode_set(path, mode);
+ }
+
+ f_directory_listing_t listing = f_directory_listing_t_initialize;
+
+ status = fl_directory_list(path, 0, 0, F_false, &listing);
+
+ if (F_status_is_error(status)) {
+ f_macro_directory_listing_t_delete_simple(listing);
+ return status;
+ }
+
+ status = F_none;
+
+ const f_string_length_t path_length = strnlen(path, f_path_max);
+
+ {
+ f_string_dynamics_t *list[] = {
+ &listing.block,
+ &listing.character,
+ &listing.regular,
+ &listing.link,
+ &listing.fifo,
+ &listing.socket,
+ &listing.unknown,
+ };
+
+ uint8_t i = 0;
+ f_array_length_t j = 0;
+
+ for (; i < 7; i++) {
+ for (j = 0; F_status_is_fine(status) && j < list[i]->used; j++) {
+ const f_string_length_t length = path_length + list[i]->array[j].used + 1;
+
+ char path_sub[length + 1];
+
+ memcpy(path_sub, path, path_length);
+ memcpy(path_sub + path_length + 1, list[i]->array[j].string, list[i]->array[j].used);
+
+ path_sub[path_length] = f_path_separator[0];
+ path_sub[length] = 0;
+
+ status = f_file_mode_set(path_sub, mode);
+ } // for
+
+ f_macro_string_dynamics_t_delete_simple((*list[i]));
+ } // for
+ }
+
+ f_macro_string_dynamics_t_delete_simple(listing.unknown);
+
+ for (f_array_length_t i = 0; F_status_is_fine(status) && i < listing.directory.used; i++) {
+ const f_string_length_t length = path_length + listing.directory.array[i].used + 1;
+
+ char path_sub[length + 1];
+
+ memcpy(path_sub, path, path_length);
+ memcpy(path_sub + path_length + 1, listing.directory.array[i].string, listing.directory.array[i].used);
+
+ path_sub[path_length] = f_path_separator[0];
+ path_sub[length] = 0;
+
+ status = f_directory_exists(path_sub);
+ if (F_status_is_error(status)) break;
+
+ if (status == F_false) {
+ status = F_status_set_error(F_directory);
+ break;
+ }
+
+ status = private_fll_file_mode_set_all(path_sub, mode, depth_max, depth + 1);
+ if (F_status_is_error(status)) break;
+ } // for
+
+ f_macro_string_dynamics_t_delete_simple(listing.directory);
+
+ if (F_status_is_error(status)) return status;
+
+ return f_file_mode_set(path, mode);
+ }
+#endif // !defined(_di_fll_file_mode_set_all_)
+
+#if !defined(_di_fll_file_role_change_all_)
+ f_return_status private_fll_file_role_change_all(const f_string_t path, const uid_t uid, const gid_t gid, const bool dereference, const f_number_unsigned_t depth_max, const f_number_unsigned_t depth) {
+
+ if (depth >= depth_max) return F_status_set_error(F_recurse);
+
+ f_status_t status = F_none;
+
+ status = f_directory_is(path);
+ if (F_status_is_error(status)) return status;
+
+ if (status == F_false) {
+ return f_file_role_change(path, uid, gid, dereference);
+ }
+
+ f_directory_listing_t listing = f_directory_listing_t_initialize;
+
+ status = fl_directory_list(path, 0, 0, F_false, &listing);
+
+ if (F_status_is_error(status)) {
+ f_macro_directory_listing_t_delete_simple(listing);
+ return status;
+ }
+
+ status = F_none;
+
+ const f_string_length_t path_length = strnlen(path, f_path_max);
+
+ {
+ f_string_dynamics_t *list[] = {
+ &listing.block,
+ &listing.character,
+ &listing.regular,
+ &listing.link,
+ &listing.fifo,
+ &listing.socket,
+ &listing.unknown,
+ };
+
+ uint8_t i = 0;
+ f_array_length_t j = 0;
+
+ for (; i < 7; i++) {
+ for (j = 0; F_status_is_fine(status) && j < list[i]->used; j++) {
+ const f_string_length_t length = path_length + list[i]->array[j].used + 1;
+
+ char path_sub[length + 1];
+
+ memcpy(path_sub, path, path_length);
+ memcpy(path_sub + path_length + 1, list[i]->array[j].string, list[i]->array[j].used);
+
+ path_sub[path_length] = f_path_separator[0];
+ path_sub[length] = 0;
+
+ status = f_file_role_change(path_sub, uid, gid, dereference);
+ } // for
+
+ f_macro_string_dynamics_t_delete_simple((*list[i]));
+ } // for
+ }
+
+ for (f_array_length_t i = 0; F_status_is_fine(status) && i < listing.directory.used; i++) {
+ const f_string_length_t length = path_length + listing.directory.array[i].used + 1;
+
+ char path_sub[length + 1];
+
+ memcpy(path_sub, path, path_length);
+ memcpy(path_sub + path_length + 1, listing.directory.array[i].string, listing.directory.array[i].used);
+
+ path_sub[path_length] = f_path_separator[0];
+ path_sub[length] = 0;
+
+ status = f_directory_exists(path_sub);
+ if (F_status_is_error(status)) break;
+
+ if (status == F_false) {
+ status = F_status_set_error(F_directory);
+ break;
+ }
+
+ status = private_fll_file_role_change_all(path_sub, uid, gid, dereference, depth_max, depth + 1);
+ if (F_status_is_error(status)) break;
+ } // for
+
+ f_macro_string_dynamics_t_delete_simple(listing.directory);
+
+ if (F_status_is_error(status)) return status;
+
+ return f_file_role_change(path, uid, gid, dereference);
+ }
+#endif // !defined(_di_fll_file_role_change_all_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 2
+ *
+ * Project: File
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * Provides structures and data types for a file I/O.
+ * Provides operations for opening/closing files.
+ */
+#ifndef _PRIVATE_FLL_file_h
+#define _PRIVATE_FLL_file_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Private implementation of fll_file_mode_set_all().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param path
+ * The path file name.
+ * @param mode
+ * The new mode to use.
+ * @param depth_max
+ * The max recursion depth.
+ * @param depth
+ * The current depth.
+ *
+ * @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_recurse (with error bit) if recursion failed, due to max depth reached.
+ * F_failure (with error bit) for any other error.
+ */
+#if !defined(_di_fll_file_mode_set_all_)
+ extern f_return_status private_fll_file_mode_set_all(const f_string_t path, const mode_t mode, const f_number_unsigned_t depth_max, const f_number_unsigned_t depth) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fll_file_mode_set_all_)
+
+/**
+ * Private implementation of fll_file_role_change_all().
+ *
+ * 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.
+ * @param depth_max
+ * The max recursion depth.
+ * @param depth
+ * The current depth.
+ *
+ * @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.
+ */
+#if !defined(_di_fll_file_role_change_all_)
+ extern f_return_status private_fll_file_role_change_all(const f_string_t path, const uid_t uid, const gid_t gid, const bool dereference, const f_number_unsigned_t depth_max, const f_number_unsigned_t depth) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fll_file_role_change_all_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_FLL_file_h
f_status
f_memory
f_string
+f_directory
+f_file
fl_color
+fl_directory
build_indexer ar
build_language c
build_libraries -lc
-build_libraries-individual -lfl_color -lf_print -lf_file -lf_memory
-build_sources_library file.c
+build_libraries-individual -lfl_color -lfl_directory -lf_print -lf_file -lf_directory -lf_memory
+build_sources_library file.c private-file.c
build_sources_program
build_sources_headers file.h
build_sources_script
// fll-2 includes
#include <level_2/execute.h>
+#include <level_2/file.h>
#include <level_2/fss.h>
#include <level_2/fss_basic_list.h>
#include <level_2/fss_extended.h>
*status = fake_make_get_id_group(data, data_make->print, arguments.array[0], &id);
if (F_status_is_error(*status)) return;
+ f_status_t status_file = F_none;
+
for (f_array_length_t i = 1; i < arguments.used; i++) {
- *status = f_file_role_change(arguments.array[i].string, -1, id, F_false);
+ status_file = fake_make_assure_inside_project(data, arguments.array[i], data_make);
+
+ if (F_status_is_error(status_file)) {
+ *status = status_file;
+
+ fake_print_message_section_operation_path_outside(data, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string, data_make->print);
+
+ continue;
+ }
+
+ status_file = f_file_role_change(arguments.array[i].string, -1, id, F_false);
+
+ if (F_status_is_error(status_file)) {
+ *status = status_file;
- if (F_status_is_error(*status)) {
fake_print_message_file(data, *status, "f_file_role_change", arguments.array[i].string, "change group of", F_true, F_true, data_make->print);
}
else if (data.verbosity == fake_verbosity_verbose) {
*status = fake_make_get_id_group(data, data_make->print, arguments.array[0], &id);
if (F_status_is_error(*status)) return;
+ f_status_t status_file = F_none;
+
for (f_array_length_t i = 1; i < arguments.used; i++) {
- // @todo: recursive.
- *status = f_file_role_change(arguments.array[i].string, -1, id, F_false);
+ status_file = fake_make_assure_inside_project(data, arguments.array[i], data_make);
- if (F_status_is_error(*status)) {
- fake_print_message_file(data, *status, "f_file_role_change", arguments.array[i].string, "change group of", F_true, F_true, data_make->print);
+ if (F_status_is_error(status_file)) {
+ *status = status_file;
+
+ fake_print_message_section_operation_path_outside(data, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string, data_make->print);
+
+ continue;
+ }
+
+ status_file = fll_file_role_change_all(arguments.array[i].string, -1, id, F_false, fake_make_operation_recursion_depth_max);
+
+ if (F_status_is_error(status_file)) {
+ *status = status_file;
+
+ fake_print_message_file(data, F_status_set_fine(*status), "fll_file_role_change_all", arguments.array[i].string, "change group of", F_true, F_true, data_make->print);
}
else if (data.verbosity == fake_verbosity_verbose) {
printf("Changed group of '%s' to %llu.%c", arguments.array[i].string, id, f_string_eol[0]);
mode_t mode_file = 0;
for (f_array_length_t i = 1; i < arguments.used; i++) {
- // @todo recursive.
mode = 0;
*status = f_file_mode_read(arguments.array[i].string, &mode_file);
break;
}
- *status = f_file_mode_set(arguments.array[i].string, mode);
+ *status = fll_file_mode_set_all(arguments.array[i].string, mode, fake_make_operation_recursion_depth_max);
if (F_status_is_error(*status)) {
- fake_print_message_file(data, F_status_set_fine(*status), "f_file_mode_set", arguments.array[i].string, "change mode of", F_true, F_true, data_make->print);
+ fake_print_message_file(data, F_status_set_fine(*status), "fll_file_mode_set_all", arguments.array[i].string, "change mode of", F_true, F_true, data_make->print);
break;
}
*status = fake_make_get_id_owner(data, data_make->print, arguments.array[0], &id);
if (F_status_is_error(*status)) return;
+ f_status_t status_file = F_none;
+
for (f_array_length_t i = 1; i < arguments.used; i++) {
- *status = f_file_role_change(arguments.array[i].string, id, -1, F_false);
- if (F_status_is_error(*status)) {
+ status_file = fake_make_assure_inside_project(data, arguments.array[i], data_make);
+
+ if (F_status_is_error(status_file)) {
+ *status = status_file;
+
+ fake_print_message_section_operation_path_outside(data, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string, data_make->print);
+
+ continue;
+ }
+
+ status_file = f_file_role_change(arguments.array[i].string, id, -1, F_false);
+
+ if (F_status_is_error(status_file)) {
+ *status = status_file;
+
fake_print_message_file(data, F_status_set_fine(*status), "f_file_role_change", arguments.array[i].string, "change owner of", F_true, F_true, data_make->print);
break;
}
-
- if (data.verbosity == fake_verbosity_verbose) {
+ else if (data.verbosity == fake_verbosity_verbose) {
printf("Changed owner of '%s' to %d.%c", arguments.array[i].string, id, f_string_eol[0]);
}
} // for
*status = fake_make_get_id_owner(data, data_make->print, arguments.array[0], &id);
if (F_status_is_error(*status)) return;
+ f_status_t status_file = F_none;
+
for (f_array_length_t i = 1; i < arguments.used; i++) {
- // @todo recursive.
- *status = f_file_role_change(arguments.array[i].string, id, -1, F_false);
- if (F_status_is_error(*status)) {
- fake_print_message_file(data, F_status_set_fine(*status), "f_file_role_change", arguments.array[i].string, "change owner of", F_true, F_true, data_make->print);
+ status_file = fake_make_assure_inside_project(data, arguments.array[i], data_make);
+
+ if (F_status_is_error(status_file)) {
+ *status = status_file;
+
+ fake_print_message_section_operation_path_outside(data, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string, data_make->print);
+
+ continue;
}
- if (data.verbosity == fake_verbosity_verbose) {
+ status_file = fll_file_role_change_all(arguments.array[i].string, id, -1, F_false, fake_make_operation_recursion_depth_max);
+
+ if (F_status_is_error(status_file)) {
+ *status = status_file;
+
+ fake_print_message_file(data, F_status_set_fine(*status), "fll_file_role_change_all", arguments.array[i].string, "change owner of", F_true, F_true, data_make->print);
+ }
+ else if (data.verbosity == fake_verbosity_verbose) {
printf("Changed owner of '%s' to %o.%c", arguments.array[i].string, id, f_string_eol[0]);
}
} // for
path_file[data.path_data_build.used + arguments.array[0].used] = 0;
- f_status_t status_file = f_file_is(path_file, f_file_type_regular);
+ f_status_t status_file = f_file_is(path_file, f_file_type_regular, F_false);
if (status_file == F_file_found_not) {
if (data.verbosity != fake_verbosity_quiet && data_make->print.to) {
f_status_t status_file = F_none;
for (f_array_length_t i = 1; i < arguments.used; i++) {
- status_file = f_file_is(arguments.array[i].string, f_file_type_regular);
+ status_file = f_file_is(arguments.array[i].string, f_file_type_regular, F_false);
if (status_file == F_file_found_not) {
if (data.verbosity != fake_verbosity_quiet && data_make->print.to) {
}
else if (arguments.used) {
if (arguments.array[0].used) {
- f_status_t status_file = f_file_is(arguments.array[0].string, f_file_type_directory);
+ f_status_t status_file = f_file_is(arguments.array[0].string, f_file_type_directory, F_false);
if (status_file == F_file_found_not) {
if (data.verbosity != fake_verbosity_quiet && data_make->print.to) {
fake_make_operation_fail_type_warn,
fake_make_operation_fail_type_ignore,
};
+
+ #define fake_make_operation_recursion_depth_max 65535
#endif // _di_fake_make_operation_
// @todo each one of these should be made available to be passed to the program as "$parameter_define[X]" for multi-value (define) or "$parameter_no_color" for single-value (no_color).
return F_false;
}
+ if (status == F_access_owner) {
+ if (data.verbosity != fake_verbosity_quiet) {
+ fprintf(print.to, "%c", f_string_eol[0]);
+ fl_color_print(print.to, print.context, data.context.reset, "%s: Currrent user is not allowed to use the given owner while trying to %s %s '", print.prefix, operation, file_or_directory);
+ fl_color_print(print.to, data.context.notable, data.context.reset, "%s", name);
+ fl_color_print_line(print.to, print.context, data.context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_access_group) {
+ if (data.verbosity != fake_verbosity_quiet) {
+ fprintf(print.to, "%c", f_string_eol[0]);
+ fl_color_print(print.to, print.context, data.context.reset, "%s: Currrent user is not allowed to use the given group while trying to %s %s '", print.prefix, operation, file_or_directory);
+ fl_color_print(print.to, data.context.notable, data.context.reset, "%s", name);
+ fl_color_print_line(print.to, print.context, data.context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
if (is_file) {
if (status == F_directory_found_not) {
if (data.verbosity != fake_verbosity_quiet) {
if (path.used == 0) return F_none;
- status = f_file_is(path.string, f_file_type_regular);
+ status = f_file_is(path.string, f_file_type_regular, F_false);
if (status == F_true) {
if (data.verbosity == fake_verbosity_verbose) {
printf("File '%s' already exists.%c", path.string, f_string_eol[0]);
// symbolic links might also be fine.
if (status == F_false) {
- status = f_file_is(path.string, f_file_type_link);
+ status = f_file_is(path.string, f_file_type_link, F_false);
if (status == F_true) {
if (data.verbosity == fake_verbosity_verbose) {
The return code for programs can still be retrieved through using the reserved iki vaiable "return".
- - index\:
+ - indexer\:
This represents the name of the indexer program to use, such as "ar".
When specified and "load_build" is "true", then this will override the "build_indexer" specified in the loaded build settings.
This is processed top-down until the end of the list is reached.
The following operations are available\:
- - archive\:
- Execute the linker program, such as "ar".
- This uses "archive" instead of "link" to avoid confusion between this and generating a symbolic link to some file.
-
- All Content are passed as arguments to the respective "ar" program.
-
- build\:
Run the fake build operation as if "fake build" was run instead of "fake make".
Command line arguments are automatically passed to the fake build operation.
for example, "if defined parameter verbose silent" would test if both the "verbose" and the "silent" variables are defined via the "parameter" setting.
for example, "if defined environment PWD SHELL" would test if both the "PWD" and the "SHELL" variables are defined via the "environment" variables.
+ - index\:
+ Execute the linker program, such as "ar".
+
+ All Content are passed as arguments to the respective "ar" program.
+
- link\:
Create a symbolic link from some point to some target.
- main: contains a list of Operation Objects and Content in FSS-0001 (Extended) format.
The Settings Objects are\:
- - archiver: Only one Content, which must only be a valid filename.
- compiler: Only one Content, which must only be a valid filename.
- define: First Content represents variable name (case-sensitive), remaining Content represents varaiable value for IKI substitution.
- environment: Zero or more Content representing valid environment variable names (alpha-numeric with underscore, but cannot begin with a number).
- fail: Only one Content, which must be either "exit", "warn" or "ignore" (quotes not required) (case-sensitive).
+ - indexer: Only one Content, which must only be a valid filename.
- load_build: Only one Content, which must be either "yes" or "no" (quotes not required) (case-sensitive).
- parameter: First Content represents variable name (case-sensitive), remaining Content represents varaiable value for IKI substitution.