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