static bool arg_clean = false;
static bool arg_remove = false;
-static const char *arg_prefix = NULL;
+static char **include_prefixes = NULL;
+static char **exclude_prefixes = NULL;
static const char conf_file_dirs[] =
"/etc/tmpfiles.d\0"
}
static void load_unix_sockets(void) {
- FILE _cleanup_fclose_ *f = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
char line[LINE_MAX];
if (unix_sockets)
path_kill_slashes(s);
- k = set_put(unix_sockets, s);
- if (k < 0) {
- free(s);
-
- if (k != -EEXIST)
- goto fail;
- }
+ k = set_consume(unix_sockets, s);
+ if (k < 0 && k != -EEXIST)
+ goto fail;
}
return;
while ((dent = readdir(d))) {
struct stat s;
usec_t age;
- char _cleanup_free_ *sub_path = NULL;
+ _cleanup_free_ char *sub_path = NULL;
if (streq(dent->d_name, ".") ||
streq(dent->d_name, ".."))
if (maxdepth <= 0)
log_warning("Reached max depth on %s.", sub_path);
else {
- DIR _cleanup_closedir_ *sub_dir;
+ _cleanup_closedir_ DIR *sub_dir;
int q;
sub_dir = xopendirat(dirfd(d), dent->d_name, O_NOFOLLOW|O_NOATIME);
}
static int recursive_relabel_children(Item *i, const char *path) {
- DIR _cleanup_closedir_ *d;
+ _cleanup_closedir_ DIR *d;
int ret = 0;
/* This returns the first error we run into, but nevertheless
union dirent_storage buf;
bool is_dir;
int r;
- char _cleanup_free_ *entry_path = NULL;
+ _cleanup_free_ char *entry_path = NULL;
r = readdir_r(d, &buf.de, &de);
if (r != 0) {
static int glob_item(Item *i, int (*action)(Item *, const char *)) {
int r = 0, k;
- glob_t _cleanup_globfree_ g = {};
+ _cleanup_globfree_ glob_t g = {};
char **fn;
errno = 0;
if (have_effective_cap(CAP_MKNOD) == 0) {
/* In a container we lack CAP_MKNOD. We
- shouldnt attempt to create the device node in
+ shouldn't attempt to create the device node in
that case to avoid noise, and we don't support
virtualized devices in containers anyway. */
r = glob_item(i, item_set_perms);
if (r < 0)
- return 0;
+ return r;
break;
case RECURSIVE_RELABEL_PATH:
}
static int clean_item_instance(Item *i, const char* instance) {
- DIR _cleanup_closedir_ *d = NULL;
+ _cleanup_closedir_ DIR *d = NULL;
struct stat s, ps;
bool mountpoint;
int r;
free(i);
}
+static inline void item_freep(Item **i) {
+ if (*i)
+ item_free(*i);
+}
+#define _cleanup_item_free_ _cleanup_(item_freep)
+
static bool item_equal(Item *a, Item *b) {
assert(a);
assert(b);
return true;
}
+static bool should_include_path(const char *path) {
+ char **prefix;
+
+ STRV_FOREACH(prefix, exclude_prefixes) {
+ if (path_startswith(path, *prefix))
+ return false;
+ }
+
+ STRV_FOREACH(prefix, include_prefixes) {
+ if (path_startswith(path, *prefix))
+ return true;
+ }
+
+ /* no matches, so we should include this path only if we
+ * have no whitelist at all */
+ return strv_length(include_prefixes) == 0;
+}
+
static int parse_line(const char *fname, unsigned line, const char *buffer) {
- Item _cleanup_free_ *i = NULL;
+ _cleanup_item_free_ Item *i = NULL;
Item *existing;
- char _cleanup_free_
+ _cleanup_free_ char
*mode = NULL, *user = NULL, *group = NULL, *age = NULL;
char type;
Hashmap *h;
path_kill_slashes(i->path);
- if (arg_prefix && !path_startswith(i->path, arg_prefix))
+ if (!should_include_path(i->path))
return 0;
if (user && !streq(user, "-")) {
printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
"Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
- " -h --help Show this help\n"
- " --create Create marked files/directories\n"
- " --clean Clean up marked directories\n"
- " --remove Remove marked files/directories\n"
- " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n",
+ " -h --help Show this help\n"
+ " --create Create marked files/directories\n"
+ " --clean Clean up marked directories\n"
+ " --remove Remove marked files/directories\n"
+ " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n"
+ " --exclude-prefix=PATH Ignore rules that apply to paths with the specified prefix\n",
program_invocation_short_name);
return 0;
ARG_CREATE,
ARG_CLEAN,
ARG_REMOVE,
- ARG_PREFIX
+ ARG_PREFIX,
+ ARG_EXCLUDE_PREFIX,
};
static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "create", no_argument, NULL, ARG_CREATE },
- { "clean", no_argument, NULL, ARG_CLEAN },
- { "remove", no_argument, NULL, ARG_REMOVE },
- { "prefix", required_argument, NULL, ARG_PREFIX },
- { NULL, 0, NULL, 0 }
+ { "help", no_argument, NULL, 'h' },
+ { "create", no_argument, NULL, ARG_CREATE },
+ { "clean", no_argument, NULL, ARG_CLEAN },
+ { "remove", no_argument, NULL, ARG_REMOVE },
+ { "prefix", required_argument, NULL, ARG_PREFIX },
+ { "exclude-prefix", required_argument, NULL, ARG_EXCLUDE_PREFIX },
+ { NULL, 0, NULL, 0 }
};
int c;
break;
case ARG_PREFIX:
- arg_prefix = optarg;
+ if (strv_extend(&include_prefixes, optarg) < 0)
+ return log_oom();
+ break;
+
+ case ARG_EXCLUDE_PREFIX:
+ if (strv_extend(&exclude_prefixes, optarg) < 0)
+ return log_oom();
break;
case '?':
hashmap_free(items);
hashmap_free(globs);
+ strv_free(include_prefixes);
+
set_free_free(unix_sockets);
label_finish();