#include "capability.h"
#include "bus-policy.h"
-static const char *arg_address = KERNEL_SYSTEM_BUS_PATH;
+static char *arg_address = NULL;
static char *arg_command_line_buffer = NULL;
static bool arg_drop_privileges = false;
static char **arg_configuration = NULL;
" --version Show package version\n"
" --drop-privileges Drop privileges\n"
" --configuration=PATH Configuration file or directory\n"
+ " --machine=MACHINE Connect to specified machine\n"
" --address=ADDRESS Connect to the bus specified by ADDRESS\n"
- " (default: " KERNEL_SYSTEM_BUS_PATH ")\n",
+ " (default: " DEFAULT_SYSTEM_BUS_PATH ")\n",
program_invocation_short_name);
return 0;
ARG_ADDRESS,
ARG_DROP_PRIVILEGES,
ARG_CONFIGURATION,
+ ARG_MACHINE,
};
static const struct option options[] = {
{ "address", required_argument, NULL, ARG_ADDRESS },
{ "drop-privileges", no_argument, NULL, ARG_DROP_PRIVILEGES },
{ "configuration", required_argument, NULL, ARG_CONFIGURATION },
- { NULL, 0, NULL, 0 },
+ { "machine", required_argument, NULL, ARG_MACHINE },
+ {},
};
int c, r;
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+ while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
switch (c) {
puts(SYSTEMD_FEATURES);
return 0;
- case ARG_ADDRESS:
- arg_address = optarg;
+ case ARG_ADDRESS: {
+ char *a;
+
+ a = strdup(optarg);
+ if (!a)
+ return log_oom();
+
+ free(arg_address);
+ arg_address = a;
break;
+ }
case ARG_DROP_PRIVILEGES:
arg_drop_privileges = true;
return log_oom();
break;
+ case ARG_MACHINE: {
+ _cleanup_free_ char *e = NULL;
+ char *a;
+
+ e = bus_address_escape(optarg);
+ if (!e)
+ return log_oom();
+
+#ifdef ENABLE_KDBUS
+ a = strjoin("x-container-kernel:machine=", e, ";x-container-unix:machine=", e, NULL);
+#else
+ a = strjoin("x-container-unix:machine=", e, NULL);
+#endif
+ if (!a)
+ return log_oom();
+
+ free(arg_address);
+ 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 */
arg_command_line_buffer = argv[optind];
- if (argc > optind + 1 ||
- (arg_command_line_buffer && arg_command_line_buffer[strspn(arg_command_line_buffer, "x")] != 0)) {
+ if (argc > optind + 1 || (arg_command_line_buffer && !in_charset(arg_command_line_buffer, "x"))) {
log_error("Too many arguments");
return -EINVAL;
}
+ if (!arg_address) {
+ arg_address = strdup(DEFAULT_SYSTEM_BUS_PATH);
+ if (!arg_address)
+ return log_oom();
+ }
+
return 1;
}
pid, p,
uid, name,
a->unique_name);
- ;
+
return 0;
}
assert(b);
assert(m);
+ if (!a->is_kernel)
+ return 0;
+
if (!sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "GetAll"))
return 0;
assert(b);
assert(m);
+ if (!a->is_kernel)
+ return 0;
+
if (!streq_ptr(sd_bus_message_get_destination(m), "org.freedesktop.DBus"))
return 0;
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
- if (service_name_is_valid(arg0) < 0)
+ if (!service_name_is_valid(arg0))
return synthetic_reply_method_errno(m, -EINVAL, NULL);
cmd.flags = KDBUS_NAME_LIST_QUEUED;
name_list = (struct kdbus_name_list *) ((uint8_t *) a->kdbus_buffer + cmd.offset);
KDBUS_ITEM_FOREACH(name, name_list, names) {
+ const char *entry_name = NULL;
+ struct kdbus_item *item;
char *n;
- if (name->size <= sizeof(*name))
- continue;
+ KDBUS_ITEM_FOREACH(item, name, items)
+ if (item->type == KDBUS_ITEM_NAME)
+ entry_name = item->str;
- if (!streq(name->name, arg0))
+ if (!streq_ptr(entry_name, arg0))
continue;
if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0) {
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
- if (err > 0)
+ if (err < 0)
return synthetic_reply_method_errno(m, err, NULL);
return synthetic_reply_return_strv(m, owners);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
- if (service_name_is_valid(name) < 0)
+ if (!service_name_is_valid(name))
return synthetic_reply_method_errno(m, -EINVAL, NULL);
if (streq(name, "org.freedesktop.DBus"))
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
- if (service_name_is_valid(name) < 0)
+ if (!service_name_is_valid(name))
return synthetic_reply_method_errno(m, -EINVAL, NULL);
r = sd_bus_release_name(a, name);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
- if (service_name_is_valid(name) < 0)
+ if (!service_name_is_valid(name))
return synthetic_reply_method_errno(m, -EINVAL, NULL);
if ((flags & ~(BUS_NAME_ALLOW_REPLACEMENT|BUS_NAME_REPLACE_EXISTING|BUS_NAME_DO_NOT_QUEUE)) != 0)
return synthetic_reply_method_errno(m, -EINVAL, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
- if (service_name_is_valid(name) < 0)
+ if (!service_name_is_valid(name))
return synthetic_reply_method_errno(m, -EINVAL, NULL);
if (flags != 0)
return synthetic_reply_method_errno(m, -EINVAL, NULL);
int main(int argc, char *argv[]) {
- _cleanup_bus_unref_ sd_bus *a = NULL, *b = NULL;
+ _cleanup_bus_close_unref_ sd_bus *a = NULL, *b = NULL;
sd_id128_t server_id;
int r, in_fd, out_fd;
bool got_hello = false;
else {
k = sd_bus_send(a, m, NULL);
if (k < 0) {
- if (r == -ECONNRESET)
+ if (k == -ECONNRESET)
r = 0;
else {
r = k;
}
finish:
- sd_bus_flush(a);
- sd_bus_flush(b);
+ sd_notify(false,
+ "STOPPING=1\n"
+ "STATUS=Shutting down.");
policy_free(&policy);
strv_free(arg_configuration);
+ free(arg_address);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}