]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/path/path.c
c2936e0bca130e00c10f172a83e211d81351fdb4
[thirdparty/systemd.git] / src / path / path.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
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 <stdio.h>
23 #include <getopt.h>
24 #include <error.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "sd-path.h"
31 #include "build.h"
32 #include "macro.h"
33 #include "util.h"
34 #include "log.h"
35
36 static const char *arg_suffix = NULL;
37
38 static const char* const path_table[_SD_PATH_MAX] = {
39 [SD_PATH_TEMPORARY] = "temporary",
40 [SD_PATH_TEMPORARY_LARGE] = "temporary-large",
41 [SD_PATH_SYSTEM_BINARIES] = "system-binaries",
42 [SD_PATH_SYSTEM_INCLUDE] = "system-include",
43 [SD_PATH_SYSTEM_LIBRARY_PRIVATE] = "system-library-private",
44 [SD_PATH_SYSTEM_LIBRARY_ARCH] = "system-library-arch",
45 [SD_PATH_SYSTEM_SHARED] = "system-shared",
46 [SD_PATH_SYSTEM_CONFIGURATION_FACTORY] = "system-configuration-factory",
47 [SD_PATH_SYSTEM_STATE_FACTORY] = "system-state-factory",
48 [SD_PATH_SYSTEM_CONFIGURATION] = "system-configuration",
49 [SD_PATH_SYSTEM_RUNTIME] = "system-runtime",
50 [SD_PATH_SYSTEM_RUNTIME_LOGS] = "system-runtime-logs",
51 [SD_PATH_SYSTEM_STATE_PRIVATE] = "system-state-private",
52 [SD_PATH_SYSTEM_STATE_LOGS] = "system-state-logs",
53 [SD_PATH_SYSTEM_STATE_CACHE] = "system-state-cache",
54 [SD_PATH_SYSTEM_STATE_SPOOL] = "system-state-spool",
55 [SD_PATH_USER_BINARIES] = "user-binaries",
56 [SD_PATH_USER_LIBRARY_PRIVATE] = "user-library-private",
57 [SD_PATH_USER_LIBRARY_ARCH] = "user-library-arch",
58 [SD_PATH_USER_SHARED] = "user-shared",
59 [SD_PATH_USER_CONFIGURATION] = "user-configuration",
60 [SD_PATH_USER_RUNTIME] = "user-runtime",
61 [SD_PATH_USER_STATE_CACHE] = "user-state-cache",
62 [SD_PATH_USER] = "user",
63 [SD_PATH_USER_DOCUMENTS] = "user-documents",
64 [SD_PATH_USER_MUSIC] = "user-music",
65 [SD_PATH_USER_PICTURES] = "user-pictures",
66 [SD_PATH_USER_VIDEOS] = "user-videos",
67 [SD_PATH_USER_DOWNLOAD] = "user-download",
68 [SD_PATH_USER_PUBLIC] = "user-public",
69 [SD_PATH_USER_TEMPLATES] = "user-templates",
70 [SD_PATH_USER_DESKTOP] = "user-desktop",
71 [SD_PATH_SEARCH_BINARIES] = "search-binaries",
72 [SD_PATH_SEARCH_LIBRARY_PRIVATE] = "search-library-private",
73 [SD_PATH_SEARCH_LIBRARY_ARCH] = "search-library-arch",
74 [SD_PATH_SEARCH_SHARED] = "search-shared",
75 [SD_PATH_SEARCH_CONFIGURATION_FACTORY] = "search-configuration-factory",
76 [SD_PATH_SEARCH_STATE_FACTORY] = "search-state-factory",
77 [SD_PATH_SEARCH_CONFIGURATION] = "search-configuration",
78 };
79
80 static int help(void) {
81
82 printf("%s [OPTIONS...] [NAME...]\n\n"
83 "Show system and user paths.\n\n"
84 " -h --help Show this help\n"
85 " --version Show package version\n"
86 " --suffix=SUFFIX Suffix to append to paths\n",
87 program_invocation_short_name);
88
89 return 0;
90 }
91
92 static int list_homes(void) {
93 uint64_t i = 0;
94 int r = 0;
95
96 for (i = 0; i < ELEMENTSOF(path_table); i++) {
97 _cleanup_free_ char *p = NULL;
98 int q;
99
100 q = sd_path_home(i, arg_suffix, &p);
101 if (q == -ENXIO)
102 continue;
103 if (q < 0) {
104 log_error("Failed to query %s: %s", path_table[i], strerror(-r));
105 r = q;
106 continue;
107 }
108
109 printf("%s: %s\n", path_table[i], p);
110 }
111
112 return r;
113 }
114
115 static int print_home(const char *n) {
116 uint64_t i = 0;
117 int r;
118
119 for (i = 0; i < ELEMENTSOF(path_table); i++) {
120 if (streq(path_table[i], n)) {
121 _cleanup_free_ char *p = NULL;
122
123 r = sd_path_home(i, arg_suffix, &p);
124 if (r < 0) {
125 log_error("Failed to query %s: %s", n, strerror(-r));
126 return r;
127 }
128
129 printf("%s\n", p);
130 return 0;
131 }
132 }
133
134 log_error("Path %s not known.", n);
135 return -ENOTSUP;
136 }
137
138 static int parse_argv(int argc, char *argv[]) {
139
140 enum {
141 ARG_VERSION = 0x100,
142 ARG_SUFFIX,
143 };
144
145 static const struct option options[] = {
146 { "help", no_argument, NULL, 'h' },
147 { "version", no_argument, NULL, ARG_VERSION },
148 { "suffix", required_argument, NULL, ARG_SUFFIX },
149 {}
150 };
151
152 int c;
153
154 assert(argc >= 0);
155 assert(argv);
156
157 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
158
159 switch (c) {
160
161 case 'h':
162 return help();
163
164 case ARG_VERSION:
165 puts(PACKAGE_STRING);
166 puts(SYSTEMD_FEATURES);
167 return 0;
168
169 case ARG_SUFFIX:
170 arg_suffix = optarg;
171 break;
172
173 case '?':
174 return -EINVAL;
175
176 default:
177 assert_not_reached("Unhandled option");
178 }
179 }
180
181 return 1;
182 }
183
184 int main(int argc, char* argv[]) {
185 int r;
186
187 log_parse_environment();
188 log_open();
189
190 r = parse_argv(argc, argv);
191 if (r <= 0)
192 goto finish;
193
194 if (argc > optind) {
195 int i, q;
196
197 for (i = optind; i < argc; i++) {
198 q = print_home(argv[i]);
199 if (q < 0)
200 r = q;
201 }
202 } else
203 r = list_homes();
204
205
206 finish:
207 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
208 }