1 /*-------------------------------------------------------------------------
3 * streamutil.c - utility functions for pg_basebackup and pg_receivelog
5 * Author: Magnus Hagander <magnus@hagander.net>
7 * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
10 * src/bin/pg_basebackup/streamutil.c
11 *-------------------------------------------------------------------------
15 * We have to use postgres.h not postgres_fe.h here, because there's so much
16 * backend-only stuff in the XLOG include files we need. But we need a
17 * frontend-ish environment otherwise. Hence this ugly hack.
21 #include "streamutil.h"
30 int dbgetpassword = 0; /* 0=auto, -1=never, 1=always */
31 static char *dbpassword = NULL;
35 * strdup() and malloc() replacements that prints an error and exits
36 * if something goes wrong. Can never return NULL.
39 xstrdup(const char *s)
46 fprintf(stderr, _("%s: out of memory\n"), progname);
57 result = malloc(size);
60 fprintf(stderr, _("%s: out of memory\n"), progname);
63 MemSet(result, 0, size);
69 * Connect to the server. Returns a valid PGconn pointer if connected,
70 * or NULL on non-permanent error. On permanent error, the function will
71 * call exit(1) directly.
77 int argcount = 4; /* dbname, replication, fallback_app_name,
80 const char **keywords;
82 char *password = NULL;
92 keywords = xmalloc0((argcount + 1) * sizeof(*keywords));
93 values = xmalloc0((argcount + 1) * sizeof(*values));
95 keywords[0] = "dbname";
96 values[0] = "replication";
97 keywords[1] = "replication";
99 keywords[2] = "fallback_application_name";
100 values[2] = progname;
104 keywords[i] = "host";
110 keywords[i] = "user";
116 keywords[i] = "port";
129 * We've saved a password when a previous connection succeeded,
130 * meaning this is the call for a second session to the same
131 * database, so just forcibly reuse that password.
133 keywords[argcount - 1] = "password";
134 values[argcount - 1] = dbpassword;
135 dbgetpassword = -1; /* Don't try again if this fails */
137 else if (dbgetpassword == 1)
139 password = simple_prompt(_("Password: "), 100, false);
140 keywords[argcount - 1] = "password";
141 values[argcount - 1] = password;
144 tmpconn = PQconnectdbParams(keywords, values, true);
146 if (PQstatus(tmpconn) == CONNECTION_BAD &&
147 PQconnectionNeedsPassword(tmpconn) &&
150 dbgetpassword = 1; /* ask for password next time */
155 if (PQstatus(tmpconn) != CONNECTION_OK)
157 fprintf(stderr, _("%s: could not connect to server: %s\n"),
158 progname, PQerrorMessage(tmpconn));
167 * Ensure we have the same value of integer timestamps as the server
168 * we are connecting to.
170 tmpparam = PQparameterStatus(tmpconn, "integer_datetimes");
173 fprintf(stderr, _("%s: could not determine server setting for integer_datetimes\n"),
179 #ifdef HAVE_INT64_TIMESTAMP
180 if (strcmp(tmpparam, "on") != 0)
182 if (strcmp(tmpparam, "off") != 0)
185 fprintf(stderr, _("%s: integer_datetimes compile flag does not match server\n"),
191 /* Store the password for next run */
193 dbpassword = password;