#include "pretty-print.h"
#include "string-util.h"
#include "tpm2-util.h"
+#include "varlink-util.h"
static int status_entries(
const BootConfig *config,
if (r < 0)
return r;
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *previous = NULL;
+ r = varlink_set_sentinel(link, "io.systemd.BootControl.NoSuchBootEntry");
+ if (r < 0)
+ return r;
+
for (size_t i = 0; i < config.n_entries; i++) {
- if (previous) {
- r = sd_varlink_notifybo(link, SD_JSON_BUILD_PAIR_VARIANT("entry", previous));
- if (r < 0)
- return r;
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
- previous = sd_json_variant_unref(previous);
- }
+ r = boot_entry_to_json(&config, i, &v);
+ if (r < 0)
+ return r;
- r = boot_entry_to_json(&config, i, &previous);
+ r = sd_varlink_replybo(link, SD_JSON_BUILD_PAIR_VARIANT("entry", v));
if (r < 0)
return r;
}
- if (!previous)
- return sd_varlink_error(link, "io.systemd.BootControl.NoSuchBootEntry", NULL);
-
- return sd_varlink_replybo(link, SD_JSON_BUILD_PAIR_VARIANT("entry", previous));
+ return 0;
}
#include "uid-classification.h"
#include "user-util.h"
#include "varlink-dynamic-user.h"
+#include "varlink-util.h"
typedef struct LookupParameters {
const char *user_name;
{}
};
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
LookupParameters p = {
.uid = UID_INVALID,
};
if (!streq_ptr(p.service, "io.systemd.DynamicUser"))
return sd_varlink_error(link, "io.systemd.UserDatabase.BadService", NULL);
+ r = varlink_set_sentinel(link, "io.systemd.UserDatabase.NoRecordFound");
+ if (r < 0)
+ return r;
+
if (uid_is_valid(p.uid))
r = dynamic_user_lookup_uid(m, p.uid, &found_name);
else if (p.user_name)
if (!user_match_lookup_parameters(&p, d->name, uid))
continue;
- if (v) {
- r = sd_varlink_notify(link, v);
- if (r < 0)
- return r;
-
- v = sd_json_variant_unref(v);
- }
-
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = build_user_json(d->name, uid, &v);
if (r < 0)
return r;
- }
- if (!v)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ r = sd_varlink_reply(link, v);
+ if (r < 0)
+ return r;
+ }
- return sd_varlink_reply(link, v);
+ return 0;
}
if (r == -ESRCH)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
if (r < 0)
return r;
if (!user_match_lookup_parameters(&p, un, uid))
return sd_varlink_error(link, "io.systemd.UserDatabase.ConflictingRecordFound", NULL);
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = build_user_json(un, uid, &v);
if (r < 0)
return r;
{}
};
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
LookupParameters p = {
.gid = GID_INVALID,
};
if (r != 0)
return r;
+ r = varlink_set_sentinel(link, "io.systemd.UserDatabase.NoRecordFound");
+ if (r < 0)
+ return r;
+
if (!streq_ptr(p.service, "io.systemd.DynamicUser"))
return sd_varlink_error(link, "io.systemd.UserDatabase.BadService", NULL);
if (!group_match_lookup_parameters(&p, d->name, (gid_t) uid))
continue;
- if (v) {
- r = sd_varlink_notify(link, v);
- if (r < 0)
- return r;
-
- v = sd_json_variant_unref(v);
- }
-
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = build_group_json(d->name, (gid_t) uid, &v);
if (r < 0)
return r;
- }
- if (!v)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ r = sd_varlink_reply(link, v);
+ if (r < 0)
+ return r;
+ }
- return sd_varlink_reply(link, v);
+ return 0;
}
if (r == -ESRCH)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
if (r < 0)
return r;
if (!group_match_lookup_parameters(&p, gn, gid))
return sd_varlink_error(link, "io.systemd.UserDatabase.ConflictingRecordFound", NULL);
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = build_group_json(gn, gid, &v);
if (r < 0)
return r;
if (r <= 0)
return r;
+ r = varlink_set_sentinel(link, NULL);
+ if (r < 0)
+ return r;
+
log_info("Queuing reload/restart jobs for marked units%s", glyph(GLYPH_ELLIPSIS));
Unit *u;
const char *error_msg = bus_error.message ?: error_id ? NULL : STRERROR(r);
- r = sd_varlink_notifybo(link,
- SD_JSON_BUILD_PAIR_STRING("unitID", u->id),
- JSON_BUILD_PAIR_STRING_NON_EMPTY("error", error_id),
- JSON_BUILD_PAIR_STRING_NON_EMPTY("errorMessage", error_msg));
+ r = sd_varlink_replybo(link,
+ SD_JSON_BUILD_PAIR_STRING("unitID", u->id),
+ JSON_BUILD_PAIR_STRING_NON_EMPTY("error", error_id),
+ JSON_BUILD_PAIR_STRING_NON_EMPTY("errorMessage", error_msg));
} else
- r = sd_varlink_notifybo(link,
- SD_JSON_BUILD_PAIR_STRING("unitID", u->id),
- SD_JSON_BUILD_PAIR_INTEGER("jobID", job_id));
+ r = sd_varlink_replybo(link,
+ SD_JSON_BUILD_PAIR_STRING("unitID", u->id),
+ SD_JSON_BUILD_PAIR_INTEGER("jobID", job_id));
if (r < 0)
return r;
}
- if (ret < 0)
- return ret;
-
- return sd_varlink_reply(link, NULL);
+ return ret;
}
JSON_BUILD_PAIR_CALLBACK_NON_NULL("CGroup", unit_cgroup_runtime_build_json, u));
}
-static int list_unit_one(sd_varlink *link, Unit *unit, bool more) {
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
- int r;
-
+static int list_unit_one(sd_varlink *link, Unit *unit) {
assert(link);
assert(unit);
- r = sd_json_buildo(
- &v,
- SD_JSON_BUILD_PAIR_CALLBACK("context", unit_context_build_json, unit),
- SD_JSON_BUILD_PAIR_CALLBACK("runtime", unit_runtime_build_json, unit));
- if (r < 0)
- return r;
-
- if (more)
- return sd_varlink_notify(link, v);
-
- return sd_varlink_reply(link, v);
+ return sd_varlink_replybo(link,
+ SD_JSON_BUILD_PAIR_CALLBACK("context", unit_context_build_json, unit),
+ SD_JSON_BUILD_PAIR_CALLBACK("runtime", unit_runtime_build_json, unit));
}
-static int list_unit_one_with_selinux_access_check(sd_varlink *link, Unit *unit, bool more) {
+static int list_unit_one_with_selinux_access_check(sd_varlink *link, Unit *unit) {
int r;
assert(link);
* it means that SELinux enforce is on. It also does all the logging(). */
return sd_varlink_error(link, SD_VARLINK_ERROR_PERMISSION_DENIED, NULL);
- return list_unit_one(link, unit, more);
+ return list_unit_one(link, unit);
}
static int lookup_unit_by_pidref(sd_varlink *link, Manager *manager, PidRef *pidref, Unit **ret_unit) {
}
*ret = unit;
- return 0;
+ return !!unit;
}
int vl_method_list_units(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
_cleanup_(unit_lookup_parameters_done) UnitLookupParameters p = {
.pidref = PIDREF_NULL,
};
- Unit *unit, *previous = NULL;
+ Unit *unit;
const char *k;
int r;
if (r < 0)
return r;
if (r > 0)
- return list_unit_one_with_selinux_access_check(link, unit, /* more= */ false);
+ return list_unit_one_with_selinux_access_check(link, unit);
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL);
+ r = varlink_set_sentinel(link, "io.systemd.Manager.NoSuchUnit");
+ if (r < 0)
+ return r;
+
HASHMAP_FOREACH_KEY(unit, k, manager->units) {
/* ignore aliases */
if (k != unit->id)
continue;
- if (previous) {
- r = list_unit_one(link, previous, /* more= */ true);
- if (r < 0)
- return r;
- }
-
- previous = unit;
+ r = list_unit_one(link, unit);
+ if (r < 0)
+ return r;
}
- if (previous)
- return list_unit_one(link, previous, /* more= */ false);
-
- return sd_varlink_error(link, "io.systemd.Manager.NoSuchUnit", NULL);
+ return 0;
}
int varlink_unit_queue_job_one(
#include "user-record.h"
#include "user-record-util.h"
#include "user-util.h"
+#include "varlink-util.h"
typedef struct LookupParameters {
const char *user_name;
{}
};
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
LookupParameters p = {
.uid = UID_INVALID,
};
if (!streq_ptr(p.service, m->userdb_service))
return sd_varlink_error(link, "io.systemd.UserDatabase.BadService", NULL);
+ r = varlink_set_sentinel(link, "io.systemd.UserDatabase.NoRecordFound");
+ if (r < 0)
+ return r;
+
if (uid_is_valid(p.uid))
h = hashmap_get(m->homes_by_uid, UID_TO_PTR(p.uid));
else if (p.user_name) {
return r;
} else {
- /* If neither UID nor name was specified, then dump all homes. Do so with varlink_notify()
- * for all entries but the last, so that clients can stream the results, and easily process
- * them piecemeal. */
+ /* If neither UID nor name was specified, then dump all homes. */
HASHMAP_FOREACH(h, m->homes_by_uid) {
-
if (!home_user_match_lookup_parameters(&p, h))
continue;
- if (v) {
- /* An entry set from the previous iteration? Then send it now */
- r = sd_varlink_notify(link, v);
- if (r < 0)
- return r;
-
- v = sd_json_variant_unref(v);
- }
-
trusted = client_is_trusted(link, h);
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = build_user_json(h, trusted, &v);
if (r < 0)
return r;
- }
- if (!v)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ r = sd_varlink_reply(link, v);
+ if (r < 0)
+ return r;
+ }
- return sd_varlink_reply(link, v);
+ return 0;
}
if (!h)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
if (!home_user_match_lookup_parameters(&p, h))
return sd_varlink_error(link, "io.systemd.UserDatabase.ConflictingRecordFound", NULL);
trusted = client_is_trusted(link, h);
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = build_user_json(h, trusted, &v);
if (r < 0)
return r;
{}
};
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
LookupParameters p = {
.gid = GID_INVALID,
};
if (!streq_ptr(p.service, m->userdb_service))
return sd_varlink_error(link, "io.systemd.UserDatabase.BadService", NULL);
+ r = varlink_set_sentinel(link, "io.systemd.UserDatabase.NoRecordFound");
+ if (r < 0)
+ return r;
+
if (gid_is_valid(p.gid))
h = hashmap_get(m->homes_by_uid, UID_TO_PTR((uid_t) p.gid));
else if (p.group_name) {
if (r < 0)
return r;
} else {
-
HASHMAP_FOREACH(h, m->homes_by_uid) {
-
if (!home_group_match_lookup_parameters(&p, h))
continue;
- if (v) {
- r = sd_varlink_notify(link, v);
- if (r < 0)
- return r;
-
- v = sd_json_variant_unref(v);
- }
-
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = build_group_json(h, &v);
if (r < 0)
return r;
- }
- if (!v)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ r = sd_varlink_reply(link, v);
+ if (r < 0)
+ return r;
+ }
- return sd_varlink_reply(link, v);
+ return 0;
}
if (!h)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
if (!home_group_match_lookup_parameters(&p, h))
return sd_varlink_error(link, "io.systemd.UserDatabase.ConflictingRecordFound", NULL);
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = build_group_json(h, &v);
if (r < 0)
return r;
if (!streq_ptr(p.service, m->userdb_service))
return sd_varlink_error(link, "io.systemd.UserDatabase.BadService", NULL);
+ r = varlink_set_sentinel(link, "io.systemd.UserDatabase.NoRecordFound");
+ if (r < 0)
+ return r;
+
if (p.user_name) {
r = manager_get_home_by_name(m, p.user_name, &h);
if (r < 0)
return r;
if (!h)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
if (p.group_name) {
if (!strv_contains(h->record->member_of, p.group_name) &&
!user_record_matches_user_name(h->record, p.group_name))
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
return sd_varlink_replybo(
link,
}
STRV_FOREACH(i, h->record->member_of) {
- r = sd_varlink_notifybo(
+ r = sd_varlink_replybo(
link,
SD_JSON_BUILD_PAIR_STRING("userName", h->user_name),
SD_JSON_BUILD_PAIR_STRING("groupName", *i));
SD_JSON_BUILD_PAIR_STRING("groupName", h->user_name));
} else if (p.group_name) {
- const char *last = NULL;
-
HASHMAP_FOREACH(h, m->homes_by_uid) {
-
if (!strv_contains(h->record->member_of, p.group_name) &&
!user_record_matches_user_name(h->record, p.group_name))
continue;
- if (last) {
- r = sd_varlink_notifybo(
- link,
- SD_JSON_BUILD_PAIR_STRING("userName", last),
- SD_JSON_BUILD_PAIR_STRING("groupName", p.group_name));
- if (r < 0)
- return r;
- }
-
- last = h->user_name;
- }
-
- if (last)
- return sd_varlink_replybo(
+ r = sd_varlink_replybo(
link,
- SD_JSON_BUILD_PAIR_STRING("userName", last),
+ SD_JSON_BUILD_PAIR_STRING("userName", h->user_name),
SD_JSON_BUILD_PAIR_STRING("groupName", p.group_name));
+ if (r < 0)
+ return r;
+ }
} else {
- const char *last = NULL;
-
HASHMAP_FOREACH(h, m->homes_by_uid) {
+ r = sd_varlink_replybo(
+ link,
+ SD_JSON_BUILD_PAIR_STRING("userName", h->user_name),
+ SD_JSON_BUILD_PAIR_STRING("groupName", h->user_name));
+ if (r < 0)
+ return r;
+
STRV_FOREACH(j, h->record->member_of) {
- if (last) {
- r = sd_varlink_notifybo(
- link,
- SD_JSON_BUILD_PAIR_STRING("userName", last),
- SD_JSON_BUILD_PAIR_STRING("groupName", last));
- if (r < 0)
- return r;
-
- last = NULL;
- }
-
- r = sd_varlink_notifybo(
+ r = sd_varlink_replybo(
link,
SD_JSON_BUILD_PAIR_STRING("userName", h->user_name),
SD_JSON_BUILD_PAIR_STRING("groupName", *j));
if (r < 0)
return r;
}
-
- last = h->user_name;
}
-
- if (last)
- return sd_varlink_replybo(
- link,
- SD_JSON_BUILD_PAIR_STRING("userName", last),
- SD_JSON_BUILD_PAIR_STRING("groupName", last));
}
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
}
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL);
- Transfer *previous = NULL, *t;
- HASHMAP_FOREACH(t, m->transfers) {
+ r = varlink_set_sentinel(link, "io.systemd.Import.NoTransfers");
+ if (r < 0)
+ return r;
+ Transfer *t;
+ HASHMAP_FOREACH(t, m->transfers) {
if (p.class >= 0 && p.class != t->class)
continue;
- if (previous) {
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
-
- r = make_transfer_json(previous, &v);
- if (r < 0)
- return r;
-
- r = sd_varlink_notify(link, v);
- if (r < 0)
- return r;
- }
-
- previous = t;
- }
-
- if (previous) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
-
- r = make_transfer_json(previous, &v);
+ r = make_transfer_json(t, &v);
if (r < 0)
return r;
- return sd_varlink_reply(link, v);
+ r = sd_varlink_reply(link, v);
+ if (r < 0)
+ return r;
}
- return sd_varlink_error(link, "io.systemd.Import.NoTransfers", NULL);
+ return 0;
}
static JSON_DISPATCH_ENUM_DEFINE(json_dispatch_import_verify, ImportVerify, import_verify_from_string);
return 0;
}
-static int list_machine_one_and_maybe_read_metadata(sd_varlink *link, Machine *m, bool more, AcquireMetadata am) {
+static int list_machine_one_and_maybe_read_metadata(sd_varlink *link, Machine *m, AcquireMetadata am) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL, *addr_array = NULL;
_cleanup_strv_free_ char **os_release = NULL;
uid_t shift = UID_INVALID;
if (r < 0)
return r;
- if (more)
- return sd_varlink_notify(link, v);
-
return sd_varlink_reply(link, v);
}
_cleanup_(machine_lookup_parameters_done) MachineLookupParameters p = {
.pidref = PIDREF_NULL,
};
-
- Machine *machine;
int r;
assert(link);
if (r != 0)
return r;
+ r = varlink_set_sentinel(link, VARLINK_ERROR_MACHINE_NO_SUCH_MACHINE);
+ if (r < 0)
+ return r;
+
if (p.name || pidref_is_set(&p.pidref) || pidref_is_automatic(&p.pidref)) {
+ Machine *machine;
r = lookup_machine_by_name_or_pidref(link, m, p.name, &p.pidref, &machine);
if (r == -ESRCH)
- return sd_varlink_error(link, VARLINK_ERROR_MACHINE_NO_SUCH_MACHINE, NULL);
+ return 0;
if (r < 0)
return r;
- return list_machine_one_and_maybe_read_metadata(link, machine, /* more= */ false, p.acquire_metadata);
+ return list_machine_one_and_maybe_read_metadata(link, machine, p.acquire_metadata);
}
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL);
- Machine *previous = NULL, *i;
- HASHMAP_FOREACH(i, m->machines) {
- if (previous) {
- r = list_machine_one_and_maybe_read_metadata(link, previous, /* more= */ true, p.acquire_metadata);
- if (r < 0)
- return r;
- }
-
- previous = i;
+ Machine *machine;
+ HASHMAP_FOREACH(machine, m->machines) {
+ r = list_machine_one_and_maybe_read_metadata(link, machine, p.acquire_metadata);
+ if (r < 0)
+ return r;
}
- if (previous)
- return list_machine_one_and_maybe_read_metadata(link, previous, /* more= */ false, p.acquire_metadata);
-
- return sd_varlink_error(link, VARLINK_ERROR_MACHINE_NO_SUCH_MACHINE, NULL);
+ return 0;
}
static int lookup_machine_and_call_method(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata, sd_varlink_method_t method) {
return lookup_machine_and_call_method(link, parameters, flags, userdata, vl_method_open_root_directory_internal);
}
-static int list_image_one_and_maybe_read_metadata(Manager *m, sd_varlink *link, Image *image, bool more, AcquireMetadata am) {
+static int list_image_one_and_maybe_read_metadata(Manager *m, sd_varlink *link, Image *image, AcquireMetadata am) {
int r;
assert(m);
return r;
}
- if (more)
- return sd_varlink_notify(link, v);
-
return sd_varlink_reply(link, v);
}
if (r != 0)
return r;
+ r = varlink_set_sentinel(link, VARLINK_ERROR_MACHINE_IMAGE_NO_SUCH_IMAGE);
+ if (r < 0)
+ return r;
+
if (p.image_name) {
_cleanup_(image_unrefp) Image *found = NULL;
r = image_find(m->runtime_scope, IMAGE_MACHINE, p.image_name, /* root= */ NULL, &found);
if (r == -ENOENT)
- return sd_varlink_error(link, VARLINK_ERROR_MACHINE_IMAGE_NO_SUCH_IMAGE, NULL);
+ return 0;
if (r < 0)
return log_debug_errno(r, "Failed to find image: %m");
- return list_image_one_and_maybe_read_metadata(m, link, found, /* more= */ false, p.acquire_metadata);
+ return list_image_one_and_maybe_read_metadata(m, link, found, p.acquire_metadata);
}
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
if (r < 0)
return log_debug_errno(r, "Failed to discover images: %m");
- Image *image, *previous = NULL;
+ Image *image;
HASHMAP_FOREACH(image, images) {
- if (previous) {
- r = list_image_one_and_maybe_read_metadata(m, link, previous, /* more= */ true, p.acquire_metadata);
- if (r < 0)
- return r;
- }
-
- previous = image;
+ r = list_image_one_and_maybe_read_metadata(m, link, image, p.acquire_metadata);
+ if (r < 0)
+ return r;
}
- if (previous)
- return list_image_one_and_maybe_read_metadata(m, link, previous, /* more= */ false, p.acquire_metadata);
-
- return sd_varlink_error(link, VARLINK_ERROR_MACHINE_IMAGE_NO_SUCH_IMAGE, NULL);
+ return 0;
}
static int manager_varlink_init_userdb(Manager *m) {
if (r < 0)
return r;
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *rec_cel = NULL;
+ // FIXME: We can't use a NULL sentinel here because the output fields in the IDL are non-nullable.
+ r = varlink_set_sentinel(link, NULL);
+ if (r < 0)
+ return r;
FOREACH_ARRAY(rr, el->records, el->n_records) {
-
- if (rec_cel) {
- r = sd_varlink_notifybo(link, SD_JSON_BUILD_PAIR_VARIANT("record", rec_cel));
- if (r < 0)
- return r;
-
- rec_cel = sd_json_variant_unref(rec_cel);
- }
-
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *rec_cel = NULL;
r = event_log_record_to_cel(*rr, &recnum, &rec_cel);
if (r < 0)
return r;
+
+ r = sd_varlink_replybo(link, SD_JSON_BUILD_PAIR_VARIANT("record", rec_cel));
+ if (r < 0)
+ return r;
}
- return sd_varlink_replybo(link, SD_JSON_BUILD_PAIR_CONDITION(!!rec_cel, "record", SD_JSON_BUILD_VARIANT(rec_cel)));
+ return 0;
}
typedef struct MethodMakePolicyParameters {
if (r < 0)
return r;
- if (n == 0)
- return sd_varlink_error(link, "io.systemd.Repart.NoCandidateDevices", NULL);
+ r = varlink_set_sentinel(link, "io.systemd.Repart.NoCandidateDevices");
+ if (r < 0)
+ return r;
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
FOREACH_ARRAY(d, l, n) {
- if (v) {
- r = sd_varlink_notify(link, v);
- if (r < 0)
- return r;
-
- v = sd_json_variant_unref(v);
- }
-
- r = sd_json_buildo(
- &v,
+ r = sd_varlink_replybo(link,
SD_JSON_BUILD_PAIR_STRING("node", d->node),
JSON_BUILD_PAIR_STRV_NON_EMPTY("symlinks", d->symlinks),
JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("diskseq", d->diskseq, UINT64_MAX),
return r;
}
- assert(v);
- return sd_varlink_reply(link, v);
+ return 0;
}
static JSON_DISPATCH_ENUM_DEFINE(json_dispatch_empty_mode, EmptyMode, empty_mode_from_string);
#include "varlink-io.systemd.Metrics.h"
#include "varlink-util.h"
-static void metric_family_context_done(MetricFamilyContext *ctx) {
- assert(ctx);
-
- sd_json_variant_unref(ctx->previous);
-}
-
int metrics_setup_varlink_server(
sd_varlink_server **server, /* in and out param */
sd_varlink_server_flags_t flags,
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(metric_family_type, MetricFamilyType);
-static int metric_family_build_send(sd_varlink *link, const MetricFamily *mf, bool more) {
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
- int r;
-
- assert(link);
+static int metric_family_build_json(const MetricFamily *mf, sd_json_variant **ret) {
assert(mf);
- r = sd_json_buildo(
- &v,
+ return sd_json_buildo(
+ ret,
SD_JSON_BUILD_PAIR_STRING("name", mf->name),
SD_JSON_BUILD_PAIR_STRING("description", mf->description),
SD_JSON_BUILD_PAIR_STRING("type", metric_family_type_to_string(mf->type)));
- if (r < 0)
- return r;
-
- if (more)
- return sd_varlink_notify(link, v);
-
- return sd_varlink_reply(link, v);
}
int metrics_method_describe(
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL);
- const MetricFamily *previous = NULL;
+ r = varlink_set_sentinel(link, "io.systemd.Metrics.NoSuchMetric");
+ if (r < 0)
+ return r;
+
for (const MetricFamily *mf = metric_family_table; mf && mf->name; mf++) {
- if (previous) {
- r = metric_family_build_send(link, previous, /* more= */ true);
- if (r < 0)
- return log_debug_errno(
- r, "Failed to describe metric family '%s': %m", previous->name);
- }
-
- previous = mf;
- }
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
- if (!previous)
- return sd_varlink_error(link, "io.systemd.Metrics.NoSuchMetric", NULL);
+ r = metric_family_build_json(mf, &v);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to describe metric family '%s': %m", mf->name);
- r = metric_family_build_send(link, previous, /* more= */ false);
- if (r < 0)
- return log_debug_errno(r, "Failed to describe metric family '%s': %m", previous->name);
+ r = sd_varlink_reply(link, v);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to send varlink reply: %m");
+ }
return 0;
}
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL);
- _cleanup_(metric_family_context_done) MetricFamilyContext ctx = { .link = link };
+ r = varlink_set_sentinel(link, "io.systemd.Metrics.NoSuchMetric");
+ if (r < 0)
+ return r;
+
+ MetricFamilyContext ctx = { .link = link };
for (const MetricFamily *mf = metric_family_table; mf && mf->name; mf++) {
assert(mf->generate);
r, "Failed to list metrics for metric family '%s': %m", mf->name);
}
- if (!ctx.previous)
- return sd_varlink_error(link, "io.systemd.Metrics.NoSuchMetric", NULL);
-
- /* produce the last metric */
- return sd_varlink_reply(link, ctx.previous);
+ return 0;
}
static int metric_build_send(MetricFamilyContext *context, const char *object, sd_json_variant *value, sd_json_variant *fields) {
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
- int r;
-
assert(context);
assert(value);
assert(context->link);
assert(sd_json_variant_is_string(e));
}
- r = sd_json_buildo(
- &v,
+ return sd_varlink_replybo(context->link,
SD_JSON_BUILD_PAIR_STRING("name", context->metric_family->name),
JSON_BUILD_PAIR_STRING_NON_EMPTY("object", object),
SD_JSON_BUILD_PAIR("value", SD_JSON_BUILD_VARIANT(value)),
JSON_BUILD_PAIR_VARIANT_NON_NULL("fields", fields));
- if (r < 0)
- return r;
-
- if (context->previous) {
- r = sd_varlink_notify(context->link, context->previous);
- if (r < 0)
- return r;
-
- context->previous = sd_json_variant_unref(context->previous);
- }
-
- context->previous = TAKE_PTR(v);
-
- return 0;
}
int metric_build_send_string(MetricFamilyContext *context, const char *object, const char *value, sd_json_variant *fields) {
typedef struct MetricFamilyContext {
const MetricFamily* metric_family;
sd_varlink *link;
- sd_json_variant *previous;
} MetricFamilyContext;
typedef int (*metric_family_generate_func_t) (MetricFamilyContext *mfc, void *userdata);
VARLINK_DISPATCH_POLKIT_FIELD,
{}
};
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
Hashmap **polkit_registry = ASSERT_PTR(userdata);
int r;
if (r < 0)
return r;
+ r = varlink_set_sentinel(link, "io.systemd.sysext.NoImagesFound");
+ if (r < 0)
+ return r;
+
Image *img;
HASHMAP_FOREACH(img, images) {
- if (v) {
- /* Send previous item with more=true */
- r = sd_varlink_notify(link, v);
- if (r < 0)
- return r;
- }
-
- v = sd_json_variant_unref(v);
-
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = image_to_json(img, &v);
if (r < 0)
return r;
- }
- if (v) /* Send final item with more=false */
- return sd_varlink_reply(link, v);
+ r = sd_varlink_reply(link, v);
+ if (r < 0)
+ return r;
+ }
- return sd_varlink_error(link, "io.systemd.sysext.NoImagesFound", NULL);
+ return 0;
}
static int verb_help(int argc, char **argv, void *userdata) {
{}
};
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
_cleanup_(user_record_unrefp) UserRecord *hr = NULL;
_cleanup_(lookup_parameters_done) LookupParameters p = {
.uid = UID_INVALID,
* we are done'; == 0 means 'not processed, caller should process now' */
return r;
+ r = varlink_set_sentinel(link, "io.systemd.UserDatabase.NoRecordFound");
+ if (r < 0)
+ return r;
+
if (uid_is_valid(p.uid))
r = userdb_by_uid(p.uid, &p.match, userdb_flags, &hr);
else if (p.name)
r = userdb_by_name(p.name, &p.match, userdb_flags, &hr);
else {
_cleanup_(userdb_iterator_freep) UserDBIterator *iterator = NULL;
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *last = NULL;
r = userdb_all(&p.match, userdb_flags, &iterator);
if (IN_SET(r, -ESRCH, -ENOLINK))
* implementation detail and always return NoRecordFound in this case, since from a
* client's perspective it's irrelevant if there was no entry at all or just not on
* the service that the query was limited to. */
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
if (r < 0)
return r;
if (r < 0)
return r;
- if (last) {
- r = sd_varlink_notify(link, last);
- if (r < 0)
- return r;
-
- last = sd_json_variant_unref(last);
- }
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
+ r = build_user_json(link, z, &v);
+ if (r < 0)
+ return r;
- r = build_user_json(link, z, &last);
+ r = sd_varlink_reply(link, v);
if (r < 0)
return r;
}
- if (!last)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
-
- return sd_varlink_reply(link, last);
+ return 0;
}
if (r == -ESRCH)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
if (r == -ENOEXEC)
return sd_varlink_error(link, "io.systemd.UserDatabase.NonMatchingRecordFound", NULL);
if (r < 0) {
(p.name && !user_record_matches_user_name(hr, p.name)))
return sd_varlink_error(link, "io.systemd.UserDatabase.ConflictingRecordFound", NULL);
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = build_user_json(link, hr, &v);
if (r < 0)
return r;
{}
};
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
_cleanup_(group_record_unrefp) GroupRecord *g = NULL;
_cleanup_(lookup_parameters_done) LookupParameters p = {
.gid = GID_INVALID,
if (r != 0)
return r;
+ r = varlink_set_sentinel(link, "io.systemd.UserDatabase.NoRecordFound");
+ if (r < 0)
+ return r;
+
if (gid_is_valid(p.gid))
r = groupdb_by_gid(p.gid, &p.match, userdb_flags, &g);
else if (p.name)
r = groupdb_by_name(p.name, &p.match, userdb_flags, &g);
else {
_cleanup_(userdb_iterator_freep) UserDBIterator *iterator = NULL;
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *last = NULL;
r = groupdb_all(&p.match, userdb_flags, &iterator);
if (IN_SET(r, -ESRCH, -ENOLINK))
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
if (r < 0)
return r;
if (r < 0)
return r;
- if (last) {
- r = sd_varlink_notify(link, last);
- if (r < 0)
- return r;
-
- last = sd_json_variant_unref(last);
- }
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
+ r = build_group_json(link, z, &v);
+ if (r < 0)
+ return r;
- r = build_group_json(link, z, &last);
+ r = sd_varlink_reply(link, v);
if (r < 0)
return r;
}
- if (!last)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
-
- return sd_varlink_reply(link, last);
+ return 0;
}
if (r == -ESRCH)
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
if (r == -ENOEXEC)
return sd_varlink_error(link, "io.systemd.UserDatabase.NonMatchingRecordFound", NULL);
if (r < 0) {
(p.name && !group_record_matches_group_name(g, p.name)))
return sd_varlink_error(link, "io.systemd.UserDatabase.ConflictingRecordFound", NULL);
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
r = build_group_json(link, g, &v);
if (r < 0)
return r;
{}
};
- _cleanup_free_ char *last_user_name = NULL, *last_group_name = NULL;
_cleanup_(userdb_iterator_freep) UserDBIterator *iterator = NULL;
MembershipLookupParameters p = {};
UserDBFlags userdb_flags;
if (r != 0)
return r;
+ r = varlink_set_sentinel(link, "io.systemd.UserDatabase.NoRecordFound");
+ if (r < 0)
+ return r;
+
if (p.group_name)
r = membershipdb_by_group(p.group_name, userdb_flags, &iterator);
else if (p.user_name)
else
r = membershipdb_all(userdb_flags, &iterator);
if (IN_SET(r, -ESRCH, -ENOLINK))
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ return 0;
if (r < 0)
return r;
if (p.group_name && p.user_name && !streq(group_name, p.group_name))
continue;
- if (last_user_name) {
- assert(last_group_name);
-
- r = sd_varlink_notifybo(
- link,
- SD_JSON_BUILD_PAIR_STRING("userName", last_user_name),
- SD_JSON_BUILD_PAIR_STRING("groupName", last_group_name));
- if (r < 0)
- return r;
- }
-
- free_and_replace(last_user_name, user_name);
- free_and_replace(last_group_name, group_name);
- }
-
- if (!last_user_name) {
- assert(!last_group_name);
- return sd_varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL);
+ r = sd_varlink_replybo(
+ link,
+ SD_JSON_BUILD_PAIR_STRING("userName", user_name),
+ SD_JSON_BUILD_PAIR_STRING("groupName", group_name));
+ if (r < 0)
+ return r;
}
- assert(last_group_name);
-
- return sd_varlink_replybo(
- link,
- SD_JSON_BUILD_PAIR_STRING("userName", last_user_name),
- SD_JSON_BUILD_PAIR_STRING("groupName", last_group_name));
+ return 0;
}
static int process_connection(sd_varlink_server *server, int _fd) {