1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Daniel Mack
8 Copyright 2014 Kay Sievers
10 systemd is free software; you can redistribute it and/or modify it
11 under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
15 systemd is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public License
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
32 #include "sd-daemon.h"
34 #include "bus-internal.h"
41 static char *arg_address = NULL;
42 static char *arg_command_line_buffer = NULL;
44 static int help(void) {
46 printf("%s [OPTIONS...]\n\n"
47 "Connect STDIO to a given bus address.\n\n"
48 " -h --help Show this help\n"
49 " --version Show package version\n"
50 " --machine=MACHINE Connect to specified machine\n"
51 " --address=ADDRESS Connect to the bus specified by ADDRESS\n"
52 " (default: " DEFAULT_SYSTEM_BUS_ADDRESS ")\n",
53 program_invocation_short_name);
58 static int parse_argv(int argc, char *argv[]) {
66 static const struct option options[] = {
67 { "help", no_argument, NULL, 'h' },
68 { "version", no_argument, NULL, ARG_VERSION },
69 { "address", required_argument, NULL, ARG_ADDRESS },
70 { "machine", required_argument, NULL, ARG_MACHINE },
79 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
89 puts(SYSTEMD_FEATURES);
105 _cleanup_free_ char *e = NULL;
108 e = bus_address_escape(optarg);
113 a = strjoin("x-machine-kernel:machine=", e, ";x-machine-unix:machine=", e, NULL);
115 a = strjoin("x-machine-unix:machine=", e, NULL);
130 assert_not_reached("Unhandled option");
133 /* If the first command line argument is only "x" characters
134 * we'll write who we are talking to into it, so that "ps" is
136 arg_command_line_buffer = argv[optind];
137 if (argc > optind + 1 || (arg_command_line_buffer && !in_charset(arg_command_line_buffer, "x"))) {
138 log_error("Too many arguments");
143 arg_address = strdup(DEFAULT_SYSTEM_BUS_ADDRESS);
151 static int rename_service(sd_bus *a, sd_bus *b) {
152 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
153 _cleanup_free_ char *p = NULL, *name = NULL;
163 r = sd_bus_get_owner_creds(b, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_AUGMENT, &creds);
167 r = sd_bus_creds_get_euid(creds, &uid);
171 r = sd_bus_creds_get_pid(creds, &pid);
175 r = sd_bus_creds_get_cmdline(creds, &cmdline);
179 r = sd_bus_creds_get_comm(creds, &comm);
183 name = uid_to_name(uid);
187 p = strv_join(cmdline, " ");
191 /* The status string gets the full command line ... */
193 "STATUS=Processing requests from client PID "PID_FMT" (%s); UID "UID_FMT" (%s)",
197 /* ... and the argv line only the short comm */
198 if (arg_command_line_buffer) {
201 m = strlen(arg_command_line_buffer);
202 w = snprintf(arg_command_line_buffer, m,
203 "[PID "PID_FMT"/%s; UID "UID_FMT"/%s]",
208 memzero(arg_command_line_buffer + w, m - w);
211 log_debug("Running on behalf of PID "PID_FMT" (%s), UID "UID_FMT" (%s), %s",
219 int main(int argc, char *argv[]) {
220 _cleanup_(proxy_freep) Proxy *p = NULL;
223 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
224 log_parse_environment();
227 r = parse_argv(argc, argv);
231 r = proxy_new(&p, STDIN_FILENO, STDOUT_FILENO, arg_address);
235 r = rename_service(p->destination_bus, p->local_bus);
237 log_debug_errno(r, "Failed to rename process: %m");
244 "STATUS=Shutting down.");
248 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;