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/>.
31 #include "sd-daemon.h"
33 #include "alloc-util.h"
34 #include "bus-internal.h"
37 #include "formats-util.h"
41 #include "user-util.h"
44 static char *arg_address
= NULL
;
45 static char *arg_command_line_buffer
= NULL
;
47 static int help(void) {
49 printf("%s [OPTIONS...]\n\n"
50 "Connect STDIO to a given bus address.\n\n"
51 " -h --help Show this help\n"
52 " --version Show package version\n"
53 " --machine=MACHINE Connect to specified machine\n"
54 " --address=ADDRESS Connect to the bus specified by ADDRESS\n"
55 " (default: " DEFAULT_SYSTEM_BUS_ADDRESS
")\n",
56 program_invocation_short_name
);
61 static int parse_argv(int argc
, char *argv
[]) {
69 static const struct option options
[] = {
70 { "help", no_argument
, NULL
, 'h' },
71 { "version", no_argument
, NULL
, ARG_VERSION
},
72 { "address", required_argument
, NULL
, ARG_ADDRESS
},
73 { "machine", required_argument
, NULL
, ARG_MACHINE
},
82 while ((c
= getopt_long(argc
, argv
, "h", options
, NULL
)) >= 0)
106 _cleanup_free_
char *e
= NULL
;
109 e
= bus_address_escape(optarg
);
113 a
= strjoin("x-machine-kernel:machine=", e
, ";x-machine-unix:machine=", e
, NULL
);
127 assert_not_reached("Unhandled option");
130 /* If the first command line argument is only "x" characters
131 * we'll write who we are talking to into it, so that "ps" is
133 arg_command_line_buffer
= argv
[optind
];
134 if (argc
> optind
+ 1 || (arg_command_line_buffer
&& !in_charset(arg_command_line_buffer
, "x"))) {
135 log_error("Too many arguments");
140 arg_address
= strdup(DEFAULT_SYSTEM_BUS_ADDRESS
);
148 static int rename_service(sd_bus
*a
, sd_bus
*b
) {
149 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
150 _cleanup_free_
char *p
= NULL
, *name
= NULL
;
160 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
);
164 r
= sd_bus_creds_get_euid(creds
, &uid
);
168 r
= sd_bus_creds_get_pid(creds
, &pid
);
172 r
= sd_bus_creds_get_cmdline(creds
, &cmdline
);
176 r
= sd_bus_creds_get_comm(creds
, &comm
);
180 name
= uid_to_name(uid
);
184 p
= strv_join(cmdline
, " ");
188 /* The status string gets the full command line ... */
190 "STATUS=Processing requests from client PID "PID_FMT
" (%s); UID "UID_FMT
" (%s)",
194 /* ... and the argv line only the short comm */
195 if (arg_command_line_buffer
) {
198 m
= strlen(arg_command_line_buffer
);
199 w
= snprintf(arg_command_line_buffer
, m
,
200 "[PID "PID_FMT
"/%s; UID "UID_FMT
"/%s]",
205 memzero(arg_command_line_buffer
+ w
, m
- w
);
208 log_debug("Running on behalf of PID "PID_FMT
" (%s), UID "UID_FMT
" (%s), %s",
216 int main(int argc
, char *argv
[]) {
217 _cleanup_(proxy_freep
) Proxy
*p
= NULL
;
220 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG
);
221 log_parse_environment();
224 r
= parse_argv(argc
, argv
);
228 r
= proxy_new(&p
, STDIN_FILENO
, STDOUT_FILENO
, arg_address
);
232 r
= rename_service(p
->destination_bus
, p
->local_bus
);
234 log_debug_errno(r
, "Failed to rename process: %m");
241 "STATUS=Shutting down.");
245 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;