41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering/***
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering This file is part of systemd.
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering Copyright 2010 Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering systemd is free software; you can redistribute it and/or modify it
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering under the terms of the GNU Lesser General Public License as published by
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering (at your option) any later version.
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering systemd is distributed in the hope that it will be useful, but
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering Lesser General Public License for more details.
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering You should have received a copy of the GNU Lesser General Public License
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering***/
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "cgroup-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "formats-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "macro.h"
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering#include "specifier.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering#include "strv.h"
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering#include "unit-name.h"
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering#include "unit-printf.h"
b1d4f8e154bf61b5de1b27461ef8e9c8c5e838a1Lennart Poettering#include "unit.h"
b1d4f8e154bf61b5de1b27461ef8e9c8c5e838a1Lennart Poettering#include "user-util.h"
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering Unit *u = userdata;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering assert(u);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return unit_name_to_prefix_and_instance(u->id, ret);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic int specifier_prefix(char specifier, void *data, void *userdata, char **ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering Unit *u = userdata;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering assert(u);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return unit_name_to_prefix(u->id, ret);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic int specifier_prefix_unescaped(char specifier, void *data, void *userdata, char **ret) {
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering _cleanup_free_ char *p = NULL;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering Unit *u = userdata;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering int r;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering assert(u);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering r = unit_name_to_prefix(u->id, &p);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering if (r < 0)
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return r;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return unit_name_unescape(p, ret);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic int specifier_instance_unescaped(char specifier, void *data, void *userdata, char **ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering Unit *u = userdata;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering assert(u);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
115cbf7e209a86cf5317fa12d44566247b4af332Evgeny Vereshchagin return unit_name_unescape(strempty(u->instance), ret);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic int specifier_filename(char specifier, void *data, void *userdata, char **ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering Unit *u = userdata;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering assert(u);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering if (u->instance)
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return unit_name_path_unescape(u->instance, ret);
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering else
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering return unit_name_to_path(u->id, ret);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic int specifier_cgroup(char specifier, void *data, void *userdata, char **ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering Unit *u = userdata;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering char *n;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering assert(u);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering if (u->cgroup_path)
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering n = strdup(u->cgroup_path);
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering else
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering n = unit_default_cgroup_path(u);
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering if (!n)
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return -ENOMEM;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering *ret = n;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return 0;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic int specifier_cgroup_root(char specifier, void *data, void *userdata, char **ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering Unit *u = userdata;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering char *n;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering assert(u);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering n = strdup(u->manager->cgroup_root);
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering if (!n)
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering return -ENOMEM;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering *ret = n;
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering return 0;
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering}
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poetteringstatic int specifier_cgroup_slice(char specifier, void *data, void *userdata, char **ret) {
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering Unit *u = userdata;
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering char *n;
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering assert(u);
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering if (UNIT_ISSET(u->slice)) {
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering Unit *slice;
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering slice = UNIT_DEREF(u->slice);
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering if (slice->cgroup_path)
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering n = strdup(slice->cgroup_path);
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering else
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering n = unit_default_cgroup_path(slice);
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering } else
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering n = strdup(u->manager->cgroup_root);
115cbf7e209a86cf5317fa12d44566247b4af332Evgeny Vereshchagin if (!n)
115cbf7e209a86cf5317fa12d44566247b4af332Evgeny Vereshchagin return -ENOMEM;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering *ret = n;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return 0;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic int specifier_runtime(char specifier, void *data, void *userdata, char **ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering Unit *u = userdata;
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering const char *e;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering char *n = NULL;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering assert(u);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering if (u->manager->running_as == MANAGER_SYSTEM)
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering e = "/run";
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering else {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering e = getenv("XDG_RUNTIME_DIR");
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering if (!e)
15411c0cb1192799b37ec8f25d6f30e8d7292fc6David Herrmann return -EOPNOTSUPP;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering }
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering n = strdup(e);
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering if (!n)
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering return -ENOMEM;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering *ret = n;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return 0;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringstatic int specifier_user_name(char specifier, void *data, void *userdata, char **ret) {
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering char *t;
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering /* If we are UID 0 (root), this will not result in NSS,
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering * otherwise it might. This is good, as we want to be able to
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering * run this in PID 1, where our user ID is 0, but where NSS
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering * lookups are not allowed. */
067d851d30386c553e3a84f59d81d003ff638b91Daniel Wallace
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering t = getusername_malloc();
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering if (!t)
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return -ENOMEM;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering *ret = t;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return 0;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poetteringstatic int specifier_user_id(char specifier, void *data, void *userdata, char **ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering if (asprintf(ret, UID_FMT, getuid()) < 0)
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return -ENOMEM;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return 0;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poetteringstatic int specifier_user_home(char specifier, void *data, void *userdata, char **ret) {
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering /* On PID 1 (which runs as root) this will not result in NSS,
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering * which is good. See above */
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering return get_home_dir(ret);
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering}
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poetteringstatic int specifier_user_shell(char specifier, void *data, void *userdata, char **ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering /* On PID 1 (which runs as root) this will not result in NSS,
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering * which is good. See above */
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering return get_shell(ret);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringint unit_name_printf(Unit *u, const char* format, char **ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering /*
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering * This will use the passed string as format string and
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering * replace the following specifiers:
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering *
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering * %n: the full id of the unit (foo@bar.waldo)
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering * %N: the id of the unit without the suffix (foo@bar)
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering * %p: the prefix (foo)
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering * %i: the instance (bar)
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering */
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering const Specifier table[] = {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'n', specifier_string, u->id },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'N', specifier_prefix_and_instance, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'p', specifier_prefix, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'i', specifier_string, u->instance },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 0, NULL, NULL }
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering };
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering assert(u);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering assert(format);
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering assert(ret);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return specifier_printf(format, table, u, ret);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringint unit_full_printf(Unit *u, const char *format, char **ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering /* This is similar to unit_name_printf() but also supports
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering * unescaping. Also, adds a couple of additional codes:
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering *
dca348bcbb462305864526c587495a14a76bfcdeJan Engelhardt * %f the instance if set, otherwise the id
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering * %c cgroup path of unit
2cfbd749af308bdbe56edcfed7f3eea0fc2b93d2Lennart Poettering * %r where units in this slice are placed in the cgroup tree
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering * %R the root of this systemd's instance tree
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering * %U the UID of the running user
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering * %u the username of the running user
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering * %h the homedir of the running user
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering * %s the shell of the running user
6569cae18ed640a4e9f52f73e2a3ec54b07d0406Lennart Poettering * %m the machine ID of the running system
6569cae18ed640a4e9f52f73e2a3ec54b07d0406Lennart Poettering * %H the host name of the running system
7584d236eac91f9b7128b1eb08bddf18be2bce9fZbigniew Jędrzejewski-Szmek * %b the boot ID of the running system
6aaa8c2f783cd1b3ac27c5ce40625d032e7e3d71Zbigniew Jędrzejewski-Szmek * %v `uname -r` of the running system
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering */
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering const Specifier table[] = {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'n', specifier_string, u->id },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'N', specifier_prefix_and_instance, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'p', specifier_prefix, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'P', specifier_prefix_unescaped, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'i', specifier_string, u->instance },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'I', specifier_instance_unescaped, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'f', specifier_filename, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'c', specifier_cgroup, NULL },
696fd1ef4f2f8574e349332a16987c6772641eddLennart Poettering { 'r', specifier_cgroup_slice, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'R', specifier_cgroup_root, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 't', specifier_runtime, NULL },
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering
79413b673b45adc98dfeaec882bbdda2343cb2f9Lennart Poettering { 'U', specifier_user_id, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'u', specifier_user_name, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 'h', specifier_user_home, NULL },
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering { 's', specifier_user_shell, NULL },
6569cae18ed640a4e9f52f73e2a3ec54b07d0406Lennart Poettering
6569cae18ed640a4e9f52f73e2a3ec54b07d0406Lennart Poettering { 'm', specifier_machine_id, NULL },
6569cae18ed640a4e9f52f73e2a3ec54b07d0406Lennart Poettering { 'H', specifier_host_name, NULL },
6569cae18ed640a4e9f52f73e2a3ec54b07d0406Lennart Poettering { 'b', specifier_boot_id, NULL },
6aaa8c2f783cd1b3ac27c5ce40625d032e7e3d71Zbigniew Jędrzejewski-Szmek { 'v', specifier_kernel_release, NULL },
6aaa8c2f783cd1b3ac27c5ce40625d032e7e3d71Zbigniew Jędrzejewski-Szmek {}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering };
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering assert(u);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering assert(format);
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering assert(ret);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return specifier_printf(format, table, u, ret);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poetteringint unit_full_printf_strv(Unit *u, char **l, char ***ret) {
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering size_t n;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering char **r, **i, **j;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering int q;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering /* Applies unit_full_printf to every entry in l */
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering assert(u);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering n = strv_length(l);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering r = new(char*, n+1);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering if (!r)
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return -ENOMEM;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering for (i = l, j = r; *i; i++, j++) {
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering q = unit_full_printf(u, *i, j);
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering if (q < 0)
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering goto fail;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering }
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering *j = NULL;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering *ret = r;
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return 0;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poetteringfail:
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering for (j--; j >= r; j--)
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering free(*j);
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering free(r);
19f6d710772305610b928bc2678b9d77fe11e770Lennart Poettering return q;
41f9172f427bdbb8221c64029f78364b8dd4e527Lennart Poettering}