From 93b4f2e9077f1959d563ba8e4d3f41a9764cc8c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 29 Jun 2016 14:03:38 +0200
Subject: [PATCH 4/7] sssctl: use talloc with sifp

This way we completely move D-Bus memory management to talloc and
we reduce number of code lines needed to send and receive reply.
---
 src/tools/sssctl/sssctl.h         | 14 +++++++++
 src/tools/sssctl/sssctl_domains.c | 62 ++++++++++++++++++---------------------
 src/tools/sssctl/sssctl_sifp.c    | 46 +++++++++++++++++++++++++++++
 3 files changed, 88 insertions(+), 34 deletions(-)

diff --git a/src/tools/sssctl/sssctl.h b/src/tools/sssctl/sssctl.h
index be624755de531df9ff5a97f5640266801695ef6e..c16fd25ce981d92bc047933b61cddd7035b5f7e3 100644
--- a/src/tools/sssctl/sssctl.h
+++ b/src/tools/sssctl/sssctl.h
@@ -24,6 +24,7 @@
 #include "lib/sifp/sss_sifp.h"
 #include "lib/sifp/sss_sifp_dbus.h"
 #include "tools/common/sss_tools.h"
+#include "sbus/sssd_dbus.h"
 
 enum sssctl_prompt_result {
     SSSCTL_PROMPT_YES,
@@ -56,6 +57,19 @@ void _sssctl_sifp_error(sss_sifp_ctx *sifp,
 #define sssctl_sifp_error(sifp, error, message) \
     _sssctl_sifp_error(sifp, error, _(message))
 
+sss_sifp_error _sssctl_sifp_send(TALLOC_CTX *mem_ctx,
+                                 sss_sifp_ctx *sifp,
+                                 DBusMessage **_reply,
+                                 const char *path,
+                                 const char *iface,
+                                 const char *method,
+                                 int first_arg_type,
+                                 ...);
+
+#define sssctl_sifp_send(mem_ctx, sifp, reply, path, iface, method, ...) \
+    _sssctl_sifp_send(mem_ctx, sifp, reply, path, iface, method,         \
+                         ##__VA_ARGS__, DBUS_TYPE_INVALID);
+
 errno_t sssctl_list_domains(struct sss_cmdline *cmdline,
                             struct sss_tool_ctx *tool_ctx,
                             void *pvt);
diff --git a/src/tools/sssctl/sssctl_domains.c b/src/tools/sssctl/sssctl_domains.c
index e822640a1c0bee3d33219fdbd6f976ec2b60dfe3..b516298e876aa5cedc99df331cd1d32c475164a4 100644
--- a/src/tools/sssctl/sssctl_domains.c
+++ b/src/tools/sssctl/sssctl_domains.c
@@ -74,47 +74,32 @@ errno_t sssctl_list_domains(struct sss_cmdline *cmdline,
 }
 
 static errno_t sssctl_domain_status_online(struct sss_tool_ctx *tool_ctx,
-                                           const char *domain_path,
-                                           bool force_start)
+                                           sss_sifp_ctx *sifp,
+                                           const char *domain_path)
 {
-    sss_sifp_ctx *sifp;
-    sss_sifp_error sifp_error;
-    DBusMessage *reply = NULL;
-    DBusMessage *msg;
+    TALLOC_CTX *tmp_ctx;
+    sss_sifp_error error;
+    DBusMessage *reply;
     bool is_online;
     errno_t ret;
 
-    if (!sssctl_start_sssd(force_start)) {
-        ret = ERR_SSSD_NOT_RUNNING;
-        goto done;
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+        return ENOMEM;
     }
 
-    sifp_error = sssctl_sifp_init(tool_ctx, &sifp);
-    if (sifp_error != SSS_SIFP_OK) {
-        sssctl_sifp_error(sifp, sifp_error, "Unable to connect to the InfoPipe");
-        ret = EFAULT;
-        goto done;
-    }
-
-    msg = sbus_create_message(tool_ctx, SSS_SIFP_ADDRESS, domain_path,
-                              IFACE_IFP_DOMAINS_DOMAIN,
-                              IFACE_IFP_DOMAINS_DOMAIN_ISONLINE);
-    if (msg == NULL) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create D-Bus message\n");
-        ret = ENOMEM;
-        goto done;
-    }
-
-    sifp_error = sss_sifp_send_message(sifp, msg, &reply);
-    if (sifp_error != SSS_SIFP_OK) {
-        sssctl_sifp_error(sifp, sifp_error, "Unable to get online status");
+    error = sssctl_sifp_send(tmp_ctx, sifp, &reply, domain_path,
+                             IFACE_IFP_DOMAINS_DOMAIN,
+                             IFACE_IFP_DOMAINS_DOMAIN_ISONLINE);
+    if (error != SSS_SIFP_OK) {
+        sssctl_sifp_error(sifp, error, "Unable to get online status");
         ret = EIO;
         goto done;
     }
 
     ret = sbus_parse_reply(reply, DBUS_TYPE_BOOLEAN, &is_online);
     if (ret != EOK) {
-        fprintf(stderr, _("Unable to get information from SSSD\n"));
         goto done;
     }
 
@@ -123,10 +108,7 @@ static errno_t sssctl_domain_status_online(struct sss_tool_ctx *tool_ctx,
     ret = EOK;
 
 done:
-    if (reply != NULL) {
-        dbus_message_unref(reply);
-    }
-
+    talloc_free(tmp_ctx);
     return ret;
 }
 
@@ -144,6 +126,8 @@ errno_t sssctl_domain_status(struct sss_cmdline *cmdline,
                              void *pvt)
 {
     struct sssctl_domain_status_opts opts = {0};
+    sss_sifp_ctx *sifp;
+    sss_sifp_error error;
     const char *path;
     bool opt_set;
     errno_t ret;
@@ -181,7 +165,17 @@ errno_t sssctl_domain_status(struct sss_cmdline *cmdline,
         return ENOMEM;
     }
 
-    ret = sssctl_domain_status_online(tool_ctx, path, opts.force_start);
+    if (!sssctl_start_sssd(opts.force_start)) {
+        return ERR_SSSD_NOT_RUNNING;
+    }
+
+    error = sssctl_sifp_init(tool_ctx, &sifp);
+    if (error != SSS_SIFP_OK) {
+        sssctl_sifp_error(sifp, error, "Unable to connect to the InfoPipe");
+        return EFAULT;
+    }
+
+    ret = sssctl_domain_status_online(tool_ctx, sifp, path);
     if (ret != EOK) {
         fprintf(stderr, _("Unable to get online status\n"));
         return ret;
diff --git a/src/tools/sssctl/sssctl_sifp.c b/src/tools/sssctl/sssctl_sifp.c
index e541c4b27ba38e50b209b0957c8b38f03afc891a..782a72d7ce8bbf1080c6d6ac988ffac2f432955f 100644
--- a/src/tools/sssctl/sssctl_sifp.c
+++ b/src/tools/sssctl/sssctl_sifp.c
@@ -116,3 +116,49 @@ void _sssctl_sifp_error(sss_sifp_ctx *sifp,
         break;
     }
 }
+
+sss_sifp_error _sssctl_sifp_send(TALLOC_CTX *mem_ctx,
+                                 sss_sifp_ctx *sifp,
+                                 DBusMessage **_reply,
+                                 const char *path,
+                                 const char *iface,
+                                 const char *method,
+                                 int first_arg_type,
+                                 ...)
+{
+    sss_sifp_error error;
+    DBusMessage *msg;
+    dbus_bool_t bret;
+    errno_t ret;
+    va_list va;
+
+    msg = sss_sifp_create_message(path, iface, method);
+    if (msg == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create D-Bus message\n");
+        return SSS_SIFP_OUT_OF_MEMORY;
+    }
+
+    va_start(va, first_arg_type);
+    bret = dbus_message_append_args_valist(msg, first_arg_type, va);
+    va_end(va);
+    if (!bret) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n");
+        error = SSS_SIFP_OUT_OF_MEMORY;
+        goto done;
+    }
+
+    error = sss_sifp_send_message(sifp, msg, _reply);
+    if (error != SSS_SIFP_OK) {
+        goto done;
+    }
+
+    ret = sbus_talloc_bound_message(mem_ctx, *_reply);
+    if (ret != EOK) {
+        error = SSS_SIFP_OUT_OF_MEMORY;
+        goto done;
+    }
+
+done:
+    dbus_message_unref(msg);
+    return error;
+}
-- 
2.1.0

