Hi,

I  tried to use pg_dumpall in Win32 and receive a error message like this:

pg_dump.exe: [archiver (db)] connection to database "test" failed:
FATAL:  user "'postgres'" does not exist

Well, the word "'postgres'" is  the word is between simple quotations
marks and later between double quotations marks.
Then, I assume that the error must be in string that pg_dumpall mounts
to execute pg_dump

I modified pg_dumpall.c lines between  160 and 270  to add a #ifndef
WIN32... #endif clause to pgdumpopts to store
the parameters with double quotations intead simple quotation marks in
case of WIN32 ports
But, I don't have how to test it.
Please, somebody can test and fix the pg_dumpall.c of oficial source ?

Thanks in advance

Luiz


/*-------------------------------------------------------------------------
 *
 * pg_dumpall
 *
 * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * $PostgreSQL: pgsql-server/src/bin/pg_dump/pg_dumpall.c,v 1.51 2004/08/29 05:06:53 
momjian Exp $
 *
 *-------------------------------------------------------------------------
 */

#include "postgres_fe.h"

#include <unistd.h>
#ifdef ENABLE_NLS
#include <locale.h>
#endif
#ifndef HAVE_STRDUP
#include "strdup.h"
#endif
#include <errno.h>
#include <time.h>

#include "getopt_long.h"

#ifndef HAVE_OPTRESET
int                     optreset;
#endif

#include "dumputils.h"
#include "libpq-fe.h"
#include "pg_backup.h"
#include "pqexpbuffer.h"

#define _(x) gettext((x))

/* version string we expect back from postgres */
#define PG_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"


static const char *progname;

static void help(void);

static void dumpUsers(PGconn *conn, bool initdbonly);
static void dumpGroups(PGconn *conn);
static void dumpTablespaces(PGconn *conn);
static void dumpCreateDB(PGconn *conn);
static void dumpDatabaseConfig(PGconn *conn, const char *dbname);
static void dumpUserConfig(PGconn *conn, const char *username);
static void makeAlterConfigCommand(const char *arrayitem, const char *type, const char 
*name);
static void dumpDatabases(PGconn *conn);
static void dumpTimestamp(char *msg);

static int      runPgDump(const char *dbname);
static PGconn *connectDatabase(const char *dbname, const char *pghost, const char 
*pgport,
                                const char *pguser, bool require_password);
static PGresult *executeQuery(PGconn *conn, const char *query);

char            pg_dump_bin[MAXPGPATH];
PQExpBuffer pgdumpopts;
bool            output_clean = false;
bool            skip_acls = false;
bool            verbose = false;
int                     server_version;

/* flags for -X long options */
int                     disable_dollar_quoting = 0;
int                     disable_triggers = 0;
int                     use_setsessauth = 0;

