Fix pg_isready to handle conninfo properly.
authorFujii Masao <fujii@postgresql.org>
Mon, 10 Jun 2013 18:03:16 +0000 (03:03 +0900)
committerFujii Masao <fujii@postgresql.org>
Mon, 10 Jun 2013 18:03:16 +0000 (03:03 +0900)
pg_isready displays the host name and the port number that it uses to connect
to the server. So far, pg_isready didn't use the conninfo specified in -d option
for calculating those host name and port number. This can lead to wrong display
to a user. This commit changes pg_isready so that it uses the conninfo for that
calculation.

Original patch by Phil Sorber, modified by me.

src/bin/scripts/pg_isready.c

index 89542db2300c75bd1afb8388740df0089e166e67..d4fe620e431f24279afe724aaa5daee7ea0b2ac5 100644 (file)
@@ -20,9 +20,7 @@ static void
 int
 main(int argc, char **argv)
 {
-   int         c,
-               optindex,
-               opt_index = 2;
+   int         c;
 
    const char *progname;
 
@@ -32,14 +30,22 @@ main(int argc, char **argv)
    const char *pgdbname = NULL;
    const char *connect_timeout = DEFAULT_CONNECT_TIMEOUT;
 
-   const char *keywords[7] = {NULL};
-   const char *values[7] = {NULL};
+   const char *pghost_str = NULL;
+   const char *pgport_str = NULL;
+
+#define PARAMS_ARRAY_SIZE  7
+
+   const char *keywords[PARAMS_ARRAY_SIZE];
+   const char *values[PARAMS_ARRAY_SIZE];
 
    bool        quiet = false;
 
-   PGPing      rv;
-   PQconninfoOption *connect_options,
-              *conn_opt_ptr;
+   PGPing rv;
+   PQconninfoOption *opts = NULL;
+   PQconninfoOption *defs = NULL;
+   PQconninfoOption *opt;
+   PQconninfoOption *def;
+   char       *errmsg = NULL;
 
    /*
     * We accept user and database as options to avoid useless errors from
@@ -60,7 +66,7 @@ main(int argc, char **argv)
    set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
    handle_help_version_opts(argc, argv, progname, help);
 
-   while ((c = getopt_long(argc, argv, "d:h:p:qt:U:V", long_options, &optindex)) != -1)
+   while ((c = getopt_long(argc, argv, "d:h:p:qt:U:", long_options, NULL)) != -1)
    {
        switch (c)
        {
@@ -106,66 +112,74 @@ main(int argc, char **argv)
        exit(PQPING_NO_ATTEMPT);
    }
 
+   keywords[0] = "host";
+   values[0] = pghost;
+   keywords[1] = "port";
+   values[1] = pgport;
+   keywords[2] = "user";
+   values[2] = pguser;
+   keywords[3] = "dbname";
+   values[3] = pgdbname;
+   keywords[4] = "connect_timeout";
+   values[4] = connect_timeout;
+   keywords[5] = "fallback_application_name";
+   values[5] = progname;
+   keywords[6] = NULL;
+   values[6] = NULL;
+
    /*
-    * Set connection options
+    * Get the host and port so we can display them in our output
     */
-
-   keywords[0] = "connect_timeout";
-   values[0] = connect_timeout;
-   keywords[1] = "fallback_application_name";
-   values[1] = progname;
-   if (pguser)
+   if (pgdbname)
    {
-       keywords[opt_index] = "user";
-       values[opt_index] = pguser;
-       opt_index++;
+       opts = PQconninfoParse(pgdbname, &errmsg);
+       if (opts == NULL)
+       {
+           fprintf(stderr, _("%s: %s\n"), progname, errmsg);
+           exit(PQPING_NO_ATTEMPT);
+       }
    }
-   if (pgdbname)
+
+   defs = PQconndefaults();
+   if (defs == NULL)
    {
-       keywords[opt_index] = "dbname";
-       values[opt_index] = pgdbname;
-       opt_index++;
+       fprintf(stderr, _("%s: cannot fetch default options\n"), progname);
+       exit(PQPING_NO_ATTEMPT);
    }
 
-   /*
-    * Get the default host and port so we can display them in our output
-    */
-   connect_options = PQconndefaults();
-   conn_opt_ptr = connect_options;
-   while (conn_opt_ptr->keyword)
+   for (opt = opts, def = defs; def->keyword; def++)
    {
-       if (strncmp(conn_opt_ptr->keyword, "host", 5) == 0)
+       if (strcmp(def->keyword, "hostaddr") == 0 ||
+           strcmp(def->keyword, "host") == 0)
        {
-           if (pghost)
-           {
-               keywords[opt_index] = conn_opt_ptr->keyword;
-               values[opt_index] = pghost;
-               opt_index++;
-           }
-           else if (conn_opt_ptr->val)
-               pghost = conn_opt_ptr->val;
+           if (opt && opt->val)
+               pghost_str = opt->val;
+           else if (pghost)
+               pghost_str = pghost;
+           else if (def->val)
+               pghost_str = def->val;
            else
-               pghost = DEFAULT_PGSOCKET_DIR;
+               pghost_str = DEFAULT_PGSOCKET_DIR;
        }
-       else if (strncmp(conn_opt_ptr->keyword, "port", 5) == 0)
+       else if (strcmp(def->keyword, "port") == 0)
        {
-           if (pgport)
-           {
-               keywords[opt_index] = conn_opt_ptr->keyword;
-               values[opt_index] = pgport;
-               opt_index++;
-           }
-           else if (conn_opt_ptr->val)
-               pgport = conn_opt_ptr->val;
+           if (opt && opt->val)
+               pgport_str = opt->val;
+           else if (pgport)
+               pgport_str = pgport;
+           else if (def->val)
+               pgport_str = def->val;
        }
-       conn_opt_ptr++;
+
+       if (opt)
+           opt++;
    }
 
    rv = PQpingParams(keywords, values, 1);
 
    if (!quiet)
    {
-       printf("%s:%s - ", pghost, pgport);
+       printf("%s:%s - ", pghost_str, pgport_str);
 
        switch (rv)
        {
@@ -186,8 +200,6 @@ main(int argc, char **argv)
        }
    }
 
-   PQconninfoFree(connect_options);
-
    exit(rv);
 }