Add -U and -W options to pg_dump and friends to support non-interactive

specification of username (like in psql).  pg_dumpall now works with
password authentication.
This commit is contained in:
Peter Eisentraut 2001-05-17 21:12:49 +00:00
parent 761a0bb69b
commit f000ffd28e
11 changed files with 269 additions and 153 deletions

View File

@ -1,4 +1,4 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/backup.sgml,v 2.7 2001/03/19 16:19:26 petere Exp $ --> <!-- $Header: /cvsroot/pgsql/doc/src/sgml/backup.sgml,v 2.8 2001/05/17 21:12:48 petere Exp $ -->
<chapter id="backup"> <chapter id="backup">
<title>Backup and Restore</title> <title>Backup and Restore</title>
@ -61,11 +61,10 @@ pg_dump <replaceable class="parameter">dbname</replaceable> &gt; <replaceable cl
As any other <productname>Postgres</> client application, As any other <productname>Postgres</> client application,
<application>pg_dump</> will by default connect with the database <application>pg_dump</> will by default connect with the database
user name that is equal to the current Unix user name. To override user name that is equal to the current Unix user name. To override
this, either specify the <option>-u</option> option to force a prompt for this, either specify the <option>-U</option> option or set the
the user name, or set the environment variable environment variable <envar>PGUSER</envar>. Remember that
<envar>PGUSER</envar>. Remember that <application>pg_dump</> <application>pg_dump</> connections are subject to the normal
connections are subject to the normal client authentication client authentication mechanisms (which are described in <xref
mechanisms (which are described in <xref
linkend="client-authentication">). linkend="client-authentication">).
</para> </para>
@ -163,20 +162,6 @@ pg_dumpall &gt; <replaceable>outfile</>
you have database superuser access, as that is required to restore you have database superuser access, as that is required to restore
the user and group information. the user and group information.
</para> </para>
<para>
<application>pg_dumpall</application> has one little flaw: It is
not prepared for interactively authenticating to each database it
dumps. If you are using password authentication then you need to
set it the environment variable <envar>PGPASSWORD</envar> to
communicate the password the the underlying calls to
<application>pg_dump</>. More severely, if you have different
passwords set up for each database, then
<application>pg_dumpall</> will fail. You can either choose a
different authentication mechanism for the purposes of backup or
adjust the <filename>pg_dumpall</filename> shell script to your
needs.
</para>
</sect2> </sect2>
<sect2 id="backup-dump-large"> <sect2 id="backup-dump-large">

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.31 2001/03/17 16:27:31 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.32 2001/05/17 21:12:48 petere Exp $
Postgres documentation Postgres documentation
--> -->
@ -46,7 +46,8 @@ Postgres documentation
<arg>-Z <replaceable>0...9</replaceable></arg> <arg>-Z <replaceable>0...9</replaceable></arg>
<arg>-h <replaceable>host</replaceable></arg> <arg>-h <replaceable>host</replaceable></arg>
<arg>-p <replaceable>port</replaceable></arg> <arg>-p <replaceable>port</replaceable></arg>
<arg>-u</arg> <arg>-U <replaceable>username</replaceable></arg>
<arg>-W</arg>
<arg choice="plain"><replaceable>dbname</replaceable></arg> <arg choice="plain"><replaceable>dbname</replaceable></arg>
</cmdsynopsis> </cmdsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
@ -412,13 +413,20 @@ Postgres documentation
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>-u</term> <term>-U <replaceable>username</replaceable></term>
<listitem> <listitem>
<para> <para>
Use password authentication. Connect as the given user.
Prompts for </para>
<replaceable class="parameter">username</replaceable> </listitem>
and <replaceable class="parameter">password</replaceable>. </varlistentry>
<varlistentry>
<term>-W</term>
<listitem>
<para>
Force a password prompt. This should happen automatically if
the server requires password authentication.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dumpall.sgml,v 1.21 2001/03/05 18:42:57 momjian Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dumpall.sgml,v 1.22 2001/05/17 21:12:48 petere Exp $
Postgres documentation Postgres documentation
--> -->
@ -23,9 +23,11 @@ Postgres documentation
<cmdsynopsis> <cmdsynopsis>
<command>pg_dumpall</command> <command>pg_dumpall</command>
<group><arg>-c</arg><arg>--clean</arg></group> <group><arg>-c</arg><arg>--clean</arg></group>
<group><arg>-g</arg><arg>--globals-only</arg></group>
<arg>-h <replaceable>host</replaceable></arg> <arg>-h <replaceable>host</replaceable></arg>
<arg>-p <replaceable>port</replaceable></arg> <arg>-p <replaceable>port</replaceable></arg>
<group><arg>-g</arg><arg>--globals-only</arg></group> <arg>-U <replaceable>username</replaceable></arg>
<arg>-W</arg>
</cmdsynopsis> </cmdsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
@ -81,6 +83,15 @@ Postgres documentation
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>-g, --globals-only</term>
<listitem>
<para>
Only dump global objects (users and groups), no databases.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term>-h <replaceable>host</replaceable></term> <term>-h <replaceable>host</replaceable></term>
<listitem> <listitem>
@ -106,14 +117,23 @@ Postgres documentation
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>-g, --globals-only</term> <term>-U <replaceable>username</replaceable></term>
<listitem> <listitem>
<para> <para>
Only dump global objects (users and groups), no databases. Connect as the given user.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>-W</term>
<listitem>
<para>
Force a password prompt. This should happen automatically if
the server requires password authentication.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>
@ -128,8 +148,8 @@ Postgres documentation
</refsect2> </refsect2>
</refsect1> </refsect1>
<refsect1 id="app-pg-dumpall-usage"> <refsect1 id="app-pg-dumpall-ex">
<title>Usage</title> <title>Examples</title>
<para> <para>
To dump all databases: To dump all databases:

