mirror of
https://github.com/systemd/systemd.git
synced 2024-11-24 02:33:36 +08:00
tmpfiles: add --user switch
This commit is contained in:
parent
ca23eeb54c
commit
f2b5ca0e4e
@ -115,7 +115,7 @@
|
||||
<varname>T</varname>,
|
||||
<varname>a</varname>, and
|
||||
<varname>A</varname> have their ownership, access mode and
|
||||
security labels set. </para></listitem>
|
||||
security labels set.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -134,6 +134,12 @@
|
||||
removed.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--user</option></term>
|
||||
<listitem><para>Execute "user" configuration, i.e. <filename>tmpfiles.d</filename>
|
||||
files in user configuration directories.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--boot</option></term>
|
||||
<listitem><para>Also execute lines with an exclamation mark.
|
||||
|
@ -48,9 +48,17 @@
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<para><filename>/etc/tmpfiles.d/*.conf</filename></para>
|
||||
<para><filename>/run/tmpfiles.d/*.conf</filename></para>
|
||||
<para><filename>/usr/lib/tmpfiles.d/*.conf</filename></para>
|
||||
<para><literallayout><filename>/etc/tmpfiles.d/*.conf</filename>
|
||||
<filename>/run/tmpfiles.d/*.conf</filename>
|
||||
<filename>/usr/lib/tmpfiles.d/*.conf</filename>
|
||||
</literallayout></para>
|
||||
|
||||
<para><literallayout><filename>~/.config/user-tmpfiles.d/*.conf</filename>
|
||||
<filename>$XDG_RUNTIME_DIR/user-tmpfiles.d/*.conf</filename>
|
||||
<filename>~/.local/share/user-tmpfiles.d/*.conf</filename>
|
||||
<filename>…</filename>
|
||||
<filename>/usr/share/user-tmpfiles.d/*.conf</filename>
|
||||
</literallayout></para>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "mkdir.h"
|
||||
#include "mount-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-lookup.h"
|
||||
#include "path-util.h"
|
||||
#include "rm-rf.h"
|
||||
#include "selinux-util.h"
|
||||
@ -151,6 +152,7 @@ typedef struct ItemArray {
|
||||
size_t size;
|
||||
} ItemArray;
|
||||
|
||||
static bool arg_user = false;
|
||||
static bool arg_create = false;
|
||||
static bool arg_clean = false;
|
||||
static bool arg_remove = false;
|
||||
@ -160,8 +162,6 @@ static char **arg_include_prefixes = NULL;
|
||||
static char **arg_exclude_prefixes = NULL;
|
||||
static char *arg_root = NULL;
|
||||
|
||||
static const char conf_file_dirs[] = CONF_PATHS_NULSTR("tmpfiles.d");
|
||||
|
||||
#define MAX_DEPTH 256
|
||||
|
||||
static OrderedHashmap *items = NULL, *globs = NULL;
|
||||
@ -214,6 +214,57 @@ static int log_unresolvable_specifier(const char *filename, unsigned line) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int user_config_paths(char*** ret) {
|
||||
_cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
|
||||
_cleanup_free_ char *persistent_config = NULL, *runtime_config = NULL, *data_home = NULL;
|
||||
_cleanup_strv_free_ char **res = NULL;
|
||||
int r;
|
||||
|
||||
r = xdg_user_dirs(&config_dirs, &data_dirs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = xdg_user_config_dir(&persistent_config, "/user-tmpfiles.d");
|
||||
if (r < 0 && r != -ENXIO)
|
||||
return r;
|
||||
|
||||
r = xdg_user_runtime_dir(&runtime_config, "/user-tmpfiles.d");
|
||||
if (r < 0 && r != -ENXIO)
|
||||
return r;
|
||||
|
||||
r = xdg_user_data_dir(&data_home, "/user-tmpfiles.d");
|
||||
if (r < 0 && r != -ENXIO)
|
||||
return r;
|
||||
|
||||
r = strv_extend_strv_concat(&res, config_dirs, "/user-tmpfiles.d");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = strv_extend(&res, persistent_config);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = strv_extend(&res, runtime_config);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = strv_extend(&res, data_home);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = strv_extend_strv_concat(&res, data_dirs, "/user-tmpfiles.d");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = path_strv_make_absolute_cwd(res);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = res;
|
||||
res = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool needs_glob(ItemType t) {
|
||||
return IN_SET(t,
|
||||
WRITE_FILE,
|
||||
@ -2175,6 +2226,7 @@ static void help(void) {
|
||||
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"
|
||||
" --user Execute user configuration\n"
|
||||
" --version Show package version\n"
|
||||
" --create Create marked files/directories\n"
|
||||
" --clean Clean up marked directories\n"
|
||||
@ -2190,6 +2242,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_USER,
|
||||
ARG_CREATE,
|
||||
ARG_CLEAN,
|
||||
ARG_REMOVE,
|
||||
@ -2201,6 +2254,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "user", no_argument, NULL, ARG_USER },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "create", no_argument, NULL, ARG_CREATE },
|
||||
{ "clean", no_argument, NULL, ARG_CLEAN },
|
||||
@ -2228,6 +2282,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
case ARG_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_USER:
|
||||
arg_user = true;
|
||||
break;
|
||||
|
||||
case ARG_CREATE:
|
||||
arg_create = true;
|
||||
break;
|
||||
@ -2275,7 +2333,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_config_file(const char *fn, bool ignore_enoent, bool *invalid_config) {
|
||||
static int read_config_file(const char **config_dirs, const char *fn, bool ignore_enoent, bool *invalid_config) {
|
||||
_cleanup_fclose_ FILE *_f = NULL;
|
||||
FILE *f;
|
||||
char line[LINE_MAX];
|
||||
@ -2291,7 +2349,7 @@ static int read_config_file(const char *fn, bool ignore_enoent, bool *invalid_co
|
||||
fn = "<stdin>";
|
||||
f = stdin;
|
||||
} else {
|
||||
r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &_f);
|
||||
r = search_and_fopen(fn, "re", arg_root, config_dirs, &_f);
|
||||
if (r < 0) {
|
||||
if (ignore_enoent && r == -ENOENT) {
|
||||
log_debug_errno(r, "Failed to open \"%s\", ignoring: %m", fn);
|
||||
@ -2367,7 +2425,9 @@ int main(int argc, char *argv[]) {
|
||||
int r, k;
|
||||
ItemArray *a;
|
||||
Iterator iterator;
|
||||
_cleanup_strv_free_ char **config_dirs = NULL;
|
||||
bool invalid_config = false;
|
||||
char **f;
|
||||
|
||||
r = parse_argv(argc, argv);
|
||||
if (r <= 0)
|
||||
@ -2391,27 +2451,48 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
r = 0;
|
||||
|
||||
if (arg_user) {
|
||||
r = user_config_paths(&config_dirs);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to initialize configuration directory list: %m");
|
||||
goto finish;
|
||||
}
|
||||
} else {
|
||||
config_dirs = strv_split_nulstr(CONF_PATHS_NULSTR("tmpfiles.d"));
|
||||
if (!config_dirs) {
|
||||
r = log_oom();
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
t = strv_join(config_dirs, "\n\t");
|
||||
if (t)
|
||||
log_debug("Looking for configuration files in (higher priority first:\n\t%s", t);
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
int j;
|
||||
|
||||
for (j = optind; j < argc; j++) {
|
||||
k = read_config_file(argv[j], false, &invalid_config);
|
||||
k = read_config_file((const char**) config_dirs, argv[j], false, &invalid_config);
|
||||
if (k < 0 && r == 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
} else {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
char **f;
|
||||
|
||||
r = conf_files_list_nulstr(&files, ".conf", arg_root, 0, conf_file_dirs);
|
||||
r = conf_files_list_strv(&files, ".conf", arg_root, 0, (const char* const*) config_dirs);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to enumerate tmpfiles.d files: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
STRV_FOREACH(f, files) {
|
||||
k = read_config_file(*f, true, &invalid_config);
|
||||
k = read_config_file((const char**) config_dirs, *f, true, &invalid_config);
|
||||
if (k < 0 && r == 0)
|
||||
r = k;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user