diff --git a/contrib/oid2name/oid2name.c b/contrib/oid2name/oid2name.c index e5eeec21c1..5a2aa1dd0e 100644 --- a/contrib/oid2name/oid2name.c +++ b/contrib/oid2name/oid2name.c @@ -261,7 +261,8 @@ PGconn * sql_conn(struct options * my_opts) { PGconn *conn; - char *password = NULL; + bool have_password = false; + char password[100]; bool new_pass; /* @@ -282,7 +283,7 @@ sql_conn(struct options * my_opts) keywords[2] = "user"; values[2] = my_opts->username; keywords[3] = "password"; - values[3] = password; + values[3] = have_password ? password : NULL; keywords[4] = "dbname"; values[4] = my_opts->dbname; keywords[5] = "fallback_application_name"; @@ -302,17 +303,15 @@ sql_conn(struct options * my_opts) if (PQstatus(conn) == CONNECTION_BAD && PQconnectionNeedsPassword(conn) && - password == NULL) + !have_password) { PQfinish(conn); - password = simple_prompt("Password: ", 100, false); + simple_prompt("Password: ", password, sizeof(password), false); + have_password = true; new_pass = true; } } while (new_pass); - if (password) - free(password); - /* check to see that the backend connection was successfully made */ if (PQstatus(conn) == CONNECTION_BAD) { diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c index 769c805a84..0a9328dc0e 100644 --- a/contrib/vacuumlo/vacuumlo.c +++ b/contrib/vacuumlo/vacuumlo.c @@ -65,13 +65,17 @@ vacuumlo(const char *database, const struct _param * param) long matched; long deleted; int i; - static char *password = NULL; bool new_pass; bool success = true; + static bool have_password = false; + static char password[100]; /* Note: password can be carried over from a previous call */ - if (param->pg_prompt == TRI_YES && password == NULL) - password = simple_prompt("Password: ", 100, false); + if (param->pg_prompt == TRI_YES && !have_password) + { + simple_prompt("Password: ", password, sizeof(password), false); + have_password = true; + } /* * Start the connection. Loop until we have a password if requested by @@ -91,7 +95,7 @@ vacuumlo(const char *database, const struct _param * param) keywords[2] = "user"; values[2] = param->pg_user; keywords[3] = "password"; - values[3] = password; + values[3] = have_password ? password : NULL; keywords[4] = "dbname"; values[4] = database; keywords[5] = "fallback_application_name"; @@ -110,11 +114,12 @@ vacuumlo(const char *database, const struct _param * param) if (PQstatus(conn) == CONNECTION_BAD && PQconnectionNeedsPassword(conn) && - password == NULL && + !have_password && param->pg_prompt != TRI_NO) { PQfinish(conn); - password = simple_prompt("Password: ", 100, false); + simple_prompt("Password: ", password, sizeof(password), false); + have_password = true; new_pass = true; } } while (new_pass); diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 54d338d013..94074928cb 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -1557,8 +1557,8 @@ setup_auth(FILE *cmdfd) static void get_su_pwd(void) { - char *pwd1, - *pwd2; + char pwd1[100]; + char pwd2[100]; if (pwprompt) { @@ -1567,14 +1567,13 @@ get_su_pwd(void) */ printf("\n"); fflush(stdout); - pwd1 = simple_prompt("Enter new superuser password: ", 100, false); - pwd2 = simple_prompt("Enter it again: ", 100, false); + simple_prompt("Enter new superuser password: ", pwd1, sizeof(pwd1), false); + simple_prompt("Enter it again: ", pwd2, sizeof(pwd2), false); if (strcmp(pwd1, pwd2) != 0) { fprintf(stderr, _("Passwords didn't match.\n")); exit_nicely(); } - free(pwd2); } else { @@ -1587,7 +1586,6 @@ get_su_pwd(void) * for now. */ FILE *pwf = fopen(pwfilename, "r"); - char pwdbuf[MAXPGPATH]; int i; if (!pwf) @@ -1596,7 +1594,7 @@ get_su_pwd(void) progname, pwfilename, strerror(errno)); exit_nicely(); } - if (!fgets(pwdbuf, sizeof(pwdbuf), pwf)) + if (!fgets(pwd1, sizeof(pwd1), pwf)) { if (ferror(pwf)) fprintf(stderr, _("%s: could not read password from file \"%s\": %s\n"), @@ -1608,15 +1606,12 @@ get_su_pwd(void) } fclose(pwf); - i = strlen(pwdbuf); - while (i > 0 && (pwdbuf[i - 1] == '\r' || pwdbuf[i - 1] == '\n')) - pwdbuf[--i] = '\0'; - - pwd1 = pg_strdup(pwdbuf); - + i = strlen(pwd1); + while (i > 0 && (pwd1[i - 1] == '\r' || pwd1[i - 1] == '\n')) + pwd1[--i] = '\0'; } - superuser_password = pwd1; + superuser_password = pg_strdup(pwd1); } /* diff --git a/src/bin/pg_basebackup/nls.mk b/src/bin/pg_basebackup/nls.mk index ec466dcaa2..a34ca3d268 100644 --- a/src/bin/pg_basebackup/nls.mk +++ b/src/bin/pg_basebackup/nls.mk @@ -2,3 +2,4 @@ CATALOG_NAME = pg_basebackup AVAIL_LANGUAGES = de es fr it ko pl pt_BR ru zh_CN GETTEXT_FILES = pg_basebackup.c pg_receivexlog.c pg_recvlogical.c receivelog.c streamutil.c ../../common/fe_memutils.c +GETTEXT_TRIGGERS = simple_prompt diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c index 72d8657004..595eaff46a 100644 --- a/src/bin/pg_basebackup/streamutil.c +++ b/src/bin/pg_basebackup/streamutil.c @@ -41,7 +41,8 @@ char *dbport = NULL; char *replication_slot = NULL; char *dbname = NULL; int dbgetpassword = 0; /* 0=auto, -1=never, 1=always */ -static char *dbpassword = NULL; +static bool have_password = false; +static char password[100]; PGconn *conn = NULL; /* @@ -141,24 +142,23 @@ GetConnection(void) } /* If -W was given, force prompt for password, but only the first time */ - need_password = (dbgetpassword == 1 && dbpassword == NULL); + need_password = (dbgetpassword == 1 && !have_password); do { /* Get a new password if appropriate */ if (need_password) { - if (dbpassword) - free(dbpassword); - dbpassword = simple_prompt(_("Password: "), 100, false); + simple_prompt("Password: ", password, sizeof(password), false); + have_password = true; need_password = false; } /* Use (or reuse, on a subsequent connection) password if we have it */ - if (dbpassword) + if (have_password) { keywords[i] = "password"; - values[i] = dbpassword; + values[i] = password; } else { diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c index d2a3de3c5d..3b9cd89b4a 100644 --- a/src/bin/pg_dump/pg_backup_db.c +++ b/src/bin/pg_dump/pg_backup_db.c @@ -134,6 +134,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) const char *newdb; const char *newuser; char *password; + char passbuf[100]; bool new_pass; if (!reqdb) @@ -149,13 +150,12 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) ahlog(AH, 1, "connecting to database \"%s\" as user \"%s\"\n", newdb, newuser); - password = AH->savedPassword ? pg_strdup(AH->savedPassword) : NULL; + password = AH->savedPassword; if (AH->promptPassword == TRI_YES && password == NULL) { - password = simple_prompt("Password: ", 100, false); - if (password == NULL) - exit_horribly(modulename, "out of memory\n"); + simple_prompt("Password: ", passbuf, sizeof(passbuf), false); + password = passbuf; } initPQExpBuffer(&connstr); @@ -201,16 +201,14 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) fprintf(stderr, "Connecting to %s as %s\n", newdb, newuser); - if (password) - free(password); - if (AH->promptPassword != TRI_NO) - password = simple_prompt("Password: ", 100, false); + { + simple_prompt("Password: ", passbuf, sizeof(passbuf), false); + password = passbuf; + } else exit_horribly(modulename, "connection needs password\n"); - if (password == NULL) - exit_horribly(modulename, "out of memory\n"); new_pass = true; } } while (new_pass); @@ -225,8 +223,6 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) free(AH->savedPassword); AH->savedPassword = pg_strdup(PQpass(newConn)); } - if (password) - free(password); termPQExpBuffer(&connstr); @@ -258,18 +254,18 @@ ConnectDatabase(Archive *AHX, { ArchiveHandle *AH = (ArchiveHandle *) AHX; char *password; + char passbuf[100]; bool new_pass; if (AH->connection) exit_horribly(modulename, "already connected to a database\n"); - password = AH->savedPassword ? pg_strdup(AH->savedPassword) : NULL; + password = AH->savedPassword; if (prompt_password == TRI_YES && password == NULL) { - password = simple_prompt("Password: ", 100, false); - if (password == NULL) - exit_horribly(modulename, "out of memory\n"); + simple_prompt("Password: ", passbuf, sizeof(passbuf), false); + password = passbuf; } AH->promptPassword = prompt_password; @@ -309,9 +305,8 @@ ConnectDatabase(Archive *AHX, prompt_password != TRI_NO) { PQfinish(AH->connection); - password = simple_prompt("Password: ", 100, false); - if (password == NULL) - exit_horribly(modulename, "out of memory\n"); + simple_prompt("Password: ", passbuf, sizeof(passbuf), false); + password = passbuf; new_pass = true; } } while (new_pass); @@ -332,8 +327,6 @@ ConnectDatabase(Archive *AHX, free(AH->savedPassword); AH->savedPassword = pg_strdup(PQpass(AH->connection)); } - if (password) - free(password); /* check for version mismatch */ _check_database_version(AH); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 54a9f48200..b5efb46019 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -1884,13 +1884,17 @@ connectDatabase(const char *dbname, const char *connection_string, bool new_pass; const char *remoteversion_str; int my_version; - static char *password = NULL; const char **keywords = NULL; const char **values = NULL; PQconninfoOption *conn_opts = NULL; + static bool have_password = false; + static char password[100]; - if (prompt_password == TRI_YES && !password) - password = simple_prompt("Password: ", 100, false); + if (prompt_password == TRI_YES && !have_password) + { + simple_prompt("Password: ", password, sizeof(password), false); + have_password = true; + } /* * Start the connection. Loop until we have a password if requested by @@ -1970,7 +1974,7 @@ connectDatabase(const char *dbname, const char *connection_string, values[i] = pguser; i++; } - if (password) + if (have_password) { keywords[i] = "password"; values[i] = password; @@ -1998,11 +2002,12 @@ connectDatabase(const char *dbname, const char *connection_string, if (PQstatus(conn) == CONNECTION_BAD && PQconnectionNeedsPassword(conn) && - password == NULL && + !have_password && prompt_password != TRI_NO) { PQfinish(conn); - password = simple_prompt("Password: ", 100, false); + simple_prompt("Password: ", password, sizeof(password), false); + have_password = true; new_pass = true; } } while (new_pass); diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index 8027955121..56c37d537e 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -773,8 +773,9 @@ static PGconn * doConnect(void) { PGconn *conn; - static char *password = NULL; bool new_pass; + static bool have_password = false; + static char password[100]; /* * Start the connection. Loop until we have a password if requested by @@ -794,7 +795,7 @@ doConnect(void) keywords[2] = "user"; values[2] = login; keywords[3] = "password"; - values[3] = password; + values[3] = have_password ? password : NULL; keywords[4] = "dbname"; values[4] = dbName; keywords[5] = "fallback_application_name"; @@ -815,10 +816,11 @@ doConnect(void) if (PQstatus(conn) == CONNECTION_BAD && PQconnectionNeedsPassword(conn) && - password == NULL) + !have_password) { PQfinish(conn); - password = simple_prompt("Password: ", 100, false); + simple_prompt("Password: ", password, sizeof(password), false); + have_password = true; new_pass = true; } } while (new_pass); diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 4aaf657cce..38038d415f 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1089,11 +1089,11 @@ exec_command(const char *cmd, /* \password -- set user password */ else if (strcmp(cmd, "password") == 0) { - char *pw1; - char *pw2; + char pw1[100]; + char pw2[100]; - pw1 = simple_prompt("Enter new password: ", 100, false); - pw2 = simple_prompt("Enter it again: ", 100, false); + simple_prompt("Enter new password: ", pw1, sizeof(pw1), false); + simple_prompt("Enter it again: ", pw2, sizeof(pw2), false); if (strcmp(pw1, pw2) != 0) { @@ -1139,9 +1139,6 @@ exec_command(const char *cmd, if (opt0) free(opt0); } - - free(pw1); - free(pw2); } /* \prompt -- prompt and set variable */ @@ -1173,7 +1170,10 @@ exec_command(const char *cmd, opt = arg1; if (!pset.inputfile) - result = simple_prompt(prompt_text, 4096, true); + { + result = (char *) pg_malloc(4096); + simple_prompt(prompt_text, result, 4096, true); + } else { if (prompt_text) @@ -1747,20 +1747,19 @@ exec_command(const char *cmd, static char * prompt_for_password(const char *username) { - char *result; + char buf[100]; if (username == NULL) - result = simple_prompt("Password: ", 100, false); + simple_prompt("Password: ", buf, sizeof(buf), false); else { char *prompt_text; prompt_text = psprintf(_("Password for user %s: "), username); - result = simple_prompt(prompt_text, 100, false); + simple_prompt(prompt_text, buf, sizeof(buf), false); free(prompt_text); } - - return result; + return pg_strdup(buf); } static bool diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index 111593cd9d..7ce05fbe4a 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -103,7 +103,8 @@ main(int argc, char *argv[]) { struct adhoc_opts options; int successResult; - char *password = NULL; + bool have_password = false; + char password[100]; char *password_prompt = NULL; bool new_pass; @@ -210,7 +211,10 @@ main(int argc, char *argv[]) options.username); if (pset.getPassword == TRI_YES) - password = simple_prompt(password_prompt, 100, false); + { + simple_prompt(password_prompt, password, sizeof(password), false); + have_password = true; + } /* loop until we have a password if requested by backend */ do @@ -226,7 +230,7 @@ main(int argc, char *argv[]) keywords[2] = "user"; values[2] = options.username; keywords[3] = "password"; - values[3] = password; + values[3] = have_password ? password : NULL; keywords[4] = "dbname"; /* see do_connect() */ values[4] = (options.list_dbs && options.dbname == NULL) ? "postgres" : options.dbname; @@ -244,16 +248,16 @@ main(int argc, char *argv[]) if (PQstatus(pset.db) == CONNECTION_BAD && PQconnectionNeedsPassword(pset.db) && - password == NULL && + !have_password && pset.getPassword != TRI_NO) { PQfinish(pset.db); - password = simple_prompt(password_prompt, 100, false); + simple_prompt(password_prompt, password, sizeof(password), false); + have_password = true; new_pass = true; } } while (new_pass); - free(password); free(password_prompt); if (PQstatus(pset.db) == CONNECTION_BAD) diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c index 7c1ebe059f..a71cc64a8c 100644 --- a/src/bin/scripts/common.c +++ b/src/bin/scripts/common.c @@ -68,18 +68,18 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, const char *progname, bool fail_ok, bool allow_password_reuse) { PGconn *conn; - static char *password = NULL; bool new_pass; + static bool have_password = false; + static char password[100]; if (!allow_password_reuse) - { - if (password) - free(password); - password = NULL; - } + have_password = false; - if (password == NULL && prompt_password == TRI_YES) - password = simple_prompt("Password: ", 100, false); + if (!have_password && prompt_password == TRI_YES) + { + simple_prompt("Password: ", password, sizeof(password), false); + have_password = true; + } /* * Start the connection. Loop until we have a password if requested by @@ -97,7 +97,7 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, keywords[2] = "user"; values[2] = pguser; keywords[3] = "password"; - values[3] = password; + values[3] = have_password ? password : NULL; keywords[4] = "dbname"; values[4] = dbname; keywords[5] = "fallback_application_name"; @@ -123,9 +123,8 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport, prompt_password != TRI_NO) { PQfinish(conn); - if (password) - free(password); - password = simple_prompt("Password: ", 100, false); + simple_prompt("Password: ", password, sizeof(password), false); + have_password = true; new_pass = true; } } while (new_pass); @@ -275,22 +274,15 @@ yesno_prompt(const char *question) for (;;) { - char *resp; + char resp[10]; - resp = simple_prompt(prompt, 1, true); + simple_prompt(prompt, resp, sizeof(resp), true); if (strcmp(resp, _(PG_YESLETTER)) == 0) - { - free(resp); return true; - } - else if (strcmp(resp, _(PG_NOLETTER)) == 0) - { - free(resp); + if (strcmp(resp, _(PG_NOLETTER)) == 0) return false; - } - free(resp); printf(_("Please answer \"%s\" or \"%s\".\n"), _(PG_YESLETTER), _(PG_NOLETTER)); } diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c index e88879dc19..f13d9a047a 100644 --- a/src/bin/scripts/createuser.c +++ b/src/bin/scripts/createuser.c @@ -66,6 +66,8 @@ main(int argc, char *argv[]) char *conn_limit = NULL; bool pwprompt = false; char *newpassword = NULL; + char newuser_buf[128]; + char newpassword_buf[100]; /* Tri-valued variables. */ enum trivalue createdb = TRI_DEFAULT, @@ -188,7 +190,11 @@ main(int argc, char *argv[]) if (newuser == NULL) { if (interactive) - newuser = simple_prompt("Enter name of role to add: ", 128, true); + { + simple_prompt("Enter name of role to add: ", + newuser_buf, sizeof(newuser_buf), true); + newuser = newuser_buf; + } else { if (getenv("PGUSER")) @@ -200,18 +206,17 @@ main(int argc, char *argv[]) if (pwprompt) { - char *pw1, - *pw2; + char pw2[100]; - pw1 = simple_prompt("Enter password for new role: ", 100, false); - pw2 = simple_prompt("Enter it again: ", 100, false); - if (strcmp(pw1, pw2) != 0) + simple_prompt("Enter password for new role: ", + newpassword_buf, sizeof(newpassword_buf), false); + simple_prompt("Enter it again: ", pw2, sizeof(pw2), false); + if (strcmp(newpassword_buf, pw2) != 0) { fprintf(stderr, _("Passwords didn't match.\n")); exit(1); } - newpassword = pw1; - free(pw2); + newpassword = newpassword_buf; } if (superuser == 0) diff --git a/src/bin/scripts/dropuser.c b/src/bin/scripts/dropuser.c index 31fa28f7cd..ebcc15209c 100644 --- a/src/bin/scripts/dropuser.c +++ b/src/bin/scripts/dropuser.c @@ -46,6 +46,7 @@ main(int argc, char *argv[]) enum trivalue prompt_password = TRI_DEFAULT; bool echo = false; bool interactive = false; + char dropuser_buf[128]; PQExpBufferData sql; @@ -108,7 +109,11 @@ main(int argc, char *argv[]) if (dropuser == NULL) { if (interactive) - dropuser = simple_prompt("Enter name of role to drop: ", 128, true); + { + simple_prompt("Enter name of role to drop: ", + dropuser_buf, sizeof(dropuser_buf), true); + dropuser = dropuser_buf; + } else { fprintf(stderr, _("%s: missing required argument role name\n"), progname); diff --git a/src/include/port.h b/src/include/port.h index 455f72338c..b81fa4a89e 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -203,7 +203,8 @@ extern char *pgwin32_setlocale(int category, const char *locale); #endif /* WIN32 */ /* Portable prompt handling */ -extern char *simple_prompt(const char *prompt, int maxlen, bool echo); +extern void simple_prompt(const char *prompt, char *destination, size_t destlen, + bool echo); #ifdef WIN32 #define PG_SIGNAL_COUNT 32 diff --git a/src/port/sprompt.c b/src/port/sprompt.c index fd6f16ed30..15ca7a6005 100644 --- a/src/port/sprompt.c +++ b/src/port/sprompt.c @@ -12,33 +12,31 @@ * *------------------------------------------------------------------------- */ - - -/* - * simple_prompt - * - * Generalized function especially intended for reading in usernames and - * password interactively. Reads from /dev/tty or stdin/stderr. - * - * prompt: The prompt to print - * maxlen: How many characters to accept - * echo: Set to false if you want to hide what is entered (for passwords) - * - * Returns a malloc()'ed string with the input (w/o trailing newline). - */ #include "c.h" #ifdef HAVE_TERMIOS_H #include #endif -extern char *simple_prompt(const char *prompt, int maxlen, bool echo); -char * -simple_prompt(const char *prompt, int maxlen, bool echo) +/* + * simple_prompt + * + * Generalized function especially intended for reading in usernames and + * passwords interactively. Reads from /dev/tty or stdin/stderr. + * + * prompt: The prompt to print, or NULL if none (automatically localized) + * destination: buffer in which to store result + * destlen: allocated length of destination + * echo: Set to false if you want to hide what is entered (for passwords) + * + * The input (without trailing newline) is returned in the destination buffer, + * with a '\0' appended. + */ +void +simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo) { int length; - char *destination; FILE *termin, *termout; @@ -48,14 +46,10 @@ simple_prompt(const char *prompt, int maxlen, bool echo) #else #ifdef WIN32 HANDLE t = NULL; - LPDWORD t_orig = NULL; + DWORD t_orig = 0; #endif #endif - destination = (char *) malloc(maxlen + 1); - if (!destination) - return NULL; - #ifdef WIN32 /* @@ -118,11 +112,10 @@ simple_prompt(const char *prompt, int maxlen, bool echo) if (!echo) { /* get a new handle to turn echo off */ - t_orig = (LPDWORD) malloc(sizeof(DWORD)); t = GetStdHandle(STD_INPUT_HANDLE); /* save the old configuration first */ - GetConsoleMode(t, t_orig); + GetConsoleMode(t, &t_orig); /* set to the new mode */ SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); @@ -136,7 +129,7 @@ simple_prompt(const char *prompt, int maxlen, bool echo) fflush(termout); } - if (fgets(destination, maxlen + 1, termin) == NULL) + if (fgets(destination, destlen, termin) == NULL) destination[0] = '\0'; length = strlen(destination); @@ -170,10 +163,9 @@ simple_prompt(const char *prompt, int maxlen, bool echo) if (!echo) { /* reset to the original console mode */ - SetConsoleMode(t, *t_orig); + SetConsoleMode(t, t_orig); fputs("\n", termout); fflush(termout); - free(t_orig); } #endif #endif @@ -183,6 +175,4 @@ simple_prompt(const char *prompt, int maxlen, bool echo) fclose(termin); fclose(termout); } - - return destination; }