- usi.flags = USF_PRINT_DIRNAME | USF_PRINT_BYTES | USF_COMPUTE_SUMMARY;
- printf("%s (uid %u), by size%s:\n",
- ui->pw_name? ui->pw_name : "?", (unsigned)ui->uid,
- size_unit_buf);
- ret = adu_loop_reverse(ui->table, UT_BYTES, &usi, user_stats_loop_function,
- &usi.ret, &usi.osl_errno);
- if (ret < 0)
- return ret;
- printf("\n%s (uid %u), by file count%s:\n",
- ui->pw_name? ui->pw_name : "?", (unsigned)ui->uid,
- count_unit_buf);
- usi.count = conf.limit_arg,
- usi.flags = USF_PRINT_DIRNAME | USF_PRINT_FILES;
- ret = adu_loop_reverse(ui->table, UT_FILES, &usi, user_stats_loop_function,
- &usi.ret, &usi.osl_errno);
- if (ret < 0)
- return ret;
- printf("\n");
+static int dir_count_comp(const void *a, const void *b)
+{
+ return NUM_COMPARE(((struct user_info *)a)->dirs,
+ ((struct user_info *)b)->dirs);
+}
+
+static int file_count_comp(const void *a, const void *b)
+{
+ return NUM_COMPARE(((struct user_info *)a)->files,
+ ((struct user_info *)b)->files);
+}
+
+static int size_comp(const void *a, const void *b)
+{
+ return NUM_COMPARE(((struct user_info *)a)->bytes,
+ ((struct user_info *)b)->bytes);
+}
+
+/*
+ * The comparators for sorting the user summary.
+ *
+ * This is an array of pointers to functions taking two constant void *
+ * pointers and returning an int.
+ */
+static int (*summary_comparators[])(const void *, const void *) = {
+ [user_summary_sort_arg_name] = name_comp,
+ [user_summary_sort_arg_uid] = uid_comp,
+ [user_summary_sort_arg_dir_count] = dir_count_comp,
+ [user_summary_sort_arg_file_count] = file_count_comp,
+ [user_summary_sort_arg_size] = size_comp,
+};
+
+static int print_user_summary(struct format_info *fi)
+{
+ if (select_conf.no_user_summary_given)
+ return 1;
+ if (!select_conf.no_headers_given) {
+ int ret = output("User summary\n");
+ if (ret < 0)
+ return ret;
+ }
+ sort_hash_table(summary_comparators[select_conf.user_summary_sort_arg]);
+ return for_each_admissible_user(print_user_summary_line, fi);
+}
+
+static int print_user_list(struct user_info *ui, __a_unused void *data)
+{
+ int ret;
+ struct user_stats_info usi;
+ enum enum_user_list ula = select_conf.user_list_arg;
+ int print_size_list = (ula == user_list_arg_size
+ || ula == user_list_arg_both);
+
+ if (print_size_list) {
+ usi.count = select_conf.limit_arg;
+ usi.ui = ui;
+ usi.flags = USF_PRINT_DIRNAME | USF_PRINT_BYTES | USF_COMPUTE_SUMMARY;
+ if (!select_conf.no_headers_given) {
+ ret = output("%s (uid %u), by size%s:\n",
+ ui->pw_name? ui->pw_name : "?", (unsigned)ui->uid,
+ size_unit_buf);
+ if (ret < 0)
+ return ret;
+ }
+ ret = adu_loop_reverse(ui->table, UT_BYTES, &usi, user_stats_loop_function,
+ &usi.ret, &usi.osl_errno);
+ if (ret < 0)
+ return ret;
+ ret = output("\n");
+ if (ret < 0)
+ return ret;
+ }
+ if (ula == user_list_arg_file_count || ula == user_list_arg_both) {
+ if (!select_conf.no_headers_given) {
+ ret = output("%s (uid %u), by file count%s:\n",
+ ui->pw_name? ui->pw_name : "?", (unsigned)ui->uid,
+ count_unit_buf);
+ if (ret < 0)
+ return ret;
+ }
+ usi.count = select_conf.limit_arg,
+ usi.ui = ui;
+ usi.flags = USF_PRINT_DIRNAME | USF_PRINT_FILES;
+ ret = adu_loop_reverse(ui->table, UT_FILES, &usi, user_stats_loop_function,
+ &usi.ret, &usi.osl_errno);
+ if (ret < 0)
+ return ret;
+ ret = output("\n");
+ if (ret < 0)
+ return ret;
+ }
+ if (ula == user_list_arg_none && !select_conf.no_user_summary_given) {
+ usi.count = select_conf.limit_arg;
+ usi.ui = ui;
+ usi.flags = USF_COMPUTE_SUMMARY;
+ ret = adu_loop_reverse(ui->table, UT_FILES, &usi, user_stats_loop_function,
+ &usi.ret, &usi.osl_errno);
+ if (ret < 0)
+ return ret;
+ }