LCOV - code coverage report
Current view: top level - lib/sifp - sss_sifp.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 154 204 75.5 %
Date: 2015-10-19 Functions: 13 15 86.7 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Pavel Březina <pbrezina@redhat.com>
       4             : 
       5             :     Copyright (C) 2014 Red Hat
       6             : 
       7             :     This program is free software; you can redistribute it and/or modify
       8             :     it under the terms of the GNU General Public License as published by
       9             :     the Free Software Foundation; either version 3 of the License, or
      10             :     (at your option) any later version.
      11             : 
      12             :     This program is distributed in the hope that it will be useful,
      13             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :     GNU General Public License for more details.
      16             : 
      17             :     You should have received a copy of the GNU General Public License
      18             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include <dbus/dbus.h>
      22             : #include <stdlib.h>
      23             : #include <string.h>
      24             : 
      25             : #include "lib/sifp/sss_sifp.h"
      26             : #include "lib/sifp/sss_sifp_dbus.h"
      27             : #include "lib/sifp/sss_sifp_private.h"
      28             : 
      29             : #define DBUS_IFACE_PROP "org.freedesktop.DBus.Properties"
      30             : 
      31         296 : static void * default_alloc(size_t size, void *pvt)
      32             : {
      33         296 :     return malloc(size);
      34             : }
      35             : 
      36         303 : static void default_free(void *ptr, void *pvt)
      37             : {
      38         303 :     free(ptr);
      39         303 : }
      40             : 
      41           6 : static DBusMessage * sss_sifp_create_prop_msg(const char *object_path,
      42             :                                               const char *method)
      43             : {
      44           6 :     return sss_sifp_create_message(object_path, DBUS_IFACE_PROP, method);
      45             : }
      46             : 
      47             : sss_sifp_error
      48          46 : sss_sifp_init(sss_sifp_ctx **_ctx)
      49             : {
      50          46 :     return sss_sifp_init_ex(NULL, default_alloc, default_free, _ctx);
      51             : }
      52             : 
      53             : sss_sifp_error
      54          46 : sss_sifp_init_ex(void *alloc_pvt,
      55             :                  sss_sifp_alloc_func *alloc_func,
      56             :                  sss_sifp_free_func *free_func,
      57             :                  sss_sifp_ctx **_ctx)
      58             : {
      59          46 :     sss_sifp_ctx *ctx = NULL;
      60          46 :     DBusConnection *conn = NULL;
      61             :     DBusError dbus_error;
      62             :     sss_sifp_error ret;
      63             : 
      64          46 :     if (_ctx == NULL || alloc_func == NULL || free_func == NULL) {
      65           0 :         return SSS_SIFP_INVALID_ARGUMENT;
      66             :     }
      67             : 
      68          46 :     dbus_error_init(&dbus_error);
      69             : 
      70          46 :     ctx = alloc_func(sizeof(sss_sifp_ctx), alloc_pvt);
      71          46 :     if (ctx == NULL) {
      72           0 :         ret = SSS_SIFP_OUT_OF_MEMORY;
      73           0 :         goto done;
      74             :     }
      75             : 
      76          46 :     ctx->conn = NULL;
      77          46 :     ctx->alloc_fn = alloc_func;
      78          46 :     ctx->free_fn = free_func;
      79          46 :     ctx->alloc_pvt = alloc_pvt;
      80          46 :     ctx->io_error = alloc_func(sizeof(DBusError), alloc_pvt);
      81          46 :     if (ctx->io_error == NULL) {
      82           0 :         ret = SSS_SIFP_OUT_OF_MEMORY;
      83           0 :         goto done;
      84             :     }
      85             : 
      86          46 :     dbus_error_init(ctx->io_error);
      87             : 
      88          46 :     conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error);
      89          46 :     if (dbus_error_is_set(&dbus_error)) {
      90           0 :         sss_sifp_set_io_error(ctx, &dbus_error);
      91           0 :         ret = SSS_SIFP_IO_ERROR;
      92           0 :         goto done;
      93             :     }
      94             : 
      95          46 :     ctx->conn = conn;
      96          46 :     *_ctx = ctx;
      97             : 
      98          46 :     ret = SSS_SIFP_OK;
      99             : 
     100             : done:
     101          46 :     if (ret != SSS_SIFP_OK) {
     102           0 :         sss_sifp_free(&ctx);
     103             :     }
     104             : 
     105          46 :     dbus_error_free(&dbus_error);
     106          46 :     return ret;
     107             : }
     108             : 
     109             : const char *
     110           0 : sss_sifp_get_last_io_error_name(sss_sifp_ctx *ctx)
     111             : {
     112           0 :     if (ctx == NULL) {
     113           0 :         return "Invalid sss_sifp context";
     114             :     }
     115             : 
     116           0 :     if (!dbus_error_is_set(ctx->io_error)) {
     117           0 :         return NULL;
     118             :     }
     119             : 
     120           0 :     return ctx->io_error->name;
     121             : }
     122             : 
     123             : const char *
     124           0 : sss_sifp_get_last_io_error_message(sss_sifp_ctx *ctx)
     125             : {
     126           0 :     if (ctx == NULL) {
     127           0 :         return "Invalid sss_sifp context";
     128             :     }
     129             : 
     130           0 :     if (!dbus_error_is_set(ctx->io_error)) {
     131           0 :         return NULL;
     132             :     }
     133             : 
     134           0 :     return ctx->io_error->message;
     135             : }
     136             : 
     137             : sss_sifp_error
     138           3 : sss_sifp_fetch_attr(sss_sifp_ctx *ctx,
     139             :                     const char *object_path,
     140             :                     const char *interface,
     141             :                     const char *name,
     142             :                     sss_sifp_attr ***_attrs)
     143             : {
     144           3 :     DBusMessage *msg = NULL;
     145           3 :     DBusMessage *reply = NULL;
     146             :     dbus_bool_t bret;
     147             :     sss_sifp_error ret;
     148             : 
     149           3 :     if (ctx == NULL || object_path == NULL || interface == NULL
     150           3 :             || name == NULL || _attrs == NULL) {
     151           0 :         return SSS_SIFP_INVALID_ARGUMENT;
     152             :     }
     153             : 
     154             :     /* Message format:
     155             :      * In: string:interface
     156             :      * In: string:attribute
     157             :      * Out: variant(misc:value)
     158             :      */
     159             : 
     160           3 :     msg = sss_sifp_create_prop_msg(object_path, "Get");
     161           3 :     if (msg == NULL) {
     162           0 :         ret = SSS_SIFP_OUT_OF_MEMORY;
     163           0 :         goto done;
     164             :     }
     165             : 
     166           3 :     bret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &interface,
     167             :                                          DBUS_TYPE_STRING, &name,
     168             :                                          DBUS_TYPE_INVALID);
     169           3 :     if (!bret) {
     170           0 :         ret = SSS_SIFP_OUT_OF_MEMORY;
     171           0 :         goto done;
     172             :     }
     173             : 
     174           3 :     ret = sss_sifp_send_message(ctx, msg, &reply);
     175           3 :     if (ret != SSS_SIFP_OK) {
     176           0 :         goto done;
     177             :     }
     178             : 
     179           3 :     ret = sss_sifp_parse_attr(ctx, name, reply, _attrs);
     180             : 
     181             : done:
     182           3 :     if (msg != NULL) {
     183           3 :         dbus_message_unref(msg);
     184             :     }
     185             : 
     186           3 :     if (reply != NULL) {
     187           3 :         dbus_message_unref(reply);
     188             :     }
     189             : 
     190           3 :     return ret;
     191             : }
     192             : 
     193             : sss_sifp_error
     194           3 : sss_sifp_fetch_all_attrs(sss_sifp_ctx *ctx,
     195             :                          const char *object_path,
     196             :                          const char *interface,
     197             :                          sss_sifp_attr ***_attrs)
     198             : {
     199           3 :     DBusMessage *msg = NULL;
     200           3 :     DBusMessage *reply = NULL;
     201             :     dbus_bool_t bret;
     202             :     sss_sifp_error ret;
     203             : 
     204           3 :     if (ctx == NULL || object_path == NULL || interface == NULL
     205           3 :             || _attrs == NULL) {
     206           0 :         return SSS_SIFP_INVALID_ARGUMENT;
     207             :     }
     208             : 
     209           3 :     msg = sss_sifp_create_prop_msg(object_path, "GetAll");
     210           3 :     if (msg == NULL) {
     211           0 :         ret = SSS_SIFP_OUT_OF_MEMORY;
     212           0 :         goto done;
     213             :     }
     214             : 
     215           3 :     bret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &interface,
     216             :                                          DBUS_TYPE_INVALID);
     217           3 :     if (!bret) {
     218           0 :         ret = SSS_SIFP_OUT_OF_MEMORY;
     219           0 :         goto done;
     220             :     }
     221             : 
     222           3 :     ret = sss_sifp_send_message(ctx, msg, &reply);
     223           3 :     if (ret != SSS_SIFP_OK) {
     224           0 :         goto done;
     225             :     }
     226             : 
     227           3 :     ret = sss_sifp_parse_attr_list(ctx, reply, _attrs);
     228             : 
     229             : done:
     230           3 :     if (msg != NULL) {
     231           3 :         dbus_message_unref(msg);
     232             :     }
     233             : 
     234           3 :     if (reply != NULL) {
     235           3 :         dbus_message_unref(reply);
     236             :     }
     237             : 
     238           3 :     return ret;
     239             : }
     240             : 
     241             : sss_sifp_error
     242           2 : sss_sifp_fetch_object(sss_sifp_ctx *ctx,
     243             :                       const char *object_path,
     244             :                       const char *interface,
     245             :                       sss_sifp_object **_object)
     246             : {
     247           2 :     sss_sifp_object *object = NULL;
     248           2 :     sss_sifp_attr **attrs = NULL;
     249           2 :     const char *name = NULL;
     250             :     sss_sifp_error ret;
     251             : 
     252           2 :     if (ctx == NULL || object_path == NULL || interface == NULL
     253           2 :             || _object == NULL) {
     254           0 :         return SSS_SIFP_INVALID_ARGUMENT;
     255             :     }
     256             : 
     257           2 :     ret = sss_sifp_fetch_all_attrs(ctx, object_path, interface, &attrs);
     258           2 :     if (ret != SSS_SIFP_OK) {
     259           0 :         goto done;
     260             :     }
     261             : 
     262           2 :     ret = sss_sifp_find_attr_as_string(attrs, "name", &name);
     263           2 :     if (ret != SSS_SIFP_OK) {
     264           0 :         goto done;
     265             :     }
     266             : 
     267           2 :     object = _alloc_zero(ctx, sss_sifp_object, 1);
     268           2 :     if (object == NULL) {
     269           0 :         ret = SSS_SIFP_OUT_OF_MEMORY;
     270           0 :         goto done;
     271             :     }
     272             : 
     273           2 :     object->attrs = attrs;
     274             : 
     275           2 :     object->name = sss_sifp_strdup(ctx, name);
     276           2 :     if (object->name == NULL) {
     277           0 :         ret = SSS_SIFP_OUT_OF_MEMORY;
     278           0 :         goto done;
     279             :     }
     280             : 
     281           2 :     object->object_path = sss_sifp_strdup(ctx, object_path);
     282           2 :     if (object->object_path == NULL) {
     283           0 :         ret = SSS_SIFP_OUT_OF_MEMORY;
     284           0 :         goto done;
     285             :     }
     286             : 
     287           2 :     object->interface = sss_sifp_strdup(ctx, interface);
     288           2 :     if (object->interface == NULL) {
     289           0 :         ret = SSS_SIFP_OUT_OF_MEMORY;
     290           0 :         goto done;
     291             :     }
     292             : 
     293           2 :     *_object = object;
     294             : 
     295           2 :     ret = SSS_SIFP_OK;
     296             : 
     297             : done:
     298           2 :     if (ret != SSS_SIFP_OK) {
     299           0 :         sss_sifp_free_object(ctx, &object);
     300             :     }
     301             : 
     302           2 :     return ret;
     303             : }
     304             : 
     305             : void
     306          46 : sss_sifp_free(sss_sifp_ctx **_ctx)
     307             : {
     308          46 :     sss_sifp_ctx *ctx = NULL;
     309             : 
     310          46 :     if (_ctx == NULL || *_ctx == NULL) {
     311           0 :         return;
     312             :     }
     313             : 
     314          46 :     ctx = *_ctx;
     315             : 
     316          46 :     if (ctx->conn != NULL) {
     317           0 :         dbus_connection_unref(ctx->conn);
     318             :     }
     319             : 
     320          46 :     if (ctx->io_error != NULL) {
     321          46 :         dbus_error_free(ctx->io_error);
     322          46 :         _free(ctx, ctx->io_error);
     323             :     }
     324             : 
     325          46 :     _free(ctx, ctx);
     326          46 :     *_ctx = NULL;
     327             : 
     328          46 :     return;
     329             : }
     330             : 
     331             : void
     332          34 : sss_sifp_free_attrs(sss_sifp_ctx *ctx,
     333             :                     sss_sifp_attr ***_attrs)
     334             : {
     335          34 :     sss_sifp_attr **attrs = NULL;
     336             :     unsigned int i, j;
     337             : 
     338          34 :     if (_attrs == NULL || *_attrs == NULL) {
     339           2 :         return;
     340             :     }
     341             : 
     342          32 :     attrs = *_attrs;
     343             : 
     344          71 :     for (i = 0; attrs[i] != NULL; i++) {
     345          39 :         switch (attrs[i]->type) {
     346             :         case SSS_SIFP_ATTR_TYPE_BOOL:
     347           3 :             _free(ctx, attrs[i]->data.boolean);
     348           3 :             break;
     349             :         case SSS_SIFP_ATTR_TYPE_INT16:
     350           1 :             _free(ctx, attrs[i]->data.int16);
     351           1 :             break;
     352             :         case SSS_SIFP_ATTR_TYPE_UINT16:
     353           1 :             _free(ctx, attrs[i]->data.uint16);
     354           1 :             break;
     355             :         case SSS_SIFP_ATTR_TYPE_INT32:
     356           3 :             _free(ctx, attrs[i]->data.int32);
     357           3 :             break;
     358             :         case SSS_SIFP_ATTR_TYPE_UINT32:
     359          10 :             _free(ctx, attrs[i]->data.uint32);
     360          10 :             break;
     361             :         case SSS_SIFP_ATTR_TYPE_INT64:
     362           3 :             _free(ctx, attrs[i]->data.int64);
     363           3 :             break;
     364             :         case SSS_SIFP_ATTR_TYPE_UINT64:
     365           3 :             _free(ctx, attrs[i]->data.uint64);
     366           3 :             break;
     367             :         case SSS_SIFP_ATTR_TYPE_STRING:
     368          32 :             for (j = 0; j < attrs[i]->num_values; j++) {
     369          18 :                 _free(ctx, attrs[i]->data.str[j]);
     370             :             }
     371          14 :             _free(ctx, attrs[i]->data.str);
     372          14 :             break;
     373             :         case SSS_SIFP_ATTR_TYPE_STRING_DICT:
     374           1 :             if (attrs[i]->data.str_dict != NULL) {
     375           1 :                 hash_destroy(attrs[i]->data.str_dict);
     376             :             }
     377           1 :             attrs[i]->data.str_dict = NULL;
     378           1 :             break;
     379             :         }
     380          39 :         _free(ctx, attrs[i]->name);
     381          39 :         _free(ctx, attrs[i]);
     382             :     }
     383             : 
     384          32 :     _free(ctx, attrs);
     385             : 
     386          32 :     *_attrs = NULL;
     387             : }
     388             : 
     389             : void
     390           2 : sss_sifp_free_object(sss_sifp_ctx *ctx,
     391             :                      sss_sifp_object **_object)
     392             : {
     393           2 :     sss_sifp_object *object = NULL;
     394             : 
     395           2 :     if (_object == NULL || *_object == NULL) {
     396           0 :         return;
     397             :     }
     398             : 
     399           2 :     object = *_object;
     400             : 
     401           2 :     sss_sifp_free_attrs(ctx, &object->attrs);
     402           2 :     _free(ctx, object->object_path);
     403           2 :     _free(ctx, object->interface);
     404           2 :     _free(ctx, object->name);
     405           2 :     _free(ctx, object);
     406             : 
     407           2 :     *_object = NULL;
     408             : }
     409             : 
     410             : void
     411          14 : sss_sifp_free_string(sss_sifp_ctx *ctx,
     412             :                      char **_str)
     413             : {
     414          14 :     if (_str == NULL || *_str == NULL) {
     415           0 :         return;
     416             :     }
     417             : 
     418          14 :     _free(ctx, *_str);
     419             : 
     420          14 :     *_str = NULL;
     421             : }
     422             : 
     423             : void
     424           5 : sss_sifp_free_string_array(sss_sifp_ctx *ctx,
     425             :                            char ***_str_array)
     426             : {
     427           5 :     char **str_array = NULL;
     428             :     int i;
     429             : 
     430           5 :     if (_str_array == NULL || *_str_array == NULL) {
     431           0 :         return;
     432             :     }
     433             : 
     434           5 :     str_array = *_str_array;
     435             : 
     436          15 :     for (i = 0; str_array[i] != NULL; i++) {
     437          10 :         _free(ctx, str_array[i]);
     438             :     }
     439             : 
     440           5 :     _free(ctx, str_array);
     441             : 
     442           5 :     *_str_array = NULL;
     443             : }

Generated by: LCOV version 1.10