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