2003-03-18 23:19:47 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
2005-08-15 23:02:26 +02:00
|
|
|
* common.c
|
|
|
|
* Common support routines for bin/scripts/
|
|
|
|
*
|
2003-03-18 23:19:47 +01:00
|
|
|
*
|
2006-03-05 16:59:11 +01:00
|
|
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
2003-03-18 23:19:47 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
2006-09-22 21:51:14 +02:00
|
|
|
* $PostgreSQL: pgsql/src/bin/scripts/common.c,v 1.22 2006/09/22 19:51:14 tgl Exp $
|
2003-03-18 23:19:47 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "postgres_fe.h"
|
|
|
|
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2005-08-15 23:02:26 +02:00
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
#ifndef HAVE_INT_OPTRESET
|
2005-10-15 04:49:52 +02:00
|
|
|
int optreset;
|
2005-08-15 23:02:26 +02:00
|
|
|
#endif
|
|
|
|
|
2003-03-18 23:19:47 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Returns the current user name.
|
|
|
|
*/
|
|
|
|
const char *
|
|
|
|
get_user_name(const char *progname)
|
|
|
|
{
|
2003-09-07 05:43:57 +02:00
|
|
|
#ifndef WIN32
|
2003-03-18 23:19:47 +01:00
|
|
|
struct passwd *pw;
|
|
|
|
|
2005-01-08 23:51:15 +01:00
|
|
|
pw = getpwuid(geteuid());
|
2003-03-18 23:19:47 +01:00
|
|
|
if (!pw)
|
|
|
|
{
|
2004-12-12 19:26:29 +01:00
|
|
|
fprintf(stderr, _("%s: could not obtain information about current user: %s\n"),
|
2004-11-09 16:57:57 +01:00
|
|
|
progname, strerror(errno));
|
2003-03-18 23:19:47 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
return pw->pw_name;
|
2003-09-07 05:43:57 +02:00
|
|
|
#else
|
|
|
|
static char username[128]; /* remains after function exit */
|
2004-08-29 07:07:03 +02:00
|
|
|
DWORD len = sizeof(username) - 1;
|
2003-09-07 05:43:57 +02:00
|
|
|
|
2004-04-19 19:42:59 +02:00
|
|
|
if (!GetUserName(username, &len))
|
|
|
|
{
|
2004-12-12 19:26:29 +01:00
|
|
|
fprintf(stderr, _("%s: could not get current user name: %s\n"),
|
2004-11-09 16:57:57 +01:00
|
|
|
progname, strerror(errno));
|
2004-04-19 19:42:59 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
2003-09-07 05:43:57 +02:00
|
|
|
return username;
|
2004-04-19 19:42:59 +02:00
|
|
|
#endif
|
2003-03-18 23:19:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Provide strictly harmonized handling of --help and --version
|
|
|
|
* options.
|
|
|
|
*/
|
|
|
|
void
|
2005-08-15 23:02:26 +02:00
|
|
|
handle_help_version_opts(int argc, char *argv[],
|
|
|
|
const char *fixed_progname, help_handler hlp)
|
2003-03-18 23:19:47 +01:00
|
|
|
{
|
|
|
|
if (argc > 1)
|
|
|
|
{
|
|
|
|
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
|
|
|
|
{
|
|
|
|
hlp(get_progname(argv[0]));
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
|
|
|
|
{
|
|
|
|
printf("%s (PostgreSQL) " PG_VERSION "\n", fixed_progname);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make a database connection with the given parameters. An
|
|
|
|
* interactive password prompt is automatically issued if required.
|
|
|
|
*/
|
|
|
|
PGconn *
|
|
|
|
connectDatabase(const char *dbname, const char *pghost, const char *pgport,
|
2005-08-15 23:02:26 +02:00
|
|
|
const char *pguser, bool require_password,
|
|
|
|
const char *progname)
|
2003-03-18 23:19:47 +01:00
|
|
|
{
|
|
|
|
PGconn *conn;
|
|
|
|
char *password = NULL;
|
|
|
|
bool need_pass = false;
|
|
|
|
|
|
|
|
if (require_password)
|
|
|
|
password = simple_prompt("Password: ", 100, false);
|
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Start the connection. Loop until we have a password if requested by
|
|
|
|
* backend.
|
2003-03-18 23:19:47 +01:00
|
|
|
*/
|
|
|
|
do
|
|
|
|
{
|
|
|
|
need_pass = false;
|
|
|
|
conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
|
|
|
|
|
|
|
|
if (!conn)
|
|
|
|
{
|
|
|
|
fprintf(stderr, _("%s: could not connect to database %s\n"),
|
|
|
|
progname, dbname);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PQstatus(conn) == CONNECTION_BAD &&
|
2004-10-16 05:10:17 +02:00
|
|
|
strcmp(PQerrorMessage(conn), PQnoPasswordSupplied) == 0 &&
|
2003-03-18 23:19:47 +01:00
|
|
|
!feof(stdin))
|
|
|
|
{
|
|
|
|
PQfinish(conn);
|
|
|
|
need_pass = true;
|
|
|
|
free(password);
|
|
|
|
password = NULL;
|
|
|
|
password = simple_prompt("Password: ", 100, false);
|
|
|
|
}
|
|
|
|
} while (need_pass);
|
|
|
|
|
|
|
|
if (password)
|
|
|
|
free(password);
|
|
|
|
|
|
|
|
/* check to see that the backend connection was successfully made */
|
|
|
|
if (PQstatus(conn) == CONNECTION_BAD)
|
|
|
|
{
|
|
|
|
fprintf(stderr, _("%s: could not connect to database %s: %s"),
|
|
|
|
progname, dbname, PQerrorMessage(conn));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return conn;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Run a query, return the results, exit program on failure.
|
|
|
|
*/
|
|
|
|
PGresult *
|
|
|
|
executeQuery(PGconn *conn, const char *query, const char *progname, bool echo)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
|
|
|
|
if (echo)
|
|
|
|
printf("%s\n", query);
|
|
|
|
|
|
|
|
res = PQexec(conn, query);
|
|
|
|
if (!res ||
|
|
|
|
PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
|
|
{
|
2005-08-15 23:02:26 +02:00
|
|
|
fprintf(stderr, _("%s: query failed: %s"),
|
|
|
|
progname, PQerrorMessage(conn));
|
|
|
|
fprintf(stderr, _("%s: query was: %s\n"),
|
|
|
|
progname, query);
|
2003-03-18 23:19:47 +01:00
|
|
|
PQfinish(conn);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
2003-05-27 21:36:55 +02:00
|
|
|
|
|
|
|
|
2005-08-15 23:02:26 +02:00
|
|
|
/*
|
|
|
|
* As above for a SQL command (which returns nothing).
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
executeCommand(PGconn *conn, const char *query,
|
|
|
|
const char *progname, bool echo)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
|
|
|
|
if (echo)
|
|
|
|
printf("%s\n", query);
|
|
|
|
|
|
|
|
res = PQexec(conn, query);
|
|
|
|
if (!res ||
|
|
|
|
PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
|
|
{
|
|
|
|
fprintf(stderr, _("%s: query failed: %s"),
|
|
|
|
progname, PQerrorMessage(conn));
|
|
|
|
fprintf(stderr, _("%s: query was: %s\n"),
|
|
|
|
progname, query);
|
|
|
|
PQfinish(conn);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-05-27 21:36:55 +02:00
|
|
|
/*
|
2003-08-04 02:43:34 +02:00
|
|
|
* Check yes/no answer in a localized way. 1=yes, 0=no, -1=neither.
|
2003-05-27 21:36:55 +02:00
|
|
|
*/
|
|
|
|
|
2006-09-22 20:50:41 +02:00
|
|
|
/* translator: abbreviation for "yes" */
|
2003-05-27 21:36:55 +02:00
|
|
|
#define PG_YESLETTER gettext_noop("y")
|
2006-09-22 20:50:41 +02:00
|
|
|
/* translator: abbreviation for "no" */
|
2003-05-27 21:36:55 +02:00
|
|
|
#define PG_NOLETTER gettext_noop("n")
|
|
|
|
|
2006-09-22 20:50:41 +02:00
|
|
|
bool
|
|
|
|
yesno_prompt(const char *question)
|
2003-05-27 21:36:55 +02:00
|
|
|
{
|
2006-09-22 21:51:14 +02:00
|
|
|
char prompt[256];
|
2006-09-22 20:50:41 +02:00
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
char *resp;
|
|
|
|
|
|
|
|
/* translator: This is a question followed by the translated options for "yes" and "no". */
|
2006-09-22 21:51:14 +02:00
|
|
|
snprintf(prompt, sizeof(prompt), _("%s (%s/%s) "),
|
|
|
|
_(question), _(PG_YESLETTER), _(PG_NOLETTER));
|
2006-09-22 20:50:41 +02:00
|
|
|
resp = simple_prompt(prompt, 1, true);
|
|
|
|
|
|
|
|
if (strcmp(resp, _(PG_YESLETTER)) == 0)
|
|
|
|
return true;
|
|
|
|
else if (strcmp(resp, _(PG_NOLETTER)) == 0)
|
|
|
|
return false;
|
|
|
|
|
2006-09-22 21:51:14 +02:00
|
|
|
printf(_("Please answer \"%s\" or \"%s\".\n"),
|
|
|
|
_(PG_YESLETTER), _(PG_NOLETTER));
|
2006-09-22 20:50:41 +02:00
|
|
|
}
|
2003-05-27 21:36:55 +02:00
|
|
|
}
|