Re: Yet another configuration patch with include, and configuration - Mailing list pgsql-hackers

From Bruce Momjian
Subject Re: Yet another configuration patch with include, and configuration
Date
Msg-id 200303192103.h2JL3lL11299@candle.pha.pa.us
Whole thread Raw
In response to Yet another configuration patch with include, and configuration dir  (mlw <pgsql@mohawksoft.com>)
List pgsql-hackers
mlw, would you modify this to use the config_path idea we agreed upon so
we can get this into 7.4?

---------------------------------------------------------------------------

mlw wrote:
> This is a patch that allows PostgreSQL to use a configuration
> file that is outside the main database directory.
> 
> It adds one more command line parameter, "-C" which
> specifies either the location of the postgres configuration
> file or a directory containing the configuration files.
> 
> A patched version of PostgreSQL will function as:
> 
> --- Configuration file ---
> postmaster -C /etc/postgres/postgresql.conf
> 
> This will direct the postmaster program to use the
> configuration file "/etc/postgres/postgresql.conf"
> 
> --- Configuration Directory ---
> postmaster -C /etc/postgres
> 
> This will direct the postmaster program to search the
> directory "/etc/postgres" for the standard configuration
> file names: posgresql.conf, pg_hba.conf, and pg_ident.conf.
> 
> --- postgresql.conf ---
> Within the main configuration file  are four  additional
> parameters: include, hba_conf,ident_conf, and data_dir.
> 
> They are used as:
> include = '/etc/postgres/debug.conf'
> data_dir = '/vol01/postgres'
> hba_conf = '/etc/postgres/pg_hba_conf'
> ident_conf = '/etc/postgres/pg_ident.conf'
> 
> 
> The "-D" option on the command line overrides the "data_dir"
> in the configuration file.
> 
> If no hba_conf and/or ident_conf setting is specified, the default
> $PGDATA/pg_hba.conf and/or $PGDATA/pg_ident.conf will be used.
> 
> This patch is intended to move the PostgreSQL configuration out of the
> data directory so that it can be modified and backed up.
> 
> This patch is also useful for running multiple servers with the same
> parameters:
> 
> postmaster -C /etc/postgres/postgresql.conf -D /VOL01/postgres -p 5432
> postmaster -C /etc/postgres/postgresql.conf -D /VOL02/postgres -p 5433
> 
> To apply the patch, enter your PostreSQL source directory, and run:
> 
> cat pgec-PGVERSON.patch | patch -p 1
> 

