mirror of
https://github.com/systemd/systemd.git
synced 2025-01-09 01:18:19 +03:00
path: add new "systemd-path" utility for querying paths described in file-hierarchy(7)
This new tool is based on "sd-path", a new (so far unexported) API for libsystemd, that can hopefully grow into a workable API covering /opt and more one day.
This commit is contained in:
parent
cd4ba18a84
commit
9a00f57a5b
1
.gitignore
vendored
1
.gitignore
vendored
@ -86,6 +86,7 @@
|
||||
/systemd-networkd-wait-online
|
||||
/systemd-notify
|
||||
/systemd-nspawn
|
||||
/systemd-path
|
||||
/systemd-quotacheck
|
||||
/systemd-random-seed
|
||||
/systemd-rc-local-generator
|
||||
|
@ -74,6 +74,7 @@ MANPAGES += \
|
||||
man/systemd-machine-id-setup.1 \
|
||||
man/systemd-notify.1 \
|
||||
man/systemd-nspawn.1 \
|
||||
man/systemd-path.1 \
|
||||
man/systemd-remount-fs.service.8 \
|
||||
man/systemd-run.1 \
|
||||
man/systemd-shutdownd.service.8 \
|
||||
@ -1619,6 +1620,7 @@ EXTRA_DIST += \
|
||||
man/systemd-networkd.service.xml \
|
||||
man/systemd-notify.xml \
|
||||
man/systemd-nspawn.xml \
|
||||
man/systemd-path.xml \
|
||||
man/systemd-quotacheck.service.xml \
|
||||
man/systemd-random-seed.service.xml \
|
||||
man/systemd-readahead-replay.service.xml \
|
||||
|
20
Makefile.am
20
Makefile.am
@ -187,6 +187,8 @@ AM_CPPFLAGS = \
|
||||
-DPOLKIT_AGENT_BINARY_PATH=\"$(bindir)/pkttyagent\" \
|
||||
-DQUOTACHECK=\"$(QUOTACHECK)\" \
|
||||
-DKEXEC=\"$(KEXEC)\" \
|
||||
-DLIBDIR=\"$(libdir)\" \
|
||||
-DROOTLIBDIR=\"$(rootlibdir)\" \
|
||||
-I $(top_srcdir)/src \
|
||||
-I $(top_builddir)/src/shared \
|
||||
-I $(top_srcdir)/src/shared \
|
||||
@ -344,7 +346,8 @@ bin_PROGRAMS = \
|
||||
systemd-detect-virt \
|
||||
systemd-delta \
|
||||
systemd-analyze \
|
||||
systemd-run
|
||||
systemd-run \
|
||||
systemd-path
|
||||
|
||||
dist_bin_SCRIPTS = \
|
||||
src/kernel-install/kernel-install
|
||||
@ -2096,6 +2099,14 @@ systemd_notify_LDADD = \
|
||||
libsystemd-internal.la \
|
||||
libsystemd-shared.la
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
systemd_path_SOURCES = \
|
||||
src/path/path.c
|
||||
|
||||
systemd_path_LDADD = \
|
||||
libsystemd-internal.la \
|
||||
libsystemd-shared.la
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
systemd_ask_password_SOURCES = \
|
||||
src/ask-password/ask-password.c
|
||||
@ -2221,6 +2232,7 @@ libsystemd_internal_la_SOURCES = \
|
||||
src/systemd/sd-login.h \
|
||||
src/systemd/sd-id128.h \
|
||||
src/systemd/sd-daemon.h \
|
||||
src/systemd/sd-path.h \
|
||||
src/libsystemd/sd-bus/sd-bus.c \
|
||||
src/libsystemd/sd-bus/bus-control.c \
|
||||
src/libsystemd/sd-bus/bus-control.h \
|
||||
@ -2274,7 +2286,8 @@ libsystemd_internal_la_SOURCES = \
|
||||
src/libsystemd/sd-rtnl/rtnl-util.c \
|
||||
src/libsystemd/sd-id128/sd-id128.c \
|
||||
src/libsystemd/sd-daemon/sd-daemon.c \
|
||||
src/libsystemd/sd-login/sd-login.c
|
||||
src/libsystemd/sd-login/sd-login.c \
|
||||
src/libsystemd/sd-path/sd-path.c
|
||||
|
||||
nodist_libsystemd_internal_la_SOURCES = \
|
||||
src/libsystemd/libsystemd.sym \
|
||||
@ -2377,7 +2390,8 @@ pkginclude_HEADERS += \
|
||||
src/systemd/sd-utf8.h \
|
||||
src/systemd/sd-event.h \
|
||||
src/systemd/sd-rtnl.h \
|
||||
src/systemd/sd-resolve.h
|
||||
src/systemd/sd-resolve.h \
|
||||
src/systemd/sd-path.h
|
||||
endif
|
||||
|
||||
lib_LTLIBRARIES += \
|
||||
|
@ -62,6 +62,11 @@
|
||||
subset of these specifications that defines more
|
||||
strictly the suggestions and restrictions systemd
|
||||
makes on the file system hierarchy.</para>
|
||||
|
||||
<para>Many of the paths described here are queriable
|
||||
with the
|
||||
<citerefentry><refentrytitle>systemd-path</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
tool.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
@ -296,8 +301,8 @@
|
||||
<varlistentry>
|
||||
<term><filename>/usr/lib/<replaceable>arch-id</replaceable></filename></term>
|
||||
<listitem><para>Location for placing
|
||||
dynamic libraries, called <varname>$libdir</varname>.
|
||||
The architecture identifier to use, is defined on <ulink
|
||||
dynamic libraries, also called <varname>$libdir</varname>.
|
||||
The architecture identifier to use is defined on <ulink
|
||||
url="https://wiki.debian.org/Multiarch/Tuples">Multiarch Architecture Specifiers (Tuples)</ulink>
|
||||
list. Legacy locations of <varname>$libdir</varname> are
|
||||
<filename>/usr/lib</filename>,
|
||||
@ -309,7 +314,10 @@
|
||||
<varname>$libdir</varname> for the
|
||||
primary architecture of the system,
|
||||
invoke:
|
||||
<programlisting># pkg-config --variable=libdir systemd</programlisting></para></listitem>
|
||||
<programlisting># pkg-config --variable=libdir systemd</programlisting> or
|
||||
<programlisting># systemd-path system-library-arch</programlisting>
|
||||
</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -621,7 +629,10 @@
|
||||
of these directories are also standardized (though
|
||||
more weakly) by the <ulink
|
||||
url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG
|
||||
Base Directory Specification</ulink>.</para>
|
||||
Base Directory Specification</ulink>. Additional
|
||||
locations for high-level user resources are defined by
|
||||
<ulink
|
||||
url="http://www.freedesktop.org/wiki/Software/xdg-user-dirs/">xdg-user-dirs</ulink>.</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
@ -952,6 +963,7 @@
|
||||
<para>
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>hier</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd-path</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd-boot-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||
|
111
man/systemd-path.xml
Normal file
111
man/systemd-path.xml
Normal file
@ -0,0 +1,111 @@
|
||||
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||
|
||||
<!--
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2014 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<refentry id="systemd-path"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
<refentryinfo>
|
||||
<title>systemd-path</title>
|
||||
<productname>systemd</productname>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<contrib>Developer</contrib>
|
||||
<firstname>Lennart</firstname>
|
||||
<surname>Poettering</surname>
|
||||
<email>lennart@poettering.net</email>
|
||||
</author>
|
||||
</authorgroup>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>systemd-path</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>systemd-path</refname>
|
||||
<refpurpose>List and query system and user paths</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-path <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">NAME</arg></command>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para><command>systemd-path</command> may be used to
|
||||
query system and user paths. The tool makes many of
|
||||
the paths described in
|
||||
<citerefentry><refentrytitle>file-hierarchy</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||
queriable.</para>
|
||||
|
||||
<para>When invoked without arguments a list of known
|
||||
paths and their current values is shown. When at least
|
||||
one argument is passed the path with this is name is
|
||||
queried and its value shown. The variables whose name
|
||||
begins with <literal>search-</literal> don't refer to
|
||||
individual paths, but instead a to a list of
|
||||
colon-separated search paths, in their order of
|
||||
precedence.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Options</title>
|
||||
|
||||
<para>The following options are understood:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>--suffix=</option></term>
|
||||
|
||||
<listitem><para>The printed paths are
|
||||
suffixed by the specified
|
||||
string.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Exit status</title>
|
||||
|
||||
<para>On success, 0 is returned, a non-zero failure
|
||||
code otherwise.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See Also</title>
|
||||
<para>
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>file-hierarchy</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
1
src/libsystemd/sd-path/Makefile
Symbolic link
1
src/libsystemd/sd-path/Makefile
Symbolic link
@ -0,0 +1 @@
|
||||
../Makefile
|
626
src/libsystemd/sd-path/sd-path.c
Normal file
626
src/libsystemd/sd-path/sd-path.c
Normal file
@ -0,0 +1,626 @@
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2014 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "util.h"
|
||||
#include "architecture.h"
|
||||
#include "path-util.h"
|
||||
#include "strv.h"
|
||||
#include "sd-path.h"
|
||||
|
||||
static int from_environment(const char *envname, const char *fallback, const char **ret) {
|
||||
assert(ret);
|
||||
|
||||
if (envname) {
|
||||
const char *e;
|
||||
|
||||
e = secure_getenv(envname);
|
||||
if (e && path_is_absolute(e)) {
|
||||
*ret = e;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (fallback) {
|
||||
*ret = fallback;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static int from_home_dir(const char *envname, const char *suffix, char **buffer, const char **ret) {
|
||||
_cleanup_free_ char *h = NULL;
|
||||
char *cc = NULL;
|
||||
int r;
|
||||
|
||||
assert(suffix);
|
||||
assert(buffer);
|
||||
assert(ret);
|
||||
|
||||
if (envname) {
|
||||
const char *e = NULL;
|
||||
|
||||
e = secure_getenv(envname);
|
||||
if (e && path_is_absolute(e)) {
|
||||
*ret = e;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
r = get_home_dir(&h);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (endswith(h, "/"))
|
||||
cc = strappend(h, suffix);
|
||||
else
|
||||
cc = strjoin(h, "/", suffix, NULL);
|
||||
if (!cc)
|
||||
return -ENOMEM;
|
||||
|
||||
*buffer = cc;
|
||||
*ret = cc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int from_user_dir(const char *field, char **buffer, const char **ret) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_free_ char *b = NULL;
|
||||
const char *fn = NULL;
|
||||
char line[LINE_MAX];
|
||||
size_t n;
|
||||
int r;
|
||||
|
||||
assert(field);
|
||||
assert(buffer);
|
||||
assert(ret);
|
||||
|
||||
r = from_home_dir(NULL, ".config/user-dirs.dirs", &b, &fn);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
f = fopen(fn, "re");
|
||||
if (!f) {
|
||||
if (errno == ENOENT)
|
||||
goto fallback;
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* This is an awful parse, but it follows closely what
|
||||
* xdg-user-dirs does upstream */
|
||||
|
||||
n = strlen(field);
|
||||
FOREACH_LINE(line, f, return -errno) {
|
||||
char *l, *p, *e;
|
||||
|
||||
l = strstrip(line);
|
||||
|
||||
if (!strneq(l, field, n))
|
||||
continue;
|
||||
|
||||
p = l + n;
|
||||
p += strspn(p, WHITESPACE);
|
||||
|
||||
if (*p != '=')
|
||||
continue;
|
||||
p++;
|
||||
|
||||
p += strspn(p, WHITESPACE);
|
||||
|
||||
if (*p != '"')
|
||||
continue;
|
||||
p++;
|
||||
|
||||
e = strrchr(p, '"');
|
||||
if (!e)
|
||||
continue;
|
||||
*e = 0;
|
||||
|
||||
/* Three syntaxes permitted: relative to $HOME, $HOME itself, and absolute path */
|
||||
if (startswith(p, "$HOME/")) {
|
||||
_cleanup_free_ char *h = NULL;
|
||||
char *cc;
|
||||
|
||||
r = get_home_dir(&h);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
cc = strappend(h, p+5);
|
||||
if (!cc)
|
||||
return -ENOMEM;
|
||||
|
||||
*buffer = cc;
|
||||
*ret = cc;
|
||||
return 0;
|
||||
} else if (streq(p, "$HOME")) {
|
||||
|
||||
r = get_home_dir(buffer);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = *buffer;
|
||||
return 0;
|
||||
} else if (path_is_absolute(p)) {
|
||||
char *copy;
|
||||
|
||||
copy = strdup(p);
|
||||
if (!copy)
|
||||
return -ENOMEM;
|
||||
|
||||
*buffer = copy;
|
||||
*ret = copy;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fallback:
|
||||
/* The desktop directory defaults to $HOME/Desktop, the others to $HOME */
|
||||
if (streq(field, "XDG_DESKTOP_DIR")) {
|
||||
_cleanup_free_ char *h = NULL;
|
||||
char *cc;
|
||||
|
||||
r = get_home_dir(&h);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
cc = strappend(h, "/Desktop");
|
||||
if (!cc)
|
||||
return -ENOMEM;
|
||||
|
||||
*buffer = cc;
|
||||
*ret = cc;
|
||||
} else {
|
||||
|
||||
r = get_home_dir(buffer);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = *buffer;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path(uint64_t type, char **buffer, const char **ret) {
|
||||
int r;
|
||||
|
||||
assert(buffer);
|
||||
assert(ret);
|
||||
|
||||
switch (type) {
|
||||
|
||||
case SD_PATH_TEMPORARY:
|
||||
return from_environment("TMPDIR", "/tmp", ret);
|
||||
|
||||
case SD_PATH_TEMPORARY_LARGE:
|
||||
return from_environment("TMPDIR", "/var/tmp", ret);
|
||||
|
||||
case SD_PATH_SYSTEM_BINARIES:
|
||||
*ret = "/usr/bin";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_INCLUDE:
|
||||
*ret = "/usr/include";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_LIBRARY_PRIVATE:
|
||||
*ret = "/usr/lib";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_LIBRARY_ARCH:
|
||||
*ret = LIBDIR;
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_SHARED:
|
||||
*ret = "/usr/share";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_CONFIGURATION_FACTORY:
|
||||
*ret = "/usr/share/factory/etc";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_STATE_FACTORY:
|
||||
*ret = "/usr/share/factory/var";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_CONFIGURATION:
|
||||
*ret = "/etc";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_RUNTIME:
|
||||
*ret = "/run";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_RUNTIME_LOGS:
|
||||
*ret = "/run/log";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_STATE_PRIVATE:
|
||||
*ret = "/var/lib";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_STATE_LOGS:
|
||||
*ret = "/var/log";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_STATE_CACHE:
|
||||
*ret = "/var/cache";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_SYSTEM_STATE_SPOOL:
|
||||
*ret = "/var/spool";
|
||||
return 0;
|
||||
|
||||
case SD_PATH_USER_BINARIES:
|
||||
return from_home_dir(NULL, ".local/bin", buffer, ret);
|
||||
|
||||
case SD_PATH_USER_LIBRARY_PRIVATE:
|
||||
return from_home_dir(NULL, ".local/lib", buffer, ret);
|
||||
|
||||
case SD_PATH_USER_LIBRARY_ARCH:
|
||||
return from_home_dir(NULL, ".local/lib/" ARCH_TUPLE, buffer, ret);
|
||||
|
||||
case SD_PATH_USER_SHARED:
|
||||
return from_home_dir("XDG_DATA_HOME", ".local/share", buffer, ret);
|
||||
|
||||
case SD_PATH_USER_CONFIGURATION:
|
||||
return from_home_dir("XDG_CONFIG_HOME", ".config", buffer, ret);
|
||||
|
||||
case SD_PATH_USER_RUNTIME:
|
||||
return from_environment("XDG_RUNTIME_DIR", NULL, ret);
|
||||
|
||||
case SD_PATH_USER_STATE_CACHE:
|
||||
return from_home_dir("XDG_CACHE_HOME", ".cache", buffer, ret);
|
||||
|
||||
case SD_PATH_USER:
|
||||
r = get_home_dir(buffer);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = *buffer;
|
||||
return 0;
|
||||
|
||||
case SD_PATH_USER_DOCUMENTS:
|
||||
return from_user_dir("XDG_DOCUMENTS_DIR", buffer, ret);
|
||||
|
||||
case SD_PATH_USER_MUSIC:
|
||||
return from_user_dir("XDG_MUSIC_DIR", buffer, ret);
|
||||
|
||||
case SD_PATH_USER_PICTURES:
|
||||
return from_user_dir("XDG_PICTURES_DIR", buffer, ret);
|
||||
|
||||
case SD_PATH_USER_VIDEOS:
|
||||
return from_user_dir("XDG_VIDEOS_DIR", buffer, ret);
|
||||
|
||||
case SD_PATH_USER_DOWNLOAD:
|
||||
return from_user_dir("XDG_DOWNLOAD_DIR", buffer, ret);
|
||||
|
||||
case SD_PATH_USER_PUBLIC:
|
||||
return from_user_dir("XDG_PUBLICSHARE_DIR", buffer, ret);
|
||||
|
||||
case SD_PATH_USER_TEMPLATES:
|
||||
return from_user_dir("XDG_TEMPLATES_DIR", buffer, ret);
|
||||
|
||||
case SD_PATH_USER_DESKTOP:
|
||||
return from_user_dir("XDG_DESKTOP_DIR", buffer, ret);
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int sd_path_home(uint64_t type, const char *suffix, char **path) {
|
||||
char *buffer = NULL, *cc;
|
||||
const char *ret;
|
||||
int r;
|
||||
|
||||
assert_return(path, -EINVAL);
|
||||
|
||||
if (IN_SET(type,
|
||||
SD_PATH_SEARCH_BINARIES,
|
||||
SD_PATH_SEARCH_LIBRARY_PRIVATE,
|
||||
SD_PATH_SEARCH_LIBRARY_ARCH,
|
||||
SD_PATH_SEARCH_SHARED,
|
||||
SD_PATH_SEARCH_CONFIGURATION_FACTORY,
|
||||
SD_PATH_SEARCH_STATE_FACTORY,
|
||||
SD_PATH_SEARCH_CONFIGURATION)) {
|
||||
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
||||
r = sd_path_search(type, suffix, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
buffer = strv_join(l, ":");
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
*path = buffer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = get_path(type, &buffer, &ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!suffix) {
|
||||
if (!buffer) {
|
||||
buffer = strdup(ret);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*path = buffer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
suffix += strspn(suffix, "/");
|
||||
|
||||
if (endswith(ret, "/"))
|
||||
cc = strappend(ret, suffix);
|
||||
else
|
||||
cc = strjoin(ret, "/", suffix, NULL);
|
||||
|
||||
free(buffer);
|
||||
|
||||
if (!cc)
|
||||
return -ENOMEM;
|
||||
|
||||
*path = cc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int search_from_environment(
|
||||
char ***list,
|
||||
const char *env_home,
|
||||
const char *home_suffix,
|
||||
const char *env_search,
|
||||
bool env_search_sufficient,
|
||||
const char *first, ...) {
|
||||
|
||||
const char *e;
|
||||
char *h = NULL;
|
||||
char **l = NULL;
|
||||
int r;
|
||||
|
||||
assert(list);
|
||||
|
||||
if (env_search) {
|
||||
e = secure_getenv(env_search);
|
||||
if (e) {
|
||||
l = strv_split(e, ":");
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
if (env_search_sufficient) {
|
||||
*list = l;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!l && first) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, first);
|
||||
l = strv_new_ap(first, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (env_home) {
|
||||
e = secure_getenv(env_home);
|
||||
if (e && path_is_absolute(e)) {
|
||||
h = strdup(e);
|
||||
if (!h) {
|
||||
strv_free(l);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!h && home_suffix) {
|
||||
e = secure_getenv("HOME");
|
||||
if (e && path_is_absolute(e)) {
|
||||
if (endswith(e, "/"))
|
||||
h = strappend(e, home_suffix);
|
||||
else
|
||||
h = strjoin(e, "/", home_suffix, NULL);
|
||||
|
||||
if (!h) {
|
||||
strv_free(l);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (h) {
|
||||
r = strv_consume_prepend(&l, h);
|
||||
if (r < 0) {
|
||||
strv_free(l);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
*list = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_search(uint64_t type, char ***list) {
|
||||
|
||||
assert(list);
|
||||
|
||||
switch(type) {
|
||||
|
||||
case SD_PATH_SEARCH_BINARIES:
|
||||
return search_from_environment(list,
|
||||
NULL,
|
||||
".local/bin",
|
||||
"PATH",
|
||||
true,
|
||||
"/usr/local/sbin",
|
||||
"/usr/local/bin",
|
||||
"/usr/sbin",
|
||||
"/usr/bin",
|
||||
#ifdef HAVE_SPLIT_USR
|
||||
"/sbin",
|
||||
"/bin",
|
||||
#endif
|
||||
NULL);
|
||||
|
||||
case SD_PATH_SEARCH_LIBRARY_PRIVATE:
|
||||
return search_from_environment(list,
|
||||
NULL,
|
||||
".local/lib",
|
||||
NULL,
|
||||
false,
|
||||
"/usr/local/lib",
|
||||
"/usr/lib",
|
||||
#ifdef HAVE_SPLIT_USR
|
||||
"/lib",
|
||||
#endif
|
||||
NULL);
|
||||
|
||||
case SD_PATH_SEARCH_LIBRARY_ARCH:
|
||||
return search_from_environment(list,
|
||||
NULL,
|
||||
".local/lib/" ARCH_TUPLE,
|
||||
"LD_LIBRARY_PATH",
|
||||
true,
|
||||
LIBDIR,
|
||||
#ifdef HAVE_SPLIT_USR
|
||||
ROOTLIBDIR,
|
||||
#endif
|
||||
NULL);
|
||||
|
||||
case SD_PATH_SEARCH_SHARED:
|
||||
return search_from_environment(list,
|
||||
"XDG_DATA_HOME",
|
||||
".local/share",
|
||||
"XDG_DATA_DIRS",
|
||||
false,
|
||||
"/usr/local/share",
|
||||
"/usr/share",
|
||||
NULL);
|
||||
|
||||
case SD_PATH_SEARCH_CONFIGURATION_FACTORY:
|
||||
return search_from_environment(list,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
false,
|
||||
"/usr/local/share/factory/etc",
|
||||
"/usr/share/factory/etc",
|
||||
NULL);
|
||||
|
||||
case SD_PATH_SEARCH_STATE_FACTORY:
|
||||
return search_from_environment(list,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
false,
|
||||
"/usr/local/share/factory/var",
|
||||
"/usr/share/factory/var",
|
||||
NULL);
|
||||
|
||||
case SD_PATH_SEARCH_CONFIGURATION:
|
||||
return search_from_environment(list,
|
||||
"XDG_CONFIG_HOME",
|
||||
".config",
|
||||
"XDG_CONFIG_DIRS",
|
||||
false,
|
||||
"/etc",
|
||||
NULL);
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int sd_path_search(uint64_t type, const char *suffix, char ***paths) {
|
||||
char **l, **i, **j, **n;
|
||||
int r;
|
||||
|
||||
assert_return(paths, -EINVAL);
|
||||
|
||||
if (!IN_SET(type,
|
||||
SD_PATH_SEARCH_BINARIES,
|
||||
SD_PATH_SEARCH_LIBRARY_PRIVATE,
|
||||
SD_PATH_SEARCH_LIBRARY_ARCH,
|
||||
SD_PATH_SEARCH_SHARED,
|
||||
SD_PATH_SEARCH_CONFIGURATION_FACTORY,
|
||||
SD_PATH_SEARCH_STATE_FACTORY,
|
||||
SD_PATH_SEARCH_CONFIGURATION)) {
|
||||
|
||||
char *p;
|
||||
|
||||
r = sd_path_home(type, suffix, &p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
l = new(char*, 2);
|
||||
if (!l) {
|
||||
free(p);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
l[0] = p;
|
||||
l[1] = NULL;
|
||||
|
||||
*paths = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = get_search(type, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!suffix) {
|
||||
*paths = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = new(char*, strv_length(l)+1);
|
||||
if (!n) {
|
||||
strv_free(l);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
j = n;
|
||||
STRV_FOREACH(i, l) {
|
||||
|
||||
if (endswith(*i, "/"))
|
||||
*j = strappend(*i, suffix);
|
||||
else
|
||||
*j = strjoin(*i, "/", suffix, NULL);
|
||||
|
||||
if (!*j) {
|
||||
strv_free(l);
|
||||
strv_free(n);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
*j = NULL;
|
||||
*paths = n;
|
||||
return 0;
|
||||
}
|
1
src/path/Makefile
Symbolic link
1
src/path/Makefile
Symbolic link
@ -0,0 +1 @@
|
||||
../Makefile
|
208
src/path/path.c
Normal file
208
src/path/path.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2014 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <error.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sd-path.h"
|
||||
#include "build.h"
|
||||
#include "macro.h"
|
||||
#include "util.h"
|
||||
#include "log.h"
|
||||
|
||||
static const char *arg_suffix = NULL;
|
||||
|
||||
static const char* const path_table[_SD_PATH_MAX] = {
|
||||
[SD_PATH_TEMPORARY] = "temporary",
|
||||
[SD_PATH_TEMPORARY_LARGE] = "temporary-large",
|
||||
[SD_PATH_SYSTEM_BINARIES] = "system-binaries",
|
||||
[SD_PATH_SYSTEM_INCLUDE] = "system-include",
|
||||
[SD_PATH_SYSTEM_LIBRARY_PRIVATE] = "system-library-private",
|
||||
[SD_PATH_SYSTEM_LIBRARY_ARCH] = "system-library-arch",
|
||||
[SD_PATH_SYSTEM_SHARED] = "system-shared",
|
||||
[SD_PATH_SYSTEM_CONFIGURATION_FACTORY] = "system-configuration-factory",
|
||||
[SD_PATH_SYSTEM_STATE_FACTORY] = "system-state-factory",
|
||||
[SD_PATH_SYSTEM_CONFIGURATION] = "system-configuration",
|
||||
[SD_PATH_SYSTEM_RUNTIME] = "system-runtime",
|
||||
[SD_PATH_SYSTEM_RUNTIME_LOGS] = "system-runtime-logs",
|
||||
[SD_PATH_SYSTEM_STATE_PRIVATE] = "system-state-private",
|
||||
[SD_PATH_SYSTEM_STATE_LOGS] = "system-state-logs",
|
||||
[SD_PATH_SYSTEM_STATE_CACHE] = "system-state-cache",
|
||||
[SD_PATH_SYSTEM_STATE_SPOOL] = "system-state-spool",
|
||||
[SD_PATH_USER_BINARIES] = "user-binaries",
|
||||
[SD_PATH_USER_LIBRARY_PRIVATE] = "user-library-private",
|
||||
[SD_PATH_USER_LIBRARY_ARCH] = "user-library-arch",
|
||||
[SD_PATH_USER_SHARED] = "user-shared",
|
||||
[SD_PATH_USER_CONFIGURATION] = "user-configuration",
|
||||
[SD_PATH_USER_RUNTIME] = "user-runtime",
|
||||
[SD_PATH_USER_STATE_CACHE] = "user-state-cache",
|
||||
[SD_PATH_USER] = "user",
|
||||
[SD_PATH_USER_DOCUMENTS] = "user-documents",
|
||||
[SD_PATH_USER_MUSIC] = "user-music",
|
||||
[SD_PATH_USER_PICTURES] = "user-pictures",
|
||||
[SD_PATH_USER_VIDEOS] = "user-videos",
|
||||
[SD_PATH_USER_DOWNLOAD] = "user-download",
|
||||
[SD_PATH_USER_PUBLIC] = "user-public",
|
||||
[SD_PATH_USER_TEMPLATES] = "user-templates",
|
||||
[SD_PATH_USER_DESKTOP] = "user-desktop",
|
||||
[SD_PATH_SEARCH_BINARIES] = "search-binaries",
|
||||
[SD_PATH_SEARCH_LIBRARY_PRIVATE] = "search-library-private",
|
||||
[SD_PATH_SEARCH_LIBRARY_ARCH] = "search-library-arch",
|
||||
[SD_PATH_SEARCH_SHARED] = "search-shared",
|
||||
[SD_PATH_SEARCH_CONFIGURATION_FACTORY] = "search-configuration-factory",
|
||||
[SD_PATH_SEARCH_STATE_FACTORY] = "search-state-factory",
|
||||
[SD_PATH_SEARCH_CONFIGURATION] = "search-configuration",
|
||||
};
|
||||
|
||||
static int help(void) {
|
||||
|
||||
printf("%s [OPTIONS...] [NAME...]\n\n"
|
||||
"Show system and user paths.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
" --suffix=SUFFIX Suffix to append to paths\n",
|
||||
program_invocation_short_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int list_homes(void) {
|
||||
uint64_t i = 0;
|
||||
int r = 0;
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(path_table); i++) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
int q;
|
||||
|
||||
q = sd_path_home(i, arg_suffix, &p);
|
||||
if (q == -ENXIO)
|
||||
continue;
|
||||
if (q < 0) {
|
||||
log_error("Failed to query %s: %s", path_table[i], strerror(-r));
|
||||
r = q;
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("%s: %s\n", path_table[i], p);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int print_home(const char *n) {
|
||||
uint64_t i = 0;
|
||||
int r;
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(path_table); i++) {
|
||||
if (streq(path_table[i], n)) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
||||
r = sd_path_home(i, arg_suffix, &p);
|
||||
if (r < 0) {
|
||||
log_error("Failed to query %s: %s", n, strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
printf("%s\n", p);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
log_error("Path %s not known.", n);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_SUFFIX,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "suffix", required_argument, NULL, ARG_SUFFIX },
|
||||
{}
|
||||
};
|
||||
|
||||
int c;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
|
||||
|
||||
switch (c) {
|
||||
|
||||
case 'h':
|
||||
return help();
|
||||
|
||||
case ARG_VERSION:
|
||||
puts(PACKAGE_STRING);
|
||||
puts(SYSTEMD_FEATURES);
|
||||
return 0;
|
||||
|
||||
case ARG_SUFFIX:
|
||||
arg_suffix = optarg;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached("Unhandled option");
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int r;
|
||||
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
|
||||
r = parse_argv(argc, argv);
|
||||
if (r <= 0)
|
||||
goto finish;
|
||||
|
||||
if (argc > optind) {
|
||||
int i, q;
|
||||
|
||||
for (i = optind; i < argc; i++) {
|
||||
q = print_home(argv[i]);
|
||||
if (q < 0)
|
||||
r = q;
|
||||
}
|
||||
} else
|
||||
r = list_homes();
|
||||
|
||||
|
||||
finish:
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/* A cleaned up architecture definition */
|
||||
|
||||
typedef enum Architecture {
|
||||
ARCHITECTURE_X86 = 0,
|
||||
ARCHITECTURE_X86_64,
|
||||
@ -38,7 +40,9 @@ typedef enum Architecture {
|
||||
ARCHITECTURE_SPARC,
|
||||
ARCHITECTURE_SPARC64,
|
||||
ARCHITECTURE_MIPS,
|
||||
ARCHITECTURE_MIPS_LE,
|
||||
ARCHITECTURE_MIPS64,
|
||||
ARCHITECTURE_MIPS64_LE,
|
||||
ARCHITECTURE_ALPHA,
|
||||
ARCHITECTURE_ARM,
|
||||
ARCHITECTURE_ARM_BE,
|
||||
@ -55,64 +59,107 @@ typedef enum Architecture {
|
||||
|
||||
Architecture uname_architecture(void);
|
||||
|
||||
/*
|
||||
* ARCH_TUPLE should resolve to the local architecture systemd is
|
||||
* built for, according to the Debian tuple list:
|
||||
*
|
||||
* https://wiki.debian.org/Multiarch/Tuples
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__x86_64__)
|
||||
# define native_architecture() ARCHITECTURE_X86_64
|
||||
# define ARCH_TUPLE "x86_64-linux-gnu"
|
||||
#elif defined(__i386__)
|
||||
# define native_architecture() ARCHITECTURE_X86
|
||||
# define ARCH_TUPLE "i386-linux-gnu"
|
||||
#elif defined(__powerpc64__)
|
||||
# if defined(WORDS_BIGENDIAN)
|
||||
# define native_architecture() ARCHITECTURE_PPC64
|
||||
# define ARCH_TUPLE "ppc64-linux-gnu"
|
||||
# else
|
||||
# define native_architecture() ARCHITECTURE_PPC64_LE
|
||||
# error "Missing ARCH_TUPLE for PPC64LE"
|
||||
# endif
|
||||
#elif defined(__powerpc__)
|
||||
# if defined(WORDS_BIGENDIAN)
|
||||
# define native_architecture() ARCHITECTURE_PPC
|
||||
# define ARCH_TUPLE "powerpc-linux-gnu"
|
||||
# else
|
||||
# define native_architecture() ARCHITECTURE_PPC_LE
|
||||
# error "Missing ARCH_TUPLE for PPCLE"
|
||||
# endif
|
||||
#elif defined(__ia64__)
|
||||
# define native_architecture() ARCHITECTURE_IA64
|
||||
# define ARCH_TUPLE "ia64-linux-gnu"
|
||||
#elif defined(__hppa64__)
|
||||
# define native_architecture() ARCHITECTURE_PARISC64
|
||||
# error "Missing ARCH_TUPLE for HPPA64"
|
||||
#elif defined(__hppa__)
|
||||
# define native_architecture() ARCHITECTURE_PARISC
|
||||
# define ARCH_TUPLE "hppa‑linux‑gnu"
|
||||
#elif defined(__s390x__)
|
||||
# define native_architecture() ARCHITECTURE_S390X
|
||||
# define ARCH_TUPLE "s390x-linux-gnu"
|
||||
#elif defined(__s390__)
|
||||
# define native_architecture() ARCHITECTURE_S390
|
||||
# define ARCH_TUPLE "s390-linux-gnu"
|
||||
#elif defined(__sparc64__)
|
||||
# define native_architecture() ARCHITECTURE_SPARC64
|
||||
# define ARCH_TUPLE "sparc64-linux-gnu"
|
||||
#elif defined(__sparc__)
|
||||
# define native_architecture() ARCHITECTURE_SPARC
|
||||
# define ARCH_TUPLE "sparc-linux-gnu"
|
||||
#elif defined(__mips64__)
|
||||
# define native_architecture() ARCHITECTURE_MIPS64
|
||||
# if defined(WORDS_BIGENDIAN)
|
||||
# define native_architecture() ARCHITECTURE_MIPS64
|
||||
# error "Missing ARCH_TUPLE for MIPS64"
|
||||
# else
|
||||
# define native_architecture() ARCHITECTURE_MIPS64_LE
|
||||
# error "Missing ARCH_TUPLE for MIPS64_LE"
|
||||
# endif
|
||||
#elif defined(__mips__)
|
||||
# define native_architecture() ARCHITECTURE_MIPS
|
||||
# if defined(WORDS_BIGENDIAN)
|
||||
# define native_architecture() ARCHITECTURE_MIPS
|
||||
# define ARCH_TUPLE "mips-linux-gnu"
|
||||
# else
|
||||
# define native_architecture() ARCHITECTURE_MIPS_LE
|
||||
# define ARCH_TUPLE "mipsel-linux-gnu"
|
||||
#endif
|
||||
#elif defined(__alpha__)
|
||||
# define native_architecture() ARCHITECTURE_ALPHA
|
||||
# define ARCH_TUPLE "alpha-linux-gnu"
|
||||
#elif defined(__aarch64__)
|
||||
# if defined(WORDS_BIGENDIAN)
|
||||
# define native_architecture() ARCHITECTURE_ARM64_BE
|
||||
# define ARCH_TUPLE "aarch64_be-linux-gnu"
|
||||
# else
|
||||
# define native_architecture() ARCHITECTURE_ARM64
|
||||
# define ARCH_TUPLE "aarch64-linux-gnu"
|
||||
# endif
|
||||
#elif defined(__arm__)
|
||||
# if defined(WORDS_BIGENDIAN)
|
||||
# define native_architecture() ARCHITECTURE_ARM_BE
|
||||
# error "Missing ARCH_TUPLE for ARM_BE"
|
||||
# else
|
||||
# define native_architecture() ARCHITECTURE_ARM
|
||||
# error "Missing ARCH_TUPLE for ARM"
|
||||
# endif
|
||||
#elif defined(__sh64__)
|
||||
# define native_architecture() ARCHITECTURE_SH64
|
||||
# error "Missing ARCH_TUPLE for SH64"
|
||||
#elif defined(__sh__)
|
||||
# define native_architecture() ARCHITECTURE_SH
|
||||
# define ARCH_TUPLE "sh4-linux-gnu"
|
||||
#elif defined(__m68k__)
|
||||
# define native_architecture() ARCHITECTURE_M68K
|
||||
# define ARCH_TUPLE "m68k-linux-gnu"
|
||||
#elif defined(__tilegx__)
|
||||
# define native_architecture() ARCHITECTURE_TILEGX
|
||||
# error "Missing ARCH_TUPLE for TILEGX"
|
||||
#elif defined(__cris__)
|
||||
# define native_architecture() ARCHITECTURE_CRIS
|
||||
# error "Missing ARCH_TUPLE for CRIS"
|
||||
#else
|
||||
#error "Please register your architecture here!"
|
||||
#endif
|
||||
|
@ -378,6 +378,30 @@ int strv_push(char ***l, char *value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int strv_push_prepend(char ***l, char *value) {
|
||||
char **c;
|
||||
unsigned n, i;
|
||||
|
||||
if (!value)
|
||||
return 0;
|
||||
|
||||
n = strv_length(*l);
|
||||
c = new(char*, n + 2);
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
c[i+1] = (*l)[i];
|
||||
|
||||
c[0] = value;
|
||||
c[n+1] = NULL;
|
||||
|
||||
free(*l);
|
||||
*l = c;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int strv_consume(char ***l, char *value) {
|
||||
int r;
|
||||
|
||||
@ -388,6 +412,16 @@ int strv_consume(char ***l, char *value) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int strv_consume_prepend(char ***l, char *value) {
|
||||
int r;
|
||||
|
||||
r = strv_push_prepend(l, value);
|
||||
if (r < 0)
|
||||
free(value);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int strv_extend(char ***l, const char *value) {
|
||||
char *v;
|
||||
|
||||
|
@ -41,7 +41,9 @@ int strv_extend_strv_concat(char ***a, char **b, const char *suffix);
|
||||
int strv_extend(char ***l, const char *value);
|
||||
int strv_extendf(char ***l, const char *format, ...) _printf_(2,0);
|
||||
int strv_push(char ***l, char *value);
|
||||
int strv_push_prepend(char ***l, char *value);
|
||||
int strv_consume(char ***l, char *value);
|
||||
int strv_consume_prepend(char ***l, char *value);
|
||||
|
||||
char **strv_remove(char **l, const char *s);
|
||||
char **strv_uniq(char **l);
|
||||
|
@ -5226,8 +5226,8 @@ int get_home_dir(char **_h) {
|
||||
assert(_h);
|
||||
|
||||
/* Take the user specified one */
|
||||
e = getenv("HOME");
|
||||
if (e) {
|
||||
e = secure_getenv("HOME");
|
||||
if (e && path_is_absolute(e)) {
|
||||
h = strdup(e);
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
87
src/systemd/sd-path.h
Normal file
87
src/systemd/sd-path.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
#ifndef foosdpathhfoo
|
||||
#define foosdpathhfoo
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2014 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
enum {
|
||||
/* Temporary files */
|
||||
SD_PATH_TEMPORARY = 0x0ULL,
|
||||
SD_PATH_TEMPORARY_LARGE,
|
||||
|
||||
/* Vendor supplied data */
|
||||
SD_PATH_SYSTEM_BINARIES,
|
||||
SD_PATH_SYSTEM_INCLUDE,
|
||||
SD_PATH_SYSTEM_LIBRARY_PRIVATE,
|
||||
SD_PATH_SYSTEM_LIBRARY_ARCH,
|
||||
SD_PATH_SYSTEM_SHARED,
|
||||
SD_PATH_SYSTEM_CONFIGURATION_FACTORY,
|
||||
SD_PATH_SYSTEM_STATE_FACTORY,
|
||||
|
||||
/* System configuration, runtime, state, ... */
|
||||
SD_PATH_SYSTEM_CONFIGURATION,
|
||||
SD_PATH_SYSTEM_RUNTIME,
|
||||
SD_PATH_SYSTEM_RUNTIME_LOGS,
|
||||
SD_PATH_SYSTEM_STATE_PRIVATE,
|
||||
SD_PATH_SYSTEM_STATE_LOGS,
|
||||
SD_PATH_SYSTEM_STATE_CACHE,
|
||||
SD_PATH_SYSTEM_STATE_SPOOL,
|
||||
|
||||
/* Vendor supplied data */
|
||||
SD_PATH_USER_BINARIES,
|
||||
SD_PATH_USER_LIBRARY_PRIVATE,
|
||||
SD_PATH_USER_LIBRARY_ARCH,
|
||||
SD_PATH_USER_SHARED,
|
||||
|
||||
/* User configuration, state, runtime ... */
|
||||
SD_PATH_USER_CONFIGURATION, /* takes both actual configuration (like /etc) and state (like /var/lib) */
|
||||
SD_PATH_USER_RUNTIME,
|
||||
SD_PATH_USER_STATE_CACHE,
|
||||
|
||||
/* User resources */
|
||||
SD_PATH_USER, /* $HOME itself */
|
||||
SD_PATH_USER_DOCUMENTS,
|
||||
SD_PATH_USER_MUSIC,
|
||||
SD_PATH_USER_PICTURES,
|
||||
SD_PATH_USER_VIDEOS,
|
||||
SD_PATH_USER_DOWNLOAD,
|
||||
SD_PATH_USER_PUBLIC,
|
||||
SD_PATH_USER_TEMPLATES,
|
||||
SD_PATH_USER_DESKTOP,
|
||||
|
||||
/* Search paths */
|
||||
SD_PATH_SEARCH_BINARIES,
|
||||
SD_PATH_SEARCH_LIBRARY_PRIVATE,
|
||||
SD_PATH_SEARCH_LIBRARY_ARCH,
|
||||
SD_PATH_SEARCH_SHARED,
|
||||
SD_PATH_SEARCH_CONFIGURATION_FACTORY,
|
||||
SD_PATH_SEARCH_STATE_FACTORY,
|
||||
SD_PATH_SEARCH_CONFIGURATION,
|
||||
|
||||
_SD_PATH_MAX,
|
||||
};
|
||||
|
||||
int sd_path_home(uint64_t type, const char *suffix, char **path);
|
||||
int sd_path_search(uint64_t type, const char *suffix, char ***paths);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user