9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering/***
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering This file is part of systemd.
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering Copyright 2014 Lennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering systemd is free software; you can redistribute it and/or modify it
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering under the terms of the GNU Lesser General Public License as published by
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering (at your option) any later version.
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering systemd is distributed in the hope that it will be useful, but
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering Lesser General Public License for more details.
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering You should have received a copy of the GNU Lesser General Public License
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering***/
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering#include <errno.h>
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include <getopt.h>
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include <stdio.h>
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering#include <stdlib.h>
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering#include "sd-path.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "log.h"
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering#include "macro.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering#include "util.h"
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poetteringstatic const char *arg_suffix = NULL;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poetteringstatic const char* const path_table[_SD_PATH_MAX] = {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_TEMPORARY] = "temporary",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_TEMPORARY_LARGE] = "temporary-large",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_BINARIES] = "system-binaries",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_INCLUDE] = "system-include",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_LIBRARY_PRIVATE] = "system-library-private",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_LIBRARY_ARCH] = "system-library-arch",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_SHARED] = "system-shared",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_CONFIGURATION_FACTORY] = "system-configuration-factory",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_STATE_FACTORY] = "system-state-factory",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_CONFIGURATION] = "system-configuration",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_RUNTIME] = "system-runtime",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_RUNTIME_LOGS] = "system-runtime-logs",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_STATE_PRIVATE] = "system-state-private",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_STATE_LOGS] = "system-state-logs",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_STATE_CACHE] = "system-state-cache",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SYSTEM_STATE_SPOOL] = "system-state-spool",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_BINARIES] = "user-binaries",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_LIBRARY_PRIVATE] = "user-library-private",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_LIBRARY_ARCH] = "user-library-arch",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_SHARED] = "user-shared",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_CONFIGURATION] = "user-configuration",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_RUNTIME] = "user-runtime",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_STATE_CACHE] = "user-state-cache",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER] = "user",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_DOCUMENTS] = "user-documents",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_MUSIC] = "user-music",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_PICTURES] = "user-pictures",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_VIDEOS] = "user-videos",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_DOWNLOAD] = "user-download",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_PUBLIC] = "user-public",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_TEMPLATES] = "user-templates",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_USER_DESKTOP] = "user-desktop",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SEARCH_BINARIES] = "search-binaries",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SEARCH_LIBRARY_PRIVATE] = "search-library-private",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SEARCH_LIBRARY_ARCH] = "search-library-arch",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SEARCH_SHARED] = "search-shared",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SEARCH_CONFIGURATION_FACTORY] = "search-configuration-factory",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SEARCH_STATE_FACTORY] = "search-state-factory",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering [SD_PATH_SEARCH_CONFIGURATION] = "search-configuration",
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering};
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poetteringstatic int list_homes(void) {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering uint64_t i = 0;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering int r = 0;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering for (i = 0; i < ELEMENTSOF(path_table); i++) {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering _cleanup_free_ char *p = NULL;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering int q;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering q = sd_path_home(i, arg_suffix, &p);
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering if (q == -ENXIO)
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering continue;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering if (q < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to query %s: %m", path_table[i]);
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering r = q;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering continue;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering }
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering printf("%s: %s\n", path_table[i], p);
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering }
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering return r;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering}
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poetteringstatic int print_home(const char *n) {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering uint64_t i = 0;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering int r;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering for (i = 0; i < ELEMENTSOF(path_table); i++) {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering if (streq(path_table[i], n)) {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering _cleanup_free_ char *p = NULL;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering r = sd_path_home(i, arg_suffix, &p);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to query %s: %m", n);
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering printf("%s\n", p);
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering return 0;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering }
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering }
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering log_error("Path %s not known.", n);
15411c0cb1192799b37ec8f25d6f30e8d7292fc6David Herrmann return -EOPNOTSUPP;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering}
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmekstatic void help(void) {
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek printf("%s [OPTIONS...] [NAME...]\n\n"
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek "Show system and user paths.\n\n"
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek " -h --help Show this help\n"
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek " --version Show package version\n"
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek " --suffix=SUFFIX Suffix to append to paths\n",
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek program_invocation_short_name);
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek}
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering enum {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering ARG_VERSION = 0x100,
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering ARG_SUFFIX,
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering };
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering static const struct option options[] = {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering { "help", no_argument, NULL, 'h' },
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering { "version", no_argument, NULL, ARG_VERSION },
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering { "suffix", required_argument, NULL, ARG_SUFFIX },
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering {}
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering };
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering int c;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering assert(argc >= 0);
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering assert(argv);
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering switch (c) {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering case 'h':
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek help();
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek return 0;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering case ARG_VERSION:
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering return version();
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering case ARG_SUFFIX:
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering arg_suffix = optarg;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering break;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering case '?':
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering return -EINVAL;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering default:
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering assert_not_reached("Unhandled option");
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering }
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering return 1;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering}
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poetteringint main(int argc, char* argv[]) {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering int r;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering log_parse_environment();
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering log_open();
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering r = parse_argv(argc, argv);
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering if (r <= 0)
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering goto finish;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering if (argc > optind) {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering int i, q;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering for (i = optind; i < argc; i++) {
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering q = print_home(argv[i]);
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering if (q < 0)
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering r = q;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering }
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering } else
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering r = list_homes();
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poetteringfinish:
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
9a00f57a5ba7ed431e6bac8d8b36518708503b4eLennart Poettering}