Fix the global summary.
[adu.git] / select.c
index 7b3338376cd977cf316d639377279be15fa11faa..577ff724bc211eb06ac787fcef82f590dd7d9c43 100644 (file)
--- a/select.c
+++ b/select.c
 #include "error.h"
 #include "portable_io.h"
 
-/** Global dir count. */
-static uint64_t num_dirs;
-/** Global files count. */
-static uint64_t num_files;
-/** Global bytes count. */
-static uint64_t num_bytes;
-
-
 /** The decimal representation of an uint64_t never exceeds that size. */
 #define FORMATED_VALUE_SIZE 25
 
@@ -86,6 +78,17 @@ struct global_list_info {
        struct format_info *fi;
 };
 
+struct global_summary_info {
+       /** Global dir count. */
+       uint64_t num_dirs;
+       /** Global files count. */
+       uint64_t num_files;
+       /** Global bytes count. */
+       uint64_t num_bytes;
+       int ret;
+       int osl_errno;
+};
+
 enum user_stats_flags {
        USF_PRINT_DIRNAME = 1,
        USF_PRINT_BYTES = 2,
@@ -218,11 +221,32 @@ static int get_dir_name_of_row(struct osl_row *dir_table_row, char **name)
        return get_dir_name_by_number((uint64_t *)obj.data, name);
 }
 
+static int get_num_files_of_row(struct osl_row *row, uint64_t *num_files)
+{
+       struct osl_object obj;
+       int ret = osl(osl_get_object(dir_table, row, DT_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;
+       int ret = osl(osl_get_object(dir_table, row, DT_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)
 {
        struct user_stats_info *usi = data;
        struct osl_object obj;
-       int ret, summary = usi->flags & GSF_COMPUTE_SUMMARY;
+       int ret, summary = usi->flags & USF_COMPUTE_SUMMARY;
        char formated_value[FORMATED_VALUE_SIZE];
 
        check_signals();
@@ -322,18 +346,48 @@ static int adu_loop_reverse(struct osl_table *t, unsigned col_num, void *private
        return check_loop_return(ret, *loop_ret, *loop_osl_errno);
 }
 
+static int global_summary_loop_function(struct osl_row *row, void *data)
+{
+       struct global_summary_info *gsi = data;
+       int ret;
+       uint64_t num;
+
+       ret = get_num_files_of_row(row, &num);
+       if (ret < 0)
+               goto err;
+       gsi->num_files += num;
+
+       ret = get_num_bytes_of_row(row, &num);
+       if (ret < 0)
+               goto err;
+       gsi->num_bytes += num;
+       gsi->num_dirs++;
+       return 1;
+err:
+       gsi->ret = ret;
+       gsi->osl_errno = (ret == -E_OSL)? osl_errno : 0;
+       return -1;
+}
+
 static int print_global_summary(struct format_info *fi)
 {
        int ret;
        char *buf;
+       struct global_summary_info gsi = {.num_dirs = 0};
+
        union atom_value values[] = {
-               [gsa_dirs] = {.num_value = (long long unsigned)num_dirs},
-               [gsa_files] = {.num_value =  (long long unsigned)num_files},
-               [gsa_size] = {.num_value =  (long long unsigned)num_bytes}
+               [gsa_dirs] = {.num_value = 0ULL},
+               [gsa_files] = {.num_value =  0ULL},
+               [gsa_size] = {.num_value =  0ULL}
        };
 
-       if (select_conf.no_global_summary_given)
-               return 1;
+       ret = adu_loop_reverse(dir_table, DT_BYTES, &gsi,
+               global_summary_loop_function, &gsi.ret, &gsi.osl_errno);
+       if (ret < 0)
+               return ret;
+       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)
@@ -415,8 +469,6 @@ static int (*summary_comparators[])(const void *, const void *) = {
 
 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)
@@ -489,26 +541,6 @@ static int print_user_lists(void)
        return for_each_admissible_user(print_user_list, NULL);
 }
 
-static int get_num_files_of_row(struct osl_row *row, uint64_t *num_files)
-{
-       struct osl_object obj;
-       int ret = osl(osl_get_object(dir_table, row, DT_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;
-       int ret = osl(osl_get_object(dir_table, row, DT_BYTES, &obj));
-       if (ret < 0)
-               return ret;
-       *num_bytes = *(uint64_t *)obj.data;
-       return 1;
-}
-
 static int global_list_loop_function(struct osl_row *row, void *data)
 {
        struct global_list_info *gli = data;