LCOV - code coverage report
Current view: top level - src/backend/utils/misc - conffiles.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 15.9 % 69 11
Test Date: 2026-01-26 10:56:24 Functions: 50.0 % 2 1
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 7.7 % 52 4

             Branch data     Line data    Source code
       1                 :             : /*--------------------------------------------------------------------
       2                 :             :  * conffiles.c
       3                 :             :  *
       4                 :             :  * Utilities related to the handling of configuration files.
       5                 :             :  *
       6                 :             :  * This file contains some generic tools to work on configuration files
       7                 :             :  * used by PostgreSQL, be they related to GUCs or authentication.
       8                 :             :  *
       9                 :             :  *
      10                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
      11                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
      12                 :             :  *
      13                 :             :  * IDENTIFICATION
      14                 :             :  *        src/backend/utils/misc/conffiles.c
      15                 :             :  *
      16                 :             :  *--------------------------------------------------------------------
      17                 :             :  */
      18                 :             : 
      19                 :             : #include "postgres.h"
      20                 :             : 
      21                 :             : #include <dirent.h>
      22                 :             : 
      23                 :             : #include "common/file_utils.h"
      24                 :             : #include "miscadmin.h"
      25                 :             : #include "storage/fd.h"
      26                 :             : #include "utils/conffiles.h"
      27                 :             : 
      28                 :             : /*
      29                 :             :  * AbsoluteConfigLocation
      30                 :             :  *
      31                 :             :  * Given a configuration file or directory location that may be a relative
      32                 :             :  * path, return an absolute one.  We consider the location to be relative to
      33                 :             :  * the directory holding the calling file, or to DataDir if no calling file.
      34                 :             :  */
      35                 :             : char *
      36                 :          20 : AbsoluteConfigLocation(const char *location, const char *calling_file)
      37                 :             : {
      38         [ +  + ]:          20 :         if (is_absolute_path(location))
      39                 :          13 :                 return pstrdup(location);
      40                 :             :         else
      41                 :             :         {
      42                 :           7 :                 char            abs_path[MAXPGPATH];
      43                 :             : 
      44         [ -  + ]:           7 :                 if (calling_file != NULL)
      45                 :             :                 {
      46                 :           0 :                         strlcpy(abs_path, calling_file, sizeof(abs_path));
      47                 :           0 :                         get_parent_directory(abs_path);
      48                 :           0 :                         join_path_components(abs_path, abs_path, location);
      49                 :           0 :                         canonicalize_path(abs_path);
      50                 :           0 :                 }
      51                 :             :                 else
      52                 :             :                 {
      53         [ +  - ]:           7 :                         Assert(DataDir);
      54                 :           7 :                         join_path_components(abs_path, DataDir, location);
      55                 :           7 :                         canonicalize_path(abs_path);
      56                 :             :                 }
      57                 :           7 :                 return pstrdup(abs_path);
      58                 :           7 :         }
      59                 :          20 : }
      60                 :             : 
      61                 :             : 
      62                 :             : /*
      63                 :             :  * GetConfFilesInDir
      64                 :             :  *
      65                 :             :  * Returns the list of config files located in a directory, in alphabetical
      66                 :             :  * order.  On error, returns NULL with details about the error stored in
      67                 :             :  * "err_msg".
      68                 :             :  */
      69                 :             : char      **
      70                 :           0 : GetConfFilesInDir(const char *includedir, const char *calling_file,
      71                 :             :                                   int elevel, int *num_filenames, char **err_msg)
      72                 :             : {
      73                 :           0 :         char       *directory;
      74                 :           0 :         DIR                *d;
      75                 :           0 :         struct dirent *de;
      76                 :           0 :         char      **filenames = NULL;
      77                 :           0 :         int                     size_filenames;
      78                 :             : 
      79                 :             :         /*
      80                 :             :          * Reject directory name that is all-blank (including empty), as that
      81                 :             :          * leads to confusion --- we'd read the containing directory, typically
      82                 :             :          * resulting in recursive inclusion of the same file(s).
      83                 :             :          */
      84         [ #  # ]:           0 :         if (strspn(includedir, " \t\r\n") == strlen(includedir))
      85                 :             :         {
      86   [ #  #  #  #  :           0 :                 ereport(elevel,
          #  #  #  #  #  
                      # ]
      87                 :             :                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
      88                 :             :                                  errmsg("empty configuration directory name: \"%s\"",
      89                 :             :                                                 includedir)));
      90                 :           0 :                 *err_msg = "empty configuration directory name";
      91                 :           0 :                 return NULL;
      92                 :             :         }
      93                 :             : 
      94                 :           0 :         directory = AbsoluteConfigLocation(includedir, calling_file);
      95                 :           0 :         d = AllocateDir(directory);
      96         [ #  # ]:           0 :         if (d == NULL)
      97                 :             :         {
      98   [ #  #  #  #  :           0 :                 ereport(elevel,
          #  #  #  #  #  
                      # ]
      99                 :             :                                 (errcode_for_file_access(),
     100                 :             :                                  errmsg("could not open configuration directory \"%s\": %m",
     101                 :             :                                                 directory)));
     102                 :           0 :                 *err_msg = psprintf("could not open directory \"%s\"", directory);
     103                 :           0 :                 goto cleanup;
     104                 :             :         }
     105                 :             : 
     106                 :             :         /*
     107                 :             :          * Read the directory and put the filenames in an array, so we can sort
     108                 :             :          * them prior to caller processing the contents.
     109                 :             :          */
     110                 :           0 :         size_filenames = 32;
     111                 :           0 :         filenames = palloc_array(char *, size_filenames);
     112                 :           0 :         *num_filenames = 0;
     113                 :             : 
     114         [ #  # ]:           0 :         while ((de = ReadDir(d, directory)) != NULL)
     115                 :             :         {
     116                 :           0 :                 PGFileType      de_type;
     117                 :           0 :                 char            filename[MAXPGPATH];
     118                 :             : 
     119                 :             :                 /*
     120                 :             :                  * Only parse files with names ending in ".conf".  Explicitly reject
     121                 :             :                  * files starting with ".".  This excludes things like "." and "..",
     122                 :             :                  * as well as typical hidden files, backup files, and editor debris.
     123                 :             :                  */
     124         [ #  # ]:           0 :                 if (strlen(de->d_name) < 6)
     125                 :           0 :                         continue;
     126         [ #  # ]:           0 :                 if (de->d_name[0] == '.')
     127                 :           0 :                         continue;
     128         [ #  # ]:           0 :                 if (strcmp(de->d_name + strlen(de->d_name) - 5, ".conf") != 0)
     129                 :           0 :                         continue;
     130                 :             : 
     131                 :           0 :                 join_path_components(filename, directory, de->d_name);
     132                 :           0 :                 canonicalize_path(filename);
     133                 :           0 :                 de_type = get_dirent_type(filename, de, true, elevel);
     134         [ #  # ]:           0 :                 if (de_type == PGFILETYPE_ERROR)
     135                 :             :                 {
     136                 :           0 :                         *err_msg = psprintf("could not stat file \"%s\"", filename);
     137                 :           0 :                         pfree(filenames);
     138                 :           0 :                         filenames = NULL;
     139                 :           0 :                         goto cleanup;
     140                 :             :                 }
     141         [ #  # ]:           0 :                 else if (de_type != PGFILETYPE_DIR)
     142                 :             :                 {
     143                 :             :                         /* Add file to array, increasing its size in blocks of 32 */
     144         [ #  # ]:           0 :                         if (*num_filenames >= size_filenames)
     145                 :             :                         {
     146                 :           0 :                                 size_filenames += 32;
     147                 :           0 :                                 filenames = (char **) repalloc(filenames,
     148                 :           0 :                                                                                            size_filenames * sizeof(char *));
     149                 :           0 :                         }
     150                 :           0 :                         filenames[*num_filenames] = pstrdup(filename);
     151                 :           0 :                         (*num_filenames)++;
     152                 :           0 :                 }
     153   [ #  #  #  # ]:           0 :         }
     154                 :             : 
     155                 :             :         /* Sort the files by name before leaving */
     156         [ #  # ]:           0 :         if (*num_filenames > 0)
     157                 :           0 :                 qsort(filenames, *num_filenames, sizeof(char *), pg_qsort_strcmp);
     158                 :             : 
     159                 :             : cleanup:
     160         [ #  # ]:           0 :         if (d)
     161                 :           0 :                 FreeDir(d);
     162                 :           0 :         pfree(directory);
     163                 :           0 :         return filenames;
     164                 :           0 : }
        

Generated by: LCOV version 2.3.2-1