LCOV - code coverage report
Current view: top level - src/bin/scripts - pg_isready.c (source / functions) Hit Total Coverage
Test: PostgreSQL 12beta2 Lines: 81 116 69.8 %
Date: 2019-06-19 16:07:09 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * pg_isready --- checks the status of the PostgreSQL server
       4             :  *
       5             :  * Copyright (c) 2013-2019, PostgreSQL Global Development Group
       6             :  *
       7             :  * src/bin/scripts/pg_isready.c
       8             :  *
       9             :  *-------------------------------------------------------------------------
      10             :  */
      11             : 
      12             : #include "postgres_fe.h"
      13             : #include "common.h"
      14             : #include "common/logging.h"
      15             : 
      16             : #define DEFAULT_CONNECT_TIMEOUT "3"
      17             : 
      18             : static void
      19             :             help(const char *progname);
      20             : 
      21             : int
      22          10 : main(int argc, char **argv)
      23             : {
      24             :     int         c;
      25             : 
      26             :     const char *progname;
      27             : 
      28          10 :     const char *pghost = NULL;
      29          10 :     const char *pgport = NULL;
      30          10 :     const char *pguser = NULL;
      31          10 :     const char *pgdbname = NULL;
      32          10 :     const char *connect_timeout = DEFAULT_CONNECT_TIMEOUT;
      33             : 
      34          10 :     const char *pghost_str = NULL;
      35          10 :     const char *pghostaddr_str = NULL;
      36          10 :     const char *pgport_str = NULL;
      37             : 
      38             : #define PARAMS_ARRAY_SIZE   7
      39             : 
      40             :     const char *keywords[PARAMS_ARRAY_SIZE];
      41             :     const char *values[PARAMS_ARRAY_SIZE];
      42             : 
      43          10 :     bool        quiet = false;
      44             : 
      45             :     PGPing      rv;
      46          10 :     PQconninfoOption *opts = NULL;
      47          10 :     PQconninfoOption *defs = NULL;
      48             :     PQconninfoOption *opt;
      49             :     PQconninfoOption *def;
      50          10 :     char       *errmsg = NULL;
      51             : 
      52             :     /*
      53             :      * We accept user and database as options to avoid useless errors from
      54             :      * connecting with invalid params
      55             :      */
      56             : 
      57             :     static struct option long_options[] = {
      58             :         {"dbname", required_argument, NULL, 'd'},
      59             :         {"host", required_argument, NULL, 'h'},
      60             :         {"port", required_argument, NULL, 'p'},
      61             :         {"quiet", no_argument, NULL, 'q'},
      62             :         {"timeout", required_argument, NULL, 't'},
      63             :         {"username", required_argument, NULL, 'U'},
      64             :         {NULL, 0, NULL, 0}
      65             :     };
      66             : 
      67          10 :     pg_logging_init(argv[0]);
      68          10 :     progname = get_progname(argv[0]);
      69          10 :     set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
      70          10 :     handle_help_version_opts(argc, argv, progname, help);
      71             : 
      72           6 :     while ((c = getopt_long(argc, argv, "d:h:p:qt:U:", long_options, NULL)) != -1)
      73             :     {
      74           4 :         switch (c)
      75             :         {
      76             :             case 'd':
      77           0 :                 pgdbname = pg_strdup(optarg);
      78           0 :                 break;
      79             :             case 'h':
      80           0 :                 pghost = pg_strdup(optarg);
      81           0 :                 break;
      82             :             case 'p':
      83           0 :                 pgport = pg_strdup(optarg);
      84           0 :                 break;
      85             :             case 'q':
      86           0 :                 quiet = true;
      87           0 :                 break;
      88             :             case 't':
      89           2 :                 connect_timeout = pg_strdup(optarg);
      90           2 :                 break;
      91             :             case 'U':
      92           0 :                 pguser = pg_strdup(optarg);
      93           0 :                 break;
      94             :             default:
      95           2 :                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
      96             : 
      97             :                 /*
      98             :                  * We need to make sure we don't return 1 here because someone
      99             :                  * checking the return code might infer unintended meaning
     100             :                  */
     101           2 :                 exit(PQPING_NO_ATTEMPT);
     102             :         }
     103             :     }
     104             : 
     105           4 :     if (optind < argc)
     106             :     {
     107           0 :         pg_log_error("too many command-line arguments (first is \"%s\")",
     108             :                      argv[optind]);
     109           0 :         fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
     110             : 
     111             :         /*
     112             :          * We need to make sure we don't return 1 here because someone
     113             :          * checking the return code might infer unintended meaning
     114             :          */
     115           0 :         exit(PQPING_NO_ATTEMPT);
     116             :     }
     117             : 
     118           4 :     keywords[0] = "host";
     119           4 :     values[0] = pghost;
     120           4 :     keywords[1] = "port";
     121           4 :     values[1] = pgport;
     122           4 :     keywords[2] = "user";
     123           4 :     values[2] = pguser;
     124           4 :     keywords[3] = "dbname";
     125           4 :     values[3] = pgdbname;
     126           4 :     keywords[4] = "connect_timeout";
     127           4 :     values[4] = connect_timeout;
     128           4 :     keywords[5] = "fallback_application_name";
     129           4 :     values[5] = progname;
     130           4 :     keywords[6] = NULL;
     131           4 :     values[6] = NULL;
     132             : 
     133             :     /*
     134             :      * Get the host and port so we can display them in our output
     135             :      */
     136           4 :     if (pgdbname &&
     137           0 :         (strncmp(pgdbname, "postgresql://", 13) == 0 ||
     138           0 :          strncmp(pgdbname, "postgres://", 11) == 0 ||
     139           0 :          strchr(pgdbname, '=') != NULL))
     140             :     {
     141           0 :         opts = PQconninfoParse(pgdbname, &errmsg);
     142           0 :         if (opts == NULL)
     143             :         {
     144           0 :             pg_log_error("%s", errmsg);
     145           0 :             exit(PQPING_NO_ATTEMPT);
     146             :         }
     147             :     }
     148             : 
     149           4 :     defs = PQconndefaults();
     150           4 :     if (defs == NULL)
     151             :     {
     152           0 :         pg_log_error("could not fetch default options");
     153           0 :         exit(PQPING_NO_ATTEMPT);
     154             :     }
     155             : 
     156         124 :     for (opt = opts, def = defs; def->keyword; def++)
     157             :     {
     158         120 :         if (strcmp(def->keyword, "host") == 0)
     159             :         {
     160           4 :             if (opt && opt->val)
     161           0 :                 pghost_str = opt->val;
     162           4 :             else if (pghost)
     163           0 :                 pghost_str = pghost;
     164           4 :             else if (def->val)
     165           4 :                 pghost_str = def->val;
     166             :             else
     167           0 :                 pghost_str = DEFAULT_PGSOCKET_DIR;
     168             :         }
     169         116 :         else if (strcmp(def->keyword, "hostaddr") == 0)
     170             :         {
     171           4 :             if (opt && opt->val)
     172           0 :                 pghostaddr_str = opt->val;
     173           4 :             else if (def->val)
     174           0 :                 pghostaddr_str = def->val;
     175             :         }
     176         112 :         else if (strcmp(def->keyword, "port") == 0)
     177             :         {
     178           4 :             if (opt && opt->val)
     179           0 :                 pgport_str = opt->val;
     180           4 :             else if (pgport)
     181           0 :                 pgport_str = pgport;
     182           4 :             else if (def->val)
     183           4 :                 pgport_str = def->val;
     184             :         }
     185             : 
     186         120 :         if (opt)
     187           0 :             opt++;
     188             :     }
     189             : 
     190           4 :     rv = PQpingParams(keywords, values, 1);
     191             : 
     192           4 :     if (!quiet)
     193             :     {
     194           4 :         printf("%s:%s - ",
     195             :                pghostaddr_str != NULL ? pghostaddr_str : pghost_str,
     196             :                pgport_str);
     197             : 
     198           4 :         switch (rv)
     199             :         {
     200             :             case PQPING_OK:
     201           2 :                 printf(_("accepting connections\n"));
     202           2 :                 break;
     203             :             case PQPING_REJECT:
     204           0 :                 printf(_("rejecting connections\n"));
     205           0 :                 break;
     206             :             case PQPING_NO_RESPONSE:
     207           2 :                 printf(_("no response\n"));
     208           2 :                 break;
     209             :             case PQPING_NO_ATTEMPT:
     210           0 :                 printf(_("no attempt\n"));
     211           0 :                 break;
     212             :             default:
     213           0 :                 printf(_("unknown\n"));
     214             :         }
     215             :     }
     216             : 
     217           4 :     exit(rv);
     218             : }
     219             : 
     220             : static void
     221           2 : help(const char *progname)
     222             : {
     223           2 :     printf(_("%s issues a connection check to a PostgreSQL database.\n\n"), progname);
     224           2 :     printf(_("Usage:\n"));
     225           2 :     printf(_("  %s [OPTION]...\n"), progname);
     226             : 
     227           2 :     printf(_("\nOptions:\n"));
     228           2 :     printf(_("  -d, --dbname=DBNAME      database name\n"));
     229           2 :     printf(_("  -q, --quiet              run quietly\n"));
     230           2 :     printf(_("  -V, --version            output version information, then exit\n"));
     231           2 :     printf(_("  -?, --help               show this help, then exit\n"));
     232             : 
     233           2 :     printf(_("\nConnection options:\n"));
     234           2 :     printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
     235           2 :     printf(_("  -p, --port=PORT          database server port\n"));
     236           2 :     printf(_("  -t, --timeout=SECS       seconds to wait when attempting connection, 0 disables (default: %s)\n"), DEFAULT_CONNECT_TIMEOUT);
     237           2 :     printf(_("  -U, --username=USERNAME  user name to connect as\n"));
     238           2 :     printf(_("\nReport bugs to <pgsql-bugs@lists.postgresql.org>.\n"));
     239           2 : }

Generated by: LCOV version 1.13