Fix the user summary.
authorAndre Noll <maan@systemlinux.org>
Sat, 1 Nov 2008 15:21:30 +0000 (16:21 +0100)
committerAndre Noll <maan@systemlinux.org>
Sat, 1 Nov 2008 15:21:30 +0000 (16:21 +0100)
This broke recently.

Also, rename --sort to --list-sort because there's also the
--user-summary-sort option.

select.c
select.ggo

index 577ff72..a58ec39 100644 (file)
--- a/select.c
+++ b/select.c
@@ -89,6 +89,13 @@ struct global_summary_info {
        int osl_errno;
 };
 
+struct user_summary_info {
+       struct user_info *ui;
+       int ret;
+       int osl_errno;
+};
+
+
 enum user_stats_flags {
        USF_PRINT_DIRNAME = 1,
        USF_PRINT_BYTES = 2,
@@ -231,6 +238,18 @@ static int get_num_files_of_row(struct osl_row *row, uint64_t *num_files)
        return 1;
 }
 
+static int get_num_user_files(struct osl_row *row, struct user_info *ui,
+               uint64_t *num_files)
+{
+       struct osl_object obj;
+       int ret = osl(osl_get_object(ui->table, row, UT_FILES, &obj));
+
+       if (ret < 0)
+               return ret;
+       *num_files = *(uint64_t *)obj.data;
+       return 1;
+}
+
 static int get_num_bytes_of_row(struct osl_row *row, uint64_t *num_bytes)
 {
        struct osl_object obj;
@@ -241,6 +260,18 @@ static int get_num_bytes_of_row(struct osl_row *row, uint64_t *num_bytes)
        return 1;
 }
 
+static int get_num_user_bytes(struct osl_row *row, struct user_info *ui,
+               uint64_t *num_bytes)
+{
+       struct osl_object obj;
+       int ret = osl(osl_get_object(ui->table, row, UT_BYTES, &obj));
+
+       if (ret < 0)
+               return ret;
+       *num_bytes = *(uint64_t *)obj.data;
+       return 1;
+}
+
 
 static int user_stats_loop_function(struct osl_row *row, void *data)
 {
@@ -399,7 +430,37 @@ static int print_global_summary(struct format_info *fi)
        return ret;
 }
 
-static int print_user_summary_line(struct user_info *ui, __a_unused void *data)
+static int user_summary_loop_function(struct osl_row *row, void *data)
+{
+       struct user_summary_info *usi = data;
+       uint64_t num;
+       int ret;
+
+       ret = get_num_user_files(row, usi->ui, &num);
+       if (ret < 0)
+               goto err;
+       usi->ui->files += num;
+       ret = get_num_user_bytes(row, usi->ui, &num);
+       if (ret < 0)
+               goto err;
+       usi->ui->bytes += num;
+       usi->ui->dirs++;
+       return 1;
+err:
+       usi->ret = ret;
+       usi->osl_errno = (ret == -E_OSL)? osl_errno : 0;
+       return -1;
+}
+
+static int compute_user_summary(struct user_info *ui, __a_unused void *data)
+{
+       struct user_summary_info usi = {.ui = ui};
+
+       return adu_loop_reverse(ui->table, UT_BYTES, &usi, user_summary_loop_function,
+               &usi.ret, &usi.osl_errno);
+}
+
+static int print_user_summary_line(struct user_info *ui, void *data)
 {
        struct format_info *fi = data;
        union atom_value values[] = {
@@ -407,12 +468,14 @@ static int print_user_summary_line(struct user_info *ui, __a_unused void *data)
                        ui->pw_name : "?"},
                [usa_uid] = {.num_value = (long long unsigned)ui->uid},
                [usa_dirs] = {.num_value = (long long unsigned)ui->dirs},
-               [usa_files] = {.num_value =  (long long unsigned)ui->files},
+               [usa_files] = {.num_value = (long long unsigned)ui->files},
                [usa_size] = {.num_value =  (long long unsigned)ui->bytes}
        };
-       char *buf = format_items(fi, values);
-       int ret = output("%s", buf);
+       char *buf;
+       int ret;
 
+       buf = format_items(fi, values);
+       ret = output("%s", buf);
        free(buf);
        return ret;
 }
@@ -474,6 +537,9 @@ static int print_user_summary(struct format_info *fi)
                if (ret < 0)
                        return ret;
        }
+       int ret = for_each_admissible_user(compute_user_summary, fi);
+       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);
 }
@@ -600,7 +666,7 @@ static int print_global_list(struct format_info *fi)
                if (ret < 0)
                        return ret;
        }
-       if (select_conf.sort_arg == sort_arg_files)
+       if (select_conf.list_sort_arg == list_sort_arg_file_count)
                sort_column = DT_FILES;
        return adu_loop_reverse(dir_table, sort_column, &gli,
                global_list_loop_function, &gli.ret, &gli.osl_errno);
index b0b1daa..0e98f4a 100644 (file)
@@ -47,15 +47,16 @@ details="
        user_summary Print totals for each admissible uid.
 "
 
-option "sort" s
-#~~~~~~~~~~~~~~~
-"how to sort the output"
+option "list-sort" s
+#~~~~~~~~~~~~~~~~~~~
+"how to sort the user list or the global list"
 enum typestr="<key>"
-values="sizes","files","unsorted"
-default="sizes"
+values="size","file_count"
+default="size"
 optional
 details="
-       Sort by file size, file count or unsorted.
+       This option is ignored if select-mode is neither \"user_list\", nor
+       \"global_list\".
 "
 
 option "output" o