X-Git-Url: http://git.tuebingen.mpg.de/?p=adu.git;a=blobdiff_plain;f=adu.c;h=5728a3180d7f954714d0af64be713c435feb2f5f;hp=8068d205f2274dded3074158a105243bb4de1b11;hb=ceb399292dcec3ad15f70fbda94f2a09cbd30d7b;hpb=6c043b44a1cec206f3b4f8063fb8383e66ae6d53 diff --git a/adu.c b/adu.c index 8068d20..5728a31 100644 --- a/adu.c +++ b/adu.c @@ -3,17 +3,13 @@ #include "gcc-compat.h" #include "cmdline.h" -#include "osl.h" #include "fd.h" -#include "hash.h" #include "string.h" #include "error.h" +#include "portable_io.h" DEFINE_ERRLIST; -#define DATABASE_DIR "/tmp/adu" -#define UID_LIST DATABASE_DIR "/" "uid_list" - /** Command line and config file options. */ static struct gengetopt_args_info conf; @@ -177,7 +173,6 @@ static struct osl_table_description dir_table_desc = { .num_columns = NUM_DT_COLUMNS, .flags = 0, .column_descriptions = dir_table_cols, - .dir = DATABASE_DIR }; /** The columns of the id table. */ @@ -246,15 +241,15 @@ static int open_user_table(struct user_info *ui, int create) ui->desc->num_columns = NUM_UT_COLUMNS; ui->desc->flags = 0; ui->desc->column_descriptions = user_table_cols; - ui->desc->dir = para_strdup(DATABASE_DIR); + ui->desc->dir = para_strdup(conf.database_dir_arg); ui->desc->name = make_message("%u", (unsigned)ui->uid); - num_uids++; INFO_LOG(".............................uid #%u: %u\n", (unsigned)num_uids, (unsigned)ui->uid); if (create) { ret = osl_create_table(ui->desc); if (ret < 0) goto err; + num_uids++; } ret = osl_open_table(ui->desc, &ui->table); if (ret < 0) @@ -292,6 +287,7 @@ static int create_tables(void) { int ret; + dir_table_desc.dir = para_strdup(conf.database_dir_arg); ret = osl_create_table(&dir_table_desc); if (ret < 0) return ret; @@ -487,6 +483,42 @@ static int get_dir_name(struct osl_row *row, char **name) return 1; } +const uint64_t size_unit_divisors[] = { + [size_unit_arg_b] = 1ULL, + [size_unit_arg_k] = 1024ULL, + [size_unit_arg_m] = 1024ULL * 1024ULL, + [size_unit_arg_g] = 1024ULL * 1024ULL * 1024ULL, + [size_unit_arg_t] = 1024ULL * 1024ULL * 1024ULL * 1024ULL, +}; + +const uint64_t count_unit_divisors[] = { + + [count_unit_arg_n] = 1ULL, + [count_unit_arg_k] = 1000ULL, + [count_unit_arg_m] = 1000ULL * 1000ULL, + [count_unit_arg_g] = 1000ULL * 1000ULL * 1000ULL, + [count_unit_arg_t] = 1000ULL * 1000ULL * 1000ULL * 1000ULL, +}; + +const char size_unit_abbrevs[] = " BKMGT"; +const char count_unit_abbrevs[] = " KMGT"; + +static void format_size_value(enum enum_size_unit unit, uint64_t value, char *result) +{ + if (unit == size_unit_arg_h) /* human readable */ + for (unit = size_unit_arg_b; unit < size_unit_arg_t && value > size_unit_divisors[unit + 1]; unit++) + ; /* nothing */ + sprintf(result, "%llu%c", (long long unsigned)value / size_unit_divisors[unit], size_unit_abbrevs[unit]); +} + +static void format_count_value(enum enum_count_unit unit, uint64_t value, char *result) +{ + if (unit == count_unit_arg_h) /* human readable */ + for (unit = count_unit_arg_n; unit < count_unit_arg_t && value > count_unit_divisors[unit + 1]; unit++) + ; /* nothing */ + sprintf(result, "%llu%c", (long long unsigned)value / count_unit_divisors[unit], count_unit_abbrevs[unit]); +} + enum global_stats_flags { GSF_PRINT_DIRNAME = 1, GSF_PRINT_BYTES = 2, @@ -503,7 +535,7 @@ static int global_stats_loop_function(struct osl_row *row, void *data) { struct global_stats_info *gsi = data; struct osl_object obj; - char *dirname; + char *dirname, formated_value[25]; int ret, summary = gsi->flags & GSF_COMPUTE_SUMMARY; if (!gsi->count && !summary) @@ -523,9 +555,12 @@ static int global_stats_loop_function(struct osl_row *row, void *data) if (ret < 0) return ret; files = *(uint64_t *)obj.data; - if (gsi->count && (gsi->flags & GSF_PRINT_FILES)) - printf("%llu%s", (long long unsigned)files, + if (gsi->count && (gsi->flags & GSF_PRINT_FILES)) { + format_size_value(conf.size_unit_arg, files, + formated_value); + printf("%s%s", formated_value, (gsi->flags & GSF_PRINT_BYTES)? "\t" : "\n"); + } if (summary) num_files += files; } @@ -535,14 +570,17 @@ static int global_stats_loop_function(struct osl_row *row, void *data) if (ret < 0) return ret; bytes = *(uint64_t *)obj.data; - if (gsi->count && (gsi->flags & GSF_PRINT_BYTES)) - printf("%llu\n", (long long unsigned)bytes); + if (gsi->count && (gsi->flags & GSF_PRINT_BYTES)) { + format_size_value(conf.size_unit_arg, bytes, + formated_value); + printf("%s\n", formated_value); + } if (summary) { num_bytes += bytes; num_dirs++; } } - if (gsi->count) + if (gsi->count > 0) gsi->count--; return 1; } @@ -553,12 +591,21 @@ static void print_id_stats(void) printf("--------------------- user summary (uid/dirs/files/bytes):\n"); FOR_EACH_USER(ui) { + char formated_dir_count[25], formated_file_count[25], + formated_bytes[25]; if (!ui->table) continue; - printf("%u\t%llu\t%llu\t%llu\n", (unsigned)ui->uid, - (long long unsigned)ui->dirs, - (long long unsigned)ui->files, - (long long unsigned)ui->bytes); + format_count_value(conf.count_unit_arg, ui->dirs, + formated_dir_count); + format_count_value(conf.count_unit_arg, ui->files, + formated_file_count); + format_size_value(conf.size_unit_arg, ui->bytes, + formated_bytes); + printf("%u\t%s\t%s\t%s\n", (unsigned)ui->uid, + formated_dir_count, + formated_file_count, + formated_bytes + ); } } @@ -581,6 +628,7 @@ static int user_stats_loop_function(struct osl_row *row, void *data) struct osl_row *dir_row; struct osl_object obj; int ret, summary = usi->flags & GSF_COMPUTE_SUMMARY; + char formated_value[25]; if (!usi->count && !summary) return -E_LOOP_COMPLETE; @@ -608,11 +656,13 @@ static int user_stats_loop_function(struct osl_row *row, void *data) if (ret < 0) return ret; files = *(uint64_t *)obj.data; - if (usi->count && (usi->flags & USF_PRINT_FILES)) - printf("%llu%s", - (long long unsigned)files, + if (usi->count && (usi->flags & USF_PRINT_FILES)) { + format_size_value(conf.size_unit_arg, files, + formated_value); + printf("%s%s", formated_value, (usi->flags & USF_PRINT_BYTES)? "\t" : "\n" ); + } if (summary) usi->ui->files += files; } @@ -622,15 +672,18 @@ static int user_stats_loop_function(struct osl_row *row, void *data) if (ret < 0) return ret; bytes = *(uint64_t *)obj.data; - if (usi->count && (usi->flags & USF_PRINT_BYTES)) - printf("%llu\n", (long long unsigned)bytes); + if (usi->count && (usi->flags & USF_PRINT_BYTES)) { + format_size_value(conf.size_unit_arg, bytes, + formated_value); + printf("%s\n", formated_value); + } if (summary) { usi->ui->bytes += bytes; usi->ui->dirs++; } } - if (usi->count) + if (usi->count > 0) usi->count--; return 1; } @@ -641,7 +694,7 @@ static void print_user_stats(void) FOR_EACH_USER(ui) { struct user_stats_info usi = { - .count = 10, + .count = conf.limit_arg, .ui = ui }; if (!ui->table) @@ -655,7 +708,7 @@ static void print_user_stats(void) osl_rbtree_loop_reverse(ui->table, UT_BYTES, &usi, user_stats_loop_function); printf("---------- dirs containing most files ------------\n"); - usi.count = 10; + usi.count = conf.limit_arg, usi.flags = USF_PRINT_DIRNAME | USF_PRINT_FILES; osl_rbtree_loop_reverse(ui->table, UT_FILES, &usi, user_stats_loop_function); @@ -666,7 +719,7 @@ static int print_statistics(void) { int ret; struct global_stats_info gsi = { - .count = 10, + .count = conf.limit_arg, .flags = GSF_PRINT_DIRNAME | GSF_PRINT_BYTES | GSF_COMPUTE_SUMMARY }; @@ -675,7 +728,7 @@ static int print_statistics(void) global_stats_loop_function); if (ret < 0 && ret != -E_LOOP_COMPLETE) return ret; - gsi.count = 10; + gsi.count = conf.limit_arg; gsi.flags = GSF_PRINT_DIRNAME | GSF_PRINT_FILES; printf("---------- dirs containing most files ------------\n"); @@ -693,9 +746,14 @@ static int print_statistics(void) return 1; } +static char *get_uid_list_name(void) +{ + return make_message("%s/uid_list", conf.database_dir_arg); +} + static int write_uid_list(void) { - char *buf; + char *buf, *filename; uint32_t count = 0; struct user_info *ui; size_t size = num_uids * sizeof(uint32_t); @@ -709,13 +767,17 @@ static int write_uid_list(void) continue; write_u32(buf + count++ * sizeof(uint32_t), ui->uid); } - ret = para_write_file(UID_LIST, buf, size); + filename = get_uid_list_name(); + ret = para_write_file(filename, buf, size); + free(filename); free(buf); return ret; } static int open_dir_table(void) { + if (!dir_table_desc.dir) /* we did not create the table */ + dir_table_desc.dir = para_strdup(conf.database_dir_arg); return osl_open_table(&dir_table_desc, &dir_table); } @@ -728,6 +790,7 @@ static void close_dir_table(void) ret = osl_close_table(dir_table, OSL_MARK_CLEAN); if (ret < 0) ERROR_LOG("failed to close dir table: %s\n", error_txt(-ret)); + free((char *)dir_table_desc.dir); dir_table = NULL; } @@ -784,11 +847,12 @@ out: static int read_uid_file(void) { - char *map; size_t size; - int ret = mmap_full_file(UID_LIST, O_RDONLY, (void **)&map, &size, NULL); uint32_t n; + char *filename = get_uid_list_name(), *map; + int ret = mmap_full_file(filename, O_RDONLY, (void **)&map, &size, NULL); + free(filename); if (ret < 0) return ret; num_uids = size / 4;