66 * Portions Copyright (c) 1994, Regents of the University of California
77 *
88 *
9- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.62 2005/06/26 03:03:48 momjian Exp $
9+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.63 2005/07/08 16:51:30 tgl Exp $
1010 *
1111 *-------------------------------------------------------------------------
1212 */
@@ -55,7 +55,7 @@ static void dumpTimestamp(char *msg);
5555
5656static int runPgDump (const char * dbname );
5757static PGconn * connectDatabase (const char * dbname ,const char * pghost ,const char * pgport ,
58- const char * pguser ,bool require_password );
58+ const char * pguser ,bool require_password , bool fail_on_error );
5959static PGresult * executeQuery (PGconn * conn ,const char * query );
6060
6161char pg_dump_bin [MAXPGPATH ];
@@ -296,8 +296,16 @@ main(int argc, char *argv[])
296296exit (1 );
297297}
298298
299-
300- conn = connectDatabase ("postgres" ,pghost ,pgport ,pguser ,force_password );
299+ /*
300+ * First try to connect to database "postgres", and failing that
301+ * "template1". "postgres" is the preferred choice for 8.1 and later
302+ * servers, but it usually will not exist on older ones.
303+ */
304+ conn = connectDatabase ("postgres" ,pghost ,pgport ,pguser ,
305+ force_password , false);
306+ if (!conn )
307+ conn = connectDatabase ("template1" ,pghost ,pgport ,pguser ,
308+ force_password , true);
301309
302310printf ("--\n-- PostgreSQL database cluster dump\n--\n\n" );
303311if (verbose )
@@ -382,6 +390,7 @@ help(void)
382390static void
383391dumpUsers (PGconn * conn ,bool initdbonly )
384392{
393+ PQExpBuffer buf = createPQExpBuffer ();
385394PGresult * res ;
386395int i ;
387396
@@ -407,7 +416,6 @@ dumpUsers(PGconn *conn, bool initdbonly)
407416{
408417const char * username ;
409418bool clusterowner ;
410- PQExpBuffer buf = createPQExpBuffer ();
411419
412420username = PQgetvalue (res ,i ,0 );
413421clusterowner = (strcmp (PQgetvalue (res ,i ,6 ),"t" )== 0 );
@@ -421,12 +429,9 @@ dumpUsers(PGconn *conn, bool initdbonly)
421429 * other users
422430 */
423431if (!clusterowner )
424- appendPQExpBuffer (buf ,"CREATE USER %s WITH SYSID %s" ,
425- fmtId (username ),
426- PQgetvalue (res ,i ,1 ));
432+ printfPQExpBuffer (buf ,"CREATE USER %s WITH" ,fmtId (username ));
427433else
428- appendPQExpBuffer (buf ,"ALTER USER %s WITH" ,
429- fmtId (username ));
434+ printfPQExpBuffer (buf ,"ALTER USER %s WITH" ,fmtId (username ));
430435
431436if (!PQgetisnull (res ,i ,2 ))
432437{
@@ -451,14 +456,16 @@ dumpUsers(PGconn *conn, bool initdbonly)
451456appendPQExpBuffer (buf ,";\n" );
452457
453458printf ("%s" ,buf -> data );
454- destroyPQExpBuffer (buf );
455459
456460if (server_version >=70300 )
457461dumpUserConfig (conn ,username );
458462}
459463
460464PQclear (res );
465+
461466printf ("\n\n" );
467+
468+ destroyPQExpBuffer (buf );
462469}
463470
464471
@@ -472,7 +479,7 @@ dumpGroups(PGconn *conn)
472479PGresult * res ;
473480int i ;
474481
475- res = executeQuery (conn ,"SELECT groname,grosysid, grolist FROM pg_group" );
482+ res = executeQuery (conn ,"SELECT groname, grolist FROM pg_group" );
476483
477484if (PQntuples (res )> 0 || output_clean )
478485printf ("--\n-- Groups\n--\n\n" );
@@ -485,11 +492,10 @@ dumpGroups(PGconn *conn)
485492char * val ;
486493char * tok ;
487494
488- appendPQExpBuffer (buf ,"CREATE GROUP %s WITH SYSID %s;\n" ,
489- fmtId (PQgetvalue (res ,i ,0 )),
490- PQgetvalue (res ,i ,1 ));
495+ appendPQExpBuffer (buf ,"CREATE GROUP %s;\n" ,
496+ fmtId (PQgetvalue (res ,i ,0 )));
491497
492- val = strdup (PQgetvalue (res ,i ,2 ));
498+ val = strdup (PQgetvalue (res ,i ,1 ));
493499tok = strtok (val ,",{}" );
494500while (tok )
495501{
@@ -503,8 +509,10 @@ dumpGroups(PGconn *conn)
503509
504510for (j = 0 ;j < PQntuples (res2 );j ++ )
505511{
506- appendPQExpBuffer (buf ,"ALTER GROUP %s " ,fmtId (PQgetvalue (res ,i ,0 )));
507- appendPQExpBuffer (buf ,"ADD USER %s;\n" ,fmtId (PQgetvalue (res2 ,j ,0 )));
512+ appendPQExpBuffer (buf ,"ALTER GROUP %s " ,
513+ fmtId (PQgetvalue (res ,i ,0 )));
514+ appendPQExpBuffer (buf ,"ADD USER %s;\n" ,
515+ fmtId (PQgetvalue (res2 ,j ,0 )));
508516}
509517
510518PQclear (res2 );
@@ -933,18 +941,21 @@ runPgDump(const char *dbname)
933941/*
934942 * Make a database connection with the given parameters. An
935943 * interactive password prompt is automatically issued if required.
944+ *
945+ * If fail_on_error is false, we return NULL without printing any message
946+ * on failure, but preserve any prompted password for the next try.
936947 */
937948static PGconn *
938949connectDatabase (const char * dbname ,const char * pghost ,const char * pgport ,
939- const char * pguser ,bool require_password )
950+ const char * pguser ,bool require_password , bool fail_on_error )
940951{
941952PGconn * conn ;
942- char * password = NULL ;
943953bool need_pass = false;
944954const char * remoteversion_str ;
945955int my_version ;
956+ static char * password = NULL ;
946957
947- if (require_password )
958+ if (require_password && ! password )
948959password = simple_prompt ("Password: " ,100 , false);
949960
950961/*
@@ -969,21 +980,28 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
969980{
970981PQfinish (conn );
971982need_pass = true;
972- free (password );
983+ if (password )
984+ free (password );
973985password = NULL ;
974986password = simple_prompt ("Password: " ,100 , false);
975987}
976988}while (need_pass );
977989
978- if (password )
979- free (password );
980-
981990/* check to see that the backend connection was successfully made */
982991if (PQstatus (conn )== CONNECTION_BAD )
983992{
984- fprintf (stderr ,_ ("%s: could not connect to database \"%s\": %s\n" ),
985- progname ,dbname ,PQerrorMessage (conn ));
986- exit (1 );
993+ if (fail_on_error )
994+ {
995+ fprintf (stderr ,
996+ _ ("%s: could not connect to database \"%s\": %s\n" ),
997+ progname ,dbname ,PQerrorMessage (conn ));
998+ exit (1 );
999+ }
1000+ else
1001+ {
1002+ PQfinish (conn );
1003+ return NULL ;
1004+ }
9871005}
9881006
9891007remoteversion_str = PQparameterStatus (conn ,"server_version" );