int
main(int argc, char *argv[])
{
        char       *pghost = NULL;
        char       *pgport = NULL;
        char       *pguser = NULL;
        bool            force_password = false;
        bool            data_only = false;
        bool            globals_only = false;
        bool            schema_only = false;
        PGconn     *conn;
        int                     c,
                                ret;

        static struct option long_options[] = {
                {"data-only", no_argument, NULL, 'a'},
                {"clean", no_argument, NULL, 'c'},
                {"inserts", no_argument, NULL, 'd'},
                {"attribute-inserts", no_argument, NULL, 'D'},
                {"column-inserts", no_argument, NULL, 'D'},
                {"globals-only", no_argument, NULL, 'g'},
                {"host", required_argument, NULL, 'h'},
                {"ignore-version", no_argument, NULL, 'i'},
                {"oids", no_argument, NULL, 'o'},
                {"no-owner", no_argument, NULL, 'O'},
                {"port", required_argument, NULL, 'p'},
                {"password", no_argument, NULL, 'W'},
                {"schema-only", no_argument, NULL, 's'},
                {"superuser", required_argument, NULL, 'S'},
                {"username", required_argument, NULL, 'U'},
                {"verbose", no_argument, NULL, 'v'},
                {"no-privileges", no_argument, NULL, 'x'},
                {"no-acl", no_argument, NULL, 'x'},

                /*
                 * the following options don't have an equivalent short option
                 * letter, but are available as '-X long-name'
                 */
                {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
                {"disable-triggers", no_argument, &disable_triggers, 1},
                {"use-set-session-authorization", no_argument, &use_setsessauth, 1},

                {NULL, 0, NULL, 0}
        };

        int                     optindex;

        set_pglocale_pgservice(argv[0], "pg_dump");

        progname = get_progname(argv[0]);

        if (argc > 1)
        {
                if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
                {
                        help();
                        exit(0);
                }
                if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
                {
                        puts("pg_dumpall (PostgreSQL) " PG_VERSION);
                        exit(0);
                }
        }

        if ((ret = find_other_exec(argv[0], "pg_dump", PG_VERSIONSTR,
                                                           pg_dump_bin)) < 0)
        {
                if (ret == -1)
                        fprintf(stderr,
                                        _("The program \"pg_dump\" is needed by %s "
                                   "but was not found in the same directory as 
\"%s\".\n"
                                          "Check your installation.\n"),
                                        progname, progname);
                else
                        fprintf(stderr,
                                        _("The program \"pg_dump\" was found by %s "
                                          "but was not the same version as \"%s\".\n"
                                          "Check your installation.\n"),
                                        progname, progname);
                exit(1);
        }

        pgdumpopts = createPQExpBuffer();

        while ((c = getopt_long(argc, argv, "acdDgh:ioOp:sS:U:vWxX:", long_options, 
&optindex)) != -1)
        {
                switch (c)
                {
                        case 'a':
                                data_only = true;
                                appendPQExpBuffer(pgdumpopts, " -a");
                                break;

                        case 'c':
                                output_clean = true;
                                break;

                        case 'd':
                        case 'D':
                                appendPQExpBuffer(pgdumpopts, " -%c", c);
                                break;

                        case 'g':
                                globals_only = true;
                                break;

                        case 'h':
                                pghost = optarg;
#ifndef WIN32
                                appendPQExpBuffer(pgdumpopts, " -h '%s'", pghost);
#else
                                appendPQExpBuffer(pgdumpopts, " -h \"%s\"", pghost);
#endif

                                break;



                        case 'i':
                        case 'o':
                                appendPQExpBuffer(pgdumpopts, " -%c", c);
                                break;

                        case 'O':
                                appendPQExpBuffer(pgdumpopts, " -O");
                                break;

                        case 'p':
                                pgport = optarg;
#ifndef WIN32
                                appendPQExpBuffer(pgdumpopts, " -p '%s'", pgport);
#else
                                appendPQExpBuffer(pgdumpopts, " -p \"%s\"", pgport);
#endif
                                break;

                        case 's':
                                schema_only = true;
                                appendPQExpBuffer(pgdumpopts, " -s");
                                break;

                        case 'S':
#ifndef WIN32
                                appendPQExpBuffer(pgdumpopts, " -S '%s'", optarg);
#else
                                appendPQExpBuffer(pgdumpopts, " -S \"%s\"", optarg);
#endif
                                break;

                        case 'U':
                                pguser = optarg;
#ifndef WIN32
                                appendPQExpBuffer(pgdumpopts, " -U '%s'", pguser);
#else
                                appendPQExpBuffer(pgdumpopts, " -U \"%s\"", pguser);
#endif
                                break;

                        case 'v':
                                verbose = true;
                                appendPQExpBuffer(pgdumpopts, " -v");
                                break;

                        case 'W':
                                force_password = true;
                                appendPQExpBuffer(pgdumpopts, " -W");
                                break;

                        case 'x':
                                skip_acls = true;
                                appendPQExpBuffer(pgdumpopts, " -x");
                                break;

                        case 'X':
                                if (strcmp(optarg, "disable-dollar-quoting") == 0)
                                        appendPQExpBuffer(pgdumpopts, " -X 
disable-dollar-quoting");
                                else if (strcmp(optarg, "disable-triggers") == 0)
                                        appendPQExpBuffer(pgdumpopts, " -X 
disable-triggers");
                                else if (strcmp(optarg, 
"use-set-session-authorization") == 0)
                                         /* no-op, still allowed for compatibility */ ;
                                else
                                {
                                        fprintf(stderr,
                                                        _("%s: invalid -X option -- 
%s\n"),
                                                        progname, optarg);
                                        fprintf(stderr, _("Try \"%s --help\" for more 
information.\n"), progname);
                                        exit(1);
                                }
                                break;

                        case 0:
                                break;

                        default:
                                fprintf(stderr, _("Try \"%s --help\" for more 
information.\n"), progname);
                                exit(1);
                }
        }

        /* Add long options to the pg_dump argument list */
        if (disable_dollar_quoting)
                appendPQExpBuffer(pgdumpopts, " -X disable-dollar-quoting");
        if (disable_triggers)
                appendPQExpBuffer(pgdumpopts, " -X disable-triggers");
        if (use_setsessauth)
                appendPQExpBuffer(pgdumpopts, " -X use-set-session-authorization");

        if (optind < argc)
        {
                fprintf(stderr, _("%s: too many command-line arguments (first is 
\"%s\")\n"),
                                progname, argv[optind]);
                fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                                progname);
                exit(1);
        }


        conn = connectDatabase("template1", pghost, pgport, pguser, force_password);

        printf("--\n-- PostgreSQL database cluster dump\n--\n\n");
        if (verbose)
                dumpTimestamp("Started on");

        printf("\\connect \"template1\"\n\n");

        if (!data_only)
        {
                /* Dump all users excluding the initdb user */
                dumpUsers(conn, false);
                dumpGroups(conn);
                if (server_version >= 80000)
                        dumpTablespaces(conn);
                if (!globals_only)
                        dumpCreateDB(conn);
                /* Dump alter command for initdb user */
                dumpUsers(conn, true);
        }

        if (!globals_only)
                dumpDatabases(conn);

        PQfinish(conn);

        if (verbose)
                dumpTimestamp("Completed on");
        printf("--\n-- PostgreSQL database cluster dump complete\n--\n\n");

        exit(0);
}



static void
help(void)
{
        printf(_("%s extracts a PostgreSQL database cluster into an SQL script 
file.\n\n"), progname);
        printf(_("Usage:\n"));
        printf(_("  %s [OPTION]...\n"), progname);

        printf(_("\nGeneral options:\n"));
        printf(_("  -i, --ignore-version     proceed even when server version 
mismatches\n"
                         "                           pg_dumpall version\n"));
        printf(_("  --help                   show this help, then exit\n"));
        printf(_("  --version                output version information, then 
exit\n"));
        printf(_("\nOptions controlling the output content:\n"));
        printf(_("  -a, --data-only          dump only the data, not the schema\n"));
        printf(_("  -c, --clean              clean (drop) databases prior to 
create\n"));
        printf(_("  -d, --inserts            dump data as INSERT, rather than COPY, 
commands\n"));
        printf(_("  -D, --column-inserts     dump data as INSERT commands with column 
names\n"));
        printf(_("  -g, --globals-only       dump only global objects, no 
databases\n"));
        printf(_("  -o, --oids               include OIDs in dump\n"));
        printf(_("  -O, --no-owner           do not output commands to set object 
ownership\n"));
        printf(_("  -s, --schema-only        dump only the schema, no data\n"));
        printf(_("  -S, --superuser=NAME     specify the superuser user name to use in 
the dump\n"));
        printf(_("  -x, --no-privileges      do not dump privileges 
(grant/revoke)\n"));
        printf(_("  -X disable-dollar-quoting, --disable-dollar-quoting\n"
                         "                           disable dollar quoting, use SQL 
standard quoting\n"));
        printf(_("  -X disable-triggers, --disable-triggers\n"
                         "                           disable triggers during data-only 
restore\n"));
        printf(_("  -X use-set-session-authorization, 
--use-set-session-authorization\n"
                         "                           use SESSION AUTHORIZATION 
commands instead of\n"
                         "                           OWNER TO commands\n"));

        printf(_("\nConnection options:\n"));
        printf(_("  -h, --host=HOSTNAME      database server host or socket 
directory\n"));
        printf(_("  -p, --port=PORT          database server port number\n"));
        printf(_("  -U, --username=NAME      connect as specified database user\n"));
        printf(_("  -W, --password           force password prompt (should happen 
automatically)\n"));

        printf(_("\nThe SQL script will be written to the standard output.\n\n"));
        printf(_("Report bugs to <[EMAIL PROTECTED]>.\n"));
}



/*
 * Dump users
 * Is able to dump all non initdb users or just the initdb user.
 */
static void
dumpUsers(PGconn *conn, bool initdbonly)
{
        PGresult   *res;
        int                     i;

        if (server_version >= 70100)
                res = executeQuery(conn,
                                                "SELECT usename, usesysid, passwd, 
usecreatedb, "
                                                   "usesuper, valuntil, "
                                                   "(usesysid = (SELECT datdba FROM 
pg_database WHERE datname = 'template0')) AS clusterowner "
                                                   "FROM pg_shadow");
        else
                res = executeQuery(conn,
                                                "SELECT usename, usesysid, passwd, 
usecreatedb, "
                                                   "usesuper, valuntil, "
                                                   "(usesysid = (SELECT datdba FROM 
pg_database WHERE datname = 'template1')) AS clusterowner "
                                                   "FROM pg_shadow");

        if (PQntuples(res) > 0 || (!initdbonly && output_clean))
                printf("--\n-- Users\n--\n\n");
        if (!initdbonly && output_clean)
                printf("DELETE FROM pg_shadow WHERE usesysid <> (SELECT datdba FROM 
pg_database WHERE datname = 'template0');\n\n");

        for (i = 0; i < PQntuples(res); i++)
        {
                const char *username;
                bool            clusterowner;
                PQExpBuffer buf = createPQExpBuffer();

                username = PQgetvalue(res, i, 0);
                clusterowner = (strcmp(PQgetvalue(res, i, 6), "t") == 0);

                /* Check which pass we're on */
                if ((initdbonly && !clusterowner) || (!initdbonly && clusterowner))
                        continue;

                /*
                 * Dump ALTER USER for the cluster owner and CREATE USER for all
                 * other users
                 */
                if (!clusterowner)
                        appendPQExpBuffer(buf, "CREATE USER %s WITH SYSID %s",
                                                          fmtId(username),
                                                          PQgetvalue(res, i, 1));
                else
                        appendPQExpBuffer(buf, "ALTER USER %s WITH",
                                                          fmtId(username));

                if (!PQgetisnull(res, i, 2))
                {
                        appendPQExpBuffer(buf, " PASSWORD ");
                        appendStringLiteral(buf, PQgetvalue(res, i, 2), true);
                }

                if (strcmp(PQgetvalue(res, i, 3), "t") == 0)
                        appendPQExpBuffer(buf, " CREATEDB");
                else
                        appendPQExpBuffer(buf, " NOCREATEDB");

                if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
                        appendPQExpBuffer(buf, " CREATEUSER");
                else
                        appendPQExpBuffer(buf, " NOCREATEUSER");

                if (!PQgetisnull(res, i, 5))
                        appendPQExpBuffer(buf, " VALID UNTIL '%s'",
                                                          PQgetvalue(res, i, 5));

                appendPQExpBuffer(buf, ";\n");

                printf("%s", buf->data);
                destroyPQExpBuffer(buf);

                if (server_version >= 70300)
                        dumpUserConfig(conn, username);
        }

        PQclear(res);
        printf("\n\n");
}



/*
 * Dump groups.
 */
static void
dumpGroups(PGconn *conn)
{
        PGresult   *res;
        int                     i;

        res = executeQuery(conn, "SELECT groname, grosysid, grolist FROM pg_group");

        if (PQntuples(res) > 0 || output_clean)
                printf("--\n-- Groups\n--\n\n");
        if (output_clean)
                printf("DELETE FROM pg_group;\n\n");

        for (i = 0; i < PQntuples(res); i++)
        {
                PQExpBuffer buf = createPQExpBuffer();
                char       *val;
                char       *tok;

                appendPQExpBuffer(buf, "CREATE GROUP %s WITH SYSID %s;\n",
                                                  fmtId(PQgetvalue(res, i, 0)),
                                                  PQgetvalue(res, i, 1));

                val = strdup(PQgetvalue(res, i, 2));
                tok = strtok(val, ",{}");
                while (tok)
                {
                        PGresult   *res2;
                        PQExpBuffer buf2 = createPQExpBuffer();
                        int                     j;

                        appendPQExpBuffer(buf2, "SELECT usename FROM pg_shadow WHERE 
usesysid = %s;", tok);
                        res2 = executeQuery(conn, buf2->data);
                        destroyPQExpBuffer(buf2);

                        for (j = 0; j < PQntuples(res2); j++)
                        {
                                appendPQExpBuffer(buf, "ALTER GROUP %s ", 
fmtId(PQgetvalue(res, i, 0)));
                                appendPQExpBuffer(buf, "ADD USER %s;\n", 
fmtId(PQgetvalue(res2, j, 0)));
                        }

                        PQclear(res2);

                        tok = strtok(NULL, "{},");
                }
                free(val);

                printf("%s", buf->data);
                destroyPQExpBuffer(buf);
        }

        PQclear(res);
        printf("\n\n");
}

/*
 * Dump tablespaces.
 */
static void
dumpTablespaces(PGconn *conn)
{
        PGresult   *res;
        int                     i;

        /*
         * Get all tablespaces except built-in ones (which we assume are named
         * pg_xxx)
         */
        res = executeQuery(conn, "SELECT spcname, "
                                         "pg_catalog.pg_get_userbyid(spcowner) AS 
spcowner, "
                                           "spclocation, spcacl "
                                           "FROM pg_catalog.pg_tablespace "
                                           "WHERE spcname NOT LIKE 'pg\\_%'");

        if (PQntuples(res) > 0)
                printf("--\n-- Tablespaces\n--\n\n");

        for (i = 0; i < PQntuples(res); i++)
        {
                PQExpBuffer buf = createPQExpBuffer();
                char       *spcname = PQgetvalue(res, i, 0);
                char       *spcowner = PQgetvalue(res, i, 1);
                char       *spclocation = PQgetvalue(res, i, 2);
                char       *spcacl = PQgetvalue(res, i, 3);
                char       *fspcname;

                /* needed for buildACLCommands() */
                fspcname = strdup(fmtId(spcname));

                if (output_clean)
                        appendPQExpBuffer(buf, "DROP TABLESPACE %s;\n", fspcname);

                appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname);
                appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));

                appendPQExpBuffer(buf, " LOCATION ");
                appendStringLiteral(buf, spclocation, true);
                appendPQExpBuffer(buf, ";\n");

                if (!skip_acls &&
                        !buildACLCommands(fspcname, "TABLESPACE", spcacl, spcowner,
                                                          server_version, buf))
                {
                        fprintf(stderr, _("%s: could not parse ACL list (%s) for 
tablespace \"%s\"\n"),
                                        progname, spcacl, fspcname);
                        PQfinish(conn);
                        exit(1);
                }

                printf("%s", buf->data);

                free(fspcname);
                destroyPQExpBuffer(buf);
        }

        PQclear(res);
        printf("\n\n");
}

/*
 * Dump commands to create each database.
 *
 * To minimize the number of reconnections (and possibly ensuing
 * password prompts) required by the output script, we emit all CREATE
 * DATABASE commands during the initial phase of the script, and then
 * run pg_dump for each database to dump the contents of that
 * database.  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).
 */
static void
dumpCreateDB(PGconn *conn)
{
        PGresult   *res;
        int                     i;

        printf("--\n-- Database creation\n--\n\n");

        if (server_version >= 80000)
                res = executeQuery(conn,
                                                   "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, datacl, "
                                                   "(SELECT spcname FROM pg_tablespace 
t WHERE t.oid = d.dattablespace) AS dattablespace "
                "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
                                                   "WHERE datallowconn ORDER BY 1");
        else if (server_version >= 70300)
                res = executeQuery(conn,
                                                   "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, datacl, "
                                                   "'pg_default' AS dattablespace "
                "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
                                                   "WHERE datallowconn ORDER BY 1");
        else if (server_version >= 70100)
                res = executeQuery(conn,
                                                   "SELECT datname, "
                                                   "coalesce("
                                "(select usename from pg_shadow where 
usesysid=datdba), "
                                                   "(select usename from pg_shadow 
where usesysid=(select datdba from pg_database where datname='template0'))), "
                                                   "pg_encoding_to_char(d.encoding), "
                                                   "datistemplate, '' as datacl, "
                                                   "'pg_default' AS dattablespace "
                                                   "FROM pg_database d "
                                                   "WHERE datallowconn ORDER BY 1");
        else
        {
                /*
                 * Note: 7.0 fails to cope with sub-select in COALESCE, so just
                 * deal with getting a NULL by not printing any OWNER clause.
                 */
                res = executeQuery(conn,
                                                   "SELECT datname, "
                                "(select usename from pg_shadow where 
usesysid=datdba), "
                                                   "pg_encoding_to_char(d.encoding), "
                                                   "'f' as datistemplate, "
                                                   "'' as datacl, "
                                                   "'pg_default' AS dattablespace "
                                                   "FROM pg_database d "
                                                   "ORDER BY 1");
        }

        for (i = 0; i < PQntuples(res); i++)
        {
                PQExpBuffer buf;
                char       *dbname = PQgetvalue(res, i, 0);
                char       *dbowner = PQgetvalue(res, i, 1);
                char       *dbencoding = PQgetvalue(res, i, 2);
                char       *dbistemplate = PQgetvalue(res, i, 3);
                char       *dbacl = PQgetvalue(res, i, 4);
                char       *dbtablespace = PQgetvalue(res, i, 5);
                char       *fdbname;

                if (strcmp(dbname, "template1") == 0)
                        continue;

                buf = createPQExpBuffer();

                /* needed for buildACLCommands() */
                fdbname = strdup(fmtId(dbname));

                if (output_clean)
                        appendPQExpBuffer(buf, "DROP DATABASE %s;\n", fdbname);

                appendPQExpBuffer(buf, "CREATE DATABASE %s", fdbname);

                appendPQExpBuffer(buf, " WITH TEMPLATE = template0");

                if (strlen(dbowner) != 0)
                        appendPQExpBuffer(buf, " OWNER = %s",
                                                          fmtId(dbowner));

                appendPQExpBuffer(buf, " ENCODING = ");
                appendStringLiteral(buf, dbencoding, true);

                /* Output tablespace if it isn't default */
                if (strcmp(dbtablespace, "pg_default") != 0)
                        appendPQExpBuffer(buf, " TABLESPACE = %s",
                                                          fmtId(dbtablespace));

                appendPQExpBuffer(buf, ";\n");

                if (strcmp(dbistemplate, "t") == 0)
                {
                        appendPQExpBuffer(buf, "UPDATE pg_database SET datistemplate = 
't' WHERE datname = ");
                        appendStringLiteral(buf, dbname, true);
                        appendPQExpBuffer(buf, ";\n");
                }

                if (!skip_acls &&
                        !buildACLCommands(fdbname, "DATABASE", dbacl, dbowner,
                                                          server_version, buf))
                {
                        fprintf(stderr, _("%s: could not parse ACL list (%s) for 
database \"%s\"\n"),
                                        progname, dbacl, fdbname);
                        PQfinish(conn);
                        exit(1);
                }

                printf("%s", buf->data);
                destroyPQExpBuffer(buf);
                free(fdbname);

                if (server_version >= 70300)
                        dumpDatabaseConfig(conn, dbname);
        }

        PQclear(res);
        printf("\n\n");
}



/*
 * Dump database-specific configuration
 */
static void
dumpDatabaseConfig(PGconn *conn, const char *dbname)
{
        PQExpBuffer buf = createPQExpBuffer();
        int                     count = 1;

        for (;;)
        {
                PGresult   *res;

                printfPQExpBuffer(buf, "SELECT datconfig[%d] FROM pg_database WHERE 
datname = ", count);
                appendStringLiteral(buf, dbname, true);
                appendPQExpBuffer(buf, ";");

                res = executeQuery(conn, buf->data);
                if (!PQgetisnull(res, 0, 0))
                {
                        makeAlterConfigCommand(PQgetvalue(res, 0, 0), "DATABASE", 
dbname);
                        PQclear(res);
                        count++;
                }
                else
                {
                        PQclear(res);
                        break;
                }
        }

        destroyPQExpBuffer(buf);
}



/*
 * Dump user-specific configuration
 */
static void
dumpUserConfig(PGconn *conn, const char *username)
{
        PQExpBuffer buf = createPQExpBuffer();
        int                     count = 1;

        for (;;)
        {
                PGresult   *res;

                printfPQExpBuffer(buf, "SELECT useconfig[%d] FROM pg_shadow WHERE 
usename = ", count);
                appendStringLiteral(buf, username, true);
                appendPQExpBuffer(buf, ";");

                res = executeQuery(conn, buf->data);
                if (!PQgetisnull(res, 0, 0))
                {
                        makeAlterConfigCommand(PQgetvalue(res, 0, 0), "USER", 
username);
                        PQclear(res);
                        count++;
                }
                else
                {
                        PQclear(res);
                        break;
                }
        }

        destroyPQExpBuffer(buf);
}



/*
 * Helper function for dumpXXXConfig().
 */
static void
makeAlterConfigCommand(const char *arrayitem, const char *type, const char *name)
{
        char       *pos;
        char       *mine;
        PQExpBuffer buf = createPQExpBuffer();

        mine = strdup(arrayitem);
        pos = strchr(mine, '=');
        if (pos == NULL)
                return;

        *pos = 0;
        appendPQExpBuffer(buf, "ALTER %s %s ", type, fmtId(name));
        appendPQExpBuffer(buf, "SET %s TO ", fmtId(mine));

        /*
         * Some GUC variable names are 'LIST' type and hence must not be
         * quoted.
         */
        if (strcasecmp(mine, "DateStyle") == 0
                || strcasecmp(mine, "search_path") == 0)
                appendPQExpBuffer(buf, "%s", pos + 1);
        else
                appendStringLiteral(buf, pos + 1, false);
        appendPQExpBuffer(buf, ";\n");

        printf("%s", buf->data);
        destroyPQExpBuffer(buf);
        free(mine);
}



/*
 * Dump contents of databases.
 */
static void
dumpDatabases(PGconn *conn)
{
        PGresult   *res;
        int                     i;

        if (server_version >= 70100)
                res = executeQuery(conn, "SELECT datname FROM pg_database WHERE 
datallowconn ORDER BY 1");
        else
                res = executeQuery(conn, "SELECT datname FROM pg_database ORDER BY 1");

        for (i = 0; i < PQntuples(res); i++)
        {
                int                     ret;

                char       *dbname = PQgetvalue(res, i, 0);

                if (verbose)
                        fprintf(stderr, _("%s: dumping database \"%s\"...\n"), 
progname, dbname);

                printf("\\connect %s\n\n", fmtId(dbname));
                ret = runPgDump(dbname);
                if (ret != 0)
                {
                        fprintf(stderr, _("%s: pg_dump failed on database \"%s\", 
exiting\n"), progname, dbname);
                        exit(1);
                }
        }

        PQclear(res);
}



/*
 * Run pg_dump on dbname.
 */
static int
runPgDump(const char *dbname)
{
        PQExpBuffer cmd = createPQExpBuffer();
        const char *p;
        int                     ret;

        /*
         * Win32 has to use double-quotes for args, rather than single quotes.
         * Strangely enough, this is the only place we pass a database name on
         * the command line, except template1 that doesn't need quoting.
         */
#ifndef WIN32
        appendPQExpBuffer(cmd, "%s\"%s\" %s -Fp '", SYSTEMQUOTE, pg_dump_bin,
#else
        appendPQExpBuffer(cmd, "%s\"%s\" %s -Fp \"", SYSTEMQUOTE, pg_dump_bin,
#endif
                                          pgdumpopts->data);

        /* Shell quoting is not quite like SQL quoting, so can't use fmtId */
        for (p = dbname; *p; p++)
        {
#ifndef WIN32
                if (*p == '\'')
                        appendPQExpBuffer(cmd, "'\"'\"'");
#else
                if (*p == '"')
                        appendPQExpBuffer(cmd, "\\\"");
#endif
                else
                        appendPQExpBufferChar(cmd, *p);
        }

#ifndef WIN32
        appendPQExpBufferChar(cmd, '\'');
#else
        appendPQExpBufferChar(cmd, '"');
#endif

        appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE);

        if (verbose)
                fprintf(stderr, _("%s: running \"%s\"\n"), progname, cmd->data);

        fflush(stdout);
        fflush(stderr);

        ret = system(cmd->data);

        destroyPQExpBuffer(cmd);

        return ret;
}



/*
 * Make a database connection with the given parameters.  An
 * interactive password prompt is automatically issued if required.
 */
static PGconn *
connectDatabase(const char *dbname, const char *pghost, const char *pgport,
                                const char *pguser, bool require_password)
{
        PGconn     *conn;
        char       *password = NULL;
        bool            need_pass = false;
        const char *remoteversion_str;

        if (require_password)
                password = simple_prompt("Password: ", 100, false);

        /*
         * Start the connection.  Loop until we have a password if requested
         * by backend.
         */
        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 &&
                        strcmp(PQerrorMessage(conn), "fe_sendauth: no password 
supplied\n") == 0 &&
                        !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\n"),
                                progname, dbname, PQerrorMessage(conn));
                exit(1);
        }

        remoteversion_str = PQparameterStatus(conn, "server_version");
        if (!remoteversion_str)
        {
                fprintf(stderr, _("%s: could not get server version\n"), progname);
                exit(1);
        }
        server_version = parse_version(remoteversion_str);
        if (server_version < 0)
        {
                fprintf(stderr, _("%s: could not parse server version \"%s\"\n"),
                                progname, remoteversion_str);
                exit(1);
        }

        return conn;
}



/*
 * Run a query, return the results, exit program on failure.
 */
static PGresult *
executeQuery(PGconn *conn, const char *query)
{
        PGresult   *res;

        if (verbose)
                fprintf(stderr, _("%s: executing %s\n"), progname, query);

        res = PQexec(conn, query);
        if (!res ||
                PQresultStatus(res) != PGRES_TUPLES_OK)
        {
                fprintf(stderr, _("%s: query failed: %s"), progname, 
PQerrorMessage(conn));
                fprintf(stderr, _("%s: query was: %s\n"), progname, query);
                PQfinish(conn);
                exit(1);
        }

        return res;
}


/*
 * dumpTimestamp
 */
static void
dumpTimestamp(char *msg)
{
        char            buf[256];
        time_t          now = time(NULL);

        if (strftime(buf, 256, "%Y-%m-%d %H:%M:%S %Z", localtime(&now)) != 0)
                printf("-- %s %s\n\n", msg, buf);
}


---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
      subscribe-nomail command to [EMAIL PROTECTED] so that your
      message can get through to the mailing list cleanly

Reply via email to