summaryrefslogtreecommitdiffstats
path: root/src/sbus/interface/sbus_interface.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 05:31:45 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 05:31:45 +0000
commit74aa0bc6779af38018a03fd2cf4419fe85917904 (patch)
tree9cb0681aac9a94a49c153d5823e7a55d1513d91f /src/sbus/interface/sbus_interface.c
parentInitial commit. (diff)
downloadsssd-74aa0bc6779af38018a03fd2cf4419fe85917904.tar.xz
sssd-74aa0bc6779af38018a03fd2cf4419fe85917904.zip
Adding upstream version 2.9.4.upstream/2.9.4
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/sbus/interface/sbus_interface.c')
-rw-r--r--src/sbus/interface/sbus_interface.c464
1 files changed, 464 insertions, 0 deletions
diff --git a/src/sbus/interface/sbus_interface.c b/src/sbus/interface/sbus_interface.c
new file mode 100644
index 0000000..e7fc05d
--- /dev/null
+++ b/src/sbus/interface/sbus_interface.c
@@ -0,0 +1,464 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2017 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <talloc.h>
+#include <string.h>
+
+#include "sbus/sbus_annotations.h"
+#include "sbus/sbus_interface_declarations.h"
+
+static struct sbus_handler
+sbus_sync_handler(sbus_handler_sync_fn handler,
+ sbus_handler_data data)
+{
+ struct sbus_handler object = {
+ .type = SBUS_HANDLER_SYNC,
+ .sync = handler,
+ .data = data
+ };
+
+ return object;
+}
+
+static struct sbus_handler
+sbus_async_handler(sbus_handler_send_fn handler_send,
+ sbus_handler_recv_fn handler_recv,
+ sbus_handler_data data)
+{
+ struct sbus_handler object = {
+ .type = SBUS_HANDLER_ASYNC,
+ .async_send = handler_send,
+ .async_recv = handler_recv,
+ .data = data
+ };
+
+ return object;
+}
+
+struct sbus_method
+sbus_method_sync(const char *name,
+ const struct sbus_method_arguments *arguments,
+ const struct sbus_annotation *annotations,
+ sbus_invoker_issue invoker_issue,
+ sbus_invoker_keygen invoker_keygen,
+ sbus_handler_sync_fn handler,
+ sbus_handler_data data)
+{
+ struct sbus_method object = {
+ .name = name,
+ .annotations = annotations,
+ .invoker = {.issue = invoker_issue, .keygen = invoker_keygen},
+ .handler = sbus_sync_handler(handler, data),
+ .arguments = arguments
+ };
+
+ return object;
+}
+
+struct sbus_method
+sbus_method_async(const char *name,
+ const struct sbus_method_arguments *arguments,
+ const struct sbus_annotation *annotations,
+ sbus_invoker_issue invoker_issue,
+ sbus_invoker_keygen invoker_keygen,
+ sbus_handler_send_fn handler_send,
+ sbus_handler_recv_fn handler_recv,
+ sbus_handler_data data)
+{
+ struct sbus_method object = {
+ .name = name,
+ .annotations = annotations,
+ .invoker = {.issue = invoker_issue, .keygen = invoker_keygen},
+ .handler = sbus_async_handler(handler_send, handler_recv, data),
+ .arguments = arguments
+ };
+
+ return object;
+}
+
+static struct sbus_method *
+sbus_method_copy(TALLOC_CTX *mem_ctx,
+ const struct sbus_method *input)
+{
+ struct sbus_method *copy;
+ size_t count;
+
+ for (count = 0; input[count].name != NULL; count++);
+
+ copy = talloc_zero_array(mem_ctx, struct sbus_method, count + 1);
+ if (copy == NULL) {
+ return NULL;
+ }
+
+ /* All data is either pointer to a static data or it is not a pointer.
+ * We can just copy it. */
+ memcpy(copy, input, sizeof(struct sbus_method) * (count + 1));
+
+ return copy;
+}
+
+struct sbus_signal
+sbus_signal(const char *name,
+ const struct sbus_argument *arguments,
+ const struct sbus_annotation *annotations)
+{
+ struct sbus_signal object = {
+ .name = name,
+ .arguments = arguments,
+ .annotations = annotations
+ };
+
+ return object;
+}
+
+static struct sbus_signal *
+sbus_signal_copy(TALLOC_CTX *mem_ctx,
+ const struct sbus_signal *input)
+{
+ struct sbus_signal *copy;
+ size_t count;
+
+ for (count = 0; input[count].name != NULL; count++);
+
+ copy = talloc_zero_array(mem_ctx, struct sbus_signal, count + 1);
+ if (copy == NULL) {
+ return NULL;
+ }
+
+ /* All data is either pointer to a static data or it is not a pointer.
+ * We can just copy it. */
+ memcpy(copy, input, sizeof(struct sbus_signal) * (count + 1));
+
+ return copy;
+}
+
+struct sbus_property
+sbus_property_sync(const char *name,
+ const char *type,
+ enum sbus_property_access access,
+ const struct sbus_annotation *annotations,
+ sbus_invoker_issue invoker_issue,
+ sbus_handler_sync_fn handler,
+ sbus_handler_data data)
+{
+ struct sbus_property object = {
+ .name = name,
+ .type = type,
+ .access = access,
+ .annotations = annotations,
+ .invoker = {.issue = invoker_issue, .keygen = NULL},
+ .handler = sbus_sync_handler(handler, data)
+ };
+
+ return object;
+}
+
+struct sbus_property
+sbus_property_async(const char *name,
+ const char *type,
+ enum sbus_property_access access,
+ const struct sbus_annotation *annotations,
+ sbus_invoker_issue invoker_issue,
+ sbus_handler_send_fn handler_send,
+ sbus_handler_recv_fn handler_recv,
+ sbus_handler_data data)
+{
+ struct sbus_property object = {
+ .name = name,
+ .type = type,
+ .access = access,
+ .annotations = annotations,
+ .invoker = {.issue = invoker_issue, .keygen = NULL},
+ .handler = sbus_async_handler(handler_send, handler_recv, data)
+ };
+
+ return object;
+}
+
+static struct sbus_property *
+sbus_property_copy(TALLOC_CTX *mem_ctx,
+ const struct sbus_property *input)
+{
+ struct sbus_property *copy;
+ size_t count;
+
+ for (count = 0; input[count].name != NULL; count++);
+
+ copy = talloc_zero_array(mem_ctx, struct sbus_property, count + 1);
+ if (copy == NULL) {
+ return NULL;
+ }
+
+ /* All data is either pointer to a static data or it is not a pointer.
+ * We can just copy it. */
+ memcpy(copy, input, sizeof(struct sbus_property) * (count + 1));
+
+ return copy;
+}
+
+struct sbus_interface
+sbus_interface(const char *name,
+ const struct sbus_annotation *annotations,
+ const struct sbus_method *methods,
+ const struct sbus_signal *signals,
+ const struct sbus_property *properties)
+{
+ struct sbus_interface object = {
+ .name = name,
+ .annotations = annotations,
+ .methods = methods,
+ .signals = signals,
+ .properties = properties
+ };
+
+ return object;
+}
+
+struct sbus_interface *
+sbus_interface_copy(TALLOC_CTX *mem_ctx,
+ const struct sbus_interface *input)
+{
+ struct sbus_interface *copy;
+
+ copy = talloc_zero(mem_ctx, struct sbus_interface);
+ if (copy == NULL) {
+ return NULL;
+ }
+
+ /* Name and annotations are pointer to static data, no need to copy them. */
+ copy->name = input->name;
+ copy->annotations = input->annotations;
+
+ copy->methods = sbus_method_copy(copy, input->methods);
+ copy->signals = sbus_signal_copy(copy, input->signals);
+ copy->properties = sbus_property_copy(copy, input->properties);
+
+ if (copy->methods == NULL || copy->signals == NULL
+ || copy->properties == NULL) {
+ talloc_free(copy);
+ return NULL;
+ }
+
+ return copy;
+}
+
+const struct sbus_method *
+sbus_interface_find_method(struct sbus_interface *iface,
+ const char *method_name)
+{
+ unsigned int i;
+
+ for (i = 0; iface->methods[i].name != NULL; i++) {
+ if (strcmp(iface->methods[i].name, method_name) == 0) {
+ return &iface->methods[i];
+ }
+ }
+
+ return NULL;
+}
+
+const struct sbus_property *
+sbus_interface_find_property(struct sbus_interface *iface,
+ enum sbus_property_access access,
+ const char *property_name)
+{
+ unsigned int i;
+
+ for (i = 0; iface->properties[i].name != NULL; i++) {
+ if (iface->properties[i].access != access) {
+ continue;
+ }
+
+ if (strcmp(iface->properties[i].name, property_name) == 0) {
+ return &iface->properties[i];
+ }
+ }
+
+ return NULL;
+}
+
+struct sbus_listener
+sbus_listener_sync(const char *interface,
+ const char *signal_name,
+ const char *object_path,
+ sbus_invoker_issue invoker_issue,
+ sbus_invoker_keygen invoker_keygen,
+ sbus_handler_sync_fn handler,
+ sbus_handler_data data)
+{
+ struct sbus_listener object = {
+ .interface = interface,
+ .signal_name = signal_name,
+ .object_path = object_path,
+ .invoker = {.issue = invoker_issue, .keygen = invoker_keygen},
+ .handler = sbus_sync_handler(handler, data)
+ };
+
+ return object;
+}
+
+struct sbus_listener
+sbus_listener_async(const char *interface,
+ const char *signal_name,
+ const char *object_path,
+ sbus_invoker_issue invoker_issue,
+ sbus_invoker_keygen invoker_keygen,
+ sbus_handler_send_fn handler_send,
+ sbus_handler_recv_fn handler_recv,
+ sbus_handler_data data)
+{
+ struct sbus_listener object = {
+ .interface = interface,
+ .signal_name = signal_name,
+ .object_path = object_path,
+ .invoker = {.issue = invoker_issue, .keygen = invoker_keygen},
+ .handler = sbus_async_handler(handler_send, handler_recv, data)
+ };
+
+ return object;
+}
+
+struct sbus_listener *
+sbus_listener_copy(TALLOC_CTX *mem_ctx,
+ const struct sbus_listener *input)
+{
+ /* All data is either pointer to a static data or it is not a pointer.
+ * We can just copy it. */
+ return talloc_memdup(mem_ctx, input, sizeof(struct sbus_listener));
+}
+
+struct sbus_node
+sbus_node_sync(const char *path,
+ sbus_handler_sync_fn factory,
+ sbus_handler_data data)
+{
+ struct sbus_node object = {
+ .path = path,
+ .factory = sbus_sync_handler(factory, data)
+ };
+
+ return object;
+}
+
+struct sbus_node
+sbus_node_async(const char *path,
+ sbus_handler_send_fn factory_send,
+ sbus_handler_recv_fn factory_recv,
+ sbus_handler_data data)
+{
+ struct sbus_node object = {
+ .path = path,
+ .factory = sbus_async_handler(factory_send, factory_recv, data)
+ };
+
+ return object;
+}
+
+struct sbus_node *
+sbus_node_copy(TALLOC_CTX *mem_ctx,
+ struct sbus_node *input)
+{
+ struct sbus_node *copy;
+
+ copy = talloc_zero(mem_ctx, struct sbus_node);
+ if (copy == NULL) {
+ return NULL;
+ }
+
+ copy->path = talloc_strdup(copy, input->path);
+ if (copy->path == NULL) {
+ talloc_free(copy);
+ return NULL;
+ }
+
+ copy->factory = input->factory;
+
+ return copy;
+}
+
+const char *
+sbus_annotation_find(const struct sbus_annotation *annotations,
+ const char *name)
+{
+ int i;
+
+ if (annotations == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; annotations[i].name != NULL; i++) {
+ if (strcmp(annotations[i].name, name) == 0) {
+ return annotations[i].value;
+ }
+ }
+
+ return NULL;
+}
+
+bool
+sbus_annotation_find_as_bool(const struct sbus_annotation *annotations,
+ const char *name)
+{
+ const char *value;
+
+ value = sbus_annotation_find(annotations, name);
+
+ if (value != NULL && strcasecmp(value, "true") == 0) {
+ return true;
+ }
+
+ return false;
+}
+
+static void
+sbus_warn_deprecated(const struct sbus_annotation *annotations,
+ const char *iface_name,
+ const char *method_name)
+{
+ const char *by;
+ const char *member;
+ const char *dot;
+
+ if (annotations == NULL) {
+ return;
+ }
+
+ if (sbus_annotation_find_as_bool(annotations, SBUS_ANNOTATION_DEPRECATED)) {
+ member = method_name == NULL ? "" : method_name;
+ dot = method_name == NULL ? "" : ".";
+
+ by = sbus_annotation_find(annotations, SBUS_ANNOTATION_DEPRECATED_BY);
+ if (by != NULL) {
+ DEBUG(SSSDBG_IMPORTANT_INFO, "%s%s%s is deprecated by %s\n",
+ iface_name, dot, member, by);
+ } else {
+ DEBUG(SSSDBG_IMPORTANT_INFO, "%s%s%s is deprecated\n",
+ iface_name, dot, member);
+ }
+ }
+}
+
+void
+sbus_annotation_warn(const struct sbus_interface *iface,
+ const struct sbus_method *method)
+{
+ sbus_warn_deprecated(iface->annotations, iface->name, NULL);
+ sbus_warn_deprecated(method->annotations, iface->name, method->name);
+}