diff options
| author | Thorsten Töpper <atsutane@freethoughts.de> | 2025-08-02 00:02:57 +0200 |
|---|---|---|
| committer | Thorsten Töpper <atsutane@freethoughts.de> | 2025-08-02 00:02:57 +0200 |
| commit | 31aaaca68b15fab61bf8a5e2b0187111fae27f46 (patch) | |
| tree | cf79e58e336d34d2feba574e2cc0906b84e8ce32 /src/output.c | |
| parent | d4aa1654b0136d226cf23135888077468c8e8451 (diff) | |
| download | dir_monitor-31aaaca68b15fab61bf8a5e2b0187111fae27f46.tar.gz dir_monitor-31aaaca68b15fab61bf8a5e2b0187111fae27f46.tar.bz2 | |
symlinks: destination can be resolved
Diffstat (limited to 'src/output.c')
| -rw-r--r-- | src/output.c | 140 |
1 files changed, 108 insertions, 32 deletions
diff --git a/src/output.c b/src/output.c index f94e3c9..a928140 100644 --- a/src/output.c +++ b/src/output.c @@ -37,22 +37,26 @@ #define out_vsep() fputc(box_vsep, stdout) #define out_print_newline() fputc('\n', stdout) -#define out_print_fname(x) printf(" %s ", x->fname) -#define out_print_uid(x) printf(" %4u ", x->ln_stat.st_gid) -#define out_print_gid(x) printf(" %4u ", x->ln_stat.st_uid) +void out_print_fname(struct list_node *ptr, size_t longest_fname); +void out_print_gid(struct list_node *ptr); void out_print_group_name(struct list_node *ptr); void out_print_permissions(struct list_node *ptr); void out_print_size(struct list_node *ptr); +void out_print_symlink(struct list_node *ptr, size_t longest_fname); void out_print_time(time_t tv); void out_print_time_by_option(struct list_node *ptr); void out_print_type(struct list_node *ptr); +void out_print_uid(struct list_node *ptr); void out_print_user_name(struct list_node *ptr); -void out_print_format_string_header(const char *format, size_t longest_fname); +void out_print_format_string_header(const char *format, + size_t longest_fname, size_t longest_symlink); -size_t estimate_formatted_line_length(const char *format, size_t longest_fname); +size_t estimate_formatted_line_length(const char *format, + size_t longest_fname, size_t longest_symlink); size_t get_longest_filename(struct list_head *list); +size_t get_longest_symlink(struct list_head *list); char *global_sep_line = NULL; @@ -102,7 +106,7 @@ inline int fputc_width_x(char c, size_t x, FILE *fdout) { inline size_t get_longest_filename(struct list_head *list) { size_t rc = 4, tmp = 0; struct list_node *ptr = NULL; - if (list == NULL) { return 0; } + if (list == NULL) { return rc; } ptr = list->first; while (ptr != NULL) { tmp = strlen(ptr->fname); @@ -112,8 +116,66 @@ inline size_t get_longest_filename(struct list_head *list) { return rc; } +/* basic 7 due to formatted output */ +inline size_t get_longest_symlink(struct list_head *list) { + size_t rc = 7, tmp = 0; + struct list_node *ptr = NULL; + if (list == NULL) { return rc; } + ptr = list->first; + while(ptr != NULL) { + if (ptr->symlink_target != NULL) { + tmp = strlen(ptr->symlink_target); + } else { tmp = 0; } + if (tmp>rc) { rc = tmp; } + ptr = ptr->next; + } + return rc; +} + /* === FORMATTING RELATED FUNCTIONS === */ + +inline void out_print_uid(struct list_node *ptr) { + printf(" %4u ", ptr->ln_stat.st_gid); + if (option_print_boxed_table) { out_vsep(); } +} + + +inline void out_print_gid(struct list_node *ptr) { + printf(" %4u ", ptr->ln_stat.st_uid); + if (option_print_boxed_table) { out_vsep(); } +} + + +inline void out_print_fname(struct list_node *ptr, size_t longest_fname) { + size_t i = 0; + printf(" %s ", ptr->fname); + if (option_print_boxed_table) { + for (i=0; i<(longest_fname - strlen(ptr->fname)); i++) { + fputc(' ', stdout); + } + out_vsep(); + } +} + + +inline void out_print_symlink(struct list_node *ptr, size_t longest_symlink) { + size_t i = 0, sll = 0; + if (ptr->symlink_target != NULL) { + sll = strlen(ptr->symlink_target); + printf(" %s ", ptr->symlink_target); + } else { + printf(" "); + } + if (option_print_boxed_table) { + for (i=0; i<(longest_symlink - sll); i++) { + fputc(' ', stdout); + } + out_vsep(); + } +} + + /* Be aware: getting the name via uid takes a lot of time depending on the * systems setup. local, NIS, LDAP ... * Caching happens outside the executable, minimal here for skipping funcion calls. */ @@ -152,6 +214,7 @@ inline void out_print_group_name(struct list_node *ptr) { explicit_bzero(prev_group_name, 64); memcpy(prev_group_name, group->gr_name, group_name_length); printf(" %-10s ", prev_group_name); + if (option_print_boxed_table) { out_vsep(); } } /* Reminder: resolving may take some time even with cache in libraries, @@ -191,6 +254,7 @@ inline void out_print_user_name(struct list_node *ptr) { explicit_bzero(prev_user_name, 64); memcpy(prev_user_name, pwd->pw_name, user_name_length); printf(" %-10s ", prev_user_name); + if (option_print_boxed_table) { out_vsep(); } } inline void out_print_size(struct list_node *ptr) { @@ -208,6 +272,7 @@ inline void out_print_size(struct list_node *ptr) { } } printf(" %8ld %3s ", tmp, unit); + if (option_print_boxed_table) { out_vsep(); } } inline void out_print_time(time_t tv) { @@ -222,6 +287,7 @@ inline void out_print_time(time_t tv) { strftime(timestamp, sizeof(timestamp), "%H:%M:%S", tm); printf(" %-8s ", timestamp); } + if (option_print_boxed_table) { out_vsep(); } } inline void out_print_time_by_option(struct list_node *ptr) { @@ -282,6 +348,7 @@ inline void out_print_type(struct list_node *ptr) { } /* The ones longer than 12 characters are rare. */ printf(" %-12s ", entry); + if (option_print_boxed_table) { out_vsep(); } } inline void out_print_permissions(struct list_node *ptr) { @@ -327,11 +394,14 @@ inline void out_print_permissions(struct list_node *ptr) { mode |= S_ISUID; } printf(" %4o ", mode); + if (option_print_boxed_table) { out_vsep(); } } +/* === END OF FORMATTING FUNCTIONS === */ + /* Interpret the format string and based on it generate a size which will be * able to store everything including visual additions. Use strlen later. */ -inline size_t estimate_formatted_line_length(const char *format, size_t longest_fname) { +inline size_t estimate_formatted_line_length(const char *format, size_t longest_fname, size_t longest_symlink) { size_t rc = 0, i=0, format_len=0; static int login_name_max = -1; if (login_name_max < 0) { @@ -347,6 +417,7 @@ inline size_t estimate_formatted_line_length(const char *format, size_t longest_ format_len = strnlen(format, DM_OUT_FORMAT_MAX_LEN); for (i=0; i<format_len; i++) { switch (format[i]) { + case 'l': if (option_resolve_symlinks) { rc += longest_symlink+7; } break; case 'n': rc += longest_fname+4; break; case 'G': case 'U': rc += ((unsigned int)login_name_max); break; @@ -361,7 +432,9 @@ inline size_t estimate_formatted_line_length(const char *format, size_t longest_ return rc; } -inline void out_print_format_string_header(const char *format, size_t longest_fname) { + +inline void out_print_format_string_header(const char *format, + size_t longest_fname, size_t longest_symlink) { size_t i=0, j=0, k=0, format_len=0, est_length=0, tmp = 0; char *header = NULL, *sep_line = NULL; char *pos = NULL; @@ -371,7 +444,7 @@ inline void out_print_format_string_header(const char *format, size_t longest_fn format_len = strnlen(format, DM_OUT_FORMAT_MAX_LEN); - est_length = estimate_formatted_line_length(format, longest_fname); + est_length = estimate_formatted_line_length(format, longest_fname, longest_symlink); if ((header=calloc(est_length+1, sizeof(char))) == NULL) { LOGERR("ERROR: Failed to allocate memory for header\n"); return; @@ -401,7 +474,7 @@ inline void out_print_format_string_header(const char *format, size_t longest_fn for (i=0; (i < format_len) && (strlen(header) < 4064); i++) { switch (format[i]) { case 'n': - sprintf(pos, " FILE "); + sprintf(pos, " %-4s ", "FILE"); if (option_print_boxed_table) { tmp = strlen(pos); for (k=0; k<longest_fname-4; k++) { @@ -410,6 +483,18 @@ inline void out_print_format_string_header(const char *format, size_t longest_fn } LOCAL_EXTEND_SEP_LINE(); break; + case 'l': + if (option_resolve_symlinks) { + sprintf(pos, " %-7s ", "SYMLINK"); + if (option_print_boxed_table) { + tmp = strlen(pos); + for (k=0; k<longest_symlink-7; k++) { + pos[tmp+k] = ' '; + } + } + LOCAL_EXTEND_SEP_LINE(); + } + break; case 's': sprintf(pos, " %12s ", "SIZE "); LOCAL_EXTEND_SEP_LINE(); @@ -500,8 +585,6 @@ inline void out_print_format_string_header(const char *format, size_t longest_fn out_print_newline(); #undef LOCAL_EXTEND_SEP_LINE } -/* === END OF FORMATTING FUNCTIONS === */ - /* The most simple default output. */ @@ -519,6 +602,7 @@ void print_list(struct list_head *list) { * G - group name * g - group id * p - permissions and special bits + * l - symlink * * Time related * t - timestamp set by option_time_field @@ -529,8 +613,8 @@ void print_list(struct list_head *list) { 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, j = 0; - size_t longest_fname = 0; + size_t format_len = 0, i = 0; + size_t longest_fname = 0, longest_symlink = 0; size_t total_size = 0; if (format == NULL || format[0] == '\0') { @@ -558,8 +642,12 @@ void print_list_formatted(const char *format, struct list_head *list) { longest_fname = get_longest_filename(list); + if (option_resolve_symlinks) { + longest_symlink = get_longest_symlink(list); + } + if (option_print_header) { - out_print_format_string_header(format, longest_fname); + out_print_format_string_header(format, longest_fname, longest_symlink); } ptr = lh->first; @@ -568,57 +656,45 @@ void print_list_formatted(const char *format, struct list_head *list) { for (i=0; i < format_len; i++) { switch (format[i]) { case 'n': - out_print_fname(ptr); - if (option_print_boxed_table) { - for (j=0; j<(longest_fname - strlen(ptr->fname)); j++) { - fputc(' ', stdout); - } - out_vsep(); + out_print_fname(ptr, longest_fname); + break; + case 'l': + if (option_resolve_symlinks) { + out_print_symlink(ptr, longest_symlink); } break; case 's': out_print_size(ptr); - if (option_print_boxed_table) { out_vsep(); } break; case 't': out_print_time_by_option(ptr); - if (option_print_boxed_table) { out_vsep(); } break; case 'A': out_print_time(ptr->ln_stat.st_atim.tv_sec); - if (option_print_boxed_table) { out_vsep(); } break; case 'C': out_print_time(ptr->ln_stat.st_ctim.tv_sec); - if (option_print_boxed_table) { out_vsep(); } break; case 'M': out_print_time(ptr->ln_stat.st_mtim.tv_sec); - if (option_print_boxed_table) { out_vsep(); } break; case 'T': out_print_type(ptr); - if (option_print_boxed_table) { out_vsep(); } break; case 'u': out_print_uid(ptr); - if (option_print_boxed_table) { out_vsep(); } break; case 'g': out_print_gid(ptr); - if (option_print_boxed_table) { out_vsep(); } break; case 'U': out_print_user_name(ptr); - if (option_print_boxed_table) { out_vsep(); } break; case 'G': out_print_group_name(ptr); - if (option_print_boxed_table) { out_vsep(); } break; case 'p': out_print_permissions(ptr); - if (option_print_boxed_table) { out_vsep(); } break; case ' ': /* just ignore this without warning */ break; |