View File

@ -1,4 +1,4 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_restore.sgml,v 1.10 2001/03/17 16:27:31 petere Exp $ --> <!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_restore.sgml,v 1.11 2001/05/17 21:12:48 petere Exp $ -->
<refentry id="APP-PGRESTORE"> <refentry id="APP-PGRESTORE">
<docinfo> <docinfo>
@ -46,7 +46,8 @@
<arg> -x </arg> <arg> -x </arg>
<arg> -h <replaceable class="parameter">host</replaceable> </arg> <arg> -h <replaceable class="parameter">host</replaceable> </arg>
<arg> -p <replaceable class="parameter">port</replaceable> </arg> <arg> -p <replaceable class="parameter">port</replaceable> </arg>
<arg> -u </arg> <arg> -U <replaceable>username</replaceable> </arg>
<arg> -W </arg>
<arg> <replaceable class="parameter">archive-file</replaceable> </arg> <arg> <replaceable class="parameter">archive-file</replaceable> </arg>
</cmdsynopsis> </cmdsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
@ -448,10 +449,20 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>-u</term> <term>-U <replaceable>username</replaceable></term>
<listitem> <listitem>
<para> <para>
Use password authentication. Prompts for user name and password. Connect as the given user.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-W</term>
<listitem>
<para>
Force a password prompt. This should happen automatically if
the server requires password authentication.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.11 2001/04/25 07:03:19 pjw Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.12 2001/05/17 21:12:48 petere Exp $
* *
* Modifications - 28-Jun-2000 - pjw@rhyme.com.au * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
* *
@ -114,6 +114,7 @@ typedef struct _restoreOptions
char *dbname; char *dbname;
char *pgport; char *pgport;
char *pghost; char *pghost;
char *username;
int ignoreVersion; int ignoreVersion;
int requirePassword; int requirePassword;
@ -130,12 +131,16 @@ typedef struct _restoreOptions
extern void exit_horribly(Archive *AH, const char *fmt,...); extern void exit_horribly(Archive *AH, const char *fmt,...);
extern char *
simple_prompt(const char *prompt, int maxlen, bool echo);
/* Lets the archibe know we have a DB connection to shutdown if it dies */ /* Lets the archibe know we have a DB connection to shutdown if it dies */
PGconn *ConnectDatabase(Archive *AH, PGconn *ConnectDatabase(Archive *AH,
const char *dbname, const char *dbname,
const char *pghost, const char *pghost,
const char *pgport, const char *pgport,
const char *username,
const int reqPwd, const int reqPwd,
const int ignoreVersion); const int ignoreVersion);

View File

@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.26 2001/05/12 01:03:59 pjw Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.27 2001/05/17 21:12:48 petere Exp $
* *
* Modifications - 28-Jun-2000 - pjw@rhyme.com.au * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
* *
@ -180,7 +180,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
AHX->minRemoteVersion = 070100; AHX->minRemoteVersion = 070100;
AHX->maxRemoteVersion = 999999; AHX->maxRemoteVersion = 999999;
ConnectDatabase(AHX, ropt->dbname, ropt->pghost, ropt->pgport, ConnectDatabase(AHX, ropt->dbname, ropt->pghost, ropt->pgport, ropt->username,
ropt->requirePassword, ropt->ignoreVersion); ropt->requirePassword, ropt->ignoreVersion);
/* /*

View File

@ -17,7 +17,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.33 2001/05/12 01:03:59 pjw Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.34 2001/05/17 21:12:48 petere Exp $
* *
* Modifications - 28-Jun-2000 - pjw@rhyme.com.au * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
* - Initial version. * - Initial version.
@ -203,11 +203,12 @@ typedef struct _archiveHandle
CustomOutPtr CustomOutPtr; /* Alternate script output routine */ CustomOutPtr CustomOutPtr; /* Alternate script output routine */
/* Stuff for direct DB connection */ /* Stuff for direct DB connection */
char username[100]; char *username;
char *dbname; /* Name of db for connection */ char *dbname; /* Name of db for connection */
char *archdbname; /* DB name *read* from archive */ char *archdbname; /* DB name *read* from archive */
char *pghost; char *pghost;
char *pgport; char *pgport;
bool requirePassword;
PGconn *connection; PGconn *connection;
PGconn *blobConnection; /* Connection for BLOB xref */ PGconn *blobConnection; /* Connection for BLOB xref */
int txActive; /* Flag set if TX active on connection */ int txActive; /* Flag set if TX active on connection */

