diff options
Diffstat (limited to 'src/dir_monitor.c')
| -rw-r--r-- | src/dir_monitor.c | 331 |
1 files changed, 3 insertions, 328 deletions
diff --git a/src/dir_monitor.c b/src/dir_monitor.c index 5323ce8..b2257ce 100644 --- a/src/dir_monitor.c +++ b/src/dir_monitor.c @@ -10,254 +10,22 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> -#include <ctype.h> -#include <getopt.h> -#include <stdint.h> -#include <stdbool.h> #include <errno.h> -#include <sys/types.h> #include <dirent.h> #include <sys/stat.h> -#include <time.h> -#include <sys/ioctl.h> - -#define LOGERR(...) {fprintf(stderr, "[%s:%d] %s: ", __FILE__, __LINE__, __func__); fprintf(stderr, __VA_ARGS__);} - -#ifdef DEBUGBUILD -#define DBGTRC(...) LOGERR(__VA_ARGS__) -#else -#define DBGTRC(...) -#endif +#include "output.h" +#include "list_management.h" +#include "options.h" /* === DEFINITIONS === */ -#define PATH_SEP '/' - -enum esort_type { SORT_BY_SIZE, SORT_BY_TIME }; -struct list_node { - struct list_node *next; - size_t fsize; - char fname[256]; - time_t ftime; /* can be creation, access or modification */ -}; - -struct list_head { - struct list_node *first; -}; -struct list_node *create_node(char *fname, size_t fsize, time_t ftime); -struct list_head *create_list_sort_reversed(struct list_head *list); -void destroy_list(struct list_head *list); -int fputc_all_cols(char c, FILE *fdout); -int fputc_width_x(char c, size_t x, FILE *fdout); 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); -int parse_arguments(int argc, char **argv); -void print_list(struct list_head *list); -void set_option(const char *option_name, char *option_argument); -void usage(char *executable); - - - -/* === GLOBAL VARIABLES === */ -struct option long_options[] = { - { "reverse-sort", no_argument, 0, 0 }, - { "show-hidden-entries", no_argument, 0, 0 }, - { "sort-by", required_argument, 0, 0 }, - { "long-timestamp", no_argument, 0, 0 }, - { 0, 0, 0, 0 } -}; -bool option_sort_reverse_order = false; -enum esort_type option_sort_type = SORT_BY_SIZE; -bool option_show_hidden_entries = false; -bool option_timestamp_long = false; /* === IMPLEMENTATION === */ -inline struct list_node *create_node(char *fname, size_t fsize, time_t ftime) { - struct list_node *node = NULL; - - if (fname == NULL || fname[0] == '\0') { - LOGERR("ERROR: No valid filename 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; - node->fsize = fsize; - node->ftime = ftime; - strncpy(node->fname, fname, 256); - 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); -} - - -inline int fputc_all_cols(char c, FILE *fdout) { - struct winsize terminal; - ioctl(STDOUT_FILENO, TIOCGWINSZ, &terminal); - return fputc_width_x(c, ((terminal.ws_col == 0) ? 72 : terminal.ws_col), fdout); -} - - -/* Not the most performant way, but during output the time critical tasks are already done. */ -inline int fputc_width_x(char c, size_t x, FILE *fdout) { - size_t i=0; - - if (fdout == NULL) { - LOGERR("ERROR: No output stream given.\n"); - return EOF; - } - - if ( ! isprint(c) ) { c = '?'; } - - for (i=0; i<x; i++) { - if (fputc(c, fdout) == EOF) { - LOGERR("ERROR: Failed to write char 0x%02X to stream %d\n", c, fdout->_fileno); - return EOF; - } - } - - return 1; -} - -/* dirty... */ -#define INSERT_BY_NUMERIC_FIELD(list, node, field) \ -{ struct list_node *ptr = NULL; \ - if (node->field > list->first->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->field > ptr->next->field) { \ - node->next = ptr->next; ptr->next = node; \ - return 0; } \ - ptr = ptr->next; \ - } \ -} - - -/* TODO: later when, other parameters are actively used move the action to a template */ -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, fsize); - 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; - } - INSERT_BY_NUMERIC_FIELD(list, node, ftime); - return -3; -} -#undef INSERT_BY_NUMERIC_FIELD - -/* The most simple default output, formatted output is planned */ -void print_list(struct list_head *list) { - struct list_head *lh = list; - struct list_node *ptr; - struct tm *tm = NULL; - char timestamp[128]; - size_t total_size = 0; - - if (list == NULL) return; - if (option_sort_reverse_order) { - lh = create_list_sort_reversed(list); - /* be tolerant */ - if (lh == NULL) { - lh = list; - } - } - - ptr = lh->first; - while (ptr != NULL) { - printf(" %8lu %2s ", ((ptr->fsize>=1024) ? (ptr->fsize/1024) : ptr->fsize), - ((ptr->fsize >= 1024) ? "kB" : "")); - - tm = localtime(&ptr->ftime); - if (option_timestamp_long) { - strftime(timestamp, sizeof(timestamp), "%Y%m%d %H:%M:%S %Z", tm); - printf(" %20s ", timestamp); - } else { - strftime(timestamp, sizeof(timestamp), "%H:%M:%S", tm); - printf(" %8s ", timestamp); - } - printf(" %s\n", ptr->fname); - total_size += ptr->fsize; - ptr = ptr->next; - } - fputc_all_cols('=', stdout); - printf("\nTotal size: %lu %s\n", ((total_size>1024) ? total_size/1024 : total_size), - ((total_size >= 1024) ? "kB" : "")); - - if (lh != list) destroy_list(lh); -} - - - -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->fsize, ptr->ftime); - 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. @@ -339,99 +107,6 @@ struct list_head *get_data_from_directory(char *path) { } -void set_option(const char *option_name, char *option_argument) { - - DBGTRC("DEBUG: called with option_name '%s' and option_argument '%s'\n", - option_name, option_argument); - - if (option_name == NULL) - return; - - /* options WITHOUT arguments */ - if (strcmp(option_name, "show-hidden-entries") == 0) { - option_show_hidden_entries = true; - return; - } - - if (strcmp(option_name, "long-timestamp") == 0) { - option_timestamp_long = true; - return; - } - - if (strcmp("reverse-sort", option_name) == 0) { - option_sort_reverse_order = true; - return; - } - - /* options WITH arguments */ - if (option_argument == NULL || option_argument[0] == '\0') { - LOGERR("ERROR: option_name %s with missing option_argument\n", - option_name); - return; - } - - if (strcmp(option_name, "sort-by") == 0) { - if (strncmp("size", option_argument, 4) == 0) { - option_sort_type = SORT_BY_SIZE; - } else if (strncmp("time", option_argument, 4) == 0) { - option_sort_type = SORT_BY_TIME; - } else { - LOGERR("WARNING: '%s' is an invalig argument for %s\n", - option_argument, option_name); - } - return; - } - - LOGERR("ERROR: Option '%s' not recognized\n.", option_name); -} - -int parse_arguments(int argc, char **argv) { - int c = 0, index; - - while(1) { - index = 0; - c = getopt_long(argc, argv, "tv", long_options, &index); - - if (c == -1) { - break; - } - - switch (c) { - case 0: - set_option(long_options[index].name, optarg); - break; - case 't': - option_timestamp_long = true; - break; - case 'v': - option_show_hidden_entries = true; - break; - case '?': - break; - default: - LOGERR("ERROR: unrecognized option 0x%02X '%c'\n", c, c); - break; - } - } - - return optind; -} - - -void usage(char *executable) { - fprintf(stderr, "Call: %s OPTIONS path_to_open\n", executable); - fprintf(stderr, "\nOPTIONS are\n"); - /* long name, short name, optional argument, explanation */ - fprintf(stderr, " %-25s %2s %10s %s\n", "--long-timestamp", "-t", "", - "Print timestamp in long form yyyymmdd HH:MM:SS ZONE"); - fprintf(stderr, " %-25s %2s %10s %s\n", "--reverse-sort", "", "", - "Sort reversed"); - fprintf(stderr, " %-25s %2s %10s %s\n", "--show-hidden-entries", "-v", "", - "Show hidden entries in the directory"); - fprintf(stderr, " %-25s %2s %10s %s\n", "--sort-by", "", "size|time", - "Sort either by time or size"); -} - int main(int argc, char **argv) { struct list_head *list = NULL; int path_index = 1; |
