/*--------------------------------------------------------------------
* conffiles . c
*
* Utilities related to the handling of configuration files .
*
* This file contains some generic tools to work on configuration files
* used by PostgreSQL , be they related to GUCs or authentication .
*
*
* Portions Copyright ( c ) 1996 - 2025 , PostgreSQL Global Development Group
* Portions Copyright ( c ) 1994 , Regents of the University of California
*
* IDENTIFICATION
* src / backend / utils / misc / conffiles . c
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
#include "postgres.h"
#include <dirent.h>
#include "common/file_utils.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/conffiles.h"
/*
* AbsoluteConfigLocation
*
* Given a configuration file or directory location that may be a relative
* path , return an absolute one . We consider the location to be relative to
* the directory holding the calling file , or to DataDir if no calling file .
*/
char *
AbsoluteConfigLocation(const char *location, const char *calling_file)
{
if (is_absolute_path(location))
return pstrdup(location);
else
{
char abs_path[MAXPGPATH];
if (calling_file != NULL)
{
strlcpy(abs_path, calling_file, sizeof (abs_path));
get_parent_directory(abs_path);
join_path_components(abs_path, abs_path, location);
canonicalize_path(abs_path);
}
else
{
Assert(DataDir);
join_path_components(abs_path, DataDir, location);
canonicalize_path(abs_path);
}
return pstrdup(abs_path);
}
}
/*
* GetConfFilesInDir
*
* Returns the list of config files located in a directory , in alphabetical
* order . On error , returns NULL with details about the error stored in
* " err_msg " .
*/
char **
GetConfFilesInDir(const char *includedir, const char *calling_file,
int elevel, int *num_filenames, char **err_msg)
{
char *directory;
DIR *d;
struct dirent *de;
char **filenames = NULL;
int size_filenames;
/*
* Reject directory name that is all - blank ( including empty ) , as that
* leads to confusion - - - we ' d read the containing directory , typically
* resulting in recursive inclusion of the same file ( s ) .
*/
if (strspn(includedir, " \t\r\n" ) == strlen(includedir))
{
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("empty configuration directory name: \" %s\"" ,
includedir)));
*err_msg = "empty configuration directory name" ;
return NULL;
}
directory = AbsoluteConfigLocation(includedir, calling_file);
d = AllocateDir(directory);
if (d == NULL)
{
ereport(elevel,
(errcode_for_file_access(),
errmsg("could not open configuration directory \" %s\": %m" ,
directory)));
*err_msg = psprintf("could not open directory \" %s\"" , directory);
goto cleanup;
}
/*
* Read the directory and put the filenames in an array , so we can sort
* them prior to caller processing the contents .
*/
size_filenames = 32 ;
filenames = (char **) palloc(size_filenames * sizeof (char *));
*num_filenames = 0 ;
while ((de = ReadDir(d, directory)) != NULL)
{
PGFileType de_type;
char filename[MAXPGPATH];
/*
* Only parse files with names ending in " . conf " . Explicitly reject
* files starting with " . " . This excludes things like " . " and " . . " ,
* as well as typical hidden files , backup files , and editor debris .
*/
if (strlen(de->d_name) < 6 )
continue ;
if (de->d_name[0 ] == '.' )
continue ;
if (strcmp(de->d_name + strlen(de->d_name) - 5 , ".conf" ) != 0 )
continue ;
join_path_components(filename, directory, de->d_name);
canonicalize_path(filename);
de_type = get_dirent_type(filename, de, true , elevel);
if (de_type == PGFILETYPE_ERROR)
{
*err_msg = psprintf("could not stat file \" %s\"" , filename);
pfree(filenames);
filenames = NULL;
goto cleanup;
}
else if (de_type != PGFILETYPE_DIR)
{
/* Add file to array, increasing its size in blocks of 32 */
if (*num_filenames >= size_filenames)
{
size_filenames += 32 ;
filenames = (char **) repalloc(filenames,
size_filenames * sizeof (char *));
}
filenames[*num_filenames] = pstrdup(filename);
(*num_filenames)++;
}
}
/* Sort the files by name before leaving */
if (*num_filenames > 0 )
qsort(filenames, *num_filenames, sizeof (char *), pg_qsort_strcmp);
cleanup:
if (d)
FreeDir(d);
pfree(directory);
return filenames;
}
Messung V0.5 in Prozent C=95 H=94 G=94
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-08-08)
¤
*© Formatika GbR, Deutschland