diff options
Diffstat (limited to 'src/output.c')
| -rw-r--r-- | src/output.c | 173 |
1 files changed, 139 insertions, 34 deletions
diff --git a/src/output.c b/src/output.c index 53a0ff3..254d73f 100644 --- a/src/output.c +++ b/src/output.c @@ -5,6 +5,7 @@ * vim:ts=4:sw=4:expandtab */ +#include <string.h> #include <unistd.h> #include <ctype.h> #include <time.h> @@ -16,6 +17,20 @@ +/* === DEFINITIONS === */ + +#define out_vsep fputc('|', stdout) + +#define out_print_newline() fputc('\n', stdout) +#define out_print_fname(x) printf(" %s ", x->fname) + +void out_print_size(struct list_node *ptr); +void out_print_time(time_t tv); +void out_print_time_by_option(struct list_node *ptr); + + +/* === IMPLEMENTATION === */ + inline int fputc_all_cols(char c, FILE *fdout) { struct winsize terminal; ioctl(STDOUT_FILENO, TIOCGWINSZ, &terminal); @@ -45,13 +60,57 @@ inline int fputc_width_x(char c, size_t x, FILE *fdout) { } + +/* === FORMATTING RELATED FUNCTIONS === */ +inline void out_print_size(struct list_node *ptr) { + printf(" %8ld %2s ", ((ptr->ln_stat.st_size>=1024) ? (ptr->ln_stat.st_size/1024) : ptr->ln_stat.st_size), + ((ptr->ln_stat.st_size >= 1024) ? "kB" : "")); +} + +inline void out_print_time(time_t tv) { + struct tm *tm = NULL; + char timestamp[128]; + + tm = localtime(&tv); + 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); + } +} + +inline void out_print_time_by_option(struct list_node *ptr) { + time_t time_value = 0; + + switch (option_time_field) { + case 'm': + time_value = ptr->ln_stat.st_mtim.tv_sec; + break; + case 'a': + time_value = ptr->ln_stat.st_atim.tv_sec; + break; + case 'c': + time_value = ptr->ln_stat.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); + option_time_field = 'm'; + time_value = ptr->ln_stat.st_mtim.tv_sec; + break; + }; + out_print_time(time_value); +} +/* === END OF FORMATTING FUNCTIONS === */ + + + /* 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; - time_t time_value = 0; - char timestamp[128]; size_t total_size = 0; if (list == NULL) return; @@ -65,38 +124,11 @@ void print_list(struct list_head *list) { ptr = lh->first; while (ptr != NULL) { - time_value = 0; - - switch (option_time_field) { - case 'm': - time_value = ptr->ln_stat.st_mtim.tv_sec; - break; - case 'a': - time_value = ptr->ln_stat.st_atim.tv_sec; - break; - case 'c': - time_value = ptr->ln_stat.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); - option_time_field = 'm'; - time_value = ptr->ln_stat.st_mtim.tv_sec; - break; - }; - - printf(" %8ld %2s ", ((ptr->ln_stat.st_size>=1024) ? (ptr->ln_stat.st_size/1024) : ptr->ln_stat.st_size), - ((ptr->ln_stat.st_size >= 1024) ? "kB" : "")); + out_print_size(ptr); + out_print_time_by_option(ptr); + out_print_fname(ptr); + out_print_newline(); - tm = localtime(&time_value); - 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); /* Linux: Neither man stat(2) nor stat(3type) declare why struct stat field st_size * would get a negative value assigned. The type off_t masks __off_t or __off64_t * which themselves mask bits/types.h __SLONGWORD_TYPE on x86_64 that's long int. @@ -113,3 +145,76 @@ void print_list(struct list_head *list) { if (lh != list) destroy_list(lh); } + +/* For now with a large walk around common format strings and prevention of attack vectors. + * n - name + * s - file size + * + * Time related + * t - timestamp set by option_time_field + * A - timestamp from atim.tv_sec + * C - timestamp from ctim.tv_sec + * M - timestamp from mtim.tv_sec + */ +void print_list_formatted(const char *format, struct list_head *list) { + struct list_head *lh = list; + struct list_node *ptr; + size_t format_len = 0, i = 0; + + if (format == NULL || format[0] == '\0') { + LOGERR("ERROR: No format string given"); + return; + } + + if (list == NULL || list->first == NULL) { + LOGERR("ERROR: No data to print.\n"); + return; + } + + if (option_sort_reverse_order) { + lh = create_list_sort_reversed(list); + /* be tolerant */ + if (lh == NULL) { + lh = list; + } + } + + /* Note: the maximum length needs to be adjusted if the strings + * shall contain more complicated settings */ + format_len = strnlen(format, 80); + + ptr = lh->first; + while (ptr != NULL) { + for (i=0; i < format_len; i++) { + switch (format[i]) { + case 'n': + out_print_fname(ptr); + break; + case 's': + out_print_size(ptr); + break; + case 't': + out_print_time_by_option(ptr); + break; + case 'A': + out_print_time(ptr->ln_stat.st_atim.tv_sec); + break; + case 'C': + out_print_time(ptr->ln_stat.st_ctim.tv_sec); + break; + case 'M': + out_print_time(ptr->ln_stat.st_mtim.tv_sec); + break; + case ' ': /* just ignore this without warning */ + break; + default: + LOGERR("WARNING: Invalid character 0x%02X ignoring it\n", format[i]); + break; + }; + } + out_print_newline(); + ptr = ptr->next; + } + if (lh != list) destroy_list(lh); +} + |