View File

@ -5,7 +5,7 @@
* Implements the basic DB functions used by the archiver. * Implements the basic DB functions used by the archiver.
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.18 2001/04/25 07:03:19 pjw Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.19 2001/05/17 21:12:48 petere Exp $
* *
* NOTES * NOTES
* *
@ -40,18 +40,28 @@
static const char *progname = "Archiver(db)"; static const char *progname = "Archiver(db)";
static void _prompt_for_password(char *username, char *password);
static void _check_database_version(ArchiveHandle *AH, bool ignoreVersion); static void _check_database_version(ArchiveHandle *AH, bool ignoreVersion);
static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, char *newUser); static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, char *newUser);
static int _executeSqlCommand(ArchiveHandle *AH, PGconn *conn, PQExpBuffer qry, char *desc); static int _executeSqlCommand(ArchiveHandle *AH, PGconn *conn, PQExpBuffer qry, char *desc);
static void /*
_prompt_for_password(char *username, char *password) * simple_prompt
*
* Generalized function especially intended for reading in usernames and
* password interactively. Reads from stdin.
*
* 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).
*/
char *
simple_prompt(const char *prompt, int maxlen, bool echo)
{ {
char buf[512];
int length; int length;
int buflen; char *destination;
#ifdef HAVE_TERMIOS_H #ifdef HAVE_TERMIOS_H
struct termios t_orig, struct termios t_orig,
@ -59,48 +69,40 @@ _prompt_for_password(char *username, char *password)
#endif #endif
/* destination = (char *) malloc(maxlen + 2);
* Allow for forcing a specific username if (!destination)
*/ return NULL;
if (strlen(username) == 0) if (prompt)
fputs(prompt, stderr);
#ifdef HAVE_TERMIOS_H
if (!echo)
{ {
fprintf(stderr, "Username: "); tcgetattr(0, &t);
fflush(stderr); t_orig = t;
if (fgets(username, 100, stdin) == NULL) t.c_lflag &= ~ECHO;
username[0] = '\0'; tcsetattr(0, TCSADRAIN, &t);
length = strlen(username);
if (length > 0 && username[length - 1] != '\n')
{
/* eat rest of the line */
do
{
if (fgets(buf, sizeof(buf), stdin) == NULL)
break;
buflen = strlen(buf);
} while (buflen > 0 && buf[buflen - 1] != '\n');
}
if (length > 0 && username[length - 1] == '\n')
username[length - 1] = '\0';
} }
#ifdef HAVE_TERMIOS_H
tcgetattr(0, &t);
t_orig = t;
t.c_lflag &= ~ECHO;
tcsetattr(0, TCSADRAIN, &t);
#endif
fprintf(stderr, "Password: ");
fflush(stderr);
if (fgets(password, 100, stdin) == NULL)
password[0] = '\0';
#ifdef HAVE_TERMIOS_H
tcsetattr(0, TCSADRAIN, &t_orig);
#endif #endif
length = strlen(password); if (fgets(destination, maxlen, stdin) == NULL)
if (length > 0 && password[length - 1] != '\n') destination[0] = '\0';
#ifdef HAVE_TERMIOS_H
if (!echo)
{
tcsetattr(0, TCSADRAIN, &t_orig);
fputs("\n", stderr);
}
#endif
length = strlen(destination);
if (length > 0 && destination[length - 1] != '\n')
{ {
/* eat rest of the line */ /* eat rest of the line */
char buf[128];
int buflen;
do do
{ {
if (fgets(buf, sizeof(buf), stdin) == NULL) if (fgets(buf, sizeof(buf), stdin) == NULL)
@ -108,12 +110,14 @@ _prompt_for_password(char *username, char *password)
buflen = strlen(buf); buflen = strlen(buf);
} while (buflen > 0 && buf[buflen - 1] != '\n'); } while (buflen > 0 && buf[buflen - 1] != '\n');
} }
if (length > 0 && password[length - 1] == '\n') if (length > 0 && destination[length - 1] == '\n')
password[length - 1] = '\0'; /* remove trailing newline */
destination[length - 1] = '\0';
fprintf(stderr, "\n\n"); return destination;
} }
static int static int
_parse_version(ArchiveHandle *AH, const char* versionString) _parse_version(ArchiveHandle *AH, const char* versionString)
{ {
@ -244,7 +248,8 @@ ReconnectDatabase(ArchiveHandle *AH, const char *newdbname, char *newUser)
PQfinish(AH->connection); PQfinish(AH->connection);
AH->connection = newConn; AH->connection = newConn;
strcpy(AH->username, newUser); free(AH->username);
AH->username = strdup(newUser);
return 1; return 1;
} }
@ -257,8 +262,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, char *requser)
{ {
int need_pass; int need_pass;
PGconn *newConn; PGconn *newConn;
char password[100]; char *password = NULL;
char *pwparam = NULL;
int badPwd = 0; int badPwd = 0;
int noPwd = 0; int noPwd = 0;
char *newdb; char *newdb;
@ -276,20 +280,28 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, char *requser)
ahlog(AH, 1, "Connecting to %s as %s\n", newdb, newuser); ahlog(AH, 1, "Connecting to %s as %s\n", newdb, newuser);
if (AH->requirePassword)
{
password = simple_prompt("Password: ", 100, false);
if (password == NULL)
die_horribly(AH, "out of memory");
}
do do
{ {
need_pass = false; need_pass = false;
newConn = PQsetdbLogin(PQhost(AH->connection), PQport(AH->connection), newConn = PQsetdbLogin(PQhost(AH->connection), PQport(AH->connection),
NULL, NULL, newdb, NULL, NULL, newdb,
newuser, pwparam); newuser, password);
if (!newConn) if (!newConn)
die_horribly(AH, "%s: Failed to reconnect (PQsetdbLogin failed).\n", progname); die_horribly(AH, "%s: Failed to reconnect (PQsetdbLogin failed).\n", progname);
if (PQstatus(newConn) == CONNECTION_BAD) if (PQstatus(newConn) == CONNECTION_BAD)
{ {
noPwd = (strcmp(PQerrorMessage(newConn), "fe_sendauth: no password supplied\n") == 0); noPwd = (strcmp(PQerrorMessage(newConn),
badPwd = (strncmp(PQerrorMessage(newConn), "Password authentication failed for user", 39) "fe_sendauth: no password supplied\n") == 0);
== 0); badPwd = (strncmp(PQerrorMessage(newConn),
"Password authentication failed for user", 39) == 0);
if (noPwd || badPwd) if (noPwd || badPwd)
{ {
@ -297,34 +309,45 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, char *requser)
if (badPwd) if (badPwd)
fprintf(stderr, "Password incorrect\n"); fprintf(stderr, "Password incorrect\n");
fprintf(stderr, "Connecting to %s as %s\n", PQdb(AH->connection), newuser); fprintf(stderr, "Connecting to %s as %s\n",
PQdb(AH->connection), newuser);
need_pass = true; need_pass = true;
_prompt_for_password(newuser, password); if (password)
pwparam = password; free(password);
password = simple_prompt("Password: ", 100, false);
} }
else else
die_horribly(AH, "%s: Could not reconnect. %s\n", progname, PQerrorMessage(newConn)); die_horribly(AH, "%s: Could not reconnect. %s\n",
progname, PQerrorMessage(newConn));
} }
} while (need_pass); } while (need_pass);
if (password)
free(password);
return newConn; return newConn;
} }
/*
* Make a database connection with the given parameters. The
* connection handle is returned, the parameters are stored in AHX.
* An interactive password prompt is automatically issued if required.
*/
PGconn * PGconn *
ConnectDatabase(Archive *AHX, ConnectDatabase(Archive *AHX,
const char *dbname, const char *dbname,
const char *pghost, const char *pghost,
const char *pgport, const char *pgport,
const char *username,
const int reqPwd, const int reqPwd,
const int ignoreVersion) const int ignoreVersion)
{ {
ArchiveHandle *AH = (ArchiveHandle *) AHX; ArchiveHandle *AH = (ArchiveHandle *) AHX;
char connect_string[512] = ""; char *password = NULL;
char tmp_string[128]; bool need_pass = false;
char password[100];
if (AH->connection) if (AH->connection)
die_horribly(AH, "%s: already connected to database\n", progname); die_horribly(AH, "%s: already connected to database\n", progname);
@ -335,40 +358,58 @@ ConnectDatabase(Archive *AHX,
AH->dbname = strdup(dbname); AH->dbname = strdup(dbname);
if (pghost != NULL) if (pghost != NULL)
{
AH->pghost = strdup(pghost); AH->pghost = strdup(pghost);
sprintf(tmp_string, "host=%s ", AH->pghost);
strcat(connect_string, tmp_string);
}
else else
AH->pghost = NULL; AH->pghost = NULL;
if (pgport != NULL) if (pgport != NULL)
{
AH->pgport = strdup(pgport); AH->pgport = strdup(pgport);
sprintf(tmp_string, "port=%s ", AH->pgport);
strcat(connect_string, tmp_string);
}
else else
AH->pgport = NULL; AH->pgport = NULL;
sprintf(tmp_string, "dbname=%s ", AH->dbname); if (username != NULL)
strcat(connect_string, tmp_string); AH->username = strdup(username);
else
AH->username = NULL;
if (reqPwd) if (reqPwd)
{ {
AH->username[0] = '\0'; password = simple_prompt("Password: ", 100, false);
_prompt_for_password(AH->username, password); if (password == NULL)
strcat(connect_string, "authtype=password "); die_horribly(AH, "out of memory");
sprintf(tmp_string, "user=%s ", AH->username); AH->requirePassword = true;
strcat(connect_string, tmp_string);
sprintf(tmp_string, "password=%s ", password);
strcat(connect_string, tmp_string);
MemSet(tmp_string, 0, sizeof(tmp_string));
MemSet(password, 0, sizeof(password));
} }
AH->connection = PQconnectdb(connect_string); else
MemSet(connect_string, 0, sizeof(connect_string)); AH->requirePassword = false;
/*
* Start the connection. Loop until we have a password if
* requested by backend.
*/
do
{
need_pass = false;
AH->connection = PQsetdbLogin(AH->pghost, AH->pgport, NULL, NULL,
AH->dbname, AH->username, password);
if (!AH->connection)
die_horribly(AH, "%s: Failed to connect (PQsetdbLogin failed).\n",
progname);
if (PQstatus(AH->connection) == CONNECTION_BAD &&
strcmp(PQerrorMessage(AH->connection), "fe_sendauth: no password supplied\n") == 0 &&
!feof(stdin))
{
PQfinish(AH->connection);
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 */ /* check to see that the backend connection was successfully made */
if (PQstatus(AH->connection) == CONNECTION_BAD) if (PQstatus(AH->connection) == CONNECTION_BAD)

View File

@ -22,7 +22,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.207 2001/05/12 23:36:03 tgl Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.208 2001/05/17 21:12:48 petere Exp $
* *
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
* *
@ -267,8 +267,9 @@ help(const char *progname)
" -S, --superuser=NAME specify the superuser user name to use in plain\n" " -S, --superuser=NAME specify the superuser user name to use in plain\n"
" text format\n" " text format\n"
" -t, --table=TABLE dump for this table only (* for all)\n" " -t, --table=TABLE dump for this table only (* for all)\n"
" -u, --password use password authentication\n" " -U, --username=NAME connect as specified database user\n"
" -v, --verbose verbose\n" " -v, --verbose verbose\n"
" -W, --password force password prompt (should happen automatically)\n"
" -x, --no-acl do not dump ACL's (grant/revoke)\n" " -x, --no-acl do not dump ACL's (grant/revoke)\n"
" -Z, --compress {0-9} compression level for compressed formats\n" " -Z, --compress {0-9} compression level for compressed formats\n"
); );
@ -296,8 +297,9 @@ help(const char *progname)
" -S NAME specify the superuser user name to use in plain\n" " -S NAME specify the superuser user name to use in plain\n"
" text format\n" " text format\n"
" -t TABLE dump for this table only (* for all)\n" " -t TABLE dump for this table only (* for all)\n"
" -u use password authentication\n" " -U NAME connect as specified database user\n"
" -v verbose\n" " -v verbose\n"
" -W force password prompt (should happen automatically)\n"
" -x do not dump ACL's (grant/revoke)\n" " -x do not dump ACL's (grant/revoke)\n"
" -Z {0-9} compression level for compressed formats\n" " -Z {0-9} compression level for compressed formats\n"
); );
@ -711,11 +713,12 @@ main(int argc, char **argv)
const char *dbname = NULL; const char *dbname = NULL;
const char *pghost = NULL; const char *pghost = NULL;
const char *pgport = NULL; const char *pgport = NULL;
const char *username = NULL;
char *tablename = NULL; char *tablename = NULL;
bool oids = false; bool oids = false;
TableInfo *tblinfo; TableInfo *tblinfo;
int numTables; int numTables;
bool use_password = false; bool force_password = false;
int compressLevel = -1; int compressLevel = -1;
bool ignore_version = false; bool ignore_version = false;
int plainText = 0; int plainText = 0;
@ -749,7 +752,8 @@ main(int argc, char **argv)
{"schema-only", no_argument, NULL, 's'}, {"schema-only", no_argument, NULL, 's'},
{"superuser", required_argument, NULL, 'S'}, {"superuser", required_argument, NULL, 'S'},
{"table", required_argument, NULL, 't'}, {"table", required_argument, NULL, 't'},
{"password", no_argument, NULL, 'u'}, {"password", no_argument, NULL, 'W'},
{"username", required_argument, NULL, 'U'},
{"verbose", no_argument, NULL, 'v'}, {"verbose", no_argument, NULL, 'v'},
{"no-acl", no_argument, NULL, 'x'}, {"no-acl", no_argument, NULL, 'x'},
{"compress", required_argument, NULL, 'Z'}, {"compress", required_argument, NULL, 'Z'},
@ -796,9 +800,9 @@ main(int argc, char **argv)
} }
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
while ((c = getopt_long(argc, argv, "abcCdDf:F:h:inNoOp:RsS:t:uvxzZ:V?", long_options, &optindex)) != -1) while ((c = getopt_long(argc, argv, "abcCdDf:F:h:inNoOp:RsS:t:uU:vWxzZ:V?", long_options, &optindex)) != -1)
#else #else
while ((c = getopt(argc, argv, "abcCdDf:F:h:inNoOp:RsS:t:uvxzZ:V?-")) != -1) while ((c = getopt(argc, argv, "abcCdDf:F:h:inNoOp:RsS:t:uU:vWxzZ:V?-")) != -1)
#endif #endif
{ {
@ -918,13 +922,22 @@ main(int argc, char **argv)
break; break;
case 'u': case 'u':
use_password = true; force_password = true;
username = simple_prompt("Username: ", 100, true);
break;
case 'U':
username = optarg;
break; break;
case 'v': /* verbose */ case 'v': /* verbose */
g_verbose = true; g_verbose = true;
break; break;
case 'W':
force_password = true;
break;
case 'x': /* skip ACL dump */ case 'x': /* skip ACL dump */
aclsSkip = true; aclsSkip = true;
break; break;
@ -1053,7 +1066,7 @@ main(int argc, char **argv)
*/ */
g_fout->minRemoteVersion = 70000; g_fout->minRemoteVersion = 70000;
g_fout->maxRemoteVersion = 70199; g_fout->maxRemoteVersion = 70199;
g_conn = ConnectDatabase(g_fout, dbname, pghost, pgport, use_password, ignore_version); g_conn = ConnectDatabase(g_fout, dbname, pghost, pgport, username, force_password, ignore_version);
/* /*
* Start serializable transaction to dump consistent data * Start serializable transaction to dump consistent data

View File

@ -6,7 +6,7 @@
# and "pg_group" tables, which belong to the whole installation rather # and "pg_group" tables, which belong to the whole installation rather
# than any one individual database. # than any one individual database.
# #
# $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_dumpall.sh,v 1.11 2001/02/09 17:16:57 momjian Exp $ # $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_dumpall.sh,v 1.12 2001/05/17 21:12:49 petere Exp $
CMDNAME=`basename $0` CMDNAME=`basename $0`
@ -47,12 +47,14 @@ fi
# #
for prog in pg_dump psql ; do for prog in pg_dump psql ; do
if [ ! -x "$PGPATH/$prog" ] ; then if [ ! -x "$PGPATH/$prog" ] ; then
(
echo "The program $prog needed by $CMDNAME could not be found. It was" echo "The program $prog needed by $CMDNAME could not be found. It was"
echo "expected at:" echo "expected at:"
echo " $PGPATH/$prog" echo " $PGPATH/$prog"
echo "If this is not the correct directory, please start $CMDNAME" echo "If this is not the correct directory, please start $CMDNAME"
echo "with a full search path. Otherwise make sure that the program" echo "with a full search path. Otherwise make sure that the program"
echo "was installed successfully." echo "was installed successfully."
) 1>&2
exit 1 exit 1
fi fi
done done
@ -74,11 +76,7 @@ usage=
cleanschema= cleanschema=
globals_only= globals_only=
#
# Scan options. We're interested in the -h (host), -p (port),
# -c (clean), and -g (global) options.
# The rest we pass to pg_dump, which may or may not be useful.
#
while [ $# -gt 0 ] ; do while [ $# -gt 0 ] ; do
case $1 in case $1 in
--help) --help)
@ -107,6 +105,19 @@ while [ $# -gt 0 ] ; do
--port=*) --port=*)
connectopts="$connectopts -p "`echo $1 | sed 's/^--port=//'` connectopts="$connectopts -p "`echo $1 | sed 's/^--port=//'`
;; ;;
--user|--username|-U)
connectopts="$connectopts -U $2"
shift;;
-U*)
connectopts="$connectopts $1"
;;
--user=*|--username=*)
connectopts="$connectopts -U "`echo $1 | sed 's/^--user[^=]*=//'`
;;
-W|--password)
connectopts="$connectopts -W"
;;
-c|--clean) -c|--clean)
cleanschema=yes cleanschema=yes
pgdumpextraopts="$pgdumpextraopts -c" pgdumpextraopts="$pgdumpextraopts -c"
@ -126,14 +137,17 @@ if [ "$usage" ] ; then
echo "$CMDNAME extracts a PostgreSQL database cluster into an SQL script file." echo "$CMDNAME extracts a PostgreSQL database cluster into an SQL script file."
echo echo
echo "Usage:" echo "Usage:"
echo " $CMDNAME [ -c ] [ -h HOSTNAME ] [ -p PORT ] [ -g ]" echo " $CMDNAME [ options... ]"
echo echo
echo "Options:" echo "Options:"
echo " -c, --clean Clean (drop) schema prior to create" echo " -c, --clean Clean (drop) schema prior to create"
echo " -g, --globals-only Only dump global objects, no databases"
echo " -h, --host=HOSTNAME Server host name" echo " -h, --host=HOSTNAME Server host name"
echo " -p, --port=PORT Server port number" echo " -p, --port=PORT Server port number"
echo " -g, --globals-only Only dump global objects, no databases" echo " -U, --username=NAME Connect as specified database user"
echo "Any extra options will be passed to pg_dump." echo " -W, --password Force password prompts (should happen automatically)"
echo "Any extra options will be passed to pg_dump. The dump will be written"
echo "to the standard output."
echo echo
echo "Report bugs to <pgsql-bugs@postgresql.org>." echo "Report bugs to <pgsql-bugs@postgresql.org>."
exit 0 exit 0
@ -155,17 +169,18 @@ echo "${BS}connect template1"
echo "DELETE FROM pg_shadow WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0');" echo "DELETE FROM pg_shadow WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0');"
echo echo
$PSQL -d template1 -At <<__END__ echo "connected to template1..." 1>&2
$PSQL -d template1 -At -c "\
SELECT SELECT
'CREATE USER "' || usename || '" WITH SYSID ' || usesysid 'CREATE USER \"' || usename || '\" WITH SYSID ' || usesysid
|| CASE WHEN passwd IS NOT NULL THEN ' PASSWORD ''' || passwd || '''' else '' end || CASE WHEN passwd IS NOT NULL THEN ' PASSWORD ''' || passwd || '''' else '' end
|| CASE WHEN usecreatedb THEN ' CREATEDB'::text ELSE ' NOCREATEDB' END || CASE WHEN usecreatedb THEN ' CREATEDB'::text ELSE ' NOCREATEDB' END
|| CASE WHEN usesuper THEN ' CREATEUSER'::text ELSE ' NOCREATEUSER' END || CASE WHEN usesuper THEN ' CREATEUSER'::text ELSE ' NOCREATEUSER' END
|| CASE WHEN valuntil IS NOT NULL THEN ' VALID UNTIL '''::text || CASE WHEN valuntil IS NOT NULL THEN ' VALID UNTIL '''::text
|| CAST(valuntil AS TIMESTAMP) || '''' ELSE '' END || ';' || CAST(valuntil AS TIMESTAMP) || '''' ELSE '' END || ';'
FROM pg_shadow FROM pg_shadow
WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0'); WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0');" \
__END__ || exit 1
echo echo
# #
@ -188,12 +203,15 @@ done
test "$globals_only" = yes && exit 0 test "$globals_only" = yes && exit 0
# Save stdin for pg_dump password prompts.
exec 4<&0
# For each database, run pg_dump to dump the contents of that database. # For each database, run pg_dump to dump the contents of that database.
# We skip databases marked not datallowconn, since we'd be unable to # We skip databases marked not datallowconn, since we'd be unable to
# connect to them anyway (and besides, we don't want to dump template0). # connect to them anyway (and besides, we don't want to dump template0).
$PSQL -d template1 -At -F ' ' \ $PSQL -d template1 -At -F ' ' \
-c "SELECT datname, coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), pg_encoding_to_char(d.encoding), datistemplate, datpath FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) WHERE datallowconn;" | \ -c "SELECT datname, coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), pg_encoding_to_char(d.encoding), datistemplate, datpath FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) WHERE datallowconn ORDER BY 1;" | \
while read DATABASE DBOWNER ENCODING ISTEMPLATE DBPATH; do while read DATABASE DBOWNER ENCODING ISTEMPLATE DBPATH; do
echo echo
echo "--" echo "--"
@ -217,7 +235,8 @@ while read DATABASE DBOWNER ENCODING ISTEMPLATE DBPATH; do
fi fi
echo "${BS}connect $DATABASE $DBOWNER" echo "${BS}connect $DATABASE $DBOWNER"
$PGDUMP "$DATABASE" echo "dumping database \"$DATABASE\"..." 1>&2
$PGDUMP "$DATABASE" <&4
if [ "$?" -ne 0 ] ; then if [ "$?" -ne 0 ] ; then
echo "pg_dump failed on $DATABASE, exiting" 1>&2 echo "pg_dump failed on $DATABASE, exiting" 1>&2
exit 1 exit 1

View File

@ -34,7 +34,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.19 2001/03/22 04:00:15 momjian Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.20 2001/05/17 21:12:49 petere Exp $
* *
* Modifications - 28-Jun-2000 - pjw@rhyme.com.au * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
* *
@ -98,13 +98,14 @@ struct option cmdopts[] = {
{"port", 1, NULL, 'p'}, {"port", 1, NULL, 'p'},
{"oid-order", 0, NULL, 'o'}, {"oid-order", 0, NULL, 'o'},
{"orig-order", 0, NULL, 'N'}, {"orig-order", 0, NULL, 'N'},
{"password", 0, NULL, 'u'}, {"password", 0, NULL, 'W'},
{"rearrange", 0, NULL, 'r'}, {"rearrange", 0, NULL, 'r'},
{"schema-only", 0, NULL, 's'}, {"schema-only", 0, NULL, 's'},
{"superuser", 1, NULL, 'S'}, {"superuser", 1, NULL, 'S'},
{"table", 2, NULL, 't'}, {"table", 2, NULL, 't'},
{"trigger", 2, NULL, 'T'}, {"trigger", 2, NULL, 'T'},
{"use-list", 1, NULL, 'L'}, {"use-list", 1, NULL, 'L'},
{"username", 1, NULL, 'U'},
{"verbose", 0, NULL, 'v'}, {"verbose", 0, NULL, 'v'},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
@ -141,9 +142,9 @@ main(int argc, char **argv)
} }
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
while ((c = getopt_long(argc, argv, "acCd:f:F:h:i:lL:NoOp:P:rRsS:t:T:uvx", cmdopts, NULL)) != EOF) while ((c = getopt_long(argc, argv, "acCd:f:F:h:i:lL:NoOp:P:rRsS:t:T:uU:vWx", cmdopts, NULL)) != EOF)
#else #else
while ((c = getopt(argc, argv, "acCd:f:F:h:i:lL:NoOp:P:rRsS:t:T:uvx")) != -1) while ((c = getopt(argc, argv, "acCd:f:F:h:i:lL:NoOp:P:rRsS:t:T:uU:vWx")) != -1)
#endif #endif
{ {
switch (c) switch (c)
@ -236,12 +237,22 @@ main(int argc, char **argv)
break; break;
case 'u': case 'u':
opts->requirePassword = 1; opts->requirePassword = true;
opts->username = simple_prompt("Username: ", 100, true);
break;
case 'U':
opts->username = optarg;
break; break;
case 'v': /* verbose */ case 'v': /* verbose */
opts->verbose = 1; opts->verbose = 1;
break; break;
case 'W':
opts->requirePassword = true;
break;
case 'x': /* skip ACL dump */ case 'x': /* skip ACL dump */
opts->aclsSkip = 1; opts->aclsSkip = 1;
break; break;
@ -354,8 +365,9 @@ usage(const char *progname)
" disabling triggers\n" " disabling triggers\n"
" -t, --table[=TABLE] restore this table only\n" " -t, --table[=TABLE] restore this table only\n"
" -T, --trigger[=NAME] restore triggers or named trigger\n" " -T, --trigger[=NAME] restore triggers or named trigger\n"
" -u, --password use password authentication\n" " -U, --username=NAME connect as specified database user\n"
" -v, --verbose verbose\n" " -v, --verbose verbose\n"
" -W, --password force password prompt (should happen automatically)\n"
" -x, --no-acl skip dumping of ACLs (grant/revoke)\n"); " -x, --no-acl skip dumping of ACLs (grant/revoke)\n");
#else /* not HAVE_GETOPT_LONG */ #else /* not HAVE_GETOPT_LONG */
@ -385,8 +397,9 @@ usage(const char *progname)
" disabling triggers\n" " disabling triggers\n"
" -t NAME restore this table only\n" " -t NAME restore this table only\n"
" -T NAME restore triggers or named trigger\n" " -T NAME restore triggers or named trigger\n"
" -u use password authentication\n" " -U NAME connect as specified database user\n"
" -v verbose\n" " -v verbose\n"
" -W force password prompt (should happen automatically)\n"
" -x skip dumping of ACLs (grant/revoke)\n"); " -x skip dumping of ACLs (grant/revoke)\n");
#endif #endif
puts("If [file] is not supplied, then standard input is used.\n"); puts("If [file] is not supplied, then standard input is used.\n");