/** The decimal representation of an uint64_t never exceeds that size. */
#define FORMATED_VALUE_SIZE 25
+#define FOR_EACH_USER(ui) for (ui = uid_hash_table; ui && ui < uid_hash_table \
+ + uid_hash_table_size; ui++)
+
/**
* Contains info for each user that owns at least one regular file.
* returns a signed value.
*/
int64_t val;
- int ret = para_atoi64(arg, &val);
+ int ret = atoi64(arg, &val);
if (ret < 0)
return ret;
static int parse_uid_range(const char *orig_arg, struct uid_range *ur)
{
int ret;
- char *arg = para_strdup(orig_arg), *p = strchr(arg, '-');
+ char *arg = adu_strdup(orig_arg), *p = strchr(arg, '-');
if (!p || p == arg) { /* -42 or 42 */
ret = check_uid_arg(p? p + 1 : arg, &ur->high);
return ret;
}
-
/** evaluates to 1 if x < y, to -1 if x > y and to 0 if x == y */
#define NUM_COMPARE(x, y) ((int)((x) < (y)) - (int)((x) > (y)))
{
int ret;
- ui->desc = para_malloc(sizeof(*ui->desc));
+ ui->desc = adu_malloc(sizeof(*ui->desc));
ui->desc->num_columns = NUM_UT_COLUMNS;
ui->desc->flags = 0;
ui->desc->column_descriptions = user_table_cols;
- ui->desc->dir = para_strdup(conf.database_dir_arg);
+ ui->desc->dir = adu_strdup(conf.database_dir_arg);
ui->desc->name = make_message("%u", (unsigned)ui->uid);
INFO_LOG(".............................uid #%u: %u\n",
(unsigned)num_uids, (unsigned)ui->uid);
static void create_hash_table(void)
{
- uid_hash_table = para_calloc(uid_hash_table_size
+ uid_hash_table = adu_calloc(uid_hash_table_size
* sizeof(struct user_info));
}
{
int ret;
- dir_table_desc.dir = para_strdup(conf.database_dir_arg);
+ dir_table_desc.dir = adu_strdup(conf.database_dir_arg);
ret = osl(osl_create_table(&dir_table_desc));
if (ret < 0)
return ret;
return 1;
}
+static void close_dir_table(void)
+{
+ int ret;
+
+ if (!dir_table)
+ return;
+ ret = osl(osl_close_table(dir_table, OSL_MARK_CLEAN));
+ if (ret < 0)
+ ERROR_LOG("failed to close dir table: %s\n", adu_strerror(-ret));
+ free((char *)dir_table_desc.dir);
+ dir_table = NULL;
+}
+
+static void close_user_table(struct user_info *ui)
+{
+ int ret;
+
+ if (!ui || !ui_used(ui) || !ui_admissible(ui))
+ return;
+ ret = osl(osl_close_table(ui->table, OSL_MARK_CLEAN));
+ if (ret < 0)
+ ERROR_LOG("failed to close user table %u: %s\n",
+ (unsigned) ui->uid, adu_strerror(-ret));
+ free((char *)ui->desc->name);
+ ui->desc->name = NULL;
+ free((char *)ui->desc->dir);
+ ui->desc->dir = NULL;
+ free(ui->desc);
+ ui->desc = NULL;
+ ui->table = NULL;
+ ui->flags = 0;
+}
+
+static void close_user_tables(void)
+{
+ struct user_info *ui;
+
+ FOR_EACH_USER(ui)
+ close_user_table(ui);
+}
+
+static void close_all_tables(void)
+{
+ close_dir_table();
+ close_user_tables();
+ free_hash_table();
+}
+
+static int signum;
+
+static void signal_handler(int s)
+{
+ signum = s;
+}
+
+static void check_signals(void)
+{
+ if (likely(!signum))
+ return;
+ EMERG_LOG("caught signal %d\n", signum);
+ close_all_tables();
+ exit(EXIT_FAILURE);
+}
+
+static int init_signals(void)
+{
+ if (signal(SIGINT, &signal_handler) == SIG_ERR)
+ return -E_SIGNAL_SIG_ERR;
+ if (signal(SIGTERM, &signal_handler) == SIG_ERR)
+ return -E_SIGNAL_SIG_ERR;
+ return 1;
+}
+
/*
* We use a hash table of size s=2^uid_hash_bits to map the uids into the
* interval [0..s]. Hash collisions are treated by open addressing, i.e.
% uid_hash_table_size;
}
-#define FOR_EACH_USER(ui) for (ui = uid_hash_table; ui && ui < uid_hash_table \
- + uid_hash_table_size; ui++)
-
enum search_uid_flags {
OPEN_USER_TABLE = 1,
CREATE_USER_TABLE = 2,
static uint64_t num_files;
static uint64_t num_bytes;
-int scan_dir(char *dirname, uint64_t *parent_dir_num)
+/* id of the device containing the base dir. */
+static dev_t device_id;
+
+static int scan_dir(char *dirname, uint64_t *parent_dir_num)
{
DIR *dir;
struct dirent *entry;
uint64_t dir_size = 0, dir_files = 0;
uint64_t this_dir_num = ++num_dirs;
+ check_signals();
DEBUG_LOG("----------------- %llu: %s\n", (long long unsigned)num_dirs, dirname);
- ret = para_opendir(dirname, &dir, &cwd_fd);
+ ret = adu_opendir(dirname, &dir, &cwd_fd);
if (ret < 0) {
if (ret != -ERRNO_TO_ERROR(EACCES))
return ret;
if (!S_ISREG(m) && !S_ISDIR(m))
continue;
if (S_ISDIR(m)) {
+ if (conf.one_file_system_given && s.st_dev != device_id)
+ continue;
ret = scan_dir(entry->d_name, &this_dir_num);
if (ret < 0)
goto out;
&dir_size, &dir_files);
out:
closedir(dir);
- ret2 = para_fchdir(cwd_fd);
+ ret2 = adu_fchdir(cwd_fd);
if (ret2 < 0 && ret >= 0)
ret = ret2;
close(cwd_fd);
free(result);
result = tmp;
} else
- result = para_strdup((char *)obj.data);
+ result = adu_strdup((char *)obj.data);
ret = osl(osl_get_object(dir_table, row, DT_PARENT_NUM, &obj));
if (ret < 0)
goto out;
ret = osl(osl_get_object(dir_table, dir_table_row, DT_NAME, &obj));
if (ret < 0)
return ret;
- this_dir = para_strdup((char *)obj.data);
+ this_dir = adu_strdup((char *)obj.data);
ret = osl(osl_get_object(dir_table, dir_table_row, DT_PARENT_NUM, &obj));
if (ret < 0)
goto out;
char *dirname, formated_value[FORMATED_VALUE_SIZE];
int ret, summary = gsi->flags & GSF_COMPUTE_SUMMARY;
+ check_signals();
if (!gsi->count && !summary) {
ret = -E_LOOP_COMPLETE;
goto err;
int ret, summary = usi->flags & GSF_COMPUTE_SUMMARY;
char formated_value[FORMATED_VALUE_SIZE];
+ check_signals();
if (!usi->count && !summary) {
ret = -E_LOOP_COMPLETE;
goto err;
if (!num_uids)
return 0;
- buf = para_malloc(size);
+ buf = adu_malloc(size);
FOR_EACH_USER(ui) {
if (!ui_used(ui) || !ui_admissible(ui))
continue;
write_u32(buf + count++ * sizeof(uint32_t), ui->uid);
}
filename = get_uid_list_name();
- ret = para_write_file(filename, buf, size);
+ ret = adu_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);
+ dir_table_desc.dir = adu_strdup(conf.database_dir_arg);
return osl(osl_open_table(&dir_table_desc, &dir_table));
}
-
-static void close_dir_table(void)
-{
- int ret;
-
- if (!dir_table)
- return;
- ret = osl(osl_close_table(dir_table, OSL_MARK_CLEAN));
- if (ret < 0)
- ERROR_LOG("failed to close dir table: %s\n", adu_strerror(-ret));
- free((char *)dir_table_desc.dir);
- dir_table = NULL;
-}
-
-static void close_user_table(struct user_info *ui)
-{
- int ret;
-
- if (!ui || !ui_used(ui) || !ui_admissible(ui))
- return;
- ret = osl(osl_close_table(ui->table, OSL_MARK_CLEAN));
- if (ret < 0)
- ERROR_LOG("failed to close user table %u: %s\n",
- (unsigned) ui->uid, adu_strerror(-ret));
- free((char *)ui->desc->name);
- ui->desc->name = NULL;
- free((char *)ui->desc->dir);
- ui->desc->dir = NULL;
- free(ui->desc);
- ui->desc = NULL;
- ui->table = NULL;
- ui->flags = 0;
-}
-
-static void close_user_tables(void)
-{
- struct user_info *ui;
-
- FOR_EACH_USER(ui)
- close_user_table(ui);
-}
-
-static void close_all_tables(void)
-{
- close_dir_table();
- close_user_tables();
- free_hash_table();
-}
-
static int com_create()
{
uint64_t zero = 0ULL;
- int ret = create_tables();
-
+ int ret;
+ struct stat statbuf;
+
+ if (lstat(conf.base_dir_arg, &statbuf) == -1)
+ return -ERRNO_TO_ERROR(errno);
+ if (!S_ISDIR(statbuf.st_mode))
+ return -ERRNO_TO_ERROR(ENOTDIR);
+ device_id = statbuf.st_dev;
+ ret = create_tables();
if (ret < 0)
return ret;
+ check_signals();
ret = open_dir_table();
if (ret < 0)
return ret;
+ check_signals();
ret = scan_dir(conf.base_dir_arg, &zero);
if (ret < 0)
goto out;
goto out;
}
out:
- para_munmap(map, size);
+ adu_munmap(map, size);
return ret;
}
ret = open_dir_table();
if (ret < 0)
return ret;
+ check_signals();
ret = read_uid_file();
if (ret < 0)
return ret;
+ check_signals();
ret = print_statistics();
close_all_tables();
return ret;
}
if (!conf.uid_given)
return 0;
- admissible_uids = para_malloc(conf.uid_given * sizeof(*admissible_uids));
+ admissible_uids = adu_malloc(conf.uid_given * sizeof(*admissible_uids));
for (i = 0; i < conf.uid_given; i++) {
ret = parse_uid_range(conf.uid_arg[i], admissible_uids + i);
if (ret < 0)
};
cmdline_parser_ext(argc, argv, &conf, ¶ms); /* aborts on errors */
+ ret = init_signals();
+ if (ret < 0)
+ goto out;
ret = check_args();
if (ret < 0)
goto out;