appendPQExpBuffer(&sql, " %s", table);
appendPQExpBufferChar(&sql, ';');
- conn = connectDatabase(dbname, host, port, username, prompt_password,
+ conn = connectDatabase(dbname, host, port, username, NULL, prompt_password,
progname, false);
if (!executeMaintenanceCommand(conn, sql.data, echo))
{
/*
- * Make a database connection with the given parameters. An
- * interactive password prompt is automatically issued if required.
+ * Make a database connection with the given parameters.
+ *
+ * A password can be given, but if not (or if user forces us to) we prompt
+ * interactively for one, unless caller prohibited us from doing so.
*/
PGconn *
connectDatabase(const char *dbname, const char *pghost, const char *pgport,
- const char *pguser, enum trivalue prompt_password,
- const char *progname, bool fail_ok)
+ const char *pguser, const char *pgpassword,
+ enum trivalue prompt_password, const char *progname,
+ bool fail_ok)
{
PGconn *conn;
- char *password = NULL;
+ char *password;
bool new_pass;
- if (prompt_password == TRI_YES)
+ password = pgpassword ? strdup(pgpassword) : NULL;
+
+ if (prompt_password == TRI_YES && !pgpassword)
password = simple_prompt("Password: ", 100, false);
/*
new_pass = false;
conn = PQconnectdbParams(keywords, values, true);
- free(keywords);
- free(values);
-
if (!conn)
{
- fprintf(stderr, _("%s: could not connect to database %s\n"),
+ fprintf(stderr, _("%s: could not connect to database %s: out of memory\n"),
progname, dbname);
exit(1);
}
+ pg_free(keywords);
+ pg_free(values);
+
+ /*
+ * No luck? Trying asking (again) for a password.
+ */
if (PQstatus(conn) == CONNECTION_BAD &&
PQconnectionNeedsPassword(conn) &&
- password == NULL &&
prompt_password != TRI_NO)
{
PQfinish(conn);
+ if (password)
+ free(password);
password = simple_prompt("Password: ", 100, false);
new_pass = true;
}
/* If a maintenance database name was specified, just connect to it. */
if (maintenance_db)
- return connectDatabase(maintenance_db, pghost, pgport, pguser,
+ return connectDatabase(maintenance_db, pghost, pgport, pguser, NULL,
prompt_password, progname, false);
/* Otherwise, try postgres first and then template1. */
- conn = connectDatabase("postgres", pghost, pgport, pguser, prompt_password,
- progname, true);
+ conn = connectDatabase("postgres", pghost, pgport, pguser, NULL,
+ prompt_password, progname, true);
if (!conn)
- conn = connectDatabase("template1", pghost, pgport, pguser,
+ conn = connectDatabase("template1", pghost, pgport, pguser, NULL,
prompt_password, progname, false);
return conn;
extern PGconn *connectDatabase(const char *dbname, const char *pghost,
const char *pgport, const char *pguser,
- enum trivalue prompt_password, const char *progname,
- bool fail_ok);
+ const char *pgpassword, enum trivalue prompt_password,
+ const char *progname, bool fail_ok);
extern PGconn *connectMaintenanceDatabase(const char *maintenance_db,
const char *pghost, const char *pgport, const char *pguser,
printQueryOpt popt;
static const bool translate_columns[] = {false, true};
- conn = connectDatabase(dbname, host, port, username, prompt_password,
- progname, false);
+ conn = connectDatabase(dbname, host, port, username, NULL,
+ prompt_password, progname, false);
printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
"(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
if (*p >= 'A' && *p <= 'Z')
*p += ('a' - 'A');
- conn = connectDatabase(dbname, host, port, username, prompt_password,
- progname, false);
+ conn = connectDatabase(dbname, host, port, username, NULL,
+ prompt_password, progname, false);
/*
* Make sure the language isn't already installed
if (login == 0)
login = TRI_YES;
- conn = connectDatabase("postgres", host, port, username, prompt_password,
- progname, false);
+ conn = connectDatabase("postgres", host, port, username, NULL,
+ prompt_password, progname, false);
initPQExpBuffer(&sql);
printQueryOpt popt;
static const bool translate_columns[] = {false, true};
- conn = connectDatabase(dbname, host, port, username, prompt_password,
- progname, false);
+ conn = connectDatabase(dbname, host, port, username, NULL,
+ prompt_password, progname, false);
printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
"(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
if (*p >= 'A' && *p <= 'Z')
*p += ('a' - 'A');
- conn = connectDatabase(dbname, host, port, username, prompt_password,
- progname, false);
+ conn = connectDatabase(dbname, host, port, username, NULL,
+ prompt_password, progname, false);
/*
* Force schema search path to be just pg_catalog, so that we don't have
appendPQExpBuffer(&sql, "DROP ROLE %s%s;",
(if_exists ? "IF EXISTS " : ""), fmtId(dropuser));
- conn = connectDatabase("postgres", host, port, username, prompt_password,
- progname, false);
+ conn = connectDatabase("postgres", host, port, username, NULL,
+ prompt_password, progname, false);
if (echo)
printf("%s\n", sql.data);
appendPQExpBuffer(&sql, " DATABASE %s", fmtId(name));
appendPQExpBufferChar(&sql, ';');
- conn = connectDatabase(dbname, host, port, username, prompt_password,
- progname, false);
+ conn = connectDatabase(dbname, host, port, username, NULL,
+ prompt_password, progname, false);
if (!executeMaintenanceCommand(conn, sql.data, echo))
{
appendPQExpBuffer(&sql, " SYSTEM %s;", dbname);
- conn = connectDatabase(dbname, host, port, username, prompt_password,
- progname, false);
+ conn = connectDatabase(dbname, host, port, username, NULL,
+ prompt_password, progname, false);
if (!executeMaintenanceCommand(conn, sql.data, echo))
{
fprintf(stderr, _("%s: reindexing of system catalogs failed: %s"),
const char *host, const char *port,
const char *username, enum trivalue prompt_password,
int concurrentCons,
- const char *progname, bool echo, bool quiet);
+ const char *progname, bool echo, bool quiet,
+ char **password);
static void vacuum_all_databases(vacuumingOptions *vacopts,
bool analyze_in_stages,
}
else
{
+ char *password = NULL;
+
if (dbname == NULL)
{
if (getenv("PGDATABASE"))
&tables,
host, port, username, prompt_password,
concurrentCons,
- progname, echo, quiet);
+ progname, echo, quiet,
+ &password);
}
}
else
&tables,
host, port, username, prompt_password,
concurrentCons,
- progname, echo, quiet);
+ progname, echo, quiet,
+ &password);
+
+ pg_free(password);
}
exit(0);
* If concurrentCons is > 1, multiple connections are used to vacuum tables
* in parallel. In this case and if the table list is empty, we first obtain
* a list of tables from the database.
+ *
+ * 'password' is both an input and output parameter. If one is not passed,
+ * then whatever is used in a connection is returned so that caller can
+ * reuse it in future connections.
*/
static void
vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
int stage,
SimpleStringList *tables,
const char *host, const char *port,
- const char *username, enum trivalue prompt_password,
+ const char *username,
+ enum trivalue prompt_password,
int concurrentCons,
- const char *progname, bool echo, bool quiet)
+ const char *progname, bool echo, bool quiet,
+ char **password)
{
PQExpBufferData sql;
PGconn *conn;
fflush(stdout);
}
- conn = connectDatabase(dbname, host, port, username, prompt_password,
- progname, false);
+ conn = connectDatabase(dbname, host, port, username, *password,
+ prompt_password, progname, false);
+
+ /*
+ * If no password was not specified by caller and the connection required
+ * one, remember it; this suppresses further password prompts.
+ */
+ if (PQconnectionUsedPassword(conn) && *password == NULL)
+ *password = pg_strdup(PQpass(conn));
initPQExpBuffer(&sql);
init_slot(slots, conn);
if (parallel)
{
+ const char *pqpass;
+
+ /*
+ * If a password was supplied for the initial connection, use it for
+ * subsequent ones too. (Note that since we're connecting to the same
+ * database with the same user, there's no need to update the stored
+ * password any further.)
+ */
+ pqpass = PQpass(conn);
+
for (i = 1; i < concurrentCons; i++)
{
- conn = connectDatabase(dbname, host, port, username, prompt_password,
- progname, false);
+ conn = connectDatabase(dbname, host, port, username, pqpass,
+ prompt_password, progname, false);
init_slot(slots + i, conn);
}
}
PGresult *result;
int stage;
int i;
+ char *password = NULL;
conn = connectMaintenanceDatabase(maintenance_db, host, port,
username, prompt_password, progname);
+
result = executeQuery(conn,
"SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;",
progname, echo);
+
+ /*
+ * Remember the password for further connections. If no password was
+ * required for the maintenance db connection, this gets updated for the
+ * first connection that does.
+ */
+ if (PQconnectionUsedPassword(conn))
+ password = pg_strdup(PQpass(conn));
+
PQfinish(conn);
if (analyze_in_stages)
NULL,
host, port, username, prompt_password,
concurrentCons,
- progname, echo, quiet);
+ progname, echo, quiet,
+ &password);
}
}
}
NULL,
host, port, username, prompt_password,
concurrentCons,
- progname, echo, quiet);
+ progname, echo, quiet,
+ &password);
}
}
PQclear(result);
+ pg_free(password);
}
/*