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