stdio-bridge.c revision b1d4f8e154bf61b5de1b27461ef8e9c8c5e838a1
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
Copyright 2013 Daniel Mack
Copyright 2014 Kay Sievers
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <errno.h>
#include <getopt.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include "sd-daemon.h"
#include "sd-bus.h"
#include "bus-internal.h"
#include "bus-util.h"
#include "def.h"
#include "formats-util.h"
#include "log.h"
#include "proxy.h"
#include "strv.h"
#include "user-util.h"
#include "util.h"
static char *arg_address = NULL;
static char *arg_command_line_buffer = NULL;
static int help(void) {
printf("%s [OPTIONS...]\n\n"
"Connect STDIO to a given bus address.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
" --machine=MACHINE Connect to specified machine\n"
" --address=ADDRESS Connect to the bus specified by ADDRESS\n"
return 0;
}
enum {
ARG_VERSION = 0x100,
};
{},
};
int c;
switch (c) {
case 'h':
help();
return 0;
case ARG_VERSION:
return version();
case ARG_ADDRESS: {
char *a;
if (!a)
return log_oom();
arg_address = a;
break;
}
case ARG_MACHINE: {
_cleanup_free_ char *e = NULL;
char *a;
e = bus_address_escape(optarg);
if (!e)
return log_oom();
if (!a)
return log_oom();
arg_address = a;
break;
}
case '?':
return -EINVAL;
default:
assert_not_reached("Unhandled option");
}
/* If the first command line argument is only "x" characters
* we'll write who we are talking to into it, so that "ps" is
* explanatory */
log_error("Too many arguments");
return -EINVAL;
}
if (!arg_address) {
if (!arg_address)
return log_oom();
}
return 1;
}
const char *comm;
char **cmdline;
int r;
assert(a);
assert(b);
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);
if (r < 0)
return r;
if (r < 0)
return r;
if (r < 0)
return r;
if (r < 0)
return r;
if (r < 0)
return r;
if (!name)
return -ENOMEM;
if (!p)
return -ENOMEM;
/* The status string gets the full command line ... */
sd_notifyf(false,
pid, p,
/* ... and the argv line only the short comm */
if (arg_command_line_buffer) {
size_t m, w;
w = snprintf(arg_command_line_buffer, m,
if (m > w)
memzero(arg_command_line_buffer + w, m - w);
}
pid, p,
a->unique_name);
return 0;
}
int r;
log_open();
if (r <= 0)
goto finish;
if (r < 0)
goto finish;
if (r < 0)
log_debug_errno(r, "Failed to rename process: %m");
r = proxy_run(p);
sd_notify(false,
"STOPPING=1\n"
"STATUS=Shutting down.");
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}