LCOV - code coverage report
Current view: top level - src/plugins/augeas - augeas.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 225 284 79.2 %
Date: 2019-09-12 12:28:41 Functions: 17 19 89.5 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief A plugin that makes use of libaugeas to read and write configuration files
       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             : /* used for asprintf */
      15             : #define _GNU_SOURCE
      16             : 
      17             : #include <ctype.h>
      18             : #include <glob.h>
      19             : #include <libgen.h>
      20             : 
      21             : #include "aug.h"
      22             : 
      23             : struct KeyConversion
      24             : {
      25             :         KeySet * ks;
      26             :         Key * parentKey;
      27             :         int currentOrder;
      28             : };
      29             : 
      30             : struct OrphanSearch
      31             : {
      32             :         KeySet * ks;
      33             :         Key * parentKey;
      34             : };
      35             : 
      36             : typedef int (*ForeachAugNodeClb) (augeas *, const char *, void *);
      37             : 
      38         938 : int keySetOrderMeta (Key * key, int order)
      39             : {
      40             :         char * buffer;
      41             :         int result;
      42         938 :         result = asprintf (&buffer, "%d", order);
      43             : 
      44         938 :         if (result < 0) return result;
      45             : 
      46         938 :         result = keySetMeta (key, "order", buffer);
      47         938 :         elektraFree (buffer);
      48         938 :         return result;
      49             : }
      50             : 
      51         278 : static int keyCmpOrderWrapper (const void * a, const void * b)
      52             : {
      53         278 :         return elektraKeyCmpOrder (*((const Key **) a), *((const Key **) b));
      54             : }
      55             : 
      56          18 : static const char * getLensPath (Plugin * handle)
      57             : {
      58          18 :         KeySet * config = elektraPluginGetConfig (handle);
      59          18 :         Key * lensPathKey = ksLookupByName (config, "/lens", 0);
      60          18 :         return keyString (lensPathKey);
      61             : }
      62             : 
      63           2 : int elektraAugeasGenConf (KeySet * ks, Key * errorKey ELEKTRA_UNUSED)
      64             : {
      65             :         glob_t pglob;
      66           2 :         int retval = 1;
      67           2 :         const char * f = LIBAUGEAS_PREFIX "/share/augeas/lenses/dist/*.aug";
      68           2 :         if (glob (f, GLOB_NOSORT, NULL, &pglob) == 0)
      69             :         {
      70             :                 ELEKTRA_LOG ("has glob %zd", pglob.gl_pathc);
      71         422 :                 for (size_t i = 0; i < pglob.gl_pathc; ++i)
      72             :                 {
      73         422 :                         char * p = elektraStrDup (basename (pglob.gl_pathv[i]));
      74         422 :                         size_t l = strlen (p);
      75         422 :                         if (l > 4)
      76             :                         {
      77         422 :                                 p[l - 4] = '\0';
      78         422 :                                 Key * k = keyNew ("system/", KEY_END);
      79         422 :                                 keyAddBaseName (k, p);
      80         422 :                                 ksAppendKey (ks, keyDup (k));
      81             : 
      82         422 :                                 Key * b = keyDup (k);
      83         422 :                                 keyAddBaseName (b, "infos");
      84         422 :                                 ksAppendKey (ks, keyDup (b));
      85         422 :                                 keyAddBaseName (b, "provides");
      86         422 :                                 char * s = elektraFormat ("storage/%s", p);
      87         422 :                                 keySetString (b, s);
      88         422 :                                 elektraFree (s);
      89         422 :                                 ksAppendKey (ks, b);
      90             : 
      91         422 :                                 keyAddBaseName (k, "config");
      92         422 :                                 ksAppendKey (ks, keyDup (k));
      93         422 :                                 keyAddBaseName (k, "lens");
      94         422 :                                 p[0] = toupper (p[0]);
      95         422 :                                 p[l - 1] = 's';
      96         422 :                                 p[l - 2] = 'n';
      97         422 :                                 p[l - 3] = 'l';
      98         422 :                                 p[l - 4] = '.';
      99         422 :                                 keySetString (k, p);
     100         422 :                                 ksAppendKey (ks, k);
     101             :                         }
     102         422 :                         elektraFree (p);
     103             :                 }
     104           2 :                 globfree (&pglob);
     105             :         }
     106             :         else
     107             :         {
     108           0 :                 ELEKTRA_SET_INSTALLATION_ERRORF (errorKey, "Could not glob %s because of augeas", f);
     109           0 :                 retval = -1;
     110             :         }
     111           2 :         return retval;
     112             : }
     113             : 
     114           0 : static const char * getAugeasError (augeas * augeasHandle)
     115             : {
     116           0 :         const char * reason = 0;
     117           0 :         if (aug_error (augeasHandle) != 0)
     118             :         {
     119           0 :                 reason = aug_error_message (augeasHandle);
     120             :         }
     121             :         else
     122             :         {
     123             :                 const char * augeasError;
     124           0 :                 aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error", &augeasError);
     125             : 
     126           0 :                 if (augeasError)
     127             :                 {
     128             :                         const char * lens;
     129             :                         const char * line;
     130             :                         const char * character;
     131             :                         const char * message;
     132             : 
     133           0 :                         aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/lens", &lens);
     134           0 :                         aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/line", &line);
     135           0 :                         aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/char", &character);
     136           0 :                         aug_get (augeasHandle, "/augeas/text" AUGEAS_TREE_ROOT "/error/message", &message);
     137             : 
     138           0 :                         const char * format = "%s\n\tposition: %s:%s\n\tmessage: %s\n\tlens: %s";
     139           0 :                         size_t messageSize = (augeasError ? strlen (augeasError) : 0) + (line ? strlen (line) : 0) +
     140           0 :                                              (character ? strlen (character) : 0) + (message ? strlen (message) : 0) +
     141           0 :                                              (lens ? strlen (lens) : 0) + strlen (format);
     142           0 :                         char * buffer = elektraMalloc (messageSize);
     143           0 :                         snprintf (buffer, messageSize, format, augeasError ? augeasError : "", line ? line : "", character ? character : "",
     144           0 :                                   message ? message : "", lens ? lens : "");
     145           0 :                         reason = buffer;
     146             :                 }
     147             :                 else
     148             :                 {
     149             :                         reason = "No specific reason was reported";
     150             :                 }
     151             :         }
     152             : 
     153             :         /* should not happen, but avoid 0 return */
     154           0 :         if (!reason)
     155             :         {
     156           0 :                 reason = "";
     157             :         }
     158           0 :         return reason;
     159             : }
     160             : 
     161        1080 : static Key * createKeyFromPath (Key * parentKey, const char * treePath)
     162             : {
     163        1080 :         Key * key = keyDup (parentKey);
     164        1080 :         const char * baseName = (treePath + strlen (AUGEAS_TREE_ROOT) + 1);
     165             : 
     166        1080 :         size_t baseSize = keyGetNameSize (key);
     167        1080 :         size_t keyNameSize = strlen (baseName) + baseSize + 1;
     168        1080 :         char * newName = elektraMalloc (keyNameSize);
     169             : 
     170        1080 :         if (!newName) return 0;
     171             : 
     172        1080 :         strcpy (newName, keyName (key));
     173        1080 :         newName[baseSize - 1] = KDB_PATH_SEPARATOR;
     174        1080 :         newName[baseSize] = 0;
     175        1080 :         strcat (newName, baseName);
     176             : 
     177        1080 :         keySetName (key, newName);
     178        1080 :         elektraFree (newName);
     179             : 
     180        1080 :         return key;
     181             : }
     182             : 
     183             : /**
     184             :  * Creates a new Elektra key from the specified Augeas key.
     185             :  * If any step during key conversion fails, an error is returned
     186             :  * in order to prevent inconsistent keys.
     187             :  */
     188         938 : static int convertToKey (augeas * handle, const char * treePath, void * data)
     189             : {
     190         938 :         struct KeyConversion * conversionData = (struct KeyConversion *) data;
     191         938 :         int result = 0;
     192         938 :         const char * value = 0;
     193         938 :         result = aug_get (handle, treePath, &value);
     194             : 
     195             :         /* we were unable to retrieve the augeas value */
     196         938 :         if (result < 0) return result;
     197             : 
     198         938 :         Key * key = createKeyFromPath (conversionData->parentKey, treePath);
     199             : 
     200             :         /* fill key values */
     201         938 :         keySetString (key, value);
     202         938 :         conversionData->currentOrder++;
     203         938 :         result = keySetOrderMeta (key, conversionData->currentOrder);
     204             : 
     205             :         /* setting the correct key order failed */
     206         938 :         if (result < 0) return result;
     207             : 
     208         938 :         result = ksAppendKey (conversionData->ks, key);
     209             : 
     210         938 :         return result;
     211             : }
     212             : 
     213             : /**
     214             :  * Checks whether a given path must be pruned from the Augeas tree by comparing
     215             :  * it with the supplied keyset. If any operation during pruning fails, an error
     216             :  * is returned in order to prevent invalid keys.
     217             :  */
     218         120 : static int removeOrphan (augeas * handle, const char * treePath, void * data)
     219             : {
     220             :         int result;
     221         120 :         struct OrphanSearch * orphanData = (struct OrphanSearch *) data;
     222             : 
     223         120 :         Key * key = createKeyFromPath (orphanData->parentKey, treePath);
     224             : 
     225         120 :         if (!ksLookup (orphanData->ks, key, KDB_O_NONE))
     226             :         {
     227             :                 char * nodeMatch;
     228             :                 char ** matches;
     229          12 :                 result = asprintf (&nodeMatch, "%s/*", treePath);
     230             : 
     231          12 :                 if (result < 0) return -1;
     232             : 
     233          12 :                 int numChildNodes = aug_match (handle, nodeMatch, &matches);
     234          12 :                 elektraFree (nodeMatch);
     235             : 
     236             :                 /* if the node is a leaf node we can safely delete it */
     237          12 :                 if (numChildNodes == 0)
     238             :                 {
     239           6 :                         aug_rm (handle, treePath);
     240             :                 }
     241             :                 else
     242             :                 {
     243             :                         short pruneTree = 1;
     244          22 :                         for (int i = 0; i < numChildNodes; i++)
     245             :                         {
     246          22 :                                 Key * childKey = createKeyFromPath (orphanData->parentKey, matches[i]);
     247          22 :                                 if (ksLookup (orphanData->ks, childKey, KDB_O_NONE))
     248             :                                 {
     249          16 :                                         pruneTree = 0;
     250             :                                 }
     251          22 :                                 keyDel (childKey);
     252          22 :                                 elektraFree (matches[i]);
     253             :                         }
     254           6 :                         elektraFree (matches);
     255             : 
     256           6 :                         if (pruneTree)
     257             :                         {
     258           2 :                                 aug_rm (handle, treePath);
     259             :                         }
     260             :                 }
     261             :         }
     262             : 
     263         120 :         keyDel (key);
     264             : 
     265         120 :         return 0;
     266             : }
     267             : 
     268          18 : static int foreachAugeasNode (augeas * handle, const char * treePath, ForeachAugNodeClb callback, void * callbackData)
     269             : {
     270             :         char * matchPath;
     271          18 :         int result = 0;
     272          18 :         result = asprintf (&matchPath, "%s//*", treePath);
     273             : 
     274          18 :         if (result < 0) return -1;
     275             : 
     276             :         /* must be non NULL for aug_match to return matches */
     277          18 :         char ** matches = (char **) 1;
     278          18 :         int numMatches = aug_match (handle, matchPath, &matches);
     279          18 :         elektraFree (matchPath);
     280             : 
     281          18 :         if (numMatches < 0) return numMatches;
     282             : 
     283             :         int i;
     284        1058 :         for (i = 0; i < numMatches; i++)
     285             :         {
     286             :                 /* retrieve the value from augeas */
     287        1058 :                 char * curPath = matches[i];
     288             : 
     289        1058 :                 result = (*callback) (handle, curPath, callbackData);
     290             : 
     291             :                 /* if handling the key failed, abort with an error as
     292             :                  * the failed key could be a crucial one
     293             :                  */
     294        1058 :                 if (result < 0) break;
     295             : 
     296        1058 :                 elektraFree (curPath);
     297             :         }
     298             : 
     299           0 :         for (; i < numMatches; i++)
     300             :         {
     301           0 :                 elektraFree (matches[i]);
     302             :         }
     303             : 
     304          18 :         elektraFree (matches);
     305             : 
     306          18 :         return result;
     307             : }
     308             : 
     309          12 : static char * loadFile (FILE * fh)
     310             : {
     311             :         /* open the file */
     312          12 :         char * content = 0;
     313             : 
     314          12 :         if (fseek (fh, 0, SEEK_END) != 0) return 0;
     315             : 
     316          12 :         long fileSize = ftell (fh);
     317          12 :         rewind (fh);
     318             : 
     319          12 :         if (fileSize > 0)
     320             :         {
     321          10 :                 content = elektraMalloc (fileSize * sizeof (char) + 1);
     322          10 :                 if (content == 0) return 0;
     323          10 :                 int readBytes = fread (content, sizeof (char), fileSize, fh);
     324             : 
     325          10 :                 if (feof (fh) || ferror (fh) || readBytes != fileSize) return 0;
     326             : 
     327             :                 /* null terminate the string, as fread doesn't do it */
     328          10 :                 content[fileSize] = 0;
     329             :         }
     330           2 :         else if (fileSize == 0)
     331             :         {
     332           2 :                 content = elektraMalloc (1);
     333           2 :                 if (content == 0) return 0;
     334           2 :                 *content = (char) 0;
     335             :         }
     336             : 
     337             :         return content;
     338             : }
     339             : 
     340          12 : static int loadTree (augeas * augeasHandle, const char * lensPath, char * content)
     341             : {
     342          12 :         aug_set (augeasHandle, AUGEAS_CONTENT_ROOT, content);
     343             : 
     344          12 :         return aug_text_store (augeasHandle, lensPath, AUGEAS_CONTENT_ROOT, AUGEAS_TREE_ROOT);
     345             : }
     346             : 
     347           8 : static int saveFile (augeas * augeasHandle, FILE * fh)
     348             : {
     349             :         /* retrieve the file content */
     350           8 :         int ret = 0;
     351           8 :         const char * value = 0;
     352           8 :         aug_get (augeasHandle, AUGEAS_OUTPUT_ROOT, &value);
     353             : 
     354             :         /* write the file */
     355           8 :         if (value)
     356             :         {
     357           8 :                 ret = fwrite (value, sizeof (char), strlen (value), fh);
     358             : 
     359           8 :                 if (feof (fh) || ferror (fh)) return -1;
     360             :         }
     361             : 
     362             :         return ret;
     363             : }
     364             : 
     365           8 : static int saveTree (augeas * augeasHandle, KeySet * ks, const char * lensPath, Key * parentKey)
     366             : {
     367           8 :         int ret = 0;
     368             : 
     369           8 :         size_t prefixSize = keyGetNameSize (parentKey) - 1;
     370           8 :         size_t arraySize = ksGetSize (ks);
     371           8 :         Key ** keyArray = calloc (ksGetSize (ks), sizeof (Key *));
     372           8 :         ret = elektraKsToMemArray (ks, keyArray);
     373             : 
     374           8 :         if (ret < 0) goto memoryerror;
     375             : 
     376           8 :         qsort (keyArray, arraySize, sizeof (Key *), keyCmpOrderWrapper);
     377             : 
     378             :         /* convert the Elektra KeySet to an Augeas tree */
     379         124 :         for (size_t i = 0; i < arraySize; i++)
     380             :         {
     381         116 :                 Key * key = keyArray[i];
     382             :                 char * nodeName;
     383         116 :                 ret = asprintf (&nodeName, AUGEAS_TREE_ROOT "%s", (keyName (key) + prefixSize));
     384             : 
     385         116 :                 if (ret < 0) goto memoryerror;
     386             : 
     387         116 :                 aug_set (augeasHandle, nodeName, keyString (key));
     388         116 :                 elektraFree (nodeName);
     389             :         }
     390             : 
     391           8 :         elektraFree (keyArray);
     392             : 
     393             :         /* remove keys not present in the KeySet */
     394           8 :         struct OrphanSearch * data = elektraMalloc (sizeof (struct OrphanSearch));
     395             : 
     396           8 :         if (!data) return -1;
     397             : 
     398           8 :         data->ks = ks;
     399           8 :         data->parentKey = parentKey;
     400             : 
     401           8 :         ret = foreachAugeasNode (augeasHandle, AUGEAS_TREE_ROOT, &removeOrphan, data);
     402             : 
     403           8 :         elektraFree (data);
     404             : 
     405             :         /* build the tree */
     406           8 :         ret = aug_text_retrieve (augeasHandle, lensPath, AUGEAS_CONTENT_ROOT, AUGEAS_TREE_ROOT, AUGEAS_OUTPUT_ROOT);
     407             : 
     408           8 :         if (ret < 0)
     409             :         {
     410             :                 /* report the augeas specific error */
     411           0 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERROR (parentKey, getAugeasError (augeasHandle));
     412             :         }
     413             : 
     414             :         return ret;
     415             : 
     416             : memoryerror:
     417           0 :         elektraFree (keyArray);
     418           0 :         ELEKTRA_SET_OUT_OF_MEMORY_ERROR (parentKey, "Unable to allocate memory while saving the augeas tree");
     419           0 :         return -1;
     420             : }
     421             : 
     422         310 : int elektraAugeasOpen (Plugin * handle, Key * parentKey)
     423             : {
     424             :         augeas * augeasHandle;
     425         310 :         augeasHandle = aug_init (NULL, NULL, AUG_NO_MODL_AUTOLOAD | AUG_NO_ERR_CLOSE);
     426             :         int ret;
     427             : 
     428         310 :         if (aug_error (augeasHandle) != AUG_NOERROR)
     429             :         {
     430             :                 char * errormessage;
     431           0 :                 ret = asprintf (&errormessage, "Unable to initialize augeas: %s", aug_error_message (augeasHandle));
     432             : 
     433           0 :                 if (ret >= 0)
     434             :                 {
     435           0 :                         ELEKTRA_SET_OUT_OF_MEMORY_ERROR (parentKey, "Unable to allocate memory for a detailed augeas error message");
     436           0 :                         return -1;
     437             :                 }
     438             : 
     439           0 :                 ELEKTRA_SET_INSTALLATION_ERROR (parentKey, errormessage);
     440           0 :                 elektraFree (errormessage);
     441           0 :                 return -1;
     442             :         }
     443             : 
     444         310 :         elektraPluginSetData (handle, augeasHandle);
     445         310 :         return 0;
     446             : }
     447             : 
     448         310 : int elektraAugeasClose (Plugin * handle, Key * parentKey ELEKTRA_UNUSED)
     449             : {
     450         310 :         augeas * augeasHandle = elektraPluginGetData (handle);
     451             : 
     452         310 :         if (augeasHandle)
     453             :         {
     454         310 :                 aug_close (augeasHandle);
     455         310 :                 elektraPluginSetData (handle, 0);
     456             :         }
     457             : 
     458         310 :         return 0;
     459             : }
     460             : 
     461         308 : int elektraAugeasGet (Plugin * handle, KeySet * returned, Key * parentKey)
     462             : {
     463         308 :         int errnosave = errno;
     464         308 :         int ret = 0;
     465             : 
     466         308 :         if (!strcmp (keyName (parentKey), "system/elektra/modules/augeas"))
     467             :         {
     468         298 :                 KeySet * info =
     469             : #include "contract.h"
     470             : 
     471         298 :                         ksAppend (returned, info);
     472         298 :                 ksDel (info);
     473         298 :                 return 1;
     474             :         }
     475             : 
     476          10 :         augeas * augeasHandle = elektraPluginGetData (handle);
     477             : 
     478             :         /* retrieve the lens to use */
     479          10 :         const char * lensPath = getLensPath (handle);
     480          10 :         if (!lensPath) ELEKTRA_SET_INSTALLATION_ERRORF (parentKey, "No Augeas lens was configured: %s", keyName (parentKey));
     481             : 
     482          10 :         FILE * fh = fopen (keyString (parentKey), "r");
     483             : 
     484          10 :         if (fh == 0)
     485             :         {
     486           0 :                 ELEKTRA_SET_ERROR_GET (parentKey);
     487           0 :                 errno = errnosave;
     488           0 :                 return -1;
     489             :         }
     490             : 
     491             :         /* load its contents into a string */
     492          10 :         char * content = loadFile (fh);
     493             : 
     494          10 :         if (content == 0)
     495             :         {
     496           0 :                 fclose (fh);
     497           0 :                 ELEKTRA_SET_RESOURCE_ERRORF (parentKey, "Error while reading file. Reason: %s", strerror (errno));
     498             :         }
     499             : 
     500             :         /* convert the string into an augeas tree */
     501          10 :         ret = loadTree (augeasHandle, lensPath, content);
     502          10 :         elektraFree (content);
     503             : 
     504          10 :         if (ret < 0)
     505             :         {
     506           0 :                 fclose (fh);
     507           0 :                 ELEKTRA_SET_INSTALLATION_ERROR (parentKey, getAugeasError (augeasHandle));
     508             :         }
     509             : 
     510             :         /* convert the augeas tree to an Elektra KeySet */
     511          10 :         ksClear (returned);
     512          10 :         KeySet * append = ksNew (ksGetSize (returned) * 2, KS_END);
     513             : 
     514          10 :         Key * key = keyDup (parentKey);
     515          10 :         ksAppendKey (append, key);
     516             : 
     517          10 :         struct KeyConversion * conversionData = elektraMalloc (sizeof (struct KeyConversion));
     518             : 
     519          10 :         if (!conversionData)
     520             :         {
     521           0 :                 fclose (fh);
     522           0 :                 ELEKTRA_SET_OUT_OF_MEMORY_ERRORF (parentKey, "Out of memory. Errno: %s", strerror (errno));
     523             :         }
     524             : 
     525          10 :         conversionData->currentOrder = 0;
     526          10 :         conversionData->parentKey = key;
     527          10 :         conversionData->ks = append;
     528             : 
     529          10 :         ret = foreachAugeasNode (augeasHandle, AUGEAS_TREE_ROOT, &convertToKey, conversionData);
     530             : 
     531          10 :         elektraFree (conversionData);
     532             : 
     533          10 :         if (ret < 0)
     534             :         {
     535           0 :                 fclose (fh);
     536           0 :                 ksDel (append);
     537           0 :                 ELEKTRA_SET_INSTALLATION_ERROR (parentKey, getAugeasError (augeasHandle));
     538             :         }
     539             : 
     540          10 :         fclose (fh);
     541             : 
     542          10 :         ksAppend (returned, append);
     543          10 :         ksDel (append);
     544          10 :         errno = errnosave;
     545          10 :         return 1;
     546             : }
     547             : 
     548           8 : int elektraAugeasSet (Plugin * handle, KeySet * returned, Key * parentKey)
     549             : {
     550           8 :         int errnosave = errno;
     551           8 :         augeas * augeasHandle = elektraPluginGetData (handle);
     552             : 
     553           8 :         const char * lensPath = getLensPath (handle);
     554             : 
     555           8 :         if (!lensPath)
     556             :         {
     557           0 :                 ELEKTRA_SET_INSTALLATION_ERRORF (parentKey, "No Augeas lens was configured: %s", keyName (parentKey));
     558             :         }
     559             : 
     560           8 :         FILE * fh = fopen (keyValue (parentKey), "w+");
     561             : 
     562           8 :         if (fh == 0)
     563             :         {
     564           0 :                 ELEKTRA_SET_ERROR_SET (parentKey);
     565           0 :                 errno = errnosave;
     566           0 :                 return -1;
     567             :         }
     568             : 
     569           8 :         int ret = 0;
     570             : 
     571           8 :         if (aug_match (augeasHandle, AUGEAS_TREE_ROOT, NULL) == 0)
     572             :         {
     573             :                 /* load a fresh copy of the file into the tree */
     574           2 :                 char * content = loadFile (fh);
     575             : 
     576           2 :                 if (content == 0)
     577             :                 {
     578           0 :                         fclose (fh);
     579           0 :                         ELEKTRA_SET_RESOURCE_ERRORF (parentKey, "Error while reading file. Reason: %s", strerror (errno));
     580             :                 }
     581             : 
     582             :                 /* convert the string into an augeas tree */
     583           2 :                 ret = loadTree (augeasHandle, lensPath, content);
     584           2 :                 elektraFree (content);
     585             : 
     586           2 :                 if (ret < 0)
     587             :                 {
     588           0 :                         fclose (fh);
     589           0 :                         ELEKTRA_SET_INSTALLATION_ERROR (parentKey, getAugeasError (augeasHandle));
     590             :                 }
     591             :         }
     592             : 
     593           8 :         ret = saveTree (augeasHandle, returned, lensPath, parentKey);
     594             : 
     595           8 :         if (ret < 0)
     596             :         {
     597           0 :                 fclose (fh);
     598           0 :                 errno = errnosave;
     599           0 :                 return -1;
     600             :         }
     601             : 
     602             :         /* write the Augeas tree to the file */
     603           8 :         ret = saveFile (augeasHandle, fh);
     604           8 :         fclose (fh);
     605             : 
     606           8 :         if (ret < 0) ELEKTRA_SET_RESOURCE_ERRORF (parentKey, "Could not open file for writing. Reason: %s", strerror (errno));
     607             : 
     608           8 :         errno = errnosave;
     609           8 :         return 1;
     610             : }
     611             : 
     612         310 : Plugin * ELEKTRA_PLUGIN_EXPORT
     613             : {
     614             :         // clang-format off
     615         310 :         return elektraPluginExport ("augeas",
     616             :                         ELEKTRA_PLUGIN_GET, &elektraAugeasGet,
     617             :                         ELEKTRA_PLUGIN_SET, &elektraAugeasSet,
     618             :                         ELEKTRA_PLUGIN_OPEN, &elektraAugeasOpen,
     619             :                         ELEKTRA_PLUGIN_CLOSE, &elektraAugeasClose,
     620             :                         ELEKTRA_PLUGIN_END);
     621             : }
     622             : 

Generated by: LCOV version 1.13