From f6ca4ed80a79408ab55b4a27b73eaa0f32a86410 Mon Sep 17 00:00:00 2001 From: Thorsten Töpper Date: Sat, 21 Jun 2025 16:42:49 +0200 Subject: Rename list_management to data_management --- CMakeLists.txt | 2 +- include/data_management.h | 35 +++++++ include/list_management.h | 35 ------- include/options.h | 2 +- include/output.h | 2 +- src/data_management.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++ src/dir_monitor.c | 2 +- src/list_management.c | 231 ---------------------------------------------- src/output.c | 2 +- 9 files changed, 271 insertions(+), 271 deletions(-) create mode 100644 include/data_management.h delete mode 100644 include/list_management.h create mode 100644 src/data_management.c delete mode 100644 src/list_management.c diff --git a/CMakeLists.txt b/CMakeLists.txt index f9e3ad8..5afa72d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ add_compile_options(-Wall -Wextra -Wformat -Wformat=2 -Wconversion -Wimplicit-fa -Wbidi-chars=any -Werror=implicit -Werror=incompatible-pointer-types -Werror=int-conversion -fno-delete-null-pointer-checks -fstack-clash-protection -fstack-protector-strong -fstrict-flex-arrays=3) -set(SOURCE_DM src/dir_monitor.c src/list_management.c src/options.c src/output.c) +set(SOURCE_DM src/dir_monitor.c src/data_management.c src/options.c src/output.c) add_executable(dir_monitor_debug ${SOURCE_DM}) target_include_directories(dir_monitor_debug PRIVATE include) diff --git a/include/data_management.h b/include/data_management.h new file mode 100644 index 0000000..e5d1581 --- /dev/null +++ b/include/data_management.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* Copyright 2025 Thorsten Töpper + * + * vim:ts=4:sw=4:expandtab + */ + +#ifndef LIST_MANAGEMENT_H +#define LIST_MANAGEMENT_H + +#include + +/* === DEFINITIONS === */ + +struct list_node { + struct list_node *next; + char fname[256]; + struct stat ln_stat; +}; + +struct list_head { + struct list_node *first; +}; + +struct list_node *create_node(char *fname, struct stat *ln_stat); +struct list_head *create_list_sort_reversed(struct list_head *list); +void destroy_list(struct list_head *list); + +struct list_head *get_data_from_directory(char *path); +int insert_sorted_by_size(struct list_head *list, struct list_node *node); +int insert_sorted_by_time(struct list_head *list, struct list_node *node); + + +#endif + diff --git a/include/list_management.h b/include/list_management.h deleted file mode 100644 index e5d1581..0000000 --- a/include/list_management.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -/* Copyright 2025 Thorsten Töpper - * - * vim:ts=4:sw=4:expandtab - */ - -#ifndef LIST_MANAGEMENT_H -#define LIST_MANAGEMENT_H - -#include - -/* === DEFINITIONS === */ - -struct list_node { - struct list_node *next; - char fname[256]; - struct stat ln_stat; -}; - -struct list_head { - struct list_node *first; -}; - -struct list_node *create_node(char *fname, struct stat *ln_stat); -struct list_head *create_list_sort_reversed(struct list_head *list); -void destroy_list(struct list_head *list); - -struct list_head *get_data_from_directory(char *path); -int insert_sorted_by_size(struct list_head *list, struct list_node *node); -int insert_sorted_by_time(struct list_head *list, struct list_node *node); - - -#endif - diff --git a/include/options.h b/include/options.h index 4fb3c82..cfc9246 100644 --- a/include/options.h +++ b/include/options.h @@ -11,7 +11,7 @@ #include #include "output.h" -#include "list_management.h" +#include "data_management.h" diff --git a/include/output.h b/include/output.h index beb9559..35640fe 100644 --- a/include/output.h +++ b/include/output.h @@ -8,7 +8,7 @@ #define OUTPUT_H #include -#include "list_management.h" +#include "data_management.h" #define LOGERR(...) {fprintf(stderr, "[%s:%d] %s: ", __FILE__, __LINE__, __func__); fprintf(stderr, __VA_ARGS__);} diff --git a/src/data_management.c b/src/data_management.c new file mode 100644 index 0000000..a0a1667 --- /dev/null +++ b/src/data_management.c @@ -0,0 +1,231 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* Copyright 2025 Thorsten Töpper + * + * vim:ts=4:sw=4:expandtab + */ +#include +#include +#include +#include +#include +#include + +#include "output.h" +#include "data_management.h" +#include "options.h" + + + +/* === IMPLEMENTATION === */ + +inline struct list_node *create_node(char *fname, struct stat *ln_stat) { + struct list_node *node = NULL; + + if (fname == NULL || fname[0] == '\0') { + LOGERR("ERROR: No valid filename given\n"); + return NULL; + } + + if (ln_stat == NULL) { + LOGERR("ERROR: No valid file information given\n"); + return NULL; + } + + if ((node = calloc(1, sizeof(struct list_node))) == NULL) { + LOGERR("ERROR: Failed allocate memory for node: %s\n", strerror(errno)); + return NULL; + } + + node->next = NULL; + /* With strncpy and strict compiler options it complained. A file name + * can't be longer than 256 bytes, including the string terminating \0 + * byte at the end. As the code no longer's in the same file...*/ + memcpy(node->fname, fname, 255); + node->fname[255] = '\0'; + memcpy(&(node->ln_stat), ln_stat, sizeof(struct stat)); + return node; +} + + +inline void destroy_list(struct list_head *list) { + struct list_node *ptr = NULL; + if (list == NULL) + return; + while (list->first != NULL) { + ptr = list->first->next; + if (ptr == NULL) { + free(list->first); + break; + } + list->first->next = ptr->next; + free(ptr); + } + free(list); +} + + +/* dirty... */ +#define INSERT_BY_NUMERIC_FIELD(list, node, field) \ +{ struct list_node *ptr = NULL; \ + if (node->ln_stat.field > list->first->ln_stat.field) { \ + node->next = list->first; list->first = node; return 0; } \ + ptr = list->first; \ + while (ptr != NULL) { \ + if (ptr->next == NULL) { ptr->next = node; return 0; } \ + if (node->ln_stat.field > ptr->next->ln_stat.field) { \ + node->next = ptr->next; ptr->next = node; \ + return 0; } \ + ptr = ptr->next; \ + } \ +} + + +inline int insert_sorted_by_size(struct list_head *list, struct list_node *node) { + if (list == NULL) { LOGERR("ERROR: No list given.\n"); return -1; } + if (node == NULL) { LOGERR("ERROR: No node given.\n"); return -2; } + + if (list->first == NULL) { + list->first = node; + return 0; + } + INSERT_BY_NUMERIC_FIELD(list, node, st_size); + return -3; +} + +inline int insert_sorted_by_time(struct list_head *list, struct list_node *node) { + if (list == NULL) { LOGERR("ERROR: No list given.\n"); return -1; } + if (node == NULL) { LOGERR("ERROR: No node given.\n"); return -2; } + + if (list->first == NULL) { + list->first = node; + return 0; + } + switch (option_time_field) { + case 'm': /* default setting first */ + INSERT_BY_NUMERIC_FIELD(list, node, st_mtim.tv_sec); + break; + case 'a': + INSERT_BY_NUMERIC_FIELD(list, node, st_atim.tv_sec); + break; + case 'c': + INSERT_BY_NUMERIC_FIELD(list, node, st_ctim.tv_sec); + break; + default: + LOGERR("WARNING: option_time_field has invalid value %c 0x%02X - going by default m\n", + option_time_field, option_time_field); + INSERT_BY_NUMERIC_FIELD(list, node, st_mtim.tv_sec); + break; + }; + return -3; +} + + +inline struct list_head *create_list_sort_reversed(struct list_head *list) { + struct list_head *lh = NULL; + struct list_node *cpynode = NULL, *ptr = NULL; + if (list == NULL) { + LOGERR("ERROR: No list given\n"); + return NULL; + } + if ((lh = calloc(1, sizeof(struct list_head))) == NULL) { + LOGERR("ERROR: Failed to allocate memory for a struct list_head\n"); + return NULL; + } + + lh->first = NULL; + ptr = list->first; + + while (ptr != NULL) { + cpynode = create_node(ptr->fname, &(ptr->ln_stat)); + if (cpynode == NULL) { + destroy_list(lh); + return NULL; + } + cpynode->next = lh->first; + lh->first = cpynode; + ptr = ptr->next; + } + + return lh; +} + +/* This function contains the only time critical code. The loop over + * the directory content. + * + * Note for future: + * I myself use the dir_monitor in combination with watch on a directory + * containing temporary data, it may happen that a run into an error occurs, + * but it's not tragic. To reduce the chance of the error the first step + * would be to optimize the loop with putting the data into a list in stack + * form and moving the nodes into a sorted list afterwards. + */ +struct list_head *get_data_from_directory(char *path) { + char *fullpath = NULL, *fname_in_path = NULL; + DIR *dir = NULL; + size_t l; + struct dirent *de = NULL; + struct list_node *tmp = NULL; + struct list_head *list = NULL; + struct stat stat_res; + + if (path == NULL) { + LOGERR("ERROR: No path given.\n"); + return NULL; + } + + l = strlen(path); + /* 258 filename and possibly required PATH_SEP and of course string termination */ + if ((fullpath = calloc(l+258, sizeof(char))) == NULL) { + LOGERR("ERROR: Failed to allocate memory for list head.\n"); + return NULL; + } + sprintf(fullpath, "%s%c", path, ((path[l-1] == PATH_SEP) ? '\0' : PATH_SEP)); + fname_in_path = (fullpath[l] == PATH_SEP) ? &(fullpath[l+1]) : &(fullpath[l]) ; + + if ((dir = opendir(path)) == NULL) { + LOGERR("ERROR: Failed to open directory '%s': %s (errno %d)\n", + path, strerror(errno), errno); + return NULL; + } + + /* TBH: In case those few bytes are not available, the process will be killed anyways */ + if ((list = calloc(1, sizeof(struct list_head))) == NULL) { + LOGERR("ERROR: Failed to allocate memory for list head.\n"); + closedir(dir); + return NULL; + } + + errno = 0; + /* Currently the code is specific UNIXoid, needs to be adjusted in case someone ports it. */ + while ((de = readdir(dir)) != NULL) { + if (de->d_name[0] == '.' && option_show_hidden_entries == false) + continue; + + sprintf(fname_in_path, "%s", de->d_name); + DBGTRC("DEBUG: fullpath: '%s'\n", fullpath); + if (lstat(fullpath, &stat_res) != 0) { + LOGERR("ERROR: lstat call on '%s' failed: %s (errno %d)\n", + fullpath, strerror(errno), errno); + continue; + } + if ((tmp = create_node(de->d_name, &stat_res)) == NULL) { + LOGERR("ERROR: Skipping entry %s\n", de->d_name); + continue; + } + /* SORT_BY_SIZE is the default value, always check it first. */ + switch (option_sort_type) { + case SORT_BY_SIZE: + insert_sorted_by_size(list, tmp); + break; + case SORT_BY_TIME: + insert_sorted_by_time(list, tmp); + break; + }; + } + + free(fullpath); + closedir(dir); + return list; +} + diff --git a/src/dir_monitor.c b/src/dir_monitor.c index 86f2361..509e99f 100644 --- a/src/dir_monitor.c +++ b/src/dir_monitor.c @@ -10,7 +10,7 @@ #include #include "output.h" -#include "list_management.h" +#include "data_management.h" #include "options.h" diff --git a/src/list_management.c b/src/list_management.c deleted file mode 100644 index d1a93d3..0000000 --- a/src/list_management.c +++ /dev/null @@ -1,231 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -/* Copyright 2025 Thorsten Töpper - * - * vim:ts=4:sw=4:expandtab - */ -#include -#include -#include -#include -#include -#include - -#include "output.h" -#include "list_management.h" -#include "options.h" - - - -/* === IMPLEMENTATION === */ - -inline struct list_node *create_node(char *fname, struct stat *ln_stat) { - struct list_node *node = NULL; - - if (fname == NULL || fname[0] == '\0') { - LOGERR("ERROR: No valid filename given\n"); - return NULL; - } - - if (ln_stat == NULL) { - LOGERR("ERROR: No valid file information given\n"); - return NULL; - } - - if ((node = calloc(1, sizeof(struct list_node))) == NULL) { - LOGERR("ERROR: Failed allocate memory for node: %s\n", strerror(errno)); - return NULL; - } - - node->next = NULL; - /* With strncpy and strict compiler options it complained. A file name - * can't be longer than 256 bytes, including the string terminating \0 - * byte at the end. As the code no longer's in the same file...*/ - memcpy(node->fname, fname, 255); - node->fname[255] = '\0'; - memcpy(&(node->ln_stat), ln_stat, sizeof(struct stat)); - return node; -} - - -inline void destroy_list(struct list_head *list) { - struct list_node *ptr = NULL; - if (list == NULL) - return; - while (list->first != NULL) { - ptr = list->first->next; - if (ptr == NULL) { - free(list->first); - break; - } - list->first->next = ptr->next; - free(ptr); - } - free(list); -} - - -/* dirty... */ -#define INSERT_BY_NUMERIC_FIELD(list, node, field) \ -{ struct list_node *ptr = NULL; \ - if (node->ln_stat.field > list->first->ln_stat.field) { \ - node->next = list->first; list->first = node; return 0; } \ - ptr = list->first; \ - while (ptr != NULL) { \ - if (ptr->next == NULL) { ptr->next = node; return 0; } \ - if (node->ln_stat.field > ptr->next->ln_stat.field) { \ - node->next = ptr->next; ptr->next = node; \ - return 0; } \ - ptr = ptr->next; \ - } \ -} - - -inline int insert_sorted_by_size(struct list_head *list, struct list_node *node) { - if (list == NULL) { LOGERR("ERROR: No list given.\n"); return -1; } - if (node == NULL) { LOGERR("ERROR: No node given.\n"); return -2; } - - if (list->first == NULL) { - list->first = node; - return 0; - } - INSERT_BY_NUMERIC_FIELD(list, node, st_size); - return -3; -} - -inline int insert_sorted_by_time(struct list_head *list, struct list_node *node) { - if (list == NULL) { LOGERR("ERROR: No list given.\n"); return -1; } - if (node == NULL) { LOGERR("ERROR: No node given.\n"); return -2; } - - if (list->first == NULL) { - list->first = node; - return 0; - } - switch (option_time_field) { - case 'm': /* default setting first */ - INSERT_BY_NUMERIC_FIELD(list, node, st_mtim.tv_sec); - break; - case 'a': - INSERT_BY_NUMERIC_FIELD(list, node, st_atim.tv_sec); - break; - case 'c': - INSERT_BY_NUMERIC_FIELD(list, node, st_ctim.tv_sec); - break; - default: - LOGERR("WARNING: option_time_field has invalid value %c 0x%02X - going by default m\n", - option_time_field, option_time_field); - INSERT_BY_NUMERIC_FIELD(list, node, st_mtim.tv_sec); - break; - }; - return -3; -} - - -inline struct list_head *create_list_sort_reversed(struct list_head *list) { - struct list_head *lh = NULL; - struct list_node *cpynode = NULL, *ptr = NULL; - if (list == NULL) { - LOGERR("ERROR: No list given\n"); - return NULL; - } - if ((lh = calloc(1, sizeof(struct list_head))) == NULL) { - LOGERR("ERROR: Failed to allocate memory for a struct list_head\n"); - return NULL; - } - - lh->first = NULL; - ptr = list->first; - - while (ptr != NULL) { - cpynode = create_node(ptr->fname, &(ptr->ln_stat)); - if (cpynode == NULL) { - destroy_list(lh); - return NULL; - } - cpynode->next = lh->first; - lh->first = cpynode; - ptr = ptr->next; - } - - return lh; -} - -/* This function contains the only time critical code. The loop over - * the directory content. - * - * Note for future: - * I myself use the dir_monitor in combination with watch on a directory - * containing temporary data, it may happen that a run into an error occurs, - * but it's not tragic. To reduce the chance of the error the first step - * would be to optimize the loop with putting the data into a list in stack - * form and moving the nodes into a sorted list afterwards. - */ -struct list_head *get_data_from_directory(char *path) { - char *fullpath = NULL, *fname_in_path = NULL; - DIR *dir = NULL; - size_t l; - struct dirent *de = NULL; - struct list_node *tmp = NULL; - struct list_head *list = NULL; - struct stat stat_res; - - if (path == NULL) { - LOGERR("ERROR: No path given.\n"); - return NULL; - } - - l = strlen(path); - /* 258 filename and possibly required PATH_SEP and of course string termination */ - if ((fullpath = calloc(l+258, sizeof(char))) == NULL) { - LOGERR("ERROR: Failed to allocate memory for list head.\n"); - return NULL; - } - sprintf(fullpath, "%s%c", path, ((path[l-1] == PATH_SEP) ? '\0' : PATH_SEP)); - fname_in_path = (fullpath[l] == PATH_SEP) ? &(fullpath[l+1]) : &(fullpath[l]) ; - - if ((dir = opendir(path)) == NULL) { - LOGERR("ERROR: Failed to open directory '%s': %s (errno %d)\n", - path, strerror(errno), errno); - return NULL; - } - - /* TBH: In case those few bytes are not available, the process will be killed anyways */ - if ((list = calloc(1, sizeof(struct list_head))) == NULL) { - LOGERR("ERROR: Failed to allocate memory for list head.\n"); - closedir(dir); - return NULL; - } - - errno = 0; - /* Currently the code is specific UNIXoid, needs to be adjusted in case someone ports it. */ - while ((de = readdir(dir)) != NULL) { - if (de->d_name[0] == '.' && option_show_hidden_entries == false) - continue; - - sprintf(fname_in_path, "%s", de->d_name); - DBGTRC("DEBUG: fullpath: '%s'\n", fullpath); - if (lstat(fullpath, &stat_res) != 0) { - LOGERR("ERROR: lstat call on '%s' failed: %s (errno %d)\n", - fullpath, strerror(errno), errno); - continue; - } - if ((tmp = create_node(de->d_name, &stat_res)) == NULL) { - LOGERR("ERROR: Skipping entry %s\n", de->d_name); - continue; - } - /* SORT_BY_SIZE is the default value, always check it first. */ - switch (option_sort_type) { - case SORT_BY_SIZE: - insert_sorted_by_size(list, tmp); - break; - case SORT_BY_TIME: - insert_sorted_by_time(list, tmp); - break; - }; - } - - free(fullpath); - closedir(dir); - return list; -} - diff --git a/src/output.c b/src/output.c index 64971fa..53a0ff3 100644 --- a/src/output.c +++ b/src/output.c @@ -11,7 +11,7 @@ #include #include "output.h" -#include "list_management.h" +#include "data_management.h" #include "options.h" -- cgit v1.2.3-70-g09d2