#define MAX_DEPTH 256
-static OrderedHashmap *items = NULL, *globs = NULL;
-static Set *unix_sockets = NULL;
+typedef struct Context {
+ OrderedHashmap *items, *globs;
+ Set *unix_sockets;
+} Context;
-STATIC_DESTRUCTOR_REGISTER(items, ordered_hashmap_freep);
-STATIC_DESTRUCTOR_REGISTER(globs, ordered_hashmap_freep);
-STATIC_DESTRUCTOR_REGISTER(unix_sockets, set_freep);
STATIC_DESTRUCTOR_REGISTER(arg_include_prefixes, freep);
STATIC_DESTRUCTOR_REGISTER(arg_exclude_prefixes, freep);
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(creation_mode_verb, CreationMode);
+static void context_done(Context *c) {
+ assert(c);
+
+ ordered_hashmap_free(c->items);
+ ordered_hashmap_free(c->globs);
+
+ set_free(c->unix_sockets);
+}
+
/* Different kinds of errors that mean that information is not available in the environment. */
static inline bool ERRNO_IS_NOINFO(int r) {
return IN_SET(abs(r),
return NULL;
}
-static int load_unix_sockets(void) {
+static int load_unix_sockets(Context *c) {
_cleanup_set_free_ Set *sockets = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
- if (unix_sockets)
+ if (c->unix_sockets)
return 0;
/* We maintain a cache of the sockets we found in /proc/net/unix to speed things up a little. */
return log_warning_errno(r, "Failed to add AF_UNIX socket to set, ignoring: %m");
}
- unix_sockets = TAKE_PTR(sockets);
+ c->unix_sockets = TAKE_PTR(sockets);
return 1;
}
-static bool unix_socket_alive(const char *fn) {
+static bool unix_socket_alive(Context *c, const char *fn) {
+ assert(c);
assert(fn);
- if (load_unix_sockets() < 0)
+ if (load_unix_sockets(c) < 0)
return true; /* We don't know, so assume yes */
- return set_contains(unix_sockets, fn);
+ return set_contains(c->unix_sockets, fn);
}
/* Accessors for the argument in binary format */
}
static int dir_cleanup(
+ Context *c,
Item *i,
const char *p,
DIR *d,
bool deleted = false;
int r = 0;
+ assert(c);
+ assert(i);
+ assert(d);
+
FOREACH_DIRENT_ALL(de, d, break) {
_cleanup_free_ char *sub_path = NULL;
nsec_t atime_nsec, mtime_nsec, ctime_nsec, btime_nsec;
}
/* Is there an item configured for this path? */
- if (ordered_hashmap_get(items, sub_path)) {
+ if (ordered_hashmap_get(c->items, sub_path)) {
log_debug("Ignoring \"%s\": a separate entry exists.", sub_path);
continue;
}
- if (find_glob(globs, sub_path)) {
+ if (find_glob(c->globs, sub_path)) {
log_debug("Ignoring \"%s\": a separate glob exists.", sub_path);
continue;
}
continue;
}
- q = dir_cleanup(i,
+ q = dir_cleanup(c, i,
sub_path, sub_dir,
atime_nsec, mtime_nsec, cutoff_nsec,
rootdev_major, rootdev_minor,
}
/* Ignore sockets that are listed in /proc/net/unix */
- if (S_ISSOCK(sx.stx_mode) && unix_socket_alive(sub_path)) {
+ if (S_ISSOCK(sx.stx_mode) && unix_socket_alive(c, sub_path)) {
log_debug("Skipping \"%s\": live socket.", sub_path);
continue;
}
}
static int fd_set_perms(
+ Context *c,
Item *i,
int fd,
const char *path,
gid_t new_gid;
int r;
+ assert(c);
assert(i);
assert(fd >= 0);
assert(path);
}
static int path_set_perms(
+ Context *c,
Item *i,
const char *path,
CreationMode creation) {
_cleanup_close_ int fd = -EBADF;
+ assert(c);
assert(i);
assert(path);
if (fd < 0)
return fd;
- return fd_set_perms(i, fd, path, /* st= */ NULL, creation);
+ return fd_set_perms(c, i, fd, path, /* st= */ NULL, creation);
}
static int parse_xattrs_from_arg(Item *i) {
}
static int fd_set_xattrs(
+ Context *c,
Item *i,
int fd,
const char *path,
const struct stat *st,
CreationMode creation) {
+ assert(c);
assert(i);
assert(fd >= 0);
assert(path);
}
static int path_set_xattrs(
+ Context *c,
Item *i,
const char *path,
CreationMode creation) {
_cleanup_close_ int fd = -EBADF;
+ assert(c);
assert(i);
assert(path);
if (fd < 0)
return fd;
- return fd_set_xattrs(i, fd, path, /* st = */ NULL, creation);
+ return fd_set_xattrs(c, i, fd, path, /* st = */ NULL, creation);
}
static int parse_acls_from_arg(Item *item) {
}
static int path_set_acl(
+ Context *c,
const char *path,
const char *pretty,
acl_type_t type,
_cleanup_(acl_freep) acl_t dup = NULL;
int r;
- /* Returns 0 for success, positive error if already warned,
- * negative error otherwise. */
+ assert(c);
+
+ /* Returns 0 for success, positive error if already warned, negative error otherwise. */
if (modify) {
r = acls_for_file(path, type, acl, &dup);
#endif
static int fd_set_acls(
+ Context *c,
Item *item,
int fd,
const char *path,
_cleanup_(acl_freep) acl_t access_with_exec_parsed = NULL;
struct stat stbuf;
+ assert(c);
assert(item);
assert(fd >= 0);
assert(path);
if (r < 0)
return log_error_errno(r, "Failed to parse conditionalized execute bit for \"%s\": %m", path);
- r = path_set_acl(FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_ACCESS, access_with_exec_parsed, item->append_or_force);
+ r = path_set_acl(c, FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_ACCESS, access_with_exec_parsed, item->append_or_force);
} else if (item->acl_access)
- r = path_set_acl(FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_ACCESS, item->acl_access, item->append_or_force);
+ r = path_set_acl(c, FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_ACCESS, item->acl_access, item->append_or_force);
/* set only default acls to folders */
if (r == 0 && item->acl_default && S_ISDIR(st->st_mode))
- r = path_set_acl(FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_DEFAULT, item->acl_default, item->append_or_force);
+ r = path_set_acl(c, FORMAT_PROC_FD_PATH(fd), path, ACL_TYPE_DEFAULT, item->acl_default, item->append_or_force);
if (ERRNO_IS_NOT_SUPPORTED(r)) {
log_debug_errno(r, "ACLs not supported by file system at %s", path);
return r;
}
-static int path_set_acls(Item *item, const char *path, CreationMode creation) {
+static int path_set_acls(
+ Context *c,
+ Item *item,
+ const char *path,
+ CreationMode creation) {
+
int r = 0;
#if HAVE_ACL
_cleanup_close_ int fd = -EBADF;
+ assert(c);
assert(item);
assert(path);
if (fd < 0)
return fd;
- r = fd_set_acls(item, fd, path, /* st= */ NULL, creation);
+ r = fd_set_acls(c, item, fd, path, /* st= */ NULL, creation);
#endif
return r;
}
}
static int fd_set_attribute(
+ Context *c,
Item *item,
int fd,
const char *path,
unsigned f;
int r;
+ assert(c);
assert(item);
assert(fd >= 0);
assert(path);
return 0;
}
-static int path_set_attribute(Item *item, const char *path, CreationMode creation) {
+static int path_set_attribute(
+ Context *c,
+ Item *item,
+ const char *path,
+ CreationMode creation) {
+
_cleanup_close_ int fd = -EBADF;
+ assert(c);
+ assert(item);
+
if (!item->attribute_set || item->attribute_mask == 0)
return 0;
if (fd < 0)
return fd;
- return fd_set_attribute(item, fd, path, /* st= */ NULL, creation);
+ return fd_set_attribute(c, item, fd, path, /* st= */ NULL, creation);
}
static int write_argument_data(Item *i, int fd, const char *path) {
return 0;
}
-static int write_one_file(Item *i, const char *path, CreationMode creation) {
+static int write_one_file(Context *c, Item *i, const char *path, CreationMode creation) {
_cleanup_close_ int fd = -EBADF, dir_fd = -EBADF;
_cleanup_free_ char *bn = NULL;
int r;
+ assert(c);
assert(i);
assert(path);
assert(i->type == WRITE_FILE);
if (r < 0)
return r;
- return fd_set_perms(i, fd, path, NULL, creation);
+ return fd_set_perms(c, i, fd, path, NULL, creation);
}
-static int create_file(Item *i, const char *path) {
+static int create_file(
+ Context *c,
+ Item *i,
+ const char *path) {
+
_cleanup_close_ int fd = -EBADF, dir_fd = -EBADF;
_cleanup_free_ char *bn = NULL;
struct stat stbuf, *st = NULL;
CreationMode creation;
int r = 0;
+ assert(c);
assert(i);
assert(path);
assert(i->type == CREATE_FILE);
creation = CREATION_NORMAL;
}
- return fd_set_perms(i, fd, path, st, creation);
+ return fd_set_perms(c, i, fd, path, st, creation);
}
-static int truncate_file(Item *i, const char *path) {
+static int truncate_file(
+ Context *c,
+ Item *i,
+ const char *path) {
+
_cleanup_close_ int fd = -EBADF, dir_fd = -EBADF;
_cleanup_free_ char *bn = NULL;
struct stat stbuf, *st = NULL;
bool erofs = false;
int r = 0;
+ assert(c);
assert(i);
assert(path);
assert(i->type == TRUNCATE_FILE || (i->type == CREATE_FILE && i->append_or_force));
return r;
}
- return fd_set_perms(i, fd, path, st, creation);
+ return fd_set_perms(c, i, fd, path, st, creation);
}
-static int copy_files(Item *i) {
+static int copy_files(Context *c, Item *i) {
_cleanup_close_ int dfd = -EBADF, fd = -EBADF;
_cleanup_free_ char *bn = NULL;
struct stat st, a;
return 0;
}
- return fd_set_perms(i, fd, i->path, &st, _CREATION_MODE_INVALID);
+ return fd_set_perms(c, i, fd, i->path, &st, _CREATION_MODE_INVALID);
}
static int create_directory_or_subvolume(
return fd;
}
-static int create_directory(Item *i, const char *path) {
+static int create_directory(
+ Context *c,
+ Item *i,
+ const char *path) {
+
_cleanup_close_ int fd = -EBADF;
CreationMode creation;
struct stat st;
+ assert(c);
assert(i);
assert(IN_SET(i->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY));
if (fd < 0)
return fd;
- return fd_set_perms(i, fd, path, &st, creation);
+ return fd_set_perms(c, i, fd, path, &st, creation);
}
-static int create_subvolume(Item *i, const char *path) {
+static int create_subvolume(
+ Context *c,
+ Item *i,
+ const char *path) {
+
_cleanup_close_ int fd = -EBADF;
CreationMode creation;
struct stat st;
int r, q = 0;
+ assert(c);
assert(i);
assert(IN_SET(i->type, CREATE_SUBVOLUME, CREATE_SUBVOLUME_NEW_QUOTA, CREATE_SUBVOLUME_INHERIT_QUOTA));
log_debug("Quota for subvolume \"%s\" already in place, no change made.", i->path);
}
- r = fd_set_perms(i, fd, path, &st, creation);
+ r = fd_set_perms(c, i, fd, path, &st, creation);
if (q < 0) /* prefer the quota change error from above */
return q;
return r;
}
-static int empty_directory(Item *i, const char *path, CreationMode creation) {
+static int empty_directory(
+ Context *c,
+ Item *i,
+ const char *path,
+ CreationMode creation) {
+
_cleanup_close_ int fd = -EBADF;
struct stat st;
int r;
+ assert(c);
assert(i);
assert(i->type == EMPTY_DIRECTORY);
return 0;
}
- return fd_set_perms(i, fd, path, &st, creation);
+ return fd_set_perms(c, i, fd, path, &st, creation);
}
-static int create_device(Item *i, mode_t file_type) {
+static int create_device(
+ Context *c,
+ Item *i,
+ mode_t file_type) {
+
_cleanup_close_ int dfd = -EBADF, fd = -EBADF;
_cleanup_free_ char *bn = NULL;
CreationMode creation;
struct stat st;
int r;
+ assert(c);
assert(i);
assert(IN_SET(i->type, CREATE_BLOCK_DEVICE, CREATE_CHAR_DEVICE));
assert(IN_SET(file_type, S_IFBLK, S_IFCHR));
i->type == CREATE_BLOCK_DEVICE ? "block" : "char",
i->path, major(i->mode), minor(i->mode));
- return fd_set_perms(i, fd, i->path, &st, creation);
+ return fd_set_perms(c, i, fd, i->path, &st, creation);
handle_privilege:
log_debug_errno(r,
return 0;
}
-static int create_fifo(Item *i) {
+static int create_fifo(Context *c, Item *i) {
_cleanup_close_ int pfd = -EBADF, fd = -EBADF;
_cleanup_free_ char *bn = NULL;
CreationMode creation;
struct stat st;
int r;
+ assert(c);
assert(i);
assert(i->type == CREATE_FIFO);
log_debug("%s fifo \"%s\".", creation_mode_verb_to_string(creation), i->path);
- return fd_set_perms(i, fd, i->path, &st, creation);
+ return fd_set_perms(c, i, fd, i->path, &st, creation);
}
-static int create_symlink(Item *i) {
+static int create_symlink(Context *c, Item *i) {
_cleanup_close_ int pfd = -EBADF, fd = -EBADF;
_cleanup_free_ char *bn = NULL;
CreationMode creation;
bool good = false;
int r;
+ assert(c);
assert(i);
r = path_extract_filename(i->path, &bn);
}
log_debug("%s symlink \"%s\".", creation_mode_verb_to_string(creation), i->path);
- return fd_set_perms(i, fd, i->path, &st, creation);
+ return fd_set_perms(c, i, fd, i->path, &st, creation);
}
-typedef int (*action_t)(Item *i, const char *path, CreationMode creation);
-typedef int (*fdaction_t)(Item *i, int fd, const char *path, const struct stat *st, CreationMode creation);
+typedef int (*action_t)(Context *c, Item *i, const char *path, CreationMode creation);
+typedef int (*fdaction_t)(Context *c, Item *i, int fd, const char *path, const struct stat *st, CreationMode creation);
static int item_do(
+ Context *c,
Item *i,
int fd,
const char *path,
struct stat st;
int r = 0, q;
+ assert(c);
assert(i);
assert(path);
assert(fd >= 0);
}
/* This returns the first error we run into, but nevertheless tries to go on */
- r = action(i, fd, path, &st, creation);
+ r = action(c, i, fd, path, &st, creation);
if (S_ISDIR(st.st_mode)) {
_cleanup_closedir_ DIR *d = NULL;
q = log_oom();
else
/* Pass ownership of dirent fd over */
- q = item_do(i, de_fd, de_path, CREATION_EXISTING, action);
+ q = item_do(c, i, de_fd, de_path, CREATION_EXISTING, action);
}
if (q < 0 && r == 0)
return r;
}
-static int glob_item(Item *i, action_t action) {
+static int glob_item(Context *c, Item *i, action_t action) {
_cleanup_globfree_ glob_t g = {
.gl_opendir = (void *(*)(const char *)) opendir_nomod,
};
int r = 0, k;
+ assert(c);
+ assert(i);
+
k = safe_glob(i->path, GLOB_NOSORT|GLOB_BRACE, &g);
if (k < 0 && k != -ENOENT)
return log_error_errno(k, "glob(%s) failed: %m", i->path);
STRV_FOREACH(fn, g.gl_pathv) {
/* We pass CREATION_EXISTING here, since if we are globbing for it, it always has to exist */
- k = action(i, *fn, CREATION_EXISTING);
+ k = action(c, i, *fn, CREATION_EXISTING);
if (k < 0 && r == 0)
r = k;
}
return r;
}
-static int glob_item_recursively(Item *i, fdaction_t action) {
+static int glob_item_recursively(
+ Context *c,
+ Item *i,
+ fdaction_t action) {
+
_cleanup_globfree_ glob_t g = {
.gl_opendir = (void *(*)(const char *)) opendir_nomod,
};
continue;
}
- k = item_do(i, fd, *fn, CREATION_EXISTING, action);
+ k = item_do(c, i, fd, *fn, CREATION_EXISTING, action);
if (k < 0 && r == 0)
r = k;
return 0;
}
-static int create_item(Item *i) {
+static int create_item(Context *c, Item *i) {
int r;
+ assert(c);
assert(i);
log_debug("Running create action for entry %c %s", (char) i->type, i->path);
return r;
if ((i->type == CREATE_FILE && i->append_or_force) || i->type == TRUNCATE_FILE)
- r = truncate_file(i, i->path);
+ r = truncate_file(c, i, i->path);
else
- r = create_file(i, i->path);
+ r = create_file(c, i, i->path);
if (r < 0)
return r;
break;
if (r < 0)
return r;
- r = copy_files(i);
+ r = copy_files(c, i);
if (r < 0)
return r;
break;
case WRITE_FILE:
- r = glob_item(i, write_one_file);
+ r = glob_item(c, i, write_one_file);
if (r < 0)
return r;
if (r < 0)
return r;
- r = create_directory(i, i->path);
+ r = create_directory(c, i, i->path);
if (r < 0)
return r;
break;
if (r < 0)
return r;
- r = create_subvolume(i, i->path);
+ r = create_subvolume(c, i, i->path);
if (r < 0)
return r;
break;
case EMPTY_DIRECTORY:
- r = glob_item(i, empty_directory);
+ r = glob_item(c, i, empty_directory);
if (r < 0)
return r;
break;
if (r < 0)
return r;
- r = create_fifo(i);
+ r = create_fifo(c, i);
if (r < 0)
return r;
break;
if (r < 0)
return r;
- r = create_symlink(i);
+ r = create_symlink(c, i);
if (r < 0)
return r;
if (r < 0)
return r;
- r = create_device(i, i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR);
+ r = create_device(c, i, i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR);
if (r < 0)
return r;
case ADJUST_MODE:
case RELABEL_PATH:
- r = glob_item(i, path_set_perms);
+ r = glob_item(c, i, path_set_perms);
if (r < 0)
return r;
break;
case RECURSIVE_RELABEL_PATH:
- r = glob_item_recursively(i, fd_set_perms);
+ r = glob_item_recursively(c, i, fd_set_perms);
if (r < 0)
return r;
break;
case SET_XATTR:
- r = glob_item(i, path_set_xattrs);
+ r = glob_item(c, i, path_set_xattrs);
if (r < 0)
return r;
break;
case RECURSIVE_SET_XATTR:
- r = glob_item_recursively(i, fd_set_xattrs);
+ r = glob_item_recursively(c, i, fd_set_xattrs);
if (r < 0)
return r;
break;
case SET_ACL:
- r = glob_item(i, path_set_acls);
+ r = glob_item(c, i, path_set_acls);
if (r < 0)
return r;
break;
case RECURSIVE_SET_ACL:
- r = glob_item_recursively(i, fd_set_acls);
+ r = glob_item_recursively(c, i, fd_set_acls);
if (r < 0)
return r;
break;
case SET_ATTRIBUTE:
- r = glob_item(i, path_set_attribute);
+ r = glob_item(c, i, path_set_attribute);
if (r < 0)
return r;
break;
case RECURSIVE_SET_ATTRIBUTE:
- r = glob_item_recursively(i, fd_set_attribute);
+ r = glob_item_recursively(c, i, fd_set_attribute);
if (r < 0)
return r;
break;
return 0;
}
-static int remove_item_instance(Item *i, const char *instance, CreationMode creation) {
+static int remove_item_instance(
+ Context *c,
+ Item *i,
+ const char *instance,
+ CreationMode creation) {
+
int r;
+ assert(c);
assert(i);
switch (i->type) {
return 0;
}
-static int remove_item(Item *i) {
+static int remove_item(Context *c, Item *i) {
int r;
+ assert(c);
assert(i);
log_debug("Running remove action for entry %c %s", (char) i->type, i->path);
case REMOVE_PATH:
case RECURSIVE_REMOVE_PATH:
- return glob_item(i, remove_item_instance);
+ return glob_item(c, i, remove_item_instance);
default:
return 0;
}
static int clean_item_instance(
+ Context *c,
Item *i,
const char* instance,
CreationMode creation) {
ab_f, ab_d);
}
- return dir_cleanup(i, instance, d,
+ return dir_cleanup(c, i, instance, d,
load_statx_timestamp_nsec(&sx.stx_atime),
load_statx_timestamp_nsec(&sx.stx_mtime),
cutoff * NSEC_PER_USEC,
i->age_by_file, i->age_by_dir);
}
-static int clean_item(Item *i) {
+static int clean_item(Context *c, Item *i) {
+ assert(c);
assert(i);
log_debug("Running clean action for entry %c %s", (char) i->type, i->path);
switch (i->type) {
+
case CREATE_DIRECTORY:
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case TRUNCATE_DIRECTORY:
case IGNORE_PATH:
case COPY_FILES:
- clean_item_instance(i, i->path, CREATION_EXISTING);
+ clean_item_instance(c, i, i->path, CREATION_EXISTING);
return 0;
+
case EMPTY_DIRECTORY:
case IGNORE_DIRECTORY_PATH:
- return glob_item(i, clean_item_instance);
+ return glob_item(c, i, clean_item_instance);
+
default:
return 0;
}
}
-static int process_item(Item *i, OperationMask operation) {
+static int process_item(
+ Context *c,
+ Item *i,
+ OperationMask operation) {
+
OperationMask todo;
_cleanup_free_ char *_path = NULL;
const char *path;
int r, q, p;
+ assert(c);
assert(i);
todo = operation & ~i->done;
if (r < 0)
log_debug_errno(r, "Failed to determine whether '%s' is below autofs, ignoring: %m", i->path);
- r = FLAGS_SET(operation, OPERATION_CREATE) ? create_item(i) : 0;
+ r = FLAGS_SET(operation, OPERATION_CREATE) ? create_item(c, i) : 0;
/* Failure can only be tolerated for create */
if (i->allow_failure)
r = 0;
- q = FLAGS_SET(operation, OPERATION_REMOVE) ? remove_item(i) : 0;
- p = FLAGS_SET(operation, OPERATION_CLEAN) ? clean_item(i) : 0;
+ q = FLAGS_SET(operation, OPERATION_REMOVE) ? remove_item(c, i) : 0;
+ p = FLAGS_SET(operation, OPERATION_CLEAN) ? clean_item(c, i) : 0;
return r < 0 ? r :
q < 0 ? q :
p;
}
-static int process_item_array(ItemArray *array, OperationMask operation) {
+static int process_item_array(
+ Context *c,
+ ItemArray *array,
+ OperationMask operation) {
+
int r = 0;
size_t n;
+ assert(c);
assert(array);
/* Create any parent first. */
if (FLAGS_SET(operation, OPERATION_CREATE) && array->parent)
- r = process_item_array(array->parent, operation & OPERATION_CREATE);
+ r = process_item_array(c, array->parent, operation & OPERATION_CREATE);
/* Clean up all children first */
if ((operation & (OPERATION_REMOVE|OPERATION_CLEAN)) && !set_isempty(array->children)) {
- ItemArray *c;
+ ItemArray *cc;
- SET_FOREACH(c, array->children) {
+ SET_FOREACH(cc, array->children) {
int k;
- k = process_item_array(c, operation & (OPERATION_REMOVE|OPERATION_CLEAN));
+ k = process_item_array(c, cc, operation & (OPERATION_REMOVE|OPERATION_CLEAN));
if (k < 0 && r == 0)
r = k;
}
for (n = 0; n < array->n_items; n++) {
int k;
- k = process_item(array->items + n, operation);
+ k = process_item(c, array->items + n, operation);
if (k < 0 && r == 0)
r = k;
}
}
static int parse_line(
+ Context *c,
const char *fname,
unsigned line,
const char *buffer,
bool append_or_force = false, boot = false, allow_failure = false, try_replace = false,
unbase64 = false, from_cred = false, missing_user_or_group = false;
+ assert(c);
assert(fname);
assert(line >= 1);
assert(buffer);
i.age_set = true;
}
- h = needs_glob(i.type) ? globs : items;
+ h = needs_glob(i.type) ? c->globs : c->items;
existing = ordered_hashmap_get(h, i.path);
if (existing) {
}
static int read_config_file(
+ Context *c,
char **config_dirs,
const char *fn,
bool ignore_enoent,
ItemArray *ia;
int r = 0;
+ assert(c);
assert(fn);
if (streq(fn, "-")) {
if (IN_SET(*l, 0, '#'))
continue;
- k = parse_line(fn, v, l, &invalid_line, &uid_cache, &gid_cache);
+ k = parse_line(c, fn, v, l, &invalid_line, &uid_cache, &gid_cache);
if (k < 0) {
if (invalid_line)
/* Allow reporting with a special code if the caller requested this */
}
/* we have to determine age parameter for each entry of type X */
- ORDERED_HASHMAP_FOREACH(ia, globs)
+ ORDERED_HASHMAP_FOREACH(ia, c->globs)
for (size_t ni = 0; ni < ia->n_items; ni++) {
ItemArray *ja;
Item *i = ia->items + ni, *candidate_item = NULL;
if (i->type != IGNORE_DIRECTORY_PATH)
continue;
- ORDERED_HASHMAP_FOREACH(ja, items)
+ ORDERED_HASHMAP_FOREACH(ja, c->items)
for (size_t nj = 0; nj < ja->n_items; nj++) {
Item *j = ja->items + nj;
return r;
}
-static int parse_arguments(char **config_dirs, char **args, bool *invalid_config) {
+static int parse_arguments(
+ Context *c,
+ char **config_dirs,
+ char **args,
+ bool *invalid_config) {
int r;
+ assert(c);
+
STRV_FOREACH(arg, args) {
- r = read_config_file(config_dirs, *arg, false, invalid_config);
+ r = read_config_file(c, config_dirs, *arg, false, invalid_config);
if (r < 0)
return r;
}
return 0;
}
-static int read_config_files(char **config_dirs, char **args, bool *invalid_config) {
+static int read_config_files(
+ Context *c,
+ char **config_dirs,
+ char **args,
+ bool *invalid_config) {
+
_cleanup_strv_free_ char **files = NULL;
_cleanup_free_ char *p = NULL;
int r;
+ assert(c);
+
r = conf_files_list_with_replacement(arg_root, config_dirs, arg_replace, &files, &p);
if (r < 0)
return r;
if (p && path_equal(*f, p)) {
log_debug("Parsing arguments at position \"%s\"%s", *f, special_glyph(SPECIAL_GLYPH_ELLIPSIS));
- r = parse_arguments(config_dirs, args, invalid_config);
+ r = parse_arguments(c, config_dirs, args, invalid_config);
if (r < 0)
return r;
} else
/* Just warn, ignore result otherwise.
* read_config_file() has some debug output, so no need to print anything. */
- (void) read_config_file(config_dirs, *f, true, invalid_config);
+ (void) read_config_file(c, config_dirs, *f, true, invalid_config);
return 0;
}
-static int read_credential_lines(bool *invalid_config) {
+static int read_credential_lines(Context *c, bool *invalid_config) {
+
_cleanup_free_ char *j = NULL;
const char *d;
int r;
+ assert(c);
+
r = get_credentials_dir(&d);
if (r == -ENXIO)
return 0;
if (!j)
return log_oom();
- (void) read_config_file(/* config_dirs= */ NULL, j, /* ignore_enoent= */ true, invalid_config);
+ (void) read_config_file(c, /* config_dirs= */ NULL, j, /* ignore_enoent= */ true, invalid_config);
return 0;
}
-static int link_parent(ItemArray *a) {
+static int link_parent(Context *c, ItemArray *a) {
const char *path;
char *prefix;
int r;
+ assert(c);
assert(a);
/* Finds the closest "parent" item array for the specified item array. Then registers the specified item array
PATH_FOREACH_PREFIX(prefix, path) {
ItemArray *j;
- j = ordered_hashmap_get(items, prefix);
+ j = ordered_hashmap_get(c->items, prefix);
if (!j)
- j = ordered_hashmap_get(globs, prefix);
+ j = ordered_hashmap_get(c->globs, prefix);
if (j) {
r = set_ensure_put(&j->children, NULL, a);
if (r < 0)
_cleanup_(umount_and_freep) char *mounted_dir = NULL;
#endif
_cleanup_strv_free_ char **config_dirs = NULL;
+ _cleanup_(context_done) Context c = {};
bool invalid_config = false;
ItemArray *a;
enum {
assert(!arg_image);
#endif
- items = ordered_hashmap_new(&item_array_hash_ops);
- globs = ordered_hashmap_new(&item_array_hash_ops);
- if (!items || !globs)
+ c.items = ordered_hashmap_new(&item_array_hash_ops);
+ c.globs = ordered_hashmap_new(&item_array_hash_ops);
+ if (!c.items || !c.globs)
return log_oom();
/* If command line arguments are specified along with --replace, read all
* read configuration and execute it.
*/
if (arg_replace || optind >= argc)
- r = read_config_files(config_dirs, argv + optind, &invalid_config);
+ r = read_config_files(&c, config_dirs, argv + optind, &invalid_config);
else
- r = parse_arguments(config_dirs, argv + optind, &invalid_config);
+ r = parse_arguments(&c, config_dirs, argv + optind, &invalid_config);
if (r < 0)
return r;
- r = read_credential_lines(&invalid_config);
+ r = read_credential_lines(&c, &invalid_config);
if (r < 0)
return r;
/* Let's now link up all child/parent relationships */
- ORDERED_HASHMAP_FOREACH(a, items) {
- r = link_parent(a);
+ ORDERED_HASHMAP_FOREACH(a, c.items) {
+ r = link_parent(&c, a);
if (r < 0)
return r;
}
- ORDERED_HASHMAP_FOREACH(a, globs) {
- r = link_parent(a);
+ ORDERED_HASHMAP_FOREACH(a, c.globs) {
+ r = link_parent(&c, a);
if (r < 0)
return r;
}
continue;
/* The non-globbing ones usually create things, hence we apply them first */
- ORDERED_HASHMAP_FOREACH(a, items) {
- k = process_item_array(a, op);
+ ORDERED_HASHMAP_FOREACH(a, c.items) {
+ k = process_item_array(&c, a, op);
if (k < 0 && r >= 0)
r = k;
}
/* The globbing ones usually alter things, hence we apply them second. */
- ORDERED_HASHMAP_FOREACH(a, globs) {
- k = process_item_array(a, op);
+ ORDERED_HASHMAP_FOREACH(a, c.globs) {
+ k = process_item_array(&c, a, op);
if (k < 0 && r >= 0)
r = k;
}