LCOV - code coverage report
Current view: top level - src/plugins/line - line.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 47 60 78.3 %
Date: 2019-09-12 12:28:41 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief A plugin that reads configuration files and saves keys on a line by line basis *
       5             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       6             :  *
       7             :  */
       8             : 
       9             : #ifndef HAVE_KDBCONFIG
      10             : #include "kdbconfig.h"
      11             : #endif
      12             : 
      13             : #include "line.h"
      14             : 
      15             : #include <kdbease.h>
      16             : #include <kdberrors.h>
      17             : #include <kdbproposal.h>
      18             : 
      19             : #include <errno.h>
      20             : #include <stddef.h>
      21             : // The definition `_WITH_GETLINE` is required for FreeBSD
      22             : #define _WITH_GETLINE
      23             : #include <stdio.h>
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : 
      27          91 : static inline KeySet * elektraLineContract (void)
      28             : {
      29          91 :         return ksNew (30, keyNew ("system/elektra/modules/line", KEY_VALUE, "line plugin waits for your orders", KEY_END),
      30             :                       keyNew ("system/elektra/modules/line/exports", KEY_END),
      31             :                       keyNew ("system/elektra/modules/line/exports/get", KEY_FUNC, elektraLineGet, KEY_END),
      32             :                       keyNew ("system/elektra/modules/line/exports/set", KEY_FUNC, elektraLineSet, KEY_END),
      33             : #include "readme_line.c"
      34             :                       keyNew ("system/elektra/modules/line/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END), KS_END);
      35             : }
      36             : 
      37          20 : int elektraLineRead (FILE * fp, KeySet * returned)
      38             : {
      39          20 :         char * value = NULL;
      40          20 :         size_t len = 0;
      41          20 :         ssize_t n = 0;
      42          20 :         Key * read = NULL;
      43             : 
      44             :         // Read in each line
      45         150 :         while ((n = getline (&value, &len, fp)) != -1)
      46             :         {
      47             :                 // Remove trailing newline
      48         110 :                 if (value[n - 1] == '\n')
      49             :                 {
      50         110 :                         value[n - 1] = '\0';
      51             :                 }
      52         110 :                 read = keyDup (ksTail (returned));
      53         110 :                 if (elektraArrayIncName (read) == -1)
      54             :                 {
      55           0 :                         elektraFree (value);
      56           0 :                         keyDel (read);
      57           0 :                         return -1;
      58             :                 }
      59         110 :                 keySetString (read, value);
      60             : 
      61         110 :                 ksAppendKey (returned, read);
      62             :         }
      63          20 :         elektraFree (value);
      64             : 
      65          20 :         return 1;
      66             : }
      67             : 
      68             : 
      69         111 : int elektraLineGet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey)
      70             : {
      71             :         /* get all keys */
      72             : 
      73         111 :         if (!strcmp (keyName (parentKey), "system/elektra/modules/line"))
      74             :         {
      75          91 :                 KeySet * moduleConfig = elektraLineContract ();
      76          91 :                 ksAppend (returned, moduleConfig);
      77          91 :                 ksDel (moduleConfig);
      78          91 :                 return 1;
      79             :         }
      80             : 
      81          20 :         int errnosave = errno;
      82          20 :         FILE * fp = fopen (keyString (parentKey), "r");
      83             : 
      84          20 :         if (!fp)
      85             :         {
      86           0 :                 ELEKTRA_SET_ERROR_GET (parentKey);
      87           0 :                 errno = errnosave;
      88           0 :                 return -1;
      89             :         }
      90             : 
      91          20 :         Key * b = keyNew (keyName (parentKey), KEY_END);
      92          20 :         ksAppendKey (returned, keyDup (b)); // start with parentKey
      93          20 :         keyAddName (b, "#");              // start point for our array
      94          20 :         ksAppendKey (returned, b);
      95             : 
      96          20 :         int ret = elektraLineRead (fp, returned);
      97             : 
      98             :         // get rid of startpoint, if it was an empty file
      99          20 :         keyDel (ksLookup (returned, b, KDB_O_POP));
     100             : 
     101          20 :         if (ret == -1)
     102             :         {
     103           0 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERRORF (parentKey, "Could not increment array from %s", keyName (ksTail (returned)));
     104           0 :                 ret = -1;
     105             :         }
     106          20 :         else if (feof (fp) == 0)
     107             :         {
     108           0 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERROR (parentKey, "Invalid line encountered: not at the end of file");
     109           0 :                 ret = -1;
     110             :         }
     111             : 
     112          20 :         fclose (fp);
     113             : 
     114          20 :         return ret; /* success */
     115             : }
     116             : 
     117           6 : int elektraLineSet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey)
     118             : {
     119             :         /* set all keys */
     120             : 
     121           6 :         int errnosave = errno;
     122           6 :         FILE * fp = fopen (keyString (parentKey), "w");
     123             : 
     124           6 :         if (!fp)
     125             :         {
     126           0 :                 ELEKTRA_SET_ERROR_SET (parentKey);
     127           0 :                 errno = errnosave;
     128           0 :                 return -1;
     129             :         }
     130             : 
     131             :         Key * cur;
     132           6 :         if (!ksLookup (returned, parentKey, 0))
     133             :         {
     134             :                 // ignore parentKey if found
     135           1 :                 ksRewind (returned);
     136             :         }
     137             : 
     138          20 :         while ((cur = ksNext (returned)) != 0)
     139             :         {
     140          14 :                 fprintf (fp, "%s\n", keyString (cur));
     141             :         }
     142             : 
     143           6 :         fclose (fp);
     144             : 
     145           6 :         return 1; /* success */
     146             : }
     147             : 
     148         177 : Plugin * ELEKTRA_PLUGIN_EXPORT
     149             : {
     150             :         // clang-format off
     151         177 :         return elektraPluginExport("line",
     152             :                 ELEKTRA_PLUGIN_GET,     &elektraLineGet,
     153             :                 ELEKTRA_PLUGIN_SET,     &elektraLineSet,
     154             :                 ELEKTRA_PLUGIN_END);
     155             : }

Generated by: LCOV version 1.13