aboutsummaryrefslogtreecommitdiff
path: root/src/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/output.c')
-rw-r--r--src/output.c140
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;