+ if (w >= pathlen)
+ goto toolong;
+ path[w] = 0;
+ return 0;
+toolong:
+ return seterrno(ENAMETOOLONG);
+}
+#endif
+
+/********************************************************************
+ * Routines for getting paths
+ *******************************************************************/
+
+static char *get_dpath(struct sd_bus_message *msg)
+{
+ int rc;
+ const char *reply;
+ char *result;
+
+ rc = sd_bus_message_read_basic(msg, 'o', &reply);
+ rc = sderr2errno(rc);
+ if (rc < 0)
+ result = NULL;
+ else {
+ result = strdup(reply);
+ if (!result)
+ errno = ENOMEM;
+ }
+ sd_bus_message_unref(msg);
+ return result;
+}
+
+static char *get_unit_dpath(struct sd_bus *bus, const char *unit, int load)
+{
+ int rc;
+ struct sd_bus_message *ret = NULL;
+ sd_bus_error err = SD_BUS_ERROR_NULL;
+
+ rc = sd_bus_call_method(bus, sdb_destination, sdb_path, sdbi_manager, load ? sdbm_load_unit : sdbm_get_unit, &err, &ret, "s", unit);
+ if (rc < 0)
+ goto error;
+
+ return get_dpath(ret);
+error:
+ sd_bus_message_unref(ret);
+ return NULL;
+}
+
+static char *get_unit_dpath_by_pid(struct sd_bus *bus, unsigned pid)
+{
+ int rc;
+ struct sd_bus_message *ret = NULL;
+ sd_bus_error err = SD_BUS_ERROR_NULL;
+
+ rc = sd_bus_call_method(bus, sdb_destination, sdb_path, sdbi_manager, sdbm_get_unit_by_pid, &err, &ret, "u", pid);
+ if (rc < 0)
+ goto error;
+
+ return get_dpath(ret);
+error:
+ sd_bus_message_unref(ret);
+ return NULL;
+}
+
+static int unit_pid(struct sd_bus *bus, const char *dpath)
+{
+ int rc;
+ unsigned u = 0;
+ sd_bus_error err = SD_BUS_ERROR_NULL;
+
+ rc = sd_bus_get_property_trivial(bus, sdb_destination, dpath, sdbi_service, sdbp_exec_main_pid, &err, 'u', &u);
+ return rc < 0 ? rc : (int)u;
+}
+
+static enum SysD_State unit_state(struct sd_bus *bus, const char *dpath)
+{
+ int rc;
+ char *st;
+ enum SysD_State resu;
+ sd_bus_error err = SD_BUS_ERROR_NULL;
+
+ resu = SysD_State_INVALID;
+ rc = sd_bus_get_property_string(bus, sdb_destination, dpath, sdbi_unit, sdbp_active_state, &err, &st);
+ if (rc < 0) {
+ errno = -rc;
+ } else {
+ switch (st[0]) {
+ case 'a':
+ if (!strcmp(st, sds_state_names[SysD_State_Active]))
+ resu = SysD_State_Active;
+ else if (!strcmp(st, sds_state_names[SysD_State_Activating]))
+ resu = SysD_State_Activating;
+ break;
+ case 'd':
+ if (!strcmp(st, sds_state_names[SysD_State_Deactivating]))
+ resu = SysD_State_Deactivating;
+ break;
+ case 'f':
+ if (!strcmp(st, sds_state_names[SysD_State_Failed]))
+ resu = SysD_State_Failed;
+ break;
+ case 'i':
+ if (!strcmp(st, sds_state_names[SysD_State_Inactive]))
+ resu = SysD_State_Inactive;
+ break;
+ case 'r':
+ if (!strcmp(st, sds_state_names[SysD_State_Reloading]))
+ resu = SysD_State_Reloading;
+ break;
+ default:
+ break;
+ }
+ if (resu == NULL)
+ errno = EBADMSG;
+ free(st);
+ }
+ return resu;
+}
+
+static int unit_start(struct sd_bus *bus, const char *dpath)
+{
+ int rc;
+ struct sd_bus_message *ret = NULL;
+ sd_bus_error err = SD_BUS_ERROR_NULL;
+
+ rc = sd_bus_call_method(bus, sdb_destination, dpath, sdbi_unit, sdbm_start, &err, &ret, "s", "replace");
+ sd_bus_message_unref(ret);
+ return rc;
+}
+
+static int unit_restart(struct sd_bus *bus, const char *dpath)
+{
+ int rc;
+ struct sd_bus_message *ret = NULL;
+ sd_bus_error err = SD_BUS_ERROR_NULL;
+
+ rc = sd_bus_call_method(bus, sdb_destination, dpath, sdbi_unit, sdbm_restart, &err, &ret, "s", "replace");
+ sd_bus_message_unref(ret);
+ return rc;
+}
+
+static int unit_stop(struct sd_bus *bus, const char *dpath)
+{
+ int rc;
+ struct sd_bus_message *ret = NULL;
+ sd_bus_error err = SD_BUS_ERROR_NULL;
+
+ rc = sd_bus_call_method(bus, sdb_destination, dpath, sdbi_unit, sdbm_stop, &err, &ret, "s", "replace");
+ sd_bus_message_unref(ret);
+ return rc;
+}
+
+static int unit_start_name(struct sd_bus *bus, const char *name)
+{
+ int rc;
+ struct sd_bus_message *ret = NULL;
+ sd_bus_error err = SD_BUS_ERROR_NULL;
+
+ rc = sd_bus_call_method(bus, sdb_destination, sdb_path, sdbi_manager, sdbm_start_unit, &err, &ret, "ss", name, "replace");
+ sd_bus_message_unref(ret);
+ return rc;
+}
+
+static int unit_restart_name(struct sd_bus *bus, const char *name)
+{
+ int rc;
+ struct sd_bus_message *ret = NULL;
+ sd_bus_error err = SD_BUS_ERROR_NULL;
+
+ rc = sd_bus_call_method(bus, sdb_destination, sdb_path, sdbi_manager, sdbm_restart_unit, &err, &ret, "ss", name, "replace");
+ sd_bus_message_unref(ret);
+ return rc;
+}
+
+static int unit_stop_name(struct sd_bus *bus, const char *name)
+{
+ int rc;
+ struct sd_bus_message *ret = NULL;
+ sd_bus_error err = SD_BUS_ERROR_NULL;
+
+ rc = sd_bus_call_method(bus, sdb_destination, sdb_path, sdbi_manager, sdbm_stop_unit, &err, &ret, "ss", name, "replace");
+ sd_bus_message_unref(ret);