#include <sys/socket.h>
+#include "sd-bus.h"
#include "sd-daemon.h"
#include "sd-event.h"
-#include "util.h"
-#include "strv.h"
-#include "macro.h"
-#include "def.h"
-#include "path-util.h"
-#include "missing.h"
-#include "set.h"
-#include "signal-util.h"
-#include "unit-name.h"
-#include "sd-bus.h"
+#include "alloc-util.h"
#include "bus-error.h"
+#include "bus-internal.h"
#include "bus-label.h"
#include "bus-message.h"
#include "bus-util.h"
-#include "bus-internal.h"
+#include "cgroup-util.h"
+#include "def.h"
+//#include "env-util.h"
+#include "escape.h"
+#include "fd-util.h"
+#include "macro.h"
+#include "missing.h"
+#include "parse-util.h"
+#include "path-util.h"
+#include "proc-cmdline.h"
+#include "process-util.h"
+//#include "rlimit-util.h"
+#include "set.h"
+#include "signal-util.h"
+#include "stdio-util.h"
+#include "string-util.h"
+#include "strv.h"
+#include "syslog-util.h"
+#include "unit-name.h"
+#include "user-util.h"
+#include "utf8.h"
+#include "util.h"
+#if 0 /// UNNEEDED by elogind
static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
sd_event *e = userdata;
return code;
}
+#endif // 0
int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
_cleanup_bus_message_unref_ sd_bus_message *rep = NULL;
sd_bus_message *call,
int capability,
const char *action,
+ const char **details,
uid_t good_user,
bool *_challenge,
sd_bus_error *e) {
return 1;
#ifdef ENABLE_POLKIT
else {
+ _cleanup_bus_message_unref_ sd_bus_message *request = NULL;
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
int authorized = false, challenge = false;
- const char *sender;
+ const char *sender, **k, **v;
sender = sd_bus_message_get_sender(call);
if (!sender)
return -EBADMSG;
- r = sd_bus_call_method(
+ r = sd_bus_message_new_method_call(
call->bus,
+ &request,
"org.freedesktop.PolicyKit1",
"/org/freedesktop/PolicyKit1/Authority",
"org.freedesktop.PolicyKit1.Authority",
- "CheckAuthorization",
- e,
- &reply,
- "(sa{sv})sa{ss}us",
+ "CheckAuthorization");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(
+ request,
+ "(sa{sv})s",
"system-bus-name", 1, "name", "s", sender,
- action,
- 0,
- 0,
- "");
+ action);
+ if (r < 0)
+ return r;
+ r = sd_bus_message_open_container(request, 'a', "{ss}");
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH_PAIR(k, v, details) {
+ r = sd_bus_message_append(request, "{ss}", *k, *v);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_close_container(request);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(request, "us", 0, NULL);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_call(call->bus, request, 0, e, &reply);
if (r < 0) {
/* Treat no PK available as access denied */
if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
sd_bus_message *call,
int capability,
const char *action,
+ const char **details,
bool interactive,
uid_t good_user,
Hashmap **registry,
#ifdef ENABLE_POLKIT
_cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
AsyncPolkitQuery *q;
- const char *sender;
+ const char *sender, **k, **v;
sd_bus_message_handler_t callback;
void *userdata;
int c;
r = sd_bus_message_append(
pk,
- "(sa{sv})sa{ss}us",
+ "(sa{sv})s",
"system-bus-name", 1, "name", "s", sender,
- action,
- 0,
- !!interactive,
- NULL);
+ action);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(pk, 'a', "{ss}");
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH_PAIR(k, v, details) {
+ r = sd_bus_message_append(pk, "{ss}", *k, *v);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_close_container(pk);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(pk, "us", !!interactive, NULL);
if (r < 0)
return r;
#endif
}
+#if 0 /// UNNEEDED by elogind
int bus_check_peercred(sd_bus *c) {
struct ucred ucred;
socklen_t l;
return 1;
}
-int bus_open_system_systemd(sd_bus **_bus) {
+int bus_connect_system_systemd(sd_bus **_bus) {
_cleanup_bus_unref_ sd_bus *bus = NULL;
int r;
assert(_bus);
if (geteuid() != 0)
- return sd_bus_open_system(_bus);
+ return sd_bus_default_system(_bus);
/* If we are root and kdbus is not available, then let's talk
* directly to the system instance, instead of going via the
r = sd_bus_start(bus);
if (r < 0)
- return sd_bus_open_system(_bus);
+ return sd_bus_default_system(_bus);
r = bus_check_peercred(bus);
if (r < 0)
return 0;
}
-int bus_open_user_systemd(sd_bus **_bus) {
+int bus_connect_user_systemd(sd_bus **_bus) {
_cleanup_bus_unref_ sd_bus *bus = NULL;
_cleanup_free_ char *ee = NULL;
const char *e;
e = secure_getenv("XDG_RUNTIME_DIR");
if (!e)
- return sd_bus_open_user(_bus);
+ return sd_bus_default_user(_bus);
ee = bus_address_escape(e);
if (!ee)
r = sd_bus_start(bus);
if (r < 0)
- return sd_bus_open_user(_bus);
+ return sd_bus_default_user(_bus);
r = bus_check_peercred(bus);
if (r < 0)
return 0;
}
+#endif // 0
int bus_print_property(const char *name, sd_bus_message *property, bool all) {
char type;
return sd_bus_message_exit_container(m);
}
+#if 0 /// UNNEEDED by elogind
int bus_message_map_properties_changed(
sd_bus_message *m,
const struct bus_properties_map *map,
return invalidated;
}
+#endif // 0
int bus_map_all_properties(
sd_bus *bus,
return bus_message_map_all_properties(m, map, userdata);
}
-int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
+int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
int r;
assert(transport >= 0);
switch (transport) {
case BUS_TRANSPORT_LOCAL:
+#if 0 /// elogind does not support a user bus
if (user)
r = sd_bus_default_user(bus);
else
+#endif // 0
r = sd_bus_default_system(bus);
break;
return r;
}
-int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
+#if 0 /// UNNEEDED by elogind
+int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
int r;
assert(transport >= 0);
case BUS_TRANSPORT_LOCAL:
if (user)
- r = bus_open_user_systemd(bus);
+ r = bus_connect_user_systemd(bus);
else
- r = bus_open_system_systemd(bus);
+ r = bus_connect_system_systemd(bus);
break;
return r;
}
+#endif // 0
int bus_property_get_bool(
sd_bus *bus,
return log_error_errno(r, "Failed to parse bus message: %m");
}
+#if 0 /// UNNEEDED by elogind
int bus_log_create_error(int r) {
return log_error_errno(r, "Failed to create bus message: %m");
}
if (streq(field, "CPUQuota")) {
- if (isempty(eq)) {
-
- r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_append(m, "v", "t", USEC_INFINITY);
-
- } else if (endswith(eq, "%")) {
+ if (isempty(eq))
+ r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", USEC_INFINITY);
+ else if (endswith(eq, "%")) {
double percent;
if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
return -EINVAL;
}
- r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
+ r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", (usec_t) percent * USEC_PER_SEC / 100);
} else {
log_error("CPU quota needs to be in percent.");
return -EINVAL;
return bus_log_create_error(r);
return 0;
+
+ } else if (streq(field, "EnvironmentFile")) {
+
+ r = sd_bus_message_append(m, "sv", "EnvironmentFiles", "a(sb)", 1,
+ eq[0] == '-' ? eq + 1 : eq,
+ eq[0] == '-');
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ return 0;
+
+ } else if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec")) {
+ char *n;
+ usec_t t;
+ size_t l;
+ r = parse_sec(eq, &t);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse %s= parameter: %s", field, eq);
+
+ l = strlen(field);
+ n = newa(char, l + 2);
+ if (!n)
+ return log_oom();
+
+ /* Change suffix Sec → USec */
+ strcpy(mempcpy(n, field, l - 3), "USec");
+ r = sd_bus_message_append(m, "sv", n, "t", t);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ return 0;
}
r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
return bus_log_create_error(r);
if (STR_IN_SET(field,
- "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
- "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies")) {
+ "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting",
+ "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
+ "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit",
+ "PrivateTmp", "PrivateDevices", "PrivateNetwork", "NoNewPrivileges",
+ "SyslogLevelPrefix", "Delegate", "RemainAfterElapse")) {
r = parse_boolean(eq);
- if (r < 0) {
- log_error("Failed to parse boolean assignment %s.", assignment);
- return -EINVAL;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse boolean assignment %s.", assignment);
r = sd_bus_message_append(m, "v", "b", r);
} else if (streq(field, "MemoryLimit")) {
- off_t bytes;
+ uint64_t bytes;
+ if (isempty(eq) || streq(eq, "infinity"))
+ bytes = (uint64_t) -1;
+ else {
r = parse_size(eq, 1024, &bytes);
if (r < 0) {
log_error("Failed to parse bytes specification %s", assignment);
return -EINVAL;
}
+ }
+
+ r = sd_bus_message_append(m, "v", "t", bytes);
+
+ } else if (streq(field, "TasksMax")) {
+ uint64_t n;
+
+ if (isempty(eq) || streq(eq, "infinity"))
+ n = (uint64_t) -1;
+ else {
+ r = safe_atou64(eq, &n);
+ if (r < 0) {
+ log_error("Failed to parse maximum tasks specification %s", assignment);
+ return -EINVAL;
+ }
+ }
+
+ r = sd_bus_message_append(m, "v", "t", n);
+
+ } else if (STR_IN_SET(field, "CPUShares", "StartupCPUShares")) {
+ uint64_t u;
+
+ r = cg_cpu_shares_parse(eq, &u);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
- r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
+ r = sd_bus_message_append(m, "v", "t", u);
- } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
+ } else if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) {
uint64_t u;
- r = safe_atou64(eq, &u);
+ r = cg_cpu_shares_parse(eq, &u);
if (r < 0) {
log_error("Failed to parse %s value %s.", field, eq);
return -EINVAL;
r = sd_bus_message_append(m, "v", "t", u);
- } else if (STR_IN_SET(field, "User", "Group", "DevicePolicy", "KillMode"))
+ } else if (STR_IN_SET(field,
+ "User", "Group", "DevicePolicy", "KillMode",
+ "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
+ "StandardInput", "StandardOutput", "StandardError",
+ "Description", "Slice", "Type", "WorkingDirectory",
+ "RootDirectory", "SyslogIdentifier", "ProtectSystem",
+ "ProtectHome"))
r = sd_bus_message_append(m, "v", "s", eq);
- else if (streq(field, "DeviceAllow")) {
+ else if (streq(field, "SyslogLevel")) {
+ int level;
+
+ level = log_level_from_string(eq);
+ if (level < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "i", level);
+
+ } else if (streq(field, "SyslogFacility")) {
+ int facility;
+
+ facility = log_facility_unshifted_from_string(eq);
+ if (facility < 0) {
+ log_error("Failed to parse %s value %s.", field, eq);
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "i", facility);
+
+ } else if (streq(field, "DeviceAllow")) {
if (isempty(eq))
r = sd_bus_message_append(m, "v", "a(ss)", 0);
r = sd_bus_message_append(m, "v", "a(st)", 0);
else {
const char *path, *bandwidth, *e;
- off_t bytes;
+ uint64_t bytes;
e = strchr(eq, ' ');
if (e) {
return -EINVAL;
}
- r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
+ r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes);
}
} else if (streq(field, "BlockIODeviceWeight")) {
r = sd_bus_message_append(m, "v", "i", i);
- } else if (streq(field, "Environment")) {
+ } else if (STR_IN_SET(field, "Environment", "PassEnvironment")) {
+ const char *p;
+
+ r = sd_bus_message_open_container(m, 'v', "as");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(m, 'a', "s");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ p = eq;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
+ if (r < 0) {
+ log_error("Failed to parse Environment value %s", eq);
+ return -EINVAL;
+ }
+ if (r == 0)
+ break;
+
+ if (streq(field, "Environment")) {
+ if (!env_assignment_is_valid(word)) {
+ log_error("Invalid environment assignment: %s", word);
+ return -EINVAL;
+ }
+ } else { /* PassEnvironment */
+ if (!env_name_is_valid(word)) {
+ log_error("Invalid environment variable name: %s", word);
+ return -EINVAL;
+ }
+ }
+
+ r = sd_bus_message_append_basic(m, 's', word);
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
- r = sd_bus_message_append(m, "v", "as", 1, eq);
+ r = sd_bus_message_close_container(m);
} else if (streq(field, "KillSignal")) {
int sig;
r = sd_bus_message_append(m, "v", "i", sig);
- } else if (streq(field, "AccuracySec")) {
- usec_t u;
+ } else if (streq(field, "TimerSlackNSec")) {
+ nsec_t n;
- r = parse_sec(eq, &u);
+ r = parse_nsec(eq, &n);
if (r < 0) {
log_error("Failed to parse %s value %s", field, eq);
return -EINVAL;
}
- r = sd_bus_message_append(m, "v", "t", u);
+ r = sd_bus_message_append(m, "v", "t", n);
+ } else if (streq(field, "OOMScoreAdjust")) {
+ int oa;
+
+ r = safe_atoi(eq, &oa);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s", field, eq);
+ return -EINVAL;
+ }
+
+ if (!oom_score_adjust_is_valid(oa)) {
+ log_error("OOM score adjust value out of range");
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_append(m, "v", "i", oa);
+ } else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories")) {
+ const char *p;
+
+ r = sd_bus_message_open_container(m, 'v', "as");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(m, 'a', "s");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ p = eq;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+ int offset;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+ if (r < 0) {
+ log_error("Failed to parse %s value %s", field, eq);
+ return -EINVAL;
+ }
+ if (r == 0)
+ break;
+
+ if (!utf8_is_valid(word)) {
+ log_error("Failed to parse %s value %s", field, eq);
+ return -EINVAL;
+ }
+
+ offset = word[0] == '-';
+ if (!path_is_absolute(word + offset)) {
+ log_error("Failed to parse %s value %s", field, eq);
+ return -EINVAL;
+ }
+
+ path_kill_slashes(word + offset);
+
+ r = sd_bus_message_append_basic(m, 's', word);
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_close_container(m);
+
+ } else if (streq(field, "RuntimeDirectory")) {
+ const char *p;
+
+ r = sd_bus_message_open_container(m, 'v', "as");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(m, 'a', "s");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ p = eq;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse %s value %s", field, eq);
+
+ if (r == 0)
+ break;
+
+ r = sd_bus_message_append_basic(m, 's', word);
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_close_container(m);
} else {
log_error("Unknown assignment %s.", assignment);
return 0;
}
+#endif // 0
typedef struct BusWaitForJobs {
sd_bus *bus;
sd_bus_slot *slot_disconnected;
} BusWaitForJobs;
+#if 0 /// UNNEEDED by elogind
static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
assert(m);
{ "start-limit", "start of the service was attempted too often" }
};
-static void log_job_error_with_service_result(const char* service, const char *result) {
- _cleanup_free_ char *service_shell_quoted = NULL;
+static void log_job_error_with_service_result(const char* service, const char *result, const char *extra_args) {
+ _cleanup_free_ char *service_shell_quoted = NULL, *systemctl_extra_args = NULL;
assert(service);
service_shell_quoted = shell_maybe_quote(service);
+ systemctl_extra_args = strjoin("systemctl ", extra_args, " ", NULL);
+ if (!systemctl_extra_args) {
+ log_oom();
+ return;
+ }
+
+ systemctl_extra_args = strstrip(systemctl_extra_args);
+
if (!isempty(result)) {
unsigned i;
break;
if (i < ELEMENTSOF(explanations)) {
- log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
+ log_error("Job for %s failed because %s. See \"%s status %s\" and \"journalctl -xe\" for details.\n",
service,
explanations[i].explanation,
+ systemctl_extra_args,
strna(service_shell_quoted));
goto finish;
}
}
- log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
+ log_error("Job for %s failed. See \"%s status %s\" and \"journalctl -xe\" for details.\n",
service,
+ systemctl_extra_args,
strna(service_shell_quoted));
finish:
/* For some results maybe additional explanation is required */
if (streq_ptr(result, "start-limit"))
- log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
+ log_info("To force a start use \"%1$s reset-failed %2$s\" followed by \"%1$s start %2$s\" again.",
+ systemctl_extra_args,
strna(service_shell_quoted));
}
-static int check_wait_response(BusWaitForJobs *d, bool quiet) {
+static int check_wait_response(BusWaitForJobs *d, bool quiet, const char *extra_args) {
int r = 0;
assert(d->result);
else if (streq(d->result, "dependency"))
log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
else if (streq(d->result, "invalid"))
- log_error("Job for %s invalid.", strna(d->name));
+ log_error("%s is not active, cannot reload.", strna(d->name));
else if (streq(d->result, "assert"))
log_error("Assertion failed on job for %s.", strna(d->name));
else if (streq(d->result, "unsupported"))
if (q < 0)
log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
- log_job_error_with_service_result(d->name, result);
+ log_job_error_with_service_result(d->name, result, extra_args);
} else
log_error("Job failed. See \"journalctl -xe\" for details.");
}
return r;
}
-int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet) {
+int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet, const char *extra_args) {
int r = 0;
assert(d);
return log_error_errno(q, "Failed to wait for response: %m");
if (d->result) {
- q = check_wait_response(d, quiet);
+ q = check_wait_response(d, quiet, extra_args);
/* Return the first error as it is most likely to be
* meaningful. */
if (q < 0 && r == 0)
log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
}
- free(d->name);
- d->name = NULL;
-
- free(d->result);
- d->result = NULL;
+ d->name = mfree(d->name);
+ d->result = mfree(d->result);
}
return r;
return set_put_strdup(d->jobs, path);
}
-/// UNNEEDED by elogind
-#if 0
+int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet) {
+ int r;
+
+ r = bus_wait_for_jobs_add(d, path);
+ if (r < 0)
+ return log_oom();
+
+ return bus_wait_for_jobs(d, quiet, NULL);
+}
+
int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
const char *type, *path, *source;
int r;
return 0;
}
-#endif // 0
/**
* bus_path_encode_unique() - encode unique object path
*ret_external = external;
return 1;
}
+#endif // 0
bool is_kdbus_wanted(void) {
_cleanup_free_ char *value = NULL;
return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;
}
+
+#if 0 /// UNNEEDED by elogind
+int bus_property_get_rlimit(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ struct rlimit *rl;
+ uint64_t u;
+ rlim_t x;
+ const char *is_soft;
+
+ assert(bus);
+ assert(reply);
+ assert(userdata);
+
+ is_soft = endswith(property, "Soft");
+ rl = *(struct rlimit**) userdata;
+ if (rl)
+ x = is_soft ? rl->rlim_cur : rl->rlim_max;
+ else {
+ struct rlimit buf = {};
+ int z;
+ const char *s;
+
+ s = is_soft ? strndupa(property, is_soft - property) : property;
+
+ z = rlimit_from_string(strstr(s, "Limit"));
+ assert(z >= 0);
+
+ getrlimit(z, &buf);
+ x = is_soft ? buf.rlim_cur : buf.rlim_max;
+ }
+
+ /* rlim_t might have different sizes, let's map
+ * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
+ * all archs */
+ u = x == RLIM_INFINITY ? (uint64_t) -1 : (uint64_t) x;
+
+ return sd_bus_message_append(reply, "t", u);
+}
+#endif // 0