LCOV - code coverage report
Current view: top level - src/plugins/dbus - dbus.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 28 88 31.8 %
Date: 2019-09-12 12:28:41 Functions: 4 7 57.1 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief Source for dbus plugin
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  *
       8             :  */
       9             : 
      10             : #ifndef HAVE_KDBCONFIG
      11             : #include "kdbconfig.h"
      12             : #endif
      13             : 
      14             : #include "dbus.h"
      15             : 
      16             : #include <kdbhelper.h>
      17             : 
      18          20 : int elektraDbusOpen (Plugin * handle, Key * errorKey ELEKTRA_UNUSED)
      19             : {
      20          20 :         ElektraDbusPluginData * data = elektraPluginGetData (handle);
      21             : 
      22          20 :         if (!data)
      23             :         {
      24          20 :                 data = elektraMalloc (sizeof (*data));
      25          20 :                 data->keys = NULL;
      26          20 :                 data->systemBus = NULL;
      27          20 :                 data->sessionBus = NULL;
      28             :         }
      29          20 :         elektraPluginSetData (handle, data);
      30             : 
      31          20 :         return 1; /* success */
      32             : }
      33             : 
      34          20 : int elektraDbusGet (Plugin * handle, KeySet * returned, Key * parentKey)
      35             : {
      36          20 :         if (!strcmp (keyName (parentKey), "system/elektra/modules/dbus"))
      37             :         {
      38          20 :                 KeySet * contract =
      39          20 :                         ksNew (30, keyNew ("system/elektra/modules/dbus", KEY_VALUE, "dbus plugin waits for your orders", KEY_END),
      40             :                                keyNew ("system/elektra/modules/dbus/exports", KEY_END),
      41             :                                keyNew ("system/elektra/modules/dbus/exports/open", KEY_FUNC, elektraDbusOpen, KEY_END),
      42             :                                keyNew ("system/elektra/modules/dbus/exports/get", KEY_FUNC, elektraDbusGet, KEY_END),
      43             :                                keyNew ("system/elektra/modules/dbus/exports/set", KEY_FUNC, elektraDbusSet, KEY_END),
      44             :                                keyNew ("system/elektra/modules/dbus/exports/close", KEY_FUNC, elektraDbusClose, KEY_END),
      45             : #include ELEKTRA_README
      46             :                                keyNew ("system/elektra/modules/dbus/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END), KS_END);
      47          20 :                 ksAppend (returned, contract);
      48          20 :                 ksDel (contract);
      49             : 
      50          20 :                 return 1; /* success */
      51             :         }
      52             : 
      53             :         // remember all keys
      54           0 :         ElektraDbusPluginData * pluginData = elektraPluginGetData (handle);
      55           0 :         ELEKTRA_NOT_NULL (pluginData);
      56             : 
      57           0 :         KeySet * ks = pluginData->keys;
      58           0 :         if (ks) ksDel (ks);
      59           0 :         pluginData->keys = ksDup (returned);
      60             : 
      61           0 :         return 1; /* success */
      62             : }
      63             : 
      64             : /**
      65             :  * @internal
      66             :  * Announce multiple keys with same signal name.
      67             :  *
      68             :  * @param ks         key set containing modified keys
      69             :  * @param signalName signal name to use
      70             :  * @param busType    D-Bus bus type
      71             :  * @param data       plugin data containing D-Bus connections, etc.
      72             :  */
      73           0 : static void announceKeys (KeySet * ks, const char * signalName, DBusBusType busType, ElektraDbusPluginData * data)
      74             : {
      75           0 :         ELEKTRA_NOT_NULL (ks);
      76           0 :         ELEKTRA_NOT_NULL (signalName);
      77           0 :         ELEKTRA_NOT_NULL (data);
      78             : 
      79           0 :         ksRewind (ks);
      80           0 :         Key * k = 0;
      81           0 :         while ((k = ksNext (ks)) != 0)
      82             :         {
      83           0 :                 elektraDbusSendMessage (data, busType, keyName (k), signalName);
      84             :         }
      85           0 : }
      86             : 
      87           0 : int elektraDbusSet (Plugin * handle, KeySet * returned, Key * parentKey)
      88             : {
      89           0 :         ElektraDbusPluginData * pluginData = elektraPluginGetData (handle);
      90           0 :         ELEKTRA_NOT_NULL (pluginData);
      91             : 
      92           0 :         KeySet * oldKeys = pluginData->keys;
      93             :         // because elektraLogchangeGet will always be executed before elektraLogchangeSet
      94             :         // we know that oldKeys must exist here!
      95           0 :         ksRewind (oldKeys);
      96           0 :         ksRewind (returned);
      97             : 
      98           0 :         KeySet * addedKeys = ksDup (returned);
      99           0 :         KeySet * changedKeys = ksNew (0, KS_END);
     100           0 :         KeySet * removedKeys = ksNew (0, KS_END);
     101             : 
     102           0 :         Key * k = 0;
     103           0 :         while ((k = ksNext (oldKeys)) != 0)
     104             :         {
     105           0 :                 Key * p = ksLookup (addedKeys, k, KDB_O_POP);
     106             :                 // Note: keyDel not needed, because at least two references exist
     107           0 :                 if (p)
     108             :                 {
     109           0 :                         if (keyNeedSync (p))
     110             :                         {
     111           0 :                                 ksAppendKey (changedKeys, p);
     112             :                         }
     113             :                 }
     114             :                 else
     115             :                 {
     116           0 :                         ksAppendKey (removedKeys, k);
     117             :                 }
     118             :         }
     119             : 
     120           0 :         Key * resolvedParentKey = parentKey;
     121             :         // Resolve cascaded parent key to get its namespace
     122           0 :         if (!strncmp (keyName (parentKey), "/", 1))
     123             :         {
     124           0 :                 resolvedParentKey = ksLookup (returned, parentKey, 0);
     125             :         }
     126           0 :         int announceSession = 0;
     127           0 :         int announceSystem = 0;
     128           0 :         if (resolvedParentKey != NULL)
     129             :         {
     130           0 :                 announceSession = !strncmp (keyName (resolvedParentKey), "user", 4);
     131           0 :                 announceSystem = !strncmp (keyName (resolvedParentKey), "system", 6);
     132             :         }
     133             : 
     134           0 :         if (!strncmp (keyString (ksLookupByName (elektraPluginGetConfig (handle), "/announce", 0)), "once", 4))
     135             :         {
     136           0 :                 if (announceSession) elektraDbusSendMessage (pluginData, DBUS_BUS_SESSION, keyName (resolvedParentKey), "Commit");
     137           0 :                 if (announceSystem) elektraDbusSendMessage (pluginData, DBUS_BUS_SYSTEM, keyName (resolvedParentKey), "Commit");
     138             :         }
     139             :         else
     140             :         {
     141           0 :                 if (announceSession)
     142             :                 {
     143           0 :                         announceKeys (addedKeys, "KeyAdded", DBUS_BUS_SESSION, pluginData);
     144           0 :                         announceKeys (changedKeys, "KeyChanged", DBUS_BUS_SESSION, pluginData);
     145           0 :                         announceKeys (removedKeys, "KeyDeleted", DBUS_BUS_SESSION, pluginData);
     146             :                 }
     147           0 :                 if (announceSystem)
     148             :                 {
     149           0 :                         announceKeys (addedKeys, "KeyAdded", DBUS_BUS_SYSTEM, pluginData);
     150           0 :                         announceKeys (changedKeys, "KeyChanged", DBUS_BUS_SYSTEM, pluginData);
     151           0 :                         announceKeys (removedKeys, "KeyDeleted", DBUS_BUS_SYSTEM, pluginData);
     152             :                 }
     153             :         }
     154             : 
     155             : 
     156           0 :         ksDel (oldKeys);
     157           0 :         ksDel (addedKeys);
     158           0 :         ksDel (changedKeys);
     159           0 :         ksDel (removedKeys);
     160             : 
     161             :         // for next invocation of elektraLogchangeSet, remember our current keyset
     162           0 :         pluginData->keys = ksDup (returned);
     163             : 
     164           0 :         return 1; /* success */
     165             : }
     166             : 
     167          20 : int elektraDbusClose (Plugin * handle, Key * parentKey ELEKTRA_UNUSED)
     168             : {
     169          20 :         ElektraDbusPluginData * pluginData = elektraPluginGetData (handle);
     170          20 :         if (pluginData == NULL)
     171             :         {
     172             :                 return 1;
     173             :         }
     174             : 
     175          20 :         KeySet * ks = pluginData->keys;
     176          20 :         if (ks) ksDel (ks);
     177             : 
     178          20 :         if (pluginData->systemBus)
     179             :         {
     180           0 :                 dbus_connection_unref (pluginData->systemBus);
     181           0 :                 pluginData->systemBus = NULL;
     182             :         }
     183          20 :         if (pluginData->sessionBus)
     184             :         {
     185           0 :                 dbus_connection_unref (pluginData->sessionBus);
     186           0 :                 pluginData->sessionBus = NULL;
     187             :         }
     188             : 
     189          20 :         elektraFree (pluginData);
     190          20 :         elektraPluginSetData (handle, NULL);
     191             : 
     192          20 :         return 1; /* success */
     193             : }
     194             : 
     195          20 : Plugin * ELEKTRA_PLUGIN_EXPORT
     196             : {
     197             :         // clang-format off
     198          20 :         return elektraPluginExport("dbus",
     199             :                 ELEKTRA_PLUGIN_OPEN,    &elektraDbusOpen,
     200             :                 ELEKTRA_PLUGIN_GET,     &elektraDbusGet,
     201             :                 ELEKTRA_PLUGIN_SET,     &elektraDbusSet,
     202             :                 ELEKTRA_PLUGIN_CLOSE,   &elektraDbusClose,
     203             :                 ELEKTRA_PLUGIN_END);
     204             : }

Generated by: LCOV version 1.13