chiark / gitweb /
machine: make sure unpriviliged "machinectl status" can show the machine's OS version
[elogind.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 list_homes(void) {
81         uint64_t i = 0;
82         int r = 0;
83
84         for (i = 0; i < ELEMENTSOF(path_table); i++) {
85                 _cleanup_free_ char *p = NULL;
86                 int q;
87
88                 q = sd_path_home(i, arg_suffix, &p);
89                 if (q == -ENXIO)
90                         continue;
91                 if (q < 0) {
92                         log_error("Failed to query %s: %s", path_table[i], strerror(-r));
93                         r = q;
94                         continue;
95                 }
96
97                 printf("%s: %s\n", path_table[i], p);
98         }
99
100         return r;
101 }
102
103 static int print_home(const char *n) {
104         uint64_t i = 0;
105         int r;
106
107         for (i = 0; i < ELEMENTSOF(path_table); i++) {
108                 if (streq(path_table[i], n)) {
109                         _cleanup_free_ char *p = NULL;
110
111                         r = sd_path_home(i, arg_suffix, &p);
112                         if (r < 0) {
113                                 log_error("Failed to query %s: %s", n, strerror(-r));
114                                 return r;
115                         }
116
117                         printf("%s\n", p);
118                         return 0;
119                 }
120         }
121
122         log_error("Path %s not known.", n);
123         return -ENOTSUP;
124 }
125
126 static void help(void) {
127         printf("%s [OPTIONS...] [NAME...]\n\n"
128                "Show system and user paths.\n\n"
129                "  -h --help             Show this help\n"
130                "     --version          Show package version\n"
131                "     --suffix=SUFFIX    Suffix to append to paths\n",
132                program_invocation_short_name);
133 }
134
135 static int parse_argv(int argc, char *argv[]) {
136
137         enum {
138                 ARG_VERSION = 0x100,
139                 ARG_SUFFIX,
140         };
141
142         static const struct option options[] = {
143                 { "help",      no_argument,       NULL, 'h'           },
144                 { "version",   no_argument,       NULL, ARG_VERSION   },
145                 { "suffix",    required_argument, NULL, ARG_SUFFIX    },
146                 {}
147         };
148
149         int c;
150
151         assert(argc >= 0);
152         assert(argv);
153
154         while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
155
156                 switch (c) {
157
158                 case 'h':
159                         help();
160                         return 0;
161
162                 case ARG_VERSION:
163                         puts(PACKAGE_STRING);
164                         puts(SYSTEMD_FEATURES);
165                         return 0;
166
167                 case ARG_SUFFIX:
168                         arg_suffix = optarg;
169                         break;
170
171                 case '?':
172                         return -EINVAL;
173
174                 default:
175                         assert_not_reached("Unhandled option");
176                 }
177
178         return 1;
179 }
180
181 int main(int argc, char* argv[]) {
182         int r;
183
184         log_parse_environment();
185         log_open();
186
187         r = parse_argv(argc, argv);
188         if (r <= 0)
189                 goto finish;
190
191         if (argc > optind) {
192                 int i, q;
193
194                 for (i = optind; i < argc; i++) {
195                         q = print_home(argv[i]);
196                         if (q < 0)
197                                 r = q;
198                 }
199         } else
200                 r = list_homes();
201
202
203 finish:
204         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
205 }