mirror of https://github.com/postgres/postgres
TNS:
I prepared and tested a patch vs. 7.0.2, and it works fine. I've added another option which allows users to have their own service file in ~/.pg_service.conf, which might come handy sometimes. Mario Weilguni
This commit is contained in:
parent
1333f07ff1
commit
f2ef4df4a3
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.138 2000/10/14 23:56:59 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.139 2000/10/17 01:00:58 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -111,6 +111,9 @@ static const PQconninfoOption PQconninfoOptions[] = {
|
|||
{"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
|
||||
"Database-Authtype", "D", 20},
|
||||
|
||||
{"service", "PGSERVICE", NULL, NULL,
|
||||
"Database-Service", "", 20},
|
||||
|
||||
{"user", "PGUSER", NULL, NULL,
|
||||
"Database-User", "", 20},
|
||||
|
||||
|
@ -187,6 +190,8 @@ static PQconninfoOption *conninfo_parse(const char *conninfo,
|
|||
static char *conninfo_getval(PQconninfoOption *connOptions,
|
||||
const char *keyword);
|
||||
static void defaultNoticeProcessor(void *arg, const char *message);
|
||||
static int parseServiceInfo(PQconninfoOption *options,
|
||||
PQExpBuffer errorMessage);
|
||||
|
||||
|
||||
/* ----------------
|
||||
|
@ -2090,6 +2095,114 @@ pqPacketSend(PGconn *conn, const char *buf, size_t len)
|
|||
return STATUS_OK;
|
||||
}
|
||||
|
||||
int parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage) {
|
||||
char *service = conninfo_getval(options, "service");
|
||||
char *serviceFile = "/etc/pg_service.conf";
|
||||
int MAXBUFSIZE = 256;
|
||||
int group_found = 0;
|
||||
int linenr=0, i;
|
||||
|
||||
if(service != NULL) {
|
||||
FILE *f;
|
||||
char buf[MAXBUFSIZE], *line;
|
||||
|
||||
f = fopen(serviceFile, "r");
|
||||
if(f == NULL) {
|
||||
printfPQExpBuffer(errorMessage, "ERROR: Service file '%s' not found\n",
|
||||
serviceFile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* As default, set the database name to the name of the service */
|
||||
for(i = 0; options[i].keyword; i++)
|
||||
if(strcmp(options[i].keyword, "dbname") == 0) {
|
||||
if(options[i].val != NULL)
|
||||
free(options[i].val);
|
||||
options[i].val = strdup(service);
|
||||
}
|
||||
|
||||
while((line = fgets(buf, MAXBUFSIZE-1, f)) != NULL) {
|
||||
linenr++;
|
||||
|
||||
if(strlen(line) >= MAXBUFSIZE - 2) {
|
||||
fclose(f);
|
||||
printfPQExpBuffer(errorMessage,
|
||||
"ERROR: line %d too long in service file '%s'\n",
|
||||
linenr,
|
||||
serviceFile);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* ignore EOL at end of line */
|
||||
if(strlen(line) && line[strlen(line)-1] == '\n')
|
||||
line[strlen(line)-1] = 0;
|
||||
|
||||
/* ignore leading blanks */
|
||||
while(*line && isspace(line[0]))
|
||||
line++;
|
||||
|
||||
/* ignore comments and empty lines */
|
||||
if(strlen(line) == 0 || line[0] == '#')
|
||||
continue;
|
||||
|
||||
/* Check for right groupname */
|
||||
if(line[0] == '[') {
|
||||
if(group_found) {
|
||||
/* group info already read */
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strncmp(line+1, service, strlen(service)) == 0 &&
|
||||
line[strlen(service)+1] == ']')
|
||||
group_found = 1;
|
||||
else
|
||||
group_found = 0;
|
||||
} else {
|
||||
if(group_found) {
|
||||
/* Finally, we are in the right group and can parse the line */
|
||||
char *key, *val;
|
||||
int found_keyword;
|
||||
|
||||
key = strtok(line, "=");
|
||||
if(key == NULL) {
|
||||
printfPQExpBuffer(errorMessage,
|
||||
"ERROR: syntax error in service file '%s', line %d\n",
|
||||
serviceFile,
|
||||
linenr);
|
||||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
val = line + strlen(line) + 1;
|
||||
|
||||
found_keyword = 0;
|
||||
for(i = 0; options[i].keyword; i++) {
|
||||
if(strcmp(options[i].keyword, key) == 0) {
|
||||
if(options[i].val != NULL)
|
||||
free(options[i].val);
|
||||
options[i].val = strdup(val);
|
||||
found_keyword = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found_keyword) {
|
||||
printfPQExpBuffer(errorMessage,
|
||||
"ERROR: syntax error in service file '%s', line %d\n",
|
||||
serviceFile,
|
||||
linenr);
|
||||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------
|
||||
* Conninfo parser routine
|
||||
|
@ -2263,6 +2376,14 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage)
|
|||
if (option->val)
|
||||
free(option->val);
|
||||
option->val = strdup(pval);
|
||||
|
||||
}
|
||||
|
||||
/* Now check for service info */
|
||||
if(parseServiceInfo(options, errorMessage)) {
|
||||
PQconninfoFree(options);
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Done with the modifiable input string */
|
||||
|
|
Loading…
Reference in New Issue