2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "alloc-util.h"
30 #include "path-lookup.h"
31 #include "path-util.h"
33 #include "stat-util.h"
34 #include "string-util.h"
36 #include "user-util.h"
39 static int user_runtime_dir(char **ret
, const char *suffix
) {
46 e
= getenv("XDG_RUNTIME_DIR");
50 j
= strappend(e
, suffix
);
58 static int user_config_dir(char **ret
, const char *suffix
) {
65 e
= getenv("XDG_CONFIG_HOME");
67 j
= strappend(e
, suffix
);
69 _cleanup_free_
char *home
= NULL
;
71 r
= get_home_dir(&home
);
75 j
= strjoin(home
, "/.config", suffix
);
85 static int user_data_dir(char **ret
, const char *suffix
) {
93 /* We don't treat /etc/xdg/systemd here as the spec
94 * suggests because we assume that is a link to
95 * /etc/systemd/ anyway. */
97 e
= getenv("XDG_DATA_HOME");
99 j
= strappend(e
, suffix
);
101 _cleanup_free_
char *home
= NULL
;
103 r
= get_home_dir(&home
);
107 j
= strjoin(home
, "/.local/share", suffix
);
116 static char** user_dirs(
117 const char *persistent_config
,
118 const char *runtime_config
,
119 const char *generator
,
120 const char *generator_early
,
121 const char *generator_late
,
122 const char *transient
,
123 const char *persistent_control
,
124 const char *runtime_control
) {
126 const char * const config_unit_paths
[] = {
127 USER_CONFIG_UNIT_PATH
,
132 const char * const data_unit_paths
[] = {
133 "/usr/local/lib/systemd/user",
134 "/usr/local/share/systemd/user",
136 "/usr/lib/systemd/user",
137 "/usr/share/systemd/user",
141 _cleanup_strv_free_
char **config_dirs
= NULL
, **data_dirs
= NULL
;
142 _cleanup_free_
char *data_home
= NULL
;
143 _cleanup_strv_free_
char **res
= NULL
;
148 /* Implement the mechanisms defined in
150 * http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
152 * We look in both the config and the data dirs because we
153 * want to encourage that distributors ship their unit files
154 * as data, and allow overriding as configuration.
157 e
= getenv("XDG_CONFIG_DIRS");
159 config_dirs
= strv_split(e
, ":");
164 r
= user_data_dir(&data_home
, "/systemd/user");
165 if (r
< 0 && r
!= -ENXIO
)
168 e
= getenv("XDG_DATA_DIRS");
170 data_dirs
= strv_split(e
, ":");
172 data_dirs
= strv_new("/usr/local/share",
178 /* Now merge everything we found. */
179 if (strv_extend(&res
, persistent_control
) < 0)
182 if (strv_extend(&res
, runtime_control
) < 0)
185 if (strv_extend(&res
, transient
) < 0)
188 if (strv_extend(&res
, generator_early
) < 0)
191 if (strv_extend_strv_concat(&res
, config_dirs
, "/systemd/user") < 0)
194 if (strv_extend(&res
, persistent_config
) < 0)
197 if (strv_extend_strv(&res
, (char**) config_unit_paths
, false) < 0)
200 if (strv_extend(&res
, runtime_config
) < 0)
203 if (strv_extend(&res
, generator
) < 0)
206 if (strv_extend(&res
, data_home
) < 0)
209 if (strv_extend_strv_concat(&res
, data_dirs
, "/systemd/user") < 0)
212 if (strv_extend_strv(&res
, (char**) data_unit_paths
, false) < 0)
215 if (strv_extend(&res
, generator_late
) < 0)
218 if (path_strv_make_absolute_cwd(res
) < 0)
227 static int acquire_generator_dirs(
230 char **generator_early
,
231 char **generator_late
) {
233 _cleanup_free_
char *x
= NULL
, *y
= NULL
, *z
= NULL
;
237 assert(generator_early
);
238 assert(generator_late
);
242 case UNIT_FILE_SYSTEM
:
243 prefix
= "/run/systemd/";
246 case UNIT_FILE_USER
: {
249 e
= getenv("XDG_RUNTIME_DIR");
253 prefix
= strjoina(e
, "/systemd/");
257 case UNIT_FILE_GLOBAL
:
261 assert_not_reached("Hmm, unexpected scope value.");
264 x
= strappend(prefix
, "generator");
268 y
= strappend(prefix
, "generator.early");
272 z
= strappend(prefix
, "generator.late");
277 *generator_early
= y
;
284 static int acquire_transient_dir(UnitFileScope scope
, char **ret
) {
289 case UNIT_FILE_SYSTEM
: {
292 transient
= strdup("/run/systemd/transient");
301 return user_runtime_dir(ret
, "/systemd/transient");
303 case UNIT_FILE_GLOBAL
:
307 assert_not_reached("Hmm, unexpected scope value.");
311 static int acquire_config_dirs(UnitFileScope scope
, char **persistent
, char **runtime
) {
312 _cleanup_free_
char *a
= NULL
, *b
= NULL
;
320 case UNIT_FILE_SYSTEM
:
321 a
= strdup(SYSTEM_CONFIG_UNIT_PATH
);
322 b
= strdup("/run/systemd/system");
325 case UNIT_FILE_GLOBAL
:
326 a
= strdup(USER_CONFIG_UNIT_PATH
);
327 b
= strdup("/run/systemd/user");
331 r
= user_config_dir(&a
, "/systemd/user");
332 if (r
< 0 && r
!= -ENXIO
)
335 r
= user_runtime_dir(runtime
, "/systemd/user");
340 /* If XDG_RUNTIME_DIR is not set, don't consider that fatal, simply initialize the runtime
341 * directory to NULL */
351 assert_not_reached("Hmm, unexpected scope value.");
364 static int acquire_control_dirs(UnitFileScope scope
, char **persistent
, char **runtime
) {
365 _cleanup_free_
char *a
= NULL
;
373 case UNIT_FILE_SYSTEM
: {
374 _cleanup_free_
char *b
= NULL
;
376 a
= strdup("/etc/systemd/system.control");
380 b
= strdup("/run/systemd/system.control");
391 r
= user_config_dir(&a
, "/systemd/system.control");
392 if (r
< 0 && r
!= -ENXIO
)
395 r
= user_runtime_dir(runtime
, "/systemd/system.control");
400 /* If XDG_RUNTIME_DIR is not set, don't consider this fatal, simply initialize the directory to
407 case UNIT_FILE_GLOBAL
:
411 assert_not_reached("Hmm, unexpected scope value.");
420 static int patch_root_prefix(char **p
, const char *root_dir
) {
428 c
= prefix_root(root_dir
, *p
);
438 static int patch_root_prefix_strv(char **l
, const char *root_dir
) {
446 r
= patch_root_prefix(i
, root_dir
);
454 int lookup_paths_init(
457 LookupPathsFlags flags
,
458 const char *root_dir
) {
462 *persistent_config
= NULL
, *runtime_config
= NULL
,
463 *generator
= NULL
, *generator_early
= NULL
, *generator_late
= NULL
,
465 *persistent_control
= NULL
, *runtime_control
= NULL
;
466 bool append
= false; /* Add items from SYSTEMD_UNIT_PATH before normal directories */
467 _cleanup_strv_free_
char **paths
= NULL
;
473 assert(scope
< _UNIT_FILE_SCOPE_MAX
);
475 if (!isempty(root_dir
) && !path_equal(root_dir
, "/")) {
476 if (scope
== UNIT_FILE_USER
)
479 r
= is_dir(root_dir
, true);
485 root
= strdup(root_dir
);
490 /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_config to NULL */
491 r
= acquire_config_dirs(scope
, &persistent_config
, &runtime_config
);
495 if ((flags
& LOOKUP_PATHS_EXCLUDE_GENERATED
) == 0) {
496 /* Note: if XDG_RUNTIME_DIR is not set, this will fail completely with ENXIO */
497 r
= acquire_generator_dirs(scope
, &generator
, &generator_early
, &generator_late
);
498 if (r
< 0 && r
!= -EOPNOTSUPP
&& r
!= -ENXIO
)
502 /* Note: if XDG_RUNTIME_DIR is not set, this will fail completely with ENXIO */
503 r
= acquire_transient_dir(scope
, &transient
);
504 if (r
< 0 && r
!= -EOPNOTSUPP
&& r
!= -ENXIO
)
507 /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_control to NULL */
508 r
= acquire_control_dirs(scope
, &persistent_control
, &runtime_control
);
509 if (r
< 0 && r
!= -EOPNOTSUPP
)
512 /* First priority is whatever has been passed to us via env vars */
513 e
= getenv("SYSTEMD_UNIT_PATH");
517 k
= endswith(e
, ":");
519 e
= strndupa(e
, k
- e
);
523 /* FIXME: empty components in other places should be
526 r
= path_split_and_make_absolute(e
, &paths
);
531 if (!paths
|| append
) {
532 /* Let's figure something out. */
534 _cleanup_strv_free_
char **add
= NULL
;
536 /* For the user units we include share/ in the search
537 * path in order to comply with the XDG basedir spec.
538 * For the system stuff we avoid such nonsense. OTOH
539 * we include /lib in the search path for the system
540 * stuff but avoid it for user stuff. */
544 case UNIT_FILE_SYSTEM
:
546 /* If you modify this you also want to modify
547 * systemdsystemunitpath= in systemd.pc.in! */
548 STRV_IFNOTNULL(persistent_control
),
549 STRV_IFNOTNULL(runtime_control
),
550 STRV_IFNOTNULL(transient
),
551 STRV_IFNOTNULL(generator_early
),
553 SYSTEM_CONFIG_UNIT_PATH
,
554 "/etc/systemd/system",
556 "/run/systemd/system",
557 STRV_IFNOTNULL(generator
),
558 "/usr/local/lib/systemd/system",
559 SYSTEM_DATA_UNIT_PATH
,
560 "/usr/lib/systemd/system",
561 #ifdef HAVE_SPLIT_USR
562 "/lib/systemd/system",
564 STRV_IFNOTNULL(generator_late
),
568 case UNIT_FILE_GLOBAL
:
570 /* If you modify this you also want to modify
571 * systemduserunitpath= in systemd.pc.in, and
572 * the arrays in user_dirs() above! */
573 STRV_IFNOTNULL(persistent_control
),
574 STRV_IFNOTNULL(runtime_control
),
575 STRV_IFNOTNULL(transient
),
576 STRV_IFNOTNULL(generator_early
),
578 USER_CONFIG_UNIT_PATH
,
582 STRV_IFNOTNULL(generator
),
583 "/usr/local/lib/systemd/user",
584 "/usr/local/share/systemd/user",
586 "/usr/lib/systemd/user",
587 "/usr/share/systemd/user",
588 STRV_IFNOTNULL(generator_late
),
593 add
= user_dirs(persistent_config
, runtime_config
,
594 generator
, generator_early
, generator_late
,
596 persistent_config
, runtime_control
);
600 assert_not_reached("Hmm, unexpected scope?");
607 r
= strv_extend_strv(&paths
, add
, true);
611 /* Small optimization: if paths is NULL (and it usually is), we can simply assign 'add' to it,
612 * and don't have to copy anything */
618 r
= patch_root_prefix(&persistent_config
, root
);
621 r
= patch_root_prefix(&runtime_config
, root
);
625 r
= patch_root_prefix(&generator
, root
);
628 r
= patch_root_prefix(&generator_early
, root
);
631 r
= patch_root_prefix(&generator_late
, root
);
635 r
= patch_root_prefix(&transient
, root
);
639 r
= patch_root_prefix(&persistent_control
, root
);
643 r
= patch_root_prefix(&runtime_control
, root
);
647 r
= patch_root_prefix_strv(paths
, root
);
651 p
->search_path
= strv_uniq(paths
);
654 p
->persistent_config
= persistent_config
;
655 p
->runtime_config
= runtime_config
;
656 persistent_config
= runtime_config
= NULL
;
658 p
->generator
= generator
;
659 p
->generator_early
= generator_early
;
660 p
->generator_late
= generator_late
;
661 generator
= generator_early
= generator_late
= NULL
;
663 p
->transient
= transient
;
666 p
->persistent_control
= persistent_control
;
667 p
->runtime_control
= runtime_control
;
668 persistent_control
= runtime_control
= NULL
;
676 void lookup_paths_free(LookupPaths
*p
) {
680 p
->search_path
= strv_free(p
->search_path
);
682 p
->persistent_config
= mfree(p
->persistent_config
);
683 p
->runtime_config
= mfree(p
->runtime_config
);
685 p
->generator
= mfree(p
->generator
);
686 p
->generator_early
= mfree(p
->generator_early
);
687 p
->generator_late
= mfree(p
->generator_late
);
689 p
->transient
= mfree(p
->transient
);
691 p
->persistent_control
= mfree(p
->persistent_control
);
692 p
->runtime_control
= mfree(p
->runtime_control
);
694 p
->root_dir
= mfree(p
->root_dir
);
697 int lookup_paths_reduce(LookupPaths
*p
) {
698 _cleanup_free_
struct stat
*stats
= NULL
;
699 size_t n_stats
= 0, allocated
= 0;
705 /* Drop duplicates and non-existing directories from the search path. We figure out whether two directories are
706 * the same by comparing their device and inode numbers. Note one special tweak: when we have a root path set,
707 * we do not follow symlinks when retrieving them, because the kernel wouldn't take the root prefix into
708 * account when following symlinks. When we have no root path set this restriction does not apply however. */
713 while (p
->search_path
[c
]) {
718 r
= lstat(p
->search_path
[c
], &st
);
720 r
= stat(p
->search_path
[c
], &st
);
725 /* If something we don't grok happened, let's better leave it in. */
726 log_debug_errno(errno
, "Failed to stat %s: %m", p
->search_path
[c
]);
731 for (k
= 0; k
< n_stats
; k
++) {
732 if (stats
[k
].st_dev
== st
.st_dev
&&
733 stats
[k
].st_ino
== st
.st_ino
)
737 if (k
< n_stats
) /* Is there already an entry with the same device/inode? */
740 if (!GREEDY_REALLOC(stats
, allocated
, n_stats
+1))
743 stats
[n_stats
++] = st
;
748 free(p
->search_path
[c
]);
749 memmove(p
->search_path
+ c
,
750 p
->search_path
+ c
+ 1,
751 (strv_length(p
->search_path
+ c
+ 1) + 1) * sizeof(char*));
754 if (strv_isempty(p
->search_path
)) {
755 log_debug("Ignoring unit files.");
756 p
->search_path
= strv_free(p
->search_path
);
758 _cleanup_free_
char *t
;
760 t
= strv_join(p
->search_path
, "\n\t");
764 log_debug("Looking for unit files in (higher priority first):\n\t%s", t
);
770 int lookup_paths_mkdir_generator(LookupPaths
*p
) {
775 if (!p
->generator
|| !p
->generator_early
|| !p
->generator_late
)
778 r
= mkdir_p_label(p
->generator
, 0755);
780 q
= mkdir_p_label(p
->generator_early
, 0755);
784 q
= mkdir_p_label(p
->generator_late
, 0755);
791 void lookup_paths_trim_generator(LookupPaths
*p
) {
794 /* Trim empty dirs */
797 (void) rmdir(p
->generator
);
798 if (p
->generator_early
)
799 (void) rmdir(p
->generator_early
);
800 if (p
->generator_late
)
801 (void) rmdir(p
->generator_late
);
804 void lookup_paths_flush_generator(LookupPaths
*p
) {
807 /* Flush the generated unit files in full */
810 (void) rm_rf(p
->generator
, REMOVE_ROOT
);
811 if (p
->generator_early
)
812 (void) rm_rf(p
->generator_early
, REMOVE_ROOT
);
813 if (p
->generator_late
)
814 (void) rm_rf(p
->generator_late
, REMOVE_ROOT
);
817 char **generator_binary_paths(UnitFileScope scope
) {
821 case UNIT_FILE_SYSTEM
:
822 return strv_new("/run/systemd/system-generators",
823 "/etc/systemd/system-generators",
824 "/usr/local/lib/systemd/system-generators",
825 SYSTEM_GENERATOR_PATH
,
828 case UNIT_FILE_GLOBAL
:
830 return strv_new("/run/systemd/user-generators",
831 "/etc/systemd/user-generators",
832 "/usr/local/lib/systemd/user-generators",
837 assert_not_reached("Hmm, unexpected scope.");