On Wed, Sep 25, 2019 at 05:47:39PM -0300, Alvaro Herrera wrote: > This patch has been absolutely overlooked by reviewers. Euler, you're > registered as a reviewer for it. Will you submit a review soon? :-) > > It does not currently apply, so if we get a rebase, that'd be good too.
Here you go. There were four conflicts in total caused by the switch to the central logging infra for vacuumlo/oid2name and the introduction of recovery_gen.c. No actual changes except the rebase. -- Michael
diff --git a/contrib/oid2name/Makefile b/contrib/oid2name/Makefile index 361a80a7a1..c6ba092f47 100644 --- a/contrib/oid2name/Makefile +++ b/contrib/oid2name/Makefile @@ -9,7 +9,7 @@ OBJS = oid2name.o $(WIN32RES) TAP_TESTS = 1 PG_CPPFLAGS = -I$(libpq_srcdir) -PG_LIBS_INTERNAL = $(libpq_pgport) +PG_LIBS_INTERNAL = $(libpq_pgport) -L$(top_builddir)/src/fe_utils -lpgfeutils ifdef USE_PGXS PG_CONFIG = pg_config diff --git a/contrib/oid2name/oid2name.c b/contrib/oid2name/oid2name.c index fa1e7959e7..362f95165d 100644 --- a/contrib/oid2name/oid2name.c +++ b/contrib/oid2name/oid2name.c @@ -47,6 +47,8 @@ struct options const char *progname; }; +const char *progname; + /* function prototypes */ static void help(const char *progname); void get_opts(int, char **, struct options *); @@ -83,7 +85,6 @@ get_opts(int argc, char **argv, struct options *my_opts) }; int c; - const char *progname; int optindex; pg_logging_init(argv[0]); @@ -294,65 +295,20 @@ PGconn * sql_conn(struct options *my_opts) { PGconn *conn; - bool have_password = false; - char password[100]; - bool new_pass; PGresult *res; - /* - * Start the connection. Loop until we have a password if requested by - * backend. - */ - do + /* grab a connection, with password prompting */ + conn = connect_with_password_prompt(my_opts->hostname, + my_opts->port, + my_opts->username, + my_opts->dbname, + my_opts->progname, + NULL, + true); + if (conn == NULL) { -#define PARAMS_ARRAY_SIZE 7 - - const char *keywords[PARAMS_ARRAY_SIZE]; - const char *values[PARAMS_ARRAY_SIZE]; - - keywords[0] = "host"; - values[0] = my_opts->hostname; - keywords[1] = "port"; - values[1] = my_opts->port; - keywords[2] = "user"; - values[2] = my_opts->username; - keywords[3] = "password"; - values[3] = have_password ? password : NULL; - keywords[4] = "dbname"; - values[4] = my_opts->dbname; - keywords[5] = "fallback_application_name"; - values[5] = my_opts->progname; - keywords[6] = NULL; - values[6] = NULL; - - new_pass = false; - conn = PQconnectdbParams(keywords, values, true); - - if (!conn) - { - pg_log_error("could not connect to database %s", - my_opts->dbname); - exit(1); - } - - if (PQstatus(conn) == CONNECTION_BAD && - PQconnectionNeedsPassword(conn) && - !have_password) - { - PQfinish(conn); - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; - new_pass = true; - } - } while (new_pass); - - /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) - { - pg_log_error("could not connect to database %s: %s", - my_opts->dbname, PQerrorMessage(conn)); - PQfinish(conn); - exit(1); + /* an error has been generated */ + exit(-1); } res = PQexec(conn, ALWAYS_SECURE_SEARCH_PATH_SQL); diff --git a/contrib/vacuumlo/Makefile b/contrib/vacuumlo/Makefile index 3efcb46735..2515f61824 100644 --- a/contrib/vacuumlo/Makefile +++ b/contrib/vacuumlo/Makefile @@ -9,7 +9,7 @@ OBJS = vacuumlo.o $(WIN32RES) TAP_TESTS = 1 PG_CPPFLAGS = -I$(libpq_srcdir) -PG_LIBS_INTERNAL = $(libpq_pgport) +PG_LIBS_INTERNAL = $(libpq_pgport) -L$(top_builddir)/src/fe_utils -lpgfeutils ifdef USE_PGXS PG_CONFIG = pg_config diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c index 533e2ce33c..900b58c5f4 100644 --- a/contrib/vacuumlo/vacuumlo.c +++ b/contrib/vacuumlo/vacuumlo.c @@ -50,6 +50,8 @@ struct _param long transaction_limit; }; +const char *progname; + static int vacuumlo(const char *database, const struct _param *param); static void usage(const char *progname); @@ -68,7 +70,6 @@ vacuumlo(const char *database, const struct _param *param) long matched; long deleted; int i; - bool new_pass; bool success = true; static bool have_password = false; static char password[100]; @@ -80,58 +81,17 @@ vacuumlo(const char *database, const struct _param *param) have_password = true; } - /* - * Start the connection. Loop until we have a password if requested by - * backend. - */ - do + /* grab a connection, depending on password prompting */ + conn = connect_with_password_prompt(param->pg_host, + param->pg_port, + param->pg_user, + database, + progname, + password, + param->pg_prompt != TRI_NO); + if (conn == NULL) { -#define PARAMS_ARRAY_SIZE 7 - - const char *keywords[PARAMS_ARRAY_SIZE]; - const char *values[PARAMS_ARRAY_SIZE]; - - keywords[0] = "host"; - values[0] = param->pg_host; - keywords[1] = "port"; - values[1] = param->pg_port; - keywords[2] = "user"; - values[2] = param->pg_user; - keywords[3] = "password"; - values[3] = have_password ? password : NULL; - keywords[4] = "dbname"; - values[4] = database; - keywords[5] = "fallback_application_name"; - values[5] = param->progname; - keywords[6] = NULL; - values[6] = NULL; - - new_pass = false; - conn = PQconnectdbParams(keywords, values, true); - if (!conn) - { - pg_log_error("connection to database \"%s\" failed", database); - return -1; - } - - if (PQstatus(conn) == CONNECTION_BAD && - PQconnectionNeedsPassword(conn) && - !have_password && - param->pg_prompt != TRI_NO) - { - PQfinish(conn); - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; - new_pass = true; - } - } while (new_pass); - - /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) - { - pg_log_error("connection to database \"%s\" failed: %s", - database, PQerrorMessage(conn)); - PQfinish(conn); + /* an error has been generated */ return -1; } @@ -462,7 +422,6 @@ main(int argc, char **argv) struct _param param; int c; int port; - const char *progname; int optindex; pg_logging_init(argv[0]); diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c index ee822c5249..20a849a8d2 100644 --- a/src/bin/pg_dump/pg_backup_db.c +++ b/src/bin/pg_dump/pg_backup_db.c @@ -245,7 +245,6 @@ ConnectDatabase(Archive *AHX, ArchiveHandle *AH = (ArchiveHandle *) AHX; char *password; char passbuf[100]; - bool new_pass; if (AH->connection) fatal("already connected to a database"); @@ -259,53 +258,18 @@ ConnectDatabase(Archive *AHX, } AH->promptPassword = prompt_password; - /* - * Start the connection. Loop until we have a password if requested by - * backend. - */ - do + AH->connection = connect_with_password_prompt(pghost, + pgport, + username, + dbname, + progname, + password, + prompt_password != TRI_NO); + if (AH->connection == NULL) { - const char *keywords[7]; - const char *values[7]; - - keywords[0] = "host"; - values[0] = pghost; - keywords[1] = "port"; - values[1] = pgport; - keywords[2] = "user"; - values[2] = username; - keywords[3] = "password"; - values[3] = password; - keywords[4] = "dbname"; - values[4] = dbname; - keywords[5] = "fallback_application_name"; - values[5] = progname; - keywords[6] = NULL; - values[6] = NULL; - - new_pass = false; - AH->connection = PQconnectdbParams(keywords, values, true); - - if (!AH->connection) - fatal("could not connect to database"); - - if (PQstatus(AH->connection) == CONNECTION_BAD && - PQconnectionNeedsPassword(AH->connection) && - password == NULL && - prompt_password != TRI_NO) - { - PQfinish(AH->connection); - simple_prompt("Password: ", passbuf, sizeof(passbuf), false); - password = passbuf; - new_pass = true; - } - } while (new_pass); - - /* check to see that the backend connection was successfully made */ - if (PQstatus(AH->connection) == CONNECTION_BAD) - fatal("connection to database \"%s\" failed: %s", - PQdb(AH->connection) ? PQdb(AH->connection) : "", - PQerrorMessage(AH->connection)); + /* an error has been generated */ + exit_nicely(1); + } /* Start strict; later phases may override this. */ PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH, diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index 4712e3a958..c932219a56 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -3422,7 +3422,7 @@ foreach my $db (sort keys %create_sql) command_fails_like( [ 'pg_dump', '-p', "$port", 'qqq' ], - qr/\Qpg_dump: error: connection to database "qqq" failed: FATAL: database "qqq" does not exist\E/, + qr/\Qpg_dump: error: could not connect to database "qqq": FATAL: database "qqq" does not exist\E/, 'connecting to a non-existent database'); ######################################### diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index ed7652bfbf..0c5512b240 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -35,6 +35,7 @@ #include "common/int.h" #include "common/logging.h" #include "fe_utils/conditional.h" +#include "fe_utils/connect.h" #include "getopt_long.h" #include "libpq-fe.h" #include "portability/instr_time.h" @@ -1151,67 +1152,15 @@ static PGconn * doConnect(void) { PGconn *conn; - bool new_pass; - static bool have_password = false; - static char password[100]; - - /* - * Start the connection. Loop until we have a password if requested by - * backend. - */ - do - { -#define PARAMS_ARRAY_SIZE 7 - - const char *keywords[PARAMS_ARRAY_SIZE]; - const char *values[PARAMS_ARRAY_SIZE]; - - keywords[0] = "host"; - values[0] = pghost; - keywords[1] = "port"; - values[1] = pgport; - keywords[2] = "user"; - values[2] = login; - keywords[3] = "password"; - values[3] = have_password ? password : NULL; - keywords[4] = "dbname"; - values[4] = dbName; - keywords[5] = "fallback_application_name"; - values[5] = progname; - keywords[6] = NULL; - values[6] = NULL; - - new_pass = false; - - conn = PQconnectdbParams(keywords, values, true); - - if (!conn) - { - fprintf(stderr, "connection to database \"%s\" failed\n", - dbName); - return NULL; - } - - if (PQstatus(conn) == CONNECTION_BAD && - PQconnectionNeedsPassword(conn) && - !have_password) - { - PQfinish(conn); - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; - new_pass = true; - } - } while (new_pass); - - /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) - { - fprintf(stderr, "connection to database \"%s\" failed:\n%s", - dbName, PQerrorMessage(conn)); - PQfinish(conn); - return NULL; - } + /* Connect to database, with optional password prompting */ + conn = connect_with_password_prompt(pghost, + pgport, + login, + dbName, + progname, + NULL, + true); return conn; } diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl index b82d3f65c4..8357903aa3 100644 --- a/src/bin/pgbench/t/001_pgbench_with_server.pl +++ b/src/bin/pgbench/t/001_pgbench_with_server.pl @@ -78,7 +78,7 @@ pgbench( 1, [qr{^$}], [ - qr{connection to database "no-such-database" failed}, + qr{could not connect to database "no-such-database"}, qr{FATAL: database "no-such-database" does not exist} ], 'no such database'); diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c index 1b38a1da49..aed0af740d 100644 --- a/src/bin/scripts/common.c +++ b/src/bin/scripts/common.c @@ -74,7 +74,6 @@ connectDatabase(const char *dbname, const char *pghost, bool echo, bool fail_ok, bool allow_password_reuse) { PGconn *conn; - bool new_pass; static bool have_password = false; static char password[100]; @@ -87,64 +86,19 @@ connectDatabase(const char *dbname, const char *pghost, have_password = true; } - /* - * Start the connection. Loop until we have a password if requested by - * backend. - */ - do - { - const char *keywords[7]; - const char *values[7]; - - keywords[0] = "host"; - values[0] = pghost; - keywords[1] = "port"; - values[1] = pgport; - keywords[2] = "user"; - values[2] = pguser; - keywords[3] = "password"; - values[3] = have_password ? password : NULL; - keywords[4] = "dbname"; - values[4] = dbname; - keywords[5] = "fallback_application_name"; - values[5] = progname; - keywords[6] = NULL; - values[6] = NULL; - - new_pass = false; - conn = PQconnectdbParams(keywords, values, true); - - if (!conn) - { - pg_log_error("could not connect to database %s: out of memory", - dbname); - exit(1); - } - - /* - * No luck? Trying asking (again) for a password. - */ - if (PQstatus(conn) == CONNECTION_BAD && - PQconnectionNeedsPassword(conn) && - prompt_password != TRI_NO) - { - PQfinish(conn); - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; - new_pass = true; - } - } while (new_pass); - - /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) + /* grab a connection, with password prompting */ + conn = connect_with_password_prompt(pghost, + pgport, + pguser, + dbname, + progname, + password, + prompt_password != TRI_NO); + if (conn == NULL) { + /* an error has been generated */ if (fail_ok) - { - PQfinish(conn); return NULL; - } - pg_log_error("could not connect to database %s: %s", - dbname, PQerrorMessage(conn)); exit(1); } diff --git a/src/fe_utils/Makefile b/src/fe_utils/Makefile index f2e516a2aa..59c028b400 100644 --- a/src/fe_utils/Makefile +++ b/src/fe_utils/Makefile @@ -19,7 +19,7 @@ include $(top_builddir)/src/Makefile.global override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS) -OBJS = conditional.o mbprint.o print.o psqlscan.o recovery_gen.o \ +OBJS = conditional.o connect.o mbprint.o print.o psqlscan.o recovery_gen.o \ simple_list.o string_utils.o all: libpgfeutils.a diff --git a/src/fe_utils/connect.c b/src/fe_utils/connect.c new file mode 100644 index 0000000000..cae69f1f9a --- /dev/null +++ b/src/fe_utils/connect.c @@ -0,0 +1,112 @@ +/*------------------------------------------------------------------------- + * + * Utility functions to connect to a backend. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/fe_utils/connect.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres_fe.h" + +#include "common/logging.h" +#include "fe_utils/connect.h" + +#include "libpq-fe.h" + +/* + * connect_with_password_prompt + * + * Connect to a PostgreSQL backend with the given set of connection + * parameters, optionally asking for password prompting. + * + * The caller can optionally pass a password with "saved_password" + * which will be used at the first connection attempt. + * + * The result is the connection to the backend. On error, the result + * is NULL and an error is logged. + */ +PGconn * +connect_with_password_prompt(const char *hostname, + const char *port, + const char *username, + const char *dbname, + const char *progname, + char *saved_password, + bool enable_prompt) +{ + PGconn *conn; + bool new_pass; + static bool have_password = false; + static char password[100]; + + if (saved_password != NULL) + { + /* XXX: need to be more careful with overflows here */ + memcpy(password, saved_password, strlen(saved_password) + 1); + have_password = true; + } + + /* + * Start the connection. Loop until we have a password if requested by + * backend. + */ + do + { +#define PARAMS_ARRAY_SIZE 7 + + const char *keywords[PARAMS_ARRAY_SIZE]; + const char *values[PARAMS_ARRAY_SIZE]; + + keywords[0] = "host"; + values[0] = hostname; + keywords[1] = "port"; + values[1] = port; + keywords[2] = "user"; + values[2] = username; + keywords[3] = "password"; + values[3] = have_password ? password : NULL; + keywords[4] = "dbname"; + values[4] = dbname; + keywords[5] = "fallback_application_name"; + values[5] = progname; + keywords[6] = NULL; + values[6] = NULL; + + new_pass = false; + conn = PQconnectdbParams(keywords, values, true); + + if (!conn) + { + pg_log_error("could not connect to database \"%s\"", + dbname); + return NULL; + } + + if (PQstatus(conn) == CONNECTION_BAD && + PQconnectionNeedsPassword(conn) && + !have_password && + enable_prompt) + { + PQfinish(conn); + simple_prompt("Password: ", password, sizeof(password), false); + have_password = true; + new_pass = true; + } + } while (new_pass); + + /* check to see that the backend connection was successfully made */ + if (PQstatus(conn) == CONNECTION_BAD) + { + pg_log_error("could not connect to database \"%s\": %s", + dbname, PQerrorMessage(conn)); + PQfinish(conn); + return NULL; + } + + return conn; +} diff --git a/src/include/fe_utils/connect.h b/src/include/fe_utils/connect.h index c1c8c04ab0..fef5d1a1b6 100644 --- a/src/include/fe_utils/connect.h +++ b/src/include/fe_utils/connect.h @@ -13,6 +13,8 @@ #ifndef CONNECT_H #define CONNECT_H +#include "libpq-fe.h" + /* * This SQL statement installs an always-secure search path, so malicious * users can't take control. CREATE of an unqualified name will fail, because @@ -25,4 +27,12 @@ #define ALWAYS_SECURE_SEARCH_PATH_SQL \ "SELECT pg_catalog.set_config('search_path', '', false);" +extern PGconn * connect_with_password_prompt(const char *hostname, + const char *port, + const char *username, + const char *dbname, + const char *progname, + char *saved_password, + bool enable_prompt); + #endif /* CONNECT_H */ diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm index 7a103e6140..367bdeeb26 100644 --- a/src/tools/msvc/Mkvcbuild.pm +++ b/src/tools/msvc/Mkvcbuild.pm @@ -142,7 +142,7 @@ sub mkvcbuild our @pgcommonbkndfiles = @pgcommonallfiles; our @pgfeutilsfiles = qw( - conditional.c mbprint.c print.c psqlscan.l psqlscan.c + conditional.c connect.c mbprint.c print.c psqlscan.l psqlscan.c simple_list.c string_utils.c recovery_gen.c); $libpgport = $solution->AddProject('libpgport', 'lib', 'misc');
signature.asc
Description: PGP signature