Line data Source code
1 : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2 :
3 : /***
4 : This file is part of systemd.
5 :
6 : Copyright 2013 Zbigniew Jędrzejewski-Szmek
7 :
8 : systemd is free software; you can redistribute it and/or modify it
9 : under the terms of the GNU Lesser General Public License as published by
10 : the Free Software Foundation; either version 2.1 of the License, or
11 : (at your option) any later version.
12 :
13 : systemd is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : Lesser General Public License for more details.
17 :
18 : You should have received a copy of the GNU Lesser General Public License
19 : along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 : ***/
21 :
22 : #include <stdlib.h>
23 :
24 : #include "specifier.h"
25 : #include "unit-name.h"
26 : #include "util.h"
27 : #include "install-printf.h"
28 : #include "formats-util.h"
29 :
30 2 : static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) {
31 2 : UnitFileInstallInfo *i = userdata;
32 :
33 2 : assert(i);
34 :
35 2 : return unit_name_to_prefix_and_instance(i->name, ret);
36 : }
37 :
38 2 : static int specifier_prefix(char specifier, void *data, void *userdata, char **ret) {
39 2 : UnitFileInstallInfo *i = userdata;
40 :
41 2 : assert(i);
42 :
43 2 : return unit_name_to_prefix(i->name, ret);
44 : }
45 :
46 1 : static int specifier_instance(char specifier, void *data, void *userdata, char **ret) {
47 1 : UnitFileInstallInfo *i = userdata;
48 : char *instance;
49 : int r;
50 :
51 1 : assert(i);
52 :
53 1 : r = unit_name_to_instance(i->name, &instance);
54 1 : if (r < 0)
55 0 : return r;
56 :
57 1 : if (!instance) {
58 1 : instance = strdup("");
59 1 : if (!instance)
60 0 : return -ENOMEM;
61 : }
62 :
63 1 : *ret = instance;
64 1 : return 0;
65 : }
66 :
67 8 : static int specifier_user_name(char specifier, void *data, void *userdata, char **ret) {
68 8 : UnitFileInstallInfo *i = userdata;
69 : const char *username;
70 16 : _cleanup_free_ char *tmp = NULL;
71 8 : char *printed = NULL;
72 :
73 8 : assert(i);
74 :
75 8 : if (i->user)
76 4 : username = i->user;
77 : else
78 : /* get USER env from env or our own uid */
79 4 : username = tmp = getusername_malloc();
80 :
81 8 : switch (specifier) {
82 : case 'u':
83 4 : printed = strdup(username);
84 4 : break;
85 : case 'U': {
86 : /* fish username from passwd */
87 : uid_t uid;
88 : int r;
89 :
90 4 : r = get_user_creds(&username, &uid, NULL, NULL, NULL);
91 4 : if (r < 0)
92 4 : return r;
93 :
94 2 : if (asprintf(&printed, UID_FMT, uid) < 0)
95 0 : return -ENOMEM;
96 2 : break;
97 : }}
98 :
99 :
100 6 : *ret = printed;
101 6 : return 0;
102 : }
103 :
104 :
105 24 : int install_full_printf(UnitFileInstallInfo *i, const char *format, char **ret) {
106 :
107 : /* This is similar to unit_full_printf() but does not support
108 : * anything path-related.
109 : *
110 : * %n: the full id of the unit (foo@bar.waldo)
111 : * %N: the id of the unit without the suffix (foo@bar)
112 : * %p: the prefix (foo)
113 : * %i: the instance (bar)
114 :
115 : * %U the UID of the configured user or running user
116 : * %u the username of the configured user or running user
117 : * %m the machine ID of the running system
118 : * %H the host name of the running system
119 : * %b the boot ID of the running system
120 : * %v `uname -r` of the running system
121 : */
122 :
123 48 : const Specifier table[] = {
124 24 : { 'n', specifier_string, i->name },
125 : { 'N', specifier_prefix_and_instance, NULL },
126 : { 'p', specifier_prefix, NULL },
127 : { 'i', specifier_instance, NULL },
128 :
129 : { 'U', specifier_user_name, NULL },
130 : { 'u', specifier_user_name, NULL },
131 :
132 : { 'm', specifier_machine_id, NULL },
133 : { 'H', specifier_host_name, NULL },
134 : { 'b', specifier_boot_id, NULL },
135 : { 'v', specifier_kernel_release, NULL },
136 : {}
137 : };
138 :
139 24 : assert(i);
140 24 : assert(format);
141 24 : assert(ret);
142 :
143 24 : return specifier_printf(format, table, i, ret);
144 : }
|