Header And Logo

PostgreSQL
| The world's most advanced open source database.

pg_isready.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * pg_isready --- checks the status of the PostgreSQL server
00004  *
00005  * Copyright (c) 2013, PostgreSQL Global Development Group
00006  *
00007  * src/bin/scripts/pg_isready.c
00008  *
00009  *-------------------------------------------------------------------------
00010  */
00011 
00012 #include "postgres_fe.h"
00013 #include "common.h"
00014 
00015 #define DEFAULT_CONNECT_TIMEOUT "3"
00016 
00017 static void
00018 help(const char *progname);
00019 
00020 int
00021 main(int argc, char **argv)
00022 {
00023     int c,optindex,opt_index = 2;
00024 
00025     const char *progname;
00026 
00027     const char *pghost = NULL;
00028     const char *pgport = NULL;
00029     const char *pguser = NULL;
00030     const char *pgdbname = NULL;
00031     const char *connect_timeout = DEFAULT_CONNECT_TIMEOUT;
00032 
00033     const char *keywords[7] = { NULL };
00034     const char *values[7] = { NULL };
00035 
00036     bool quiet = false;
00037 
00038     PGPing rv;
00039     PQconninfoOption *connect_options, *conn_opt_ptr;
00040 
00041     /*
00042      * We accept user and database as options to avoid
00043      * useless errors from connecting with invalid params
00044      */
00045 
00046     static struct option long_options[] = {
00047             {"dbname", required_argument, NULL, 'd'},
00048             {"host", required_argument, NULL, 'h'},
00049             {"port", required_argument, NULL, 'p'},
00050             {"quiet", no_argument, NULL, 'q'},
00051             {"timeout", required_argument, NULL, 't'},
00052             {"username", required_argument, NULL, 'U'},
00053             {NULL, 0, NULL, 0}
00054         };
00055 
00056     progname = get_progname(argv[0]);
00057     set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
00058     handle_help_version_opts(argc, argv, progname, help);
00059 
00060     while ((c = getopt_long(argc, argv, "d:h:p:qt:U:V", long_options, &optindex)) != -1)
00061     {
00062         switch (c)
00063         {
00064             case 'd':
00065                 pgdbname = pg_strdup(optarg);
00066                 break;
00067             case 'h':
00068                 pghost = pg_strdup(optarg);
00069                 break;
00070             case 'p':
00071                 pgport = pg_strdup(optarg);
00072                 break;
00073             case 'q':
00074                 quiet = true;
00075                 break;
00076             case 't':
00077                 connect_timeout = pg_strdup(optarg);
00078                 break;
00079             case 'U':
00080                 pguser = pg_strdup(optarg);
00081                 break;
00082             default:
00083                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
00084                 /*
00085                  * We need to make sure we don't return 1 here because someone
00086                  * checking the return code might infer unintended meaning
00087                  */
00088                 exit(PQPING_NO_ATTEMPT);
00089         }
00090     }
00091 
00092     if (optind < argc)
00093     {
00094         fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
00095                 progname, argv[optind]);
00096         fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
00097         /*
00098          * We need to make sure we don't return 1 here because someone
00099          * checking the return code might infer unintended meaning
00100          */
00101         exit(PQPING_NO_ATTEMPT);
00102     }
00103 
00104     /*
00105      * Set connection options
00106      */
00107 
00108     keywords[0] = "connect_timeout";
00109     values[0] = connect_timeout;
00110     keywords[1] = "fallback_application_name";
00111     values[1] = progname;
00112     if (pguser)
00113     {
00114         keywords[opt_index] = "user";
00115         values[opt_index] = pguser;
00116         opt_index++;
00117     }
00118     if (pgdbname)
00119     {
00120         keywords[opt_index] = "dbname";
00121         values[opt_index] = pgdbname;
00122         opt_index++;
00123     }
00124 
00125     /*
00126      * Get the default host and port so we can display them in our output
00127      */
00128     connect_options = PQconndefaults();
00129     conn_opt_ptr = connect_options;
00130     while (conn_opt_ptr->keyword)
00131     {
00132         if (strncmp(conn_opt_ptr->keyword, "host", 5) == 0)
00133         {
00134             if (pghost)
00135             {
00136                 keywords[opt_index] = conn_opt_ptr->keyword;
00137                 values[opt_index] = pghost;
00138                 opt_index++;
00139             }
00140             else if (conn_opt_ptr->val)
00141                 pghost = conn_opt_ptr->val;
00142             else
00143                 pghost = DEFAULT_PGSOCKET_DIR;
00144         }
00145         else if (strncmp(conn_opt_ptr->keyword, "port", 5) == 0)
00146         {
00147             if (pgport)
00148             {
00149                 keywords[opt_index] = conn_opt_ptr->keyword;
00150                 values[opt_index] = pgport;
00151                 opt_index++;
00152             }
00153             else if (conn_opt_ptr->val)
00154                 pgport = conn_opt_ptr->val;
00155         }
00156         conn_opt_ptr++;
00157     }
00158 
00159     rv = PQpingParams(keywords, values, 1);
00160 
00161     if (!quiet)
00162     {
00163         printf("%s:%s - ", pghost, pgport);
00164 
00165         switch (rv)
00166         {
00167             case PQPING_OK:
00168                 printf("accepting connections\n");
00169                 break;
00170             case PQPING_REJECT:
00171                 printf("rejecting connections\n");
00172                 break;
00173             case PQPING_NO_RESPONSE:
00174                 printf("no response\n");
00175                 break;
00176             case PQPING_NO_ATTEMPT:
00177                 printf("no attempt\n");
00178                 break;
00179             default:
00180                 printf("unknown\n");
00181         }
00182     }
00183 
00184     PQconninfoFree(connect_options);
00185 
00186     exit(rv);
00187 }
00188 
00189 static void
00190 help(const char *progname)
00191 {
00192     printf(_("%s issues a connection check to a PostgreSQL database.\n\n"), progname);
00193     printf(_("Usage:\n"));
00194     printf(_("  %s [OPTION]...\n"), progname);
00195 
00196     printf(_("\nOptions:\n"));
00197     printf(_("  -d, --dbname=DBNAME      database name\n"));
00198     printf(_("  -q, --quiet              run quietly\n"));
00199     printf(_("  -V, --version            output version information, then exit\n"));
00200     printf(_("  -?, --help               show this help, then exit\n"));
00201 
00202     printf(_("\nConnection options:\n"));
00203     printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
00204     printf(_("  -p, --port=PORT          database server port\n"));
00205     printf(_("  -t, --timeout=SECS       seconds to wait when attempting connection, 0 disables (default: %s)\n"), DEFAULT_CONNECT_TIMEOUT);
00206     printf(_("  -U, --username=USERNAME  database username\n"));
00207     printf(_("\nReport bugs to <[email protected]>.\n"));
00208 }