/** Options passed to --select-options. */
struct select_args_info select_conf;
+/** Computed database dir */
+char *database_dir;
/**
* The table containing the directory names and statistics.
*/
int open_dir_table(int create)
{
+ int ret;
if (dir_table)
return 1;
- dir_table_desc.dir = adu_strdup(conf.database_dir_arg);
+ dir_table_desc.dir = adu_strdup(database_dir);
if (create) {
+ INFO_LOG("creating database directory structure\n");
+ ret = mkpath(dir_table_desc.dir, 0777);
+ if (ret < 0)
+ goto out;
NOTICE_LOG("creating dir table\n");
- int ret = osl(osl_create_table(&dir_table_desc));
- if (ret < 0) {
- free((char *)dir_table_desc.dir);
- return ret;
- }
+ ret = osl(osl_create_table(&dir_table_desc));
+ if (ret < 0)
+ goto out;
}
INFO_LOG("opening dir table\n");
return osl(osl_open_table(&dir_table_desc, &dir_table));
+out:
+ free((char *)dir_table_desc.dir);
+ return ret;
}
static int check_args(void)
if (ret < 0)
goto out;
ret = -E_SYNTAX;
+ if (conf.database_dir_given)
+ database_dir = adu_strdup(conf.database_dir_arg);
+ else
+ database_dir = make_message("%s%s",
+ conf.database_root_arg, conf.base_dir_arg);
if (conf.select_given)
ret = com_select();
else if (conf.create_given)
ERROR_LOG("%s\n", adu_strerror(-ret));
return -EXIT_FAILURE;
}
+ free(database_dir);
cmdline_parser_free(&conf);
select_cmdline_parser_free(&select_conf);
return EXIT_SUCCESS;
line option takes precedence.
"
-option "database-dir" d
-#~~~~~~~~~~~~~~~~~~~~~~
-"directory containing the osl tables"
-string typestr="path"
-required
-details="
- Full path to the directory containing the osl tables. This
- directory must exist. It must be writable for the user running
- adu in --create mode and readable in --select mode.
-
-"
option "loglevel" l
#~~~~~~~~~~~~~~~~~~
"Set loglevel (0-6)"
goes to stdout. Lower values mean more verbose logging.
"
+defgroup "database"
+#==================
+groupdesc="
+ There are two ways to specify a database directory. You can either
+ specify a full path using the database-dir option or a root path
+ using the database-root option. In the latter case, a directory
+ structure matching that of the base-dir argument is created
+ below the given full path.
+
+ The advantage of using database-root is that the base-dir is
+ used to find the relevant database both in create and select mode
+ and you do not have to care for setting the database-dir explicitly.
+"
+
+groupoption "database-dir" d
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~
+"directory containing the osl tables"
+group="database"
+string typestr="path"
+details="
+ Full path to the directory containing the osl tables. This
+ directory is created if it does not exist. It must be writable for the
+ user running adu in --create mode and readable in --select mode.
+"
+
+groupoption "database-root" r
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+"directory containing directories containing the osl tables"
+group="database"
+string typestr="path"
+default="/var/lib/adu"
+dependon="base-dir"
+optional
+details="
+ Base path to the directory containing the osl tables. The real
+ database-dir is generated by appending base-dir. This
+ directory is created if it does not exist. When used in select
+ mode you have to specify the base-dir as well.
+"
+
###############
section "Modes"
###############
adu may be started in one of three possible modes, each of
which corresponds to a different command line option. Exactly
one of these options must be given.
-
"
required
#~~~~~~~~~~~~~~~~~~
"directory to traverse"
string typestr="path"
-dependon="create"
optional
details="
The base directory to be traversed recursively. A warning
/** The adu command line options. */
extern struct gengetopt_args_info conf;
+/** Computed database dir. */
+extern char *database_dir;
+
/**
* The select command line options.
*
_ERROR(BAD_UNIT, "invalid unit specifier") \
_ERROR(BAD_ATOM, "invalid atom") \
_ERROR(BAD_OUTPUT_ARG, "invalid name for output") \
- _ERROR(REGEX, "regular expression error")
+ _ERROR(REGEX, "regular expression error") \
+ _ERROR(MKDIR, "could not create directory")
/**
#include <sys/types.h>
#include <dirent.h>
#include <sys/mman.h>
+#include <string.h>
#include "adu.h"
#include "error.h"
+#include "string.h"
/**
* Wrapper for the write system call.
strerror(err));
return -ERRNO_TO_ERROR(err);
}
+
+__must_check __malloc static char *adu_dirname(const char *name)
+{
+ char *p, *ret;
+
+ if (!name || !*name)
+ return NULL;
+ ret = adu_strdup(name);
+ p = strrchr(ret, '/');
+ if (!p)
+ *ret = '\0';
+ else
+ *p = '\0';
+ return ret;
+}
+
+/**
+ * Recursive mkdir
+ *
+ * \param p Full path that should be created.
+ *
+ * \param mode Use this mode when creating directories.
+ *
+ * \return 0 if successful, -E_MKDIR on errors.
+ */
+int mkpath(const char *p, mode_t mode)
+{
+ char *parent, *path;
+ int ret = -E_MKDIR;
+
+ DEBUG_LOG("%s\n", p);
+ if (strcmp(p, ".") == 0 || strcmp(p, "/") == 0 || strcmp(p, "") == 0) {
+ DEBUG_LOG("reached beginning of path\n");
+ return 0;
+ }
+ path = adu_strdup(p);
+ parent = adu_dirname(p);
+ if (!parent)
+ goto out;
+ ret = mkpath(parent, mode);
+ if (ret < 0)
+ goto out;
+ INFO_LOG("making dir %s\n", path);
+ ret = 0;
+ if ((mkdir(path, mode) == -1) && (errno != EEXIST))
+ ret = -E_MKDIR;
+out:
+ free(parent);
+ free(path);
+ return ret;
+}
size_t *size, int *fd_ptr);
int adu_munmap(void *start, size_t length);
int adu_write_file(const char *filename, const void *buf, size_t size);
+int mkpath(const char *p, mode_t mode);
ui->desc->num_columns = NUM_UT_COLUMNS;
ui->desc->flags = 0;
ui->desc->column_descriptions = user_table_cols;
- ui->desc->dir = adu_strdup(conf.database_dir_arg);
+ ui->desc->dir = adu_strdup(database_dir);
ui->desc->name = make_message("%u", (unsigned)ui->uid);
pw = getpwuid(ui->uid);
if (pw && pw->pw_name)
static char *get_uid_list_name(void)
{
- return make_message("%s/uid_list", conf.database_dir_arg);
+ return make_message("%s/uid_list", database_dir);
}
/**
* Open the osl tables for all admissible uids.