TNS:
authorBruce Momjian
Tue, 17 Oct 2000 01:00:58 +0000 (01:00 +0000)
committerBruce Momjian
Tue, 17 Oct 2000 01:00:58 +0000 (01:00 +0000)
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

index f27686a727aafb70dd077b0fb08841f0040128d8..bf07929f50a0635864c69d072a8ddd6f0d6dc418 100644 (file)
@@ -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 */