From f2ef4df4a39e7d5c539dd51a752628e59b656f04 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Tue, 17 Oct 2000 01:00:58 +0000
Subject: [PATCH] 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
---
 src/interfaces/libpq/fe-connect.c | 123 +++++++++++++++++++++++++++++-
 1 file changed, 122 insertions(+), 1 deletion(-)

diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index f27686a727a..bf07929f50a 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -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 */
-- 
GitLab