From: Andre Noll Date: Sun, 1 Jun 2008 16:16:58 +0000 (+0200) Subject: Move the code for the create command to its own file. X-Git-Tag: v0.0.2~15 X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=0356ff402eec5e75a2c9e24c2fcb5b2c3a1cb63d;p=adu.git Move the code for the create command to its own file. --- diff --git a/Makefile b/Makefile index 68e6443..8dcf26d 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -objects := adu.o string.o cmdline.o fd.o select.o +objects := adu.o string.o cmdline.o fd.o select.o create.c all: adu DEBUG_CPPFLAGS += -Wno-sign-compare -g -Wunused -Wundef -W diff --git a/adu.c b/adu.c index 9a0e513..c21c37f 100644 --- a/adu.c +++ b/adu.c @@ -245,25 +245,6 @@ __printf_2_3 void __log(int ll, const char* fmt,...) va_end(argp); } -static int add_directory(char *dirname, uint64_t *dir_num, uint64_t *parent_dir_num, - uint64_t *dir_size, uint64_t *dir_files) -{ - struct osl_object dir_objects[NUM_DT_COLUMNS]; - - INFO_LOG("adding #%llu: %s\n", (long long unsigned)*dir_num, dirname); - dir_objects[DT_NAME].data = dirname; - dir_objects[DT_NAME].size = strlen(dirname) + 1; - dir_objects[DT_NUM].data = dir_num; - dir_objects[DT_NUM].size = sizeof(*dir_num); - dir_objects[DT_PARENT_NUM].data = parent_dir_num; - dir_objects[DT_PARENT_NUM].size = sizeof(*parent_dir_num); - dir_objects[DT_BYTES].data = dir_size; - dir_objects[DT_BYTES].size = sizeof(*dir_size); - dir_objects[DT_FILES].data = dir_files; - dir_objects[DT_FILES].size = sizeof(*dir_files); - return osl(osl_add_row(dir_table, dir_objects)); -} - static int open_user_table(struct user_info *ui, int create) { int ret; @@ -321,18 +302,6 @@ static void free_hash_table(void) uid_hash_table = NULL; } -static int create_tables(void) -{ - int ret; - - dir_table_desc.dir = adu_strdup(conf.database_dir_arg); - ret = osl(osl_create_table(&dir_table_desc)); - if (ret < 0) - return ret; - create_hash_table(); - return 1; -} - static void close_dir_table(void) { int ret; @@ -478,185 +447,24 @@ int search_uid(uint32_t uid, enum search_uid_flags flags, return flags? -E_HASH_TABLE_OVERFLOW : -E_BAD_UID; } -static int update_user_row(struct osl_table *t, uint64_t dir_num, - uint64_t *add) -{ - struct osl_row *row; - struct osl_object obj = {.data = &dir_num, .size = sizeof(dir_num)}; - - int ret = osl(osl_get_row(t, UT_DIR_NUM, &obj, &row)); - - if (ret == -E_OSL && osl_errno != E_OSL_RB_KEY_NOT_FOUND) - return ret; - if (ret < 0) { /* this is the first file we add */ - struct osl_object objects[NUM_UT_COLUMNS]; - uint64_t num_files = 1; - - objects[UT_DIR_NUM].data = &dir_num; - objects[UT_DIR_NUM].size = sizeof(dir_num); - objects[UT_BYTES].data = add; - objects[UT_BYTES].size = sizeof(*add); - objects[UT_FILES].data = &num_files; - objects[UT_FILES].size = sizeof(num_files); - INFO_LOG("######################### ret: %d\n", ret); - ret = osl(osl_add_row(t, objects)); - INFO_LOG("######################### ret: %d\n", ret); - return ret; - } else { /* add size and increment file count */ - uint64_t num; - struct osl_object obj1, obj2 = {.data = &num, .size = sizeof(num)}; - - ret = osl(osl_get_object(t, row, UT_BYTES, &obj1)); - if (ret < 0) - return ret; - num = *(uint64_t *)obj1.data + *add; - ret = osl(osl_update_object(t, row, UT_BYTES, &obj2)); - if (ret < 0) - return ret; - ret = osl(osl_get_object(t, row, UT_FILES, &obj1)); - if (ret < 0) - return ret; - num = *(uint64_t *)obj1.data + 1; - return osl(osl_update_object(t, row, UT_FILES, &obj2)); - } -} - -/* 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; - int ret, cwd_fd, ret2; - 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 = adu_opendir(dirname, &dir, &cwd_fd); - if (ret < 0) { - if (ret != -ERRNO_TO_ERROR(EACCES)) - return ret; - WARNING_LOG("permission denied for %s\n", dirname); - return 1; - } - while ((entry = readdir(dir))) { - mode_t m; - struct stat s; - uint32_t uid; - uint64_t size; - struct user_info *ui; - - if (!strcmp(entry->d_name, ".")) - continue; - if (!strcmp(entry->d_name, "..")) - continue; - if (lstat(entry->d_name, &s) == -1) { - WARNING_LOG("lstat error for %s/%s\n", dirname, - entry->d_name); - continue; - } - m = s.st_mode; - 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; - continue; - } - /* regular file */ - size = s.st_size; - dir_size += size; - num_bytes += size; - dir_files++; - num_files++; - uid = s.st_uid; - ret = search_uid(uid, CREATE_USER_TABLE | OPEN_USER_TABLE, &ui); - if (ret < 0) - goto out; - ui->bytes += size; - ui->files++; - ret = update_user_row(ui->table, this_dir_num, &size); - if (ret < 0) - goto out; - } - ret = add_directory(dirname, &this_dir_num, parent_dir_num, - &dir_size, &dir_files); -out: - closedir(dir); - ret2 = adu_fchdir(cwd_fd); - if (ret2 < 0 && ret >= 0) - ret = ret2; - close(cwd_fd); - return ret; -} - char *get_uid_list_name(void) { return make_message("%s/uid_list", conf.database_dir_arg); } -static int write_uid_list(void) +int open_dir_table(int create) { - char *buf, *filename; - uint32_t count = 0; - struct user_info *ui; - size_t size = num_uids * sizeof(uint32_t); - int ret; + dir_table_desc.dir = adu_strdup(conf.database_dir_arg); - if (!num_uids) - return 0; - buf = adu_malloc(size); - FOR_EACH_USER(ui) { - if (!ui_used(ui) || !ui_admissible(ui)) - continue; - DEBUG_LOG("saving uid %u\n", (unsigned) ui->uid); - write_u32(buf + count++ * sizeof(uint32_t), ui->uid); + if (create) { + int ret = osl(osl_create_table(&dir_table_desc)); + if (ret < 0) { + free((char *)dir_table_desc.dir); + return ret; + } } - filename = get_uid_list_name(); - ret = adu_write_file(filename, buf, size); - free(filename); - free(buf); - return ret; -} - -int open_dir_table(void) -{ - if (!dir_table_desc.dir) /* we did not create the table */ - dir_table_desc.dir = adu_strdup(conf.database_dir_arg); return osl(osl_open_table(&dir_table_desc, &dir_table)); } -static int com_create() -{ - uint64_t zero = 0ULL; - 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; - ret = write_uid_list(); -out: - close_all_tables(); - return ret; -} static int check_args(void) { diff --git a/adu.h b/adu.h index 69488a4..ea660dd 100644 --- a/adu.h +++ b/adu.h @@ -188,7 +188,7 @@ extern struct gengetopt_args_info conf; /* adu.c */ __printf_2_3 void __log(int, const char*, ...); -int open_dir_table(void); +int open_dir_table(int create); void check_signals(void); void close_all_tables(void); char *get_uid_list_name(void); @@ -199,6 +199,9 @@ int search_uid(uint32_t uid, enum search_uid_flags flags, /* select.c */ int com_select(void); +/* create.h */ +int com_create(void); + static inline int ui_used(struct user_info *ui) { return ui->flags & UI_FL_SLOT_USED; diff --git a/select.c b/select.c index b394676..e09bce1 100644 --- a/select.c +++ b/select.c @@ -498,7 +498,7 @@ int com_select(void) else size_unit_buf[0] = '\0'; - ret = open_dir_table(); + ret = open_dir_table(0); if (ret < 0) return ret; check_signals();