Line data Source code
1 : /* SPDX-License-Identifier: LGPL-2.1+ */
2 :
3 : #include <errno.h>
4 : #include <getopt.h>
5 : #include <stdio.h>
6 : #include <stdlib.h>
7 :
8 : #include "sd-path.h"
9 :
10 : #include "alloc-util.h"
11 : #include "log.h"
12 : #include "macro.h"
13 : #include "main-func.h"
14 : #include "pretty-print.h"
15 : #include "string-util.h"
16 : #include "util.h"
17 :
18 : static const char *arg_suffix = NULL;
19 :
20 : static const char* const path_table[_SD_PATH_MAX] = {
21 : [SD_PATH_TEMPORARY] = "temporary",
22 : [SD_PATH_TEMPORARY_LARGE] = "temporary-large",
23 : [SD_PATH_SYSTEM_BINARIES] = "system-binaries",
24 : [SD_PATH_SYSTEM_INCLUDE] = "system-include",
25 : [SD_PATH_SYSTEM_LIBRARY_PRIVATE] = "system-library-private",
26 : [SD_PATH_SYSTEM_LIBRARY_ARCH] = "system-library-arch",
27 : [SD_PATH_SYSTEM_SHARED] = "system-shared",
28 : [SD_PATH_SYSTEM_CONFIGURATION_FACTORY] = "system-configuration-factory",
29 : [SD_PATH_SYSTEM_STATE_FACTORY] = "system-state-factory",
30 : [SD_PATH_SYSTEM_CONFIGURATION] = "system-configuration",
31 : [SD_PATH_SYSTEM_RUNTIME] = "system-runtime",
32 : [SD_PATH_SYSTEM_RUNTIME_LOGS] = "system-runtime-logs",
33 : [SD_PATH_SYSTEM_STATE_PRIVATE] = "system-state-private",
34 : [SD_PATH_SYSTEM_STATE_LOGS] = "system-state-logs",
35 : [SD_PATH_SYSTEM_STATE_CACHE] = "system-state-cache",
36 : [SD_PATH_SYSTEM_STATE_SPOOL] = "system-state-spool",
37 : [SD_PATH_USER_BINARIES] = "user-binaries",
38 : [SD_PATH_USER_LIBRARY_PRIVATE] = "user-library-private",
39 : [SD_PATH_USER_LIBRARY_ARCH] = "user-library-arch",
40 : [SD_PATH_USER_SHARED] = "user-shared",
41 : [SD_PATH_USER_CONFIGURATION] = "user-configuration",
42 : [SD_PATH_USER_RUNTIME] = "user-runtime",
43 : [SD_PATH_USER_STATE_CACHE] = "user-state-cache",
44 : [SD_PATH_USER] = "user",
45 : [SD_PATH_USER_DOCUMENTS] = "user-documents",
46 : [SD_PATH_USER_MUSIC] = "user-music",
47 : [SD_PATH_USER_PICTURES] = "user-pictures",
48 : [SD_PATH_USER_VIDEOS] = "user-videos",
49 : [SD_PATH_USER_DOWNLOAD] = "user-download",
50 : [SD_PATH_USER_PUBLIC] = "user-public",
51 : [SD_PATH_USER_TEMPLATES] = "user-templates",
52 : [SD_PATH_USER_DESKTOP] = "user-desktop",
53 : [SD_PATH_SEARCH_BINARIES] = "search-binaries",
54 : [SD_PATH_SEARCH_BINARIES_DEFAULT] = "search-binaries-default",
55 : [SD_PATH_SEARCH_LIBRARY_PRIVATE] = "search-library-private",
56 : [SD_PATH_SEARCH_LIBRARY_ARCH] = "search-library-arch",
57 : [SD_PATH_SEARCH_SHARED] = "search-shared",
58 : [SD_PATH_SEARCH_CONFIGURATION_FACTORY] = "search-configuration-factory",
59 : [SD_PATH_SEARCH_STATE_FACTORY] = "search-state-factory",
60 : [SD_PATH_SEARCH_CONFIGURATION] = "search-configuration",
61 : };
62 :
63 0 : static int list_homes(void) {
64 0 : uint64_t i = 0;
65 0 : int r = 0;
66 :
67 0 : for (i = 0; i < ELEMENTSOF(path_table); i++) {
68 0 : _cleanup_free_ char *p = NULL;
69 : int q;
70 :
71 0 : q = sd_path_home(i, arg_suffix, &p);
72 0 : if (q == -ENXIO)
73 0 : continue;
74 0 : if (q < 0) {
75 0 : log_error_errno(r, "Failed to query %s: %m", path_table[i]);
76 0 : r = q;
77 0 : continue;
78 : }
79 :
80 0 : printf("%s: %s\n", path_table[i], p);
81 : }
82 :
83 0 : return r;
84 : }
85 :
86 0 : static int print_home(const char *n) {
87 0 : uint64_t i = 0;
88 : int r;
89 :
90 0 : for (i = 0; i < ELEMENTSOF(path_table); i++) {
91 0 : if (streq(path_table[i], n)) {
92 0 : _cleanup_free_ char *p = NULL;
93 :
94 0 : r = sd_path_home(i, arg_suffix, &p);
95 0 : if (r < 0)
96 0 : return log_error_errno(r, "Failed to query %s: %m", n);
97 :
98 0 : printf("%s\n", p);
99 0 : return 0;
100 : }
101 : }
102 :
103 0 : return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
104 : "Path %s not known.", n);
105 : }
106 :
107 3 : static int help(void) {
108 3 : _cleanup_free_ char *link = NULL;
109 : int r;
110 :
111 3 : r = terminal_urlify_man("systemd-path", "1", &link);
112 3 : if (r < 0)
113 0 : return log_oom();
114 :
115 3 : printf("%s [OPTIONS...] [NAME...]\n\n"
116 : "Show system and user paths.\n\n"
117 : " -h --help Show this help\n"
118 : " --version Show package version\n"
119 : " --suffix=SUFFIX Suffix to append to paths\n"
120 : "\nSee the %s for details.\n"
121 : , program_invocation_short_name
122 : , link
123 : );
124 :
125 3 : return 0;
126 : }
127 :
128 4 : static int parse_argv(int argc, char *argv[]) {
129 :
130 : enum {
131 : ARG_VERSION = 0x100,
132 : ARG_SUFFIX,
133 : };
134 :
135 : static const struct option options[] = {
136 : { "help", no_argument, NULL, 'h' },
137 : { "version", no_argument, NULL, ARG_VERSION },
138 : { "suffix", required_argument, NULL, ARG_SUFFIX },
139 : {}
140 : };
141 :
142 : int c;
143 :
144 4 : assert(argc >= 0);
145 4 : assert(argv);
146 :
147 4 : while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
148 :
149 4 : switch (c) {
150 :
151 3 : case 'h':
152 3 : return help();
153 :
154 0 : case ARG_VERSION:
155 0 : return version();
156 :
157 0 : case ARG_SUFFIX:
158 0 : arg_suffix = optarg;
159 0 : break;
160 :
161 1 : case '?':
162 1 : return -EINVAL;
163 :
164 0 : default:
165 0 : assert_not_reached("Unhandled option");
166 : }
167 :
168 0 : return 1;
169 : }
170 :
171 4 : static int run(int argc, char* argv[]) {
172 : int r;
173 :
174 4 : log_show_color(true);
175 4 : log_parse_environment();
176 4 : log_open();
177 :
178 4 : r = parse_argv(argc, argv);
179 4 : if (r <= 0)
180 4 : return r;
181 :
182 0 : if (argc > optind) {
183 : int i, q;
184 :
185 0 : for (i = optind; i < argc; i++) {
186 0 : q = print_home(argv[i]);
187 0 : if (q < 0)
188 0 : r = q;
189 : }
190 :
191 0 : return r;
192 : } else
193 0 : return list_homes();
194 : }
195 :
196 4 : DEFINE_MAIN_FUNCTION(run);
|