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 09:30:15 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,20 @@ 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 + { + /* 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); + } file = AllocateFile(conf_file, "r"); if (file == NULL) @@ -979,10 +990,20 @@ 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 */ + bufsize = (strlen(DataDir) + strlen(USERMAP_FILE) + 2) * sizeof(char); + map_file = (char *) palloc(bufsize); + snprintf(map_file, bufsize, "%s/%s", DataDir, USERMAP_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 09:30:15 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.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 12:05:35 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,54 @@ 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) + { + /* + * Use explicit file + */ + filename = strdup(explicit_pgconfig); + } + else + { + /* + * Use environmental config + */ + filename = malloc(strlen(DataDir) + strlen(CONFIG_FILENAME) + 2); + sprintf(filename, "%s/" CONFIG_FILENAME, DataDir); + } + + if (filename == NULL) + { + int elevel = (context == PGC_SIGHUP) ? DEBUG3 : ERROR; + elog(elevel, "out of memory"); + return; + } + + 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 12:07:47 2003 @@ -51,6 +51,11 @@ #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; +char *pgdatadir = NULL; /* XXX these should be in other modules' header files */ extern bool Log_connections; @@ -113,6 +118,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 +152,8 @@ PGC_BOOL, PGC_INT, PGC_REAL, - PGC_STRING + PGC_STRING, + PGC_FUNCTION }; /* Generic fields applicable to all types of variables */ @@ -239,6 +246,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 +867,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 +955,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 +981,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 +1180,8 @@ conf->session_val = str; break; } + case PGC_FUNCTION: /* Nothing to do */ + break; } } @@ -1280,6 +1327,8 @@ guc_dirty = true; break; } + case PGC_FUNCTION: /* Nothing to do */ + break; } } } @@ -1421,6 +1470,8 @@ conf->gen.status = 0; break; } + case PGC_FUNCTION: /* Nothing to do */ + break; } } @@ -1684,6 +1735,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 +2125,9 @@ case PGC_STRING: return *((struct config_string *) record)->variable; + case PGC_FUNCTION: + /* Should never really happen */ + return NULL; } return NULL; } @@ -2097,6 +2162,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:04:44 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 11:41:13 2003 @@ -137,5 +137,10 @@ 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 char *pgdatadir; #endif /* GUC_H */