> diff -u -r postgresql-7.3.2/src/backend/libpq/hba.c postgresql-7.3.2.ec/src/backend/libpq/hba.c
> --- postgresql-7.3.2/src/backend/libpq/hba.c    Sat Dec 14 13:49:43 2002
> +++ postgresql-7.3.2.ec/src/backend/libpq/hba.c    Mon Feb 17 14:57:37 2003
> @@ -35,6 +35,7 @@
>  #include "miscadmin.h"
>  #include "nodes/pg_list.h"
>  #include "storage/fd.h"
> +#include "utils/guc.h"
>  
>  
>  #define IDENT_USERNAME_MAX 512
> @@ -837,10 +838,22 @@
>      if (hba_lines)
>          free_lines(&hba_lines);
>  
> -    /* Put together the full pathname to the config file. */
> -    bufsize = (strlen(DataDir) + strlen(CONF_FILE) + 2) * sizeof(char);
> -    conf_file = (char *) palloc(bufsize);
> -    snprintf(conf_file, bufsize, "%s/%s", DataDir, CONF_FILE);
> +    /* Explicit HBA in config file */
> +    if(explicit_hbafile && strlen(explicit_hbafile))
> +    {
> +        bufsize = strlen(explicit_hbafile)+1;
> +        conf_file = (char *) palloc(bufsize);
> +        strcpy(conf_file, explicit_hbafile);
> +    }
> +    else
> +    {
> +        char *confloc = (explicit_isdir) ? explicit_pgconfig : DataDir;
> +        /* put together the full pathname to the config file */
> +        bufsize = (strlen(confloc) + strlen(CONF_FILE) + 2) * sizeof(char);
> +        conf_file = (char *) palloc(bufsize);
> +        snprintf(conf_file, bufsize, "%s/%s", confloc, CONF_FILE);
> +    }
> +    /* printf("hba_conf: %s\n", conf_file); */
>  
>      file = AllocateFile(conf_file, "r");
>      if (file == NULL)
> @@ -979,10 +992,22 @@
>      if (ident_lines)
>          free_lines(&ident_lines);
>  
> -    /* put together the full pathname to the map file */
> -    bufsize = (strlen(DataDir) + strlen(USERMAP_FILE) + 2) * sizeof(char);
> -    map_file = (char *) palloc(bufsize);
> -    snprintf(map_file, bufsize, "%s/%s", DataDir, USERMAP_FILE);
> +    /* Explicit IDENT in config file */
> +    if(explicit_identfile && strlen(explicit_identfile))
> +    {
> +        bufsize = strlen(explicit_identfile)+1;
> +        map_file = (char *) palloc(bufsize);
> +        strcpy(map_file, explicit_identfile);
> +    }
> +    else
> +    {
> +        /* put together the full pathname to the map file */
> +        char *confloc = (explicit_isdir) ? explicit_pgconfig : DataDir;
> +        bufsize = (strlen(confloc) + strlen(USERMAP_FILE) + 2) * sizeof(char);
> +        map_file = (char *) palloc(bufsize);
> +        snprintf(map_file, bufsize, "%s/%s", confloc, USERMAP_FILE);
> +    }
> +    /* printf("ident_conf: %s\n", map_file); */
>  
>      file = AllocateFile(map_file, "r");
>      if (file == NULL)
> diff -u -r postgresql-7.3.2/src/backend/postmaster/postmaster.c
postgresql-7.3.2.ec/src/backend/postmaster/postmaster.c
> --- postgresql-7.3.2/src/backend/postmaster/postmaster.c    Wed Jan 15 19:27:17 2003
> +++ postgresql-7.3.2.ec/src/backend/postmaster/postmaster.c    Mon Feb 17 12:14:12 2003
> @@ -421,7 +421,7 @@
>  
>      opterr = 1;
>  
> -    while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Fh:ik:lm:MN:no:p:Ss-:")) != -1)
> +    while ((opt = getopt(argc, argv, "A:a:B:b:C:c:D:d:Fh:ik:lm:MN:no:p:Ss-:")) != -1)
>      {
>          switch (opt)
>          {
> @@ -441,6 +441,9 @@
>              case 'b':
>                  /* Can no longer set the backend executable file to use. */
>                  break;
> +            case 'C': // MLW
> +                explicit_pgconfig = optarg;
> +                break;
>              case 'D':
>                  potential_DataDir = optarg;
>                  break;
> @@ -564,13 +567,23 @@
>          ExitPostmaster(1);
>      }
>  
> -    /*
> -     * Now we can set the data directory, and then read postgresql.conf.
> -     */
> -    checkDataDir(potential_DataDir);    /* issues error messages */
> -    SetDataDir(potential_DataDir);
> -
> -    ProcessConfigFile(PGC_POSTMASTER);
> +    if(explicit_pgconfig)
> +    {
> +        ProcessConfigFile(PGC_POSTMASTER);
> +        if(!potential_DataDir && pgdatadir)
> +            potential_DataDir = pgdatadir;
> +        checkDataDir(potential_DataDir);    /* issues error messages */
> +        SetDataDir(potential_DataDir);
> +    }
> +    else
> +    {
> +        /*
> +         * Now we can set the data directory, and then read postgresql.conf.
> +         */
> +        checkDataDir(potential_DataDir);    /* issues error messages */
> +        SetDataDir(potential_DataDir);
> +        ProcessConfigFile(PGC_POSTMASTER);
> +    }
>  
>      /*
>       * Check for invalid combinations of GUC settings.
> diff -u -r postgresql-7.3.2/src/backend/utils/misc/guc-file.c postgresql-7.3.2.ec/src/backend/utils/misc/guc-file.c
> --- postgresql-7.3.2/src/backend/utils/misc/guc-file.c    Mon Feb  3 15:22:34 2003
> +++ postgresql-7.3.2.ec/src/backend/utils/misc/guc-file.c    Mon Feb 17 14:58:11 2003
> @@ -2,7 +2,6 @@
>  
>  /* Scanner skeleton version:
>   * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
> - * $FreeBSD: src/usr.bin/lex/flex.skl,v 1.4 1999/10/27 07:56:44 obrien Exp $
>   */
>  
>  #define FLEX_SCANNER
> @@ -10,6 +9,7 @@
>  #define YY_FLEX_MINOR_VERSION 5
>  
>  #include <stdio.h>
> +#include <unistd.h>
>  
>  
>  /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
> @@ -23,7 +23,6 @@
>  #ifdef __cplusplus
>  
>  #include <stdlib.h>
> -#include <unistd.h>
>  
>  /* Use prototypes in function declarations. */
>  #define YY_USE_PROTOS
> @@ -443,7 +442,7 @@
>  char *GUC_scanstr(char *);
>  #define YY_NEVER_INTERACTIVE 1
>  #define YY_NO_UNPUT 1
> -#line 447 "lex.GUC_yy.c"
> +#line 446 "lex.GUC_yy.c"
>  
>  /* Macros after this point can all be overridden by user definitions in
>   * section 1.
> @@ -591,13 +590,13 @@
>  YY_DECL
>      {
>      register GUC_yy_state_type GUC_yy_current_state;
> -    register char *GUC_yy_cp, *GUC_yy_bp;
> +    register char *GUC_yy_cp = NULL, *GUC_yy_bp = NULL;
>      register int GUC_yy_act;
>  
>  #line 71 "guc-file.l"
>  
>  
> -#line 601 "lex.GUC_yy.c"
> +#line 600 "lex.GUC_yy.c"
>  
>      if ( GUC_yy_init )
>          {
> @@ -738,7 +737,7 @@
>  #line 86 "guc-file.l"
>  ECHO;
>      YY_BREAK
> -#line 742 "lex.GUC_yy.c"
> +#line 741 "lex.GUC_yy.c"
>  case YY_STATE_EOF(INITIAL):
>      GUC_yyterminate();
>  
> @@ -1302,11 +1301,6 @@
>      }
>  
>  
> -#ifndef YY_ALWAYS_INTERACTIVE
> -#ifndef YY_NEVER_INTERACTIVE
> -extern int isatty YY_PROTO(( int ));
> -#endif
> -#endif
>
>  #ifdef YY_USE_PROTOS
>  void GUC_yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
> @@ -1658,51 +1652,27 @@
>      }
>  }
>  
> +#define ELEVEL_FROM_CONTEXT(ctx)    (ctx == PGC_SIGHUP) ? DEBUG3 : ERROR
>  
> -/*
> - * Official function to read and process the configuration file. The
> - * parameter indicates in what context the file is being read
> - * (postmaster startup, backend startup, or SIGHUP). All options
> - * mentioned in the configuration file are set to new values. This
> - * function does not return if an error occurs. If an error occurs, no
> - * values will be changed.
> - */
> -void
> -ProcessConfigFile(GucContext context)
> +static void 
> +ReadConfigFile(char *filename, GucContext context)
>  {
>      int token, parse_state;
>      char *opt_name, *opt_value;
> -    char *filename;
>      struct name_value_pair *item, *head, *tail;
> -    int elevel;
> -    FILE * fp;
> -
> -    Assert(context == PGC_POSTMASTER || context == PGC_BACKEND 
> -        || context == PGC_SIGHUP);
> -    Assert(DataDir);
> -    elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR;
> +    FILE *fp;
> +    int elevel = ELEVEL_FROM_CONTEXT(context);
>  
> -    /*
> -     * Open file
> -     */
> -    filename = malloc(strlen(DataDir) + strlen(CONFIG_FILENAME) + 2);
> -    if (filename == NULL)
> -    {
> -        elog(elevel, "out of memory");
> -        return;
> -    }
> -    sprintf(filename, "%s/" CONFIG_FILENAME, DataDir);
> -
> -    fp = AllocateFile(filename, "r");
> -    if (!fp)
> -    {
> +        fp = AllocateFile(filename, "r");
> +    if (!fp)
> +        {
> +            /* File not found is fine */
> +            if (errno != ENOENT)
> +                    elog(elevel, "could not read configuration file %s: %s", 
> +                filename, strerror(errno));
>          free(filename);
> -        /* File not found is fine */
> -        if (errno != ENOENT)
> -            elog(elevel, "could not read configuration file `" CONFIG_FILENAME "': %s", strerror(errno));
>          return;
> -    }
> -
> +        }
>      /*
>       * Parse
>       */
> @@ -1731,7 +1701,8 @@
>                      token = GUC_yylex();
>  
>                  if (token != GUC_ID && token != GUC_STRING && 
> -                    token != GUC_INTEGER && token != GUC_REAL && 
> +                    token != GUC_INTEGER && 
> +                    token != GUC_REAL && 
>                      token != GUC_UNQUOTED_STRING)
>                      goto parse_error;
>                  opt_value = strdup(GUC_yytext);
> @@ -1775,7 +1746,6 @@
>          }
>  
>      FreeFile(fp);
> -    free(filename);
>  
>      /*
>       * Check if all options are valid
> @@ -1798,7 +1768,6 @@
>  
>   parse_error:
>      FreeFile(fp);
> -    free(filename);
>      free_name_value_list(head);
>      elog(elevel, CONFIG_FILENAME ":%u: syntax error, token=\"%s\"", 
>          ConfigFileLineno,GUC_yytext);
> @@ -1806,12 +1775,78 @@
>  
>   out_of_memory:
>      FreeFile(fp);
> -    free(filename);
>      free_name_value_list(head);
>      elog(elevel, "out of memory");
>      return;
>  }
> +/*
> + * Official function to read and process the configuration file. The
> + * parameter indicates in what context the file is being read
> + * (postmaster startup, backend startup, or SIGHUP). All options
> + * mentioned in the configuration file are set to new values. This
> + * function does not return if an error occurs. If an error occurs, no
> + * values will be changed.
> + */
> +void
> +ProcessConfigFile(GucContext context)
> +{
> +    char *filename;
> +
> +    Assert(context == PGC_POSTMASTER || context == PGC_BACKEND 
> +        || context == PGC_SIGHUP);
>  
> +    /* Added for explicit config file */
> +    if(explicit_pgconfig)
> +    {
> +        struct stat sb;
> +
> +        if(stat(explicit_pgconfig, &sb)!=0)
> +        {
> +            int elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR;
> +            elog(elevel, "Invalid configuration parameter");
> +            return ;
> +        }
> +            
> +
> +        if((sb.st_mode & S_IFDIR) == S_IFDIR)
> +        {
> +            /* This will cause a small one time memory leak
> +             * if the user also specifies hba_conf,
> +             * ident_conf, and data_dir
> +             */
> +            filename = malloc(strlen(explicit_pgconfig) + strlen(CONFIG_FILENAME) + 2);
> +            sprintf(filename, "%s/%s", explicit_pgconfig, CONFIG_FILENAME);
> +            explicit_isdir = true;
> +        }
> +        else
> +        {     
> +            /*
> +             * Use explicit file
> +             */
> +            filename = strdup(explicit_pgconfig);
> +        }
> +    }
> +    else
> +    {
> +        /*
> +         * Use environmental config
> +         */
> +        filename = malloc(strlen(DataDir) + strlen(CONFIG_FILENAME) + 2);
> +        sprintf(filename, "%s/%s", DataDir, CONFIG_FILENAME);
> +    }
> +
> +    if (filename == NULL)
> +    {
> +        int elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR;
> +        elog(elevel, "out of memory");
> +        return;
> +    }
> +    /* printf("Using: %s\n", filename); */
> +
> +    ReadConfigFile(filename, context);
> +
> +    free(filename);
> +}
>  
>  
>  /* ----------------
> diff -u -r postgresql-7.3.2/src/backend/utils/misc/guc-file.l postgresql-7.3.2.ec/src/backend/utils/misc/guc-file.l
> --- postgresql-7.3.2/src/backend/utils/misc/guc-file.l    Tue Jul 30 12:33:08 2002
> +++ postgresql-7.3.2.ec/src/backend/utils/misc/guc-file.l    Mon Feb 17 14:58:07 2003
> @@ -116,51 +116,27 @@
>      }
>  }
>  
> +#define ELEVEL_FROM_CONTEXT(ctx)    (ctx == PGC_SIGHUP) ? DEBUG3 : ERROR
>  
> -/*
> - * Official function to read and process the configuration file. The
> - * parameter indicates in what context the file is being read
> - * (postmaster startup, backend startup, or SIGHUP). All options
> - * mentioned in the configuration file are set to new values. This
> - * function does not return if an error occurs. If an error occurs, no
> - * values will be changed.
> - */
> -void
> -ProcessConfigFile(GucContext context)
> +static void 
> +ReadConfigFile(char *filename, GucContext context)
>  {
>      int token, parse_state;
>      char *opt_name, *opt_value;
> -    char *filename;
>      struct name_value_pair *item, *head, *tail;
> -    int elevel;
> -    FILE * fp;
> -
> -    Assert(context == PGC_POSTMASTER || context == PGC_BACKEND 
> -        || context == PGC_SIGHUP);
> -    Assert(DataDir);
> -    elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR;
> +    FILE *fp;
> +    int elevel = ELEVEL_FROM_CONTEXT(context);
>  
> -    /*
> -     * Open file
> -     */
> -    filename = malloc(strlen(DataDir) + strlen(CONFIG_FILENAME) + 2);
> -    if (filename == NULL)
> -    {
> -        elog(elevel, "out of memory");
> -        return;
> -    }
> -    sprintf(filename, "%s/" CONFIG_FILENAME, DataDir);
> -
> -    fp = AllocateFile(filename, "r");
> -    if (!fp)
> -    {
> +        fp = AllocateFile(filename, "r");
> +    if (!fp)
> +        {
> +            /* File not found is fine */
> +            if (errno != ENOENT)
> +                    elog(elevel, "could not read configuration file %s: %s", 
> +                filename, strerror(errno));
>          free(filename);
> -        /* File not found is fine */
> -        if (errno != ENOENT)
> -            elog(elevel, "could not read configuration file `" CONFIG_FILENAME "': %s", strerror(errno));
>          return;
> -    }
> -
> +        }
>      /*
>       * Parse
>       */
> @@ -189,7 +165,8 @@
>                      token = yylex();
>  
>                  if (token != GUC_ID && token != GUC_STRING && 
> -                    token != GUC_INTEGER && token != GUC_REAL && 
> +                    token != GUC_INTEGER && 
> +                    token != GUC_REAL && 
>                      token != GUC_UNQUOTED_STRING)
>                      goto parse_error;
>                  opt_value = strdup(yytext);
> @@ -233,7 +210,6 @@
>          }
>  
>      FreeFile(fp);
> -    free(filename);
>  
>      /*
>       * Check if all options are valid
> @@ -256,7 +232,6 @@
>  
>   parse_error:
>      FreeFile(fp);
> -    free(filename);
>      free_name_value_list(head);
>      elog(elevel, CONFIG_FILENAME ":%u: syntax error, token=\"%s\"", 
>          ConfigFileLineno,yytext);
> @@ -264,12 +239,78 @@
>  
>   out_of_memory:
>      FreeFile(fp);
> -    free(filename);
>      free_name_value_list(head);
>      elog(elevel, "out of memory");
>      return;
>  }
> +/*
> + * Official function to read and process the configuration file. The
> + * parameter indicates in what context the file is being read
> + * (postmaster startup, backend startup, or SIGHUP). All options
> + * mentioned in the configuration file are set to new values. This
> + * function does not return if an error occurs. If an error occurs, no
> + * values will be changed.
> + */
> +void
> +ProcessConfigFile(GucContext context)
> +{
> +    char *filename;
> +
> +    Assert(context == PGC_POSTMASTER || context == PGC_BACKEND 
> +        || context == PGC_SIGHUP);
> +
> +    /* Added for explicit config file */
> +    if(explicit_pgconfig)
> +    {
> +        struct stat sb;
> +
> +        if(stat(explicit_pgconfig, &sb)!=0)
> +        {
> +            int elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR;
> +            elog(elevel, "Invalid configuration parameter");
> +            return ;
> +        }
> +            
> +
> +        if((sb.st_mode & S_IFDIR) == S_IFDIR)
> +        {
> +            /* This will cause a small one time memory leak
> +             * if the user also specifies hba_conf,
> +             * ident_conf, and data_dir
> +             */
> +            filename = malloc(strlen(explicit_pgconfig) + strlen(CONFIG_FILENAME) + 2);
> +            sprintf(filename, "%s/%s", explicit_pgconfig, CONFIG_FILENAME);
> +            explicit_isdir = true;
> +        }
> +        else
> +        {     
> +            /*
> +             * Use explicit file
> +             */
> +            filename = strdup(explicit_pgconfig);
> +        }
> +    }
> +    else
> +    {
> +        /*
> +         * Use environmental config
> +         */
> +        filename = malloc(strlen(DataDir) + strlen(CONFIG_FILENAME) + 2);
> +        sprintf(filename, "%s/%s", DataDir, CONFIG_FILENAME);
> +    }
> +
> +    if (filename == NULL)
> +    {
> +        int elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR;
> +        elog(elevel, "out of memory");
> +        return;
> +    }
> +    /* printf("Using: %s\n", filename); */
>  
> +    ReadConfigFile(filename, context);
> +
> +    free(filename);
> +}
>  
>  
>  /* ----------------
> diff -u -r postgresql-7.3.2/src/backend/utils/misc/guc.c postgresql-7.3.2.ec/src/backend/utils/misc/guc.c
> --- postgresql-7.3.2/src/backend/utils/misc/guc.c    Tue Jan 28 13:04:13 2003
> +++ postgresql-7.3.2.ec/src/backend/utils/misc/guc.c    Mon Feb 17 14:38:34 2003
> @@ -51,6 +51,12 @@
>  #include "utils/pg_locale.h"
>  #include "pgstat.h"
>  
> +/* Added for config file only startup MLW */
> +char *explicit_pgconfig = NULL;
> +char *explicit_hbafile = NULL;
> +char *explicit_identfile = NULL;
> +bool explicit_isdir=false;
> +char *pgdatadir = NULL;
>  
>  /* XXX these should be in other modules' header files */
>  extern bool Log_connections;
> @@ -113,6 +119,7 @@
>  char       *client_min_messages_str = NULL;
>  const char    client_min_messages_str_default[] = "notice";
>  
> +static void ReadConfigFile(char *filename, GucContext context);
>  
>  #ifndef PG_KRB_SRVTAB
>  #define PG_KRB_SRVTAB ""
> @@ -146,7 +153,8 @@
>      PGC_BOOL,
>      PGC_INT,
>      PGC_REAL,
> -    PGC_STRING
> +    PGC_STRING,
> +    PGC_FUNCTION
>  };
>  
>  /* Generic fields applicable to all types of variables */
> @@ -239,6 +247,13 @@
>      char       *tentative_val;
>  };
>  
> +struct config_function
> +{
> +    struct config_generic gen;
> +    void (*function)(char *param, GucContext context);
> +};
> +
> +
>  /* Macros for freeing malloc'd pointers only if appropriate to do so */
>  /* Some of these tests are probably redundant, but be safe ... */
>  #define SET_STRING_VARIABLE(rec, newval) \
> @@ -853,10 +868,32 @@
>      },
>  
>      {
> +        {"data_dir", PGC_POSTMASTER}, &pgdatadir,
> +        "", NULL, NULL
> +    },
> +
> +    {
> +        {"hba_conf", PGC_POSTMASTER}, &explicit_hbafile,
> +        "", NULL, NULL
> +    },
> +
> +    {
> +        {"ident_conf", PGC_POSTMASTER}, &explicit_identfile,
> +        "", NULL, NULL
> +    },
> +
> +    {
>          {NULL, 0}, NULL, NULL, NULL, NULL
>      }
>  };
>  
> +
> +static struct config_function ConfigureFunctions[] =
> +{
> +    { {"include", PGC_POSTMASTER}, ReadConfigFile},
> +    { {NULL,0}, NULL}
> +};
> +
>  /******** end of options list ********/
>  
>  
> @@ -919,6 +956,12 @@
>          conf->gen.vartype = PGC_STRING;
>          num_vars++;
>      }
> +    for(i = 0; ConfigureFunctions[i].gen.name; i++)
> +    {
> +        struct config_function *conf = &ConfigureFunctions[i];
> +        conf->gen.vartype = PGC_FUNCTION;
> +        num_vars++;
> +    }
>  
>      guc_vars = (struct config_generic **)
>          malloc(num_vars * sizeof(struct config_generic *));
> @@ -939,6 +982,9 @@
>      for (i = 0; ConfigureNamesString[i].gen.name; i++)
>          guc_vars[num_vars++] = &ConfigureNamesString[i].gen;
>  
> +    for (i = 0; ConfigureFunctions[i].gen.name; i++)
> +        guc_vars[num_vars++] = &ConfigureFunctions[i].gen;
> +
>      qsort((void *) guc_vars, num_vars, sizeof(struct config_generic *),
>            guc_var_compare);
>  
> @@ -1135,6 +1181,8 @@
>                      conf->session_val = str;
>                      break;
>                  }
> +            case PGC_FUNCTION: /* Nothing to do */
> +                break;
>          }
>      }
>  
> @@ -1280,6 +1328,8 @@
>                      guc_dirty = true;
>                      break;
>                  }
> +            case PGC_FUNCTION: /* Nothing to do */
> +                break;
>          }
>      }
>  }
> @@ -1421,6 +1471,8 @@
>                      conf->gen.status = 0;
>                      break;
>                  }
> +            case    PGC_FUNCTION: /* Nothing to do */
> +                break;
>          }
>      }
>  
> @@ -1684,6 +1736,17 @@
>       */
>      switch (record->vartype)
>      {
> +        case PGC_FUNCTION:
> +            if(!DoIt)
> +            {
> +                /* During the "checking" stage of configuration
> +                 * read, run functions 
> +                 */
> +                struct config_function *fn = 
> +                    (struct config_function *)record;
> +                fn->function((char *)value, context);
> +            }
> +            break;
>          case PGC_BOOL:
>              {
>                  struct config_bool *conf = (struct config_bool *) record;
> @@ -2063,6 +2126,9 @@
>  
>          case PGC_STRING:
>              return *((struct config_string *) record)->variable;
> +        case PGC_FUNCTION:
> +            /* Should never really happen */
> +            return NULL;
>      }
>      return NULL;
>  }
> @@ -2097,6 +2163,9 @@
>  
>          case PGC_STRING:
>              return ((struct config_string *) record)->reset_val;
> +        case PGC_FUNCTION:
> +            /* Should never really happen */
> +            return NULL;
>      }
>      return NULL;
>  }
> diff -u -r postgresql-7.3.2/src/backend/utils/misc/postgresql.conf.sample
postgresql-7.3.2.ec/src/backend/utils/misc/postgresql.conf.sample
> --- postgresql-7.3.2/src/backend/utils/misc/postgresql.conf.sample    Mon Jan 27 22:44:09 2003
> +++ postgresql-7.3.2.ec/src/backend/utils/misc/postgresql.conf.sample    Mon Feb 17 12:14:12 2003
> @@ -23,6 +23,21 @@
>  
>  #========================================================================
>  
> +# Allows PostgreSQL to include another file
> +# include = '/somedir/pgdefs.conf'
> +
> +# Allows PostgreSQL to use a pg_hba.conf file
> +# which is not in the database directory.
> +# hba_conf = '/etc/postgres/pg_hba.conf'
> +
> +# Allows PostgreSQL to use a pg_ident.conf file
> +# which is not in the database directory.
> +# ident_conf = '/etc/postgres/pg_ident.conf'
> +
> +# Allows Postgres to find its data directory
> +# from this configuration file.
> +# data_dir = '/RAID0/postgres'
> +
>  
>  #
>  #    Connection Parameters
> diff -u -r postgresql-7.3.2/src/include/utils/guc.h postgresql-7.3.2.ec/src/include/utils/guc.h
> --- postgresql-7.3.2/src/include/utils/guc.h    Mon Oct 21 14:57:35 2002
> +++ postgresql-7.3.2.ec/src/include/utils/guc.h    Mon Feb 17 14:40:57 2003
> @@ -137,5 +137,11 @@
>  extern char *client_min_messages_str;
>  
>  extern const char client_min_messages_str_default[];
> +/* Added MLW */
> +extern char *explicit_pgconfig;
> +extern char *explicit_hbafile;
> +extern char *explicit_identfile;
> +extern bool explicit_isdir;
> +extern char *pgdatadir;
>  
>  #endif   /* GUC_H */

> 
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo@postgresql.org so that your
> message can get through to the mailing list cleanly

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
359-1001+  If your life is a hard drive,     |  13 Roberts Road +  Christ can be your backup.        |  Newtown Square,
Pennsylvania19073
 


pgsql-hackers by date:

Previous
From: Bruce Momjian
Date:
Subject: Change for multiple queries in a string
Next
From: Bruce Momjian
Date:
Subject: Re: More outdated examples