From e155bb7cba1be31490cb42228f5ae3598a728b0d Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 9 Nov 2008 20:37:09 +0100 Subject: [PATCH] Make the header line configurable. This replaces the --no-header flag by --header string option. The argument is the header of the summary/list. This was not a straight-forward task because the headers for the user lists contain the uid and the user name. So introduce another set of format string directives to still allow this. --- select.c | 111 ++++++++++++++++++++++++++++++++++++----------------- select.ggo | 33 ++++++++++------ 2 files changed, 98 insertions(+), 46 deletions(-) diff --git a/select.c b/select.c index 7537f4c..d555f1c 100644 --- a/select.c +++ b/select.c @@ -67,6 +67,21 @@ struct atom user_list_atoms[] = { enum user_list_atoms {USER_LIST_ATOMS}; #undef ATOM +/* user list header */ +#define USER_LIST_HEADER_ATOMS \ + ATOM(pw_name, STRING) \ + ATOM(uid, ID) + +#define ATOM(x, y) { .name = #x, .type = AT_ ## y}, +struct atom user_list_header_atoms[] = { + USER_LIST_HEADER_ATOMS + {.name = NULL} +}; +#undef ATOM +#define ATOM(x, y) ulha_ ## x, +enum user_list_header_atoms {USER_LIST_HEADER_ATOMS}; +#undef ATOM + /* user summary */ #define USER_SUMMARY_ATOMS \ ATOM(pw_name, STRING) \ @@ -111,6 +126,11 @@ struct user_list_info { int osl_errno; }; +struct user_list_format_info { + struct format_info *fi; + struct format_info *header_fi; +}; + struct user_summary_info { struct user_info *ui; int ret; @@ -295,6 +315,8 @@ static int print_global_summary(struct format_info *fi) int ret; char *buf; struct global_summary_info gsi = {.num_dirs = 0}; + char *header = select_conf.header_given? select_conf.header_arg : + "Global summary\n"; union atom_value values[] = { [gsa_dirs] = {.num_value = 0ULL}, @@ -309,11 +331,10 @@ static int print_global_summary(struct format_info *fi) values[gsa_dirs].num_value = (long long unsigned)gsi.num_dirs; values[gsa_files].num_value = (long long unsigned)gsi.num_files; values[gsa_size].num_value = (long long unsigned)gsi.num_bytes; - if (!select_conf.no_headers_given) { - ret = output("Global summary\n"); - if (ret < 0) - return ret; - } + + ret = output("%s", header); + if (ret < 0) + return ret; buf = format_items(fi, values); ret = output("%s", buf); free(buf); @@ -414,12 +435,12 @@ static int print_user_summary(struct format_info *fi) .fi = fi, .count = select_conf.limit_arg }; + char *header = select_conf.header_given? select_conf.header_arg : + "User summary\n"; - if (!select_conf.no_headers_given) { - ret = output("User summary\n"); - if (ret < 0) - return ret; - } + ret = output("%s", header); + if (ret < 0) + return ret; ret = for_each_admissible_user(compute_user_summary, NULL); if (ret < 0) return ret; @@ -498,28 +519,47 @@ err: static int print_user_list(struct user_info *ui, void *data) { - struct format_info *fi = data; + struct user_list_format_info *ulfi = data; int ret; - enum user_table_columns sort_column = UT_BYTES; + enum user_table_columns sort_column; struct user_list_info uli = { .ui = ui, - .fi = fi, + .fi = ulfi->fi, .count = select_conf.limit_arg }; + union atom_value header_values[] = { + [ulha_uid] = {.num_value = (long long unsigned)ui->uid}, + [ulha_pw_name] = {.string_value = ui->pw_name? + ui->pw_name : "?"} + }; + char *buf = format_items(ulfi->header_fi, header_values); + ret = output("%s", buf); + free(buf); + if (ret < 0) + return ret; if (select_conf.list_sort_arg == list_sort_arg_file_count) sort_column = UT_FILES; - - if (!select_conf.no_headers_given) { - ret = output("%s (uid %u)\n", - ui->pw_name? ui->pw_name : "?", (unsigned)ui->uid); - if (ret < 0) - return ret; - } + else + sort_column = UT_BYTES; return adu_loop_reverse(ui->table, sort_column, &uli, user_list_loop_function, &uli.ret, &uli.osl_errno); } +static int print_user_lists(struct format_info *fi) +{ + struct user_list_format_info ulfi = {.fi = fi}; + char *header_fmt = select_conf.header_given? + select_conf.header_arg : "uid %(uid)(%(pw_name)):\n"; + int ret = parse_format_string(header_fmt, + user_list_header_atoms, &ulfi.header_fi); + if (ret < 0) + return ret; + ret = for_each_admissible_user(print_user_list, &ulfi); + free_format_info(ulfi.header_fi); + return ret; +} + static int global_list_loop_function(struct osl_row *row, void *data) { struct global_list_info *gli = data; @@ -570,19 +610,20 @@ err: static int print_global_list(struct format_info *fi) { int ret; - enum dir_table_columns sort_column = DT_BYTES; + enum dir_table_columns sort_column; struct global_list_info gli = { .fi = fi, .count = select_conf.limit_arg }; - - if (!select_conf.no_headers_given) { - ret = output("Global list\n"); - if (ret < 0) - return ret; - } + char *header = select_conf.header_given? + select_conf.header_arg : "Global list\n"; + ret = output("%s", header); + if (ret < 0) + return ret; if (select_conf.list_sort_arg == list_sort_arg_file_count) sort_column = DT_FILES; + else + sort_column = DT_BYTES; return adu_loop_reverse(dir_table, sort_column, &gli, global_list_loop_function, &gli.ret, &gli.osl_errno); } @@ -590,14 +631,14 @@ static int print_global_list(struct format_info *fi) static int print_statistics(struct format_info *fi) { switch (select_conf.select_mode_arg) { - case select_mode_arg_global_list: - return print_global_list(fi); - case select_mode_arg_global_summary: - return print_global_summary(fi); - case select_mode_arg_user_list: - return for_each_admissible_user(print_user_list, fi); - case select_mode_arg_user_summary: - return print_user_summary(fi); + case select_mode_arg_global_list: + return print_global_list(fi); + case select_mode_arg_global_summary: + return print_global_summary(fi); + case select_mode_arg_user_list: + return print_user_lists(fi); + case select_mode_arg_user_summary: + return print_user_summary(fi); }; ERROR_LOG("bad select mode\n"); return -ERRNO_TO_ERROR(EINVAL); diff --git a/select.ggo b/select.ggo index 914e351..f29cd2f 100644 --- a/select.ggo +++ b/select.ggo @@ -47,12 +47,22 @@ details=" except global_summary (which outputs only one single line). " -option "no-headers" - -#~~~~~~~~~~~~~~~~~~~~ -"suppress descriptions for listings/summaries" -flag off +option "header" H +#~~~~~~~~~~~~~~~~ +"use a customized header for listings/summaries" +string typestr="string" +optional details=" - This is mostly useful to feed the output of adu to scripts. + This option can be used to print any string instead of the + default header line (which depends on the selected mode). + + In user_list mode the header is a format string which allows + to include the uid and the user name in the header. See the + --format option for more details. + + It is possible to set this to the empty string to suppress + the header completely. This is mostly useful to feed the + output to scripts. " option "select-mode" m @@ -196,19 +206,20 @@ details=" together with their types, and for which modes each of them may be used. - pw_name (string): user name. Available for user_list - and user_summary + pw_name (string): user name. Available for user_list, + user_summary and for the header in user_list mode. - uid (id): user id. Available for user_list and - user_summary. + uid (id): user id. Available for user_list, + user_summary and for the header in user_list mode. - files (count): number of files. Available everywhere. + files (count): number of files. Available for all + modes. dirname (string): name of the directory. Available for user_list and global_list. size (size): total size/ directory size. Available - everywhere. + for all modes. dirs (count): number of directories. Available for user_summary and global_summary. -- 2.39.5