diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml
index 0a3b44c48ab620789bea0477ebf50e42e86a30a4..cdaf277a305f2af370d4d60a94aa951db82b8c72 100644
--- a/doc/src/sgml/ref/pg_dumpall.sgml
+++ b/doc/src/sgml/ref/pg_dumpall.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dumpall.sgml,v 1.61 2007/01/25 02:46:33 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dumpall.sgml,v 1.62 2007/01/25 03:30:43 momjian Exp $
 PostgreSQL documentation
 -->
 
@@ -128,6 +128,18 @@ PostgreSQL documentation
        </para>
       </listitem>
      </varlistentry>
+	 
+     <varlistentry>
+      <term><option>-f <replaceable class="parameter">filename</replaceable></option></term>
+      <term><option>--file=<replaceable class="parameter">filename</replaceable></option></term>
+      <listitem>
+       <para>
+        Write the output to the specified file.  This is particularly useful
+        on Windows because output redirection does not work for child
+        processes.
+       </para>
+      </listitem>
+     </varlistentry>
 
      <varlistentry>
       <term><option>-g</option></term>
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index 3ada7cc73c63f205e79fd450cdcfa629fbcc7091..a870516d7a98e7b60a68d9885422ef7ec0c60826 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup.h,v 1.44 2006/10/14 23:07:22 tgl Exp $
+ *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup.h,v 1.45 2007/01/25 03:30:43 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -46,6 +46,13 @@ typedef enum _archiveFormat
 	archNull = 4
 } ArchiveFormat;
 
+typedef enum _archiveMode
+{
+	archModeAppend,
+	archModeWrite,
+	archModeRead
+} ArchiveMode;
+
 /*
  *	We may want to have some more user-readable data, but in the mean
  *	time this gives us some abstraction and type checking.
@@ -166,7 +173,7 @@ extern Archive *OpenArchive(const char *FileSpec, const ArchiveFormat fmt);
 
 /* Create a new archive */
 extern Archive *CreateArchive(const char *FileSpec, const ArchiveFormat fmt,
-			  const int compression);
+			  const int compression, ArchiveMode mode);
 
 /* The --list option */
 extern void PrintTOCSummary(Archive *AH, RestoreOptions *ropt);
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index a4c5d6d712851666193b441dced503fbca76b94f..cd84c608827636914088e0fc3b935352b3d8974b 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.139 2007/01/23 17:54:50 tgl Exp $
+ *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.140 2007/01/25 03:30:43 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -86,10 +86,10 @@ static void ResetOutput(ArchiveHandle *AH, OutputContext savedContext);
 /* Public */
 Archive *
 CreateArchive(const char *FileSpec, const ArchiveFormat fmt,
-			  const int compression)
+			  const int compression, ArchiveMode mode)
 
 {
-	ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, archModeWrite);
+	ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, mode);
 
 	return (Archive *) AH;
 }
@@ -203,7 +203,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
 
 	/*
 	 * Setup the output file if necessary.
-	 */
+	 */	
 	if (ropt->filename || ropt->compression)
 		sav = SetOutput(AH, ropt->filename, ropt->compression);
 
@@ -940,10 +940,20 @@ SetOutput(ArchiveHandle *AH, char *filename, int compression)
 	else
 #endif
 	{							/* Use fopen */
-		if (fn >= 0)
-			AH->OF = fdopen(dup(fn), PG_BINARY_W);
+		if (AH->mode == archModeAppend)
+		{
+			if (fn >= 0)
+				AH->OF = fdopen(dup(fn), PG_BINARY_A);
+			else
+				AH->OF = fopen(filename, PG_BINARY_A);
+		}
 		else
-			AH->OF = fopen(filename, PG_BINARY_W);
+		{
+			if (fn >= 0)
+				AH->OF = fdopen(dup(fn), PG_BINARY_W);
+			else
+				AH->OF = fopen(filename, PG_BINARY_W);
+		}
 		AH->gzOut = 0;
 	}
 
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index b64b8f3d32c6d80b12657e8ef239df269a34e2ce..4a8cff359873fc6929789d70d3add85634a653d5 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -17,7 +17,7 @@
  *
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.73 2006/10/04 00:30:05 momjian Exp $
+ *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.74 2007/01/25 03:30:43 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -122,12 +122,6 @@ typedef void (*PrintTocDataPtr) (struct _archiveHandle * AH, struct _tocEntry *
 
 typedef size_t (*CustomOutPtr) (struct _archiveHandle * AH, const void *buf, size_t len);
 
-typedef enum _archiveMode
-{
-	archModeWrite,
-	archModeRead
-} ArchiveMode;
-
 typedef struct _outputContext
 {
 	void	   *OF;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index c8b3e3916a29af82e498be949d387b98eb5c8bcc..2fec7326d50032faa1a1849f3d1f70864f4806e4 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12,7 +12,7 @@
  *	by PostgreSQL
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.458 2007/01/23 17:54:50 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.459 2007/01/25 03:30:43 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -478,25 +478,31 @@ main(int argc, char **argv)
 	/* open the output file */
 	switch (format[0])
 	{
+		case 'a':
+		case 'A':
+			plainText = 1;
+			g_fout = CreateArchive(filename, archNull, 0, archModeAppend);
+			break;
+			
 		case 'c':
 		case 'C':
-			g_fout = CreateArchive(filename, archCustom, compressLevel);
+			g_fout = CreateArchive(filename, archCustom, compressLevel, archModeWrite);
 			break;
 
 		case 'f':
 		case 'F':
-			g_fout = CreateArchive(filename, archFiles, compressLevel);
+			g_fout = CreateArchive(filename, archFiles, compressLevel, archModeWrite);
 			break;
 
 		case 'p':
 		case 'P':
 			plainText = 1;
-			g_fout = CreateArchive(filename, archNull, 0);
+			g_fout = CreateArchive(filename, archNull, 0, archModeWrite);
 			break;
 
 		case 't':
 		case 'T':
-			g_fout = CreateArchive(filename, archTar, compressLevel);
+			g_fout = CreateArchive(filename, archTar, compressLevel, archModeWrite);
 			break;
 
 		default:
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 66c66d8a1a45f5ebd7a4a5c4bd6a795692dbff89..e2e3a9f5bb0a1454b61e1fc11682e823f76eaf74 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.88 2007/01/25 02:46:33 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.89 2007/01/25 03:30:43 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -68,23 +68,25 @@ static int	disable_triggers = 0;
 static int	use_setsessauth = 0;
 static int	server_version;
 
+static FILE	*OPF;
+static char	*filename = NULL;
 
 int
 main(int argc, char *argv[])
 {
-	char	   *pghost = NULL;
-	char	   *pgport = NULL;
-	char	   *pguser = NULL;
-	char	   *pgdb = NULL;
+	char		*pghost = NULL;
+	char		*pgport = NULL;
+	char		*pguser = NULL;
+	char		*pgdb = NULL;
 	bool		force_password = false;
 	bool		data_only = false;
 	bool		globals_only = false;
 	bool		roles_only = false;
 	bool		tablespaces_only = false;
 	bool		schema_only = false;
-	PGconn	   *conn;
+	PGconn		*conn;
 	int			encoding;
-	const char *std_strings;
+	const char	*std_strings;
 	int			c,
 				ret;
 
@@ -94,6 +96,7 @@ main(int argc, char *argv[])
 		{"inserts", no_argument, NULL, 'd'},
 		{"attribute-inserts", no_argument, NULL, 'D'},
 		{"column-inserts", no_argument, NULL, 'D'},
+		{"file", required_argument, NULL, 'f'},
 		{"globals-only", no_argument, NULL, 'g'},
 		{"host", required_argument, NULL, 'h'},
 		{"ignore-version", no_argument, NULL, 'i'},
@@ -167,7 +170,7 @@ main(int argc, char *argv[])
 
 	pgdumpopts = createPQExpBuffer();
 
-	while ((c = getopt_long(argc, argv, "acdDgh:il:oOp:rsS:tU:vWxX:", long_options, &optindex)) != -1)
+	while ((c = getopt_long(argc, argv, "acdDf:gh:il:oOp:rsS:tU:vWxX:", long_options, &optindex)) != -1)
 	{
 		switch (c)
 		{
@@ -184,6 +187,16 @@ main(int argc, char *argv[])
 			case 'D':
 				appendPQExpBuffer(pgdumpopts, " -%c", c);
 				break;
+				
+			case 'f':
+				filename = optarg;
+#ifndef WIN32
+				appendPQExpBuffer(pgdumpopts, " -f '%s'", filename);
+#else
+				appendPQExpBuffer(pgdumpopts, " -f \"%s\"", filename);
+#endif
+
+				break;
 
 			case 'g':
 				globals_only = true;
@@ -377,6 +390,22 @@ main(int argc, char *argv[])
 			exit(1);
 		}
 	}
+	
+	/*
+	 * Open the output file if required, otherwise use stdout
+	 */
+	if (filename)
+	{
+		OPF = fopen(filename, PG_BINARY_W);
+		if (!OPF)
+		{
+			fprintf(stderr, _("%s: could not open the output file \"%s\"\n"),
+					progname, filename);
+			exit(1);
+		}
+	}
+	else
+		OPF = stdout;
 
 	/*
 	 * Get the active encoding and the standard_conforming_strings setting, so
@@ -387,21 +416,21 @@ main(int argc, char *argv[])
 	if (!std_strings)
 		std_strings = "off";
 
-	printf("--\n-- PostgreSQL database cluster dump\n--\n\n");
+	fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
 	if (verbose)
 		dumpTimestamp("Started on");
 
-	printf("\\connect postgres\n\n");
+	fprintf(OPF, "\\connect postgres\n\n");
 
 	if (!data_only)
 	{
 		/* Replicate encoding and std_strings in output */
-		printf("SET client_encoding = '%s';\n",
+		fprintf(OPF, "SET client_encoding = '%s';\n",
 			   pg_encoding_to_char(encoding));
-		printf("SET standard_conforming_strings = %s;\n", std_strings);
+		fprintf(OPF, "SET standard_conforming_strings = %s;\n", std_strings);
 		if (strcmp(std_strings, "off") == 0)
-			printf("SET escape_string_warning = 'off';\n");
-		printf("\n");
+			fprintf(OPF, "SET escape_string_warning = 'off';\n");
+		fprintf(OPF, "\n");
 
 		if (!tablespaces_only)
 		{
@@ -434,7 +463,10 @@ main(int argc, char *argv[])
 
 	if (verbose)
 		dumpTimestamp("Completed on");
-	printf("--\n-- PostgreSQL database cluster dump complete\n--\n\n");
+	fprintf(OPF, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
+	
+	if (filename)
+		fclose(OPF);
 
 	exit(0);
 }
@@ -449,6 +481,7 @@ help(void)
 	printf(_("  %s [OPTION]...\n"), progname);
 
 	printf(_("\nGeneral options:\n"));
+	printf(_("  -f, --file=FILENAME      output file name\n"));
 	printf(_("  -i, --ignore-version     proceed even when server version mismatches\n"
 			 "                           pg_dumpall version\n"));
 	printf(_("  --help                   show this help, then exit\n"));
@@ -571,7 +604,7 @@ dumpRoles(PGconn *conn)
 	i_rolcomment = PQfnumber(res, "rolcomment");
 
 	if (PQntuples(res) > 0)
-		printf("--\n-- Roles\n--\n\n");
+		fprintf(OPF, "--\n-- Roles\n--\n\n");
 
 	for (i = 0; i < PQntuples(res); i++)
 	{
@@ -641,7 +674,7 @@ dumpRoles(PGconn *conn)
 			appendPQExpBuffer(buf, ";\n");
 		}
 
-		printf("%s", buf->data);
+		fprintf(OPF, "%s", buf->data);
 
 		if (server_version >= 70300)
 			dumpUserConfig(conn, rolename);
@@ -649,7 +682,7 @@ dumpRoles(PGconn *conn)
 
 	PQclear(res);
 
-	printf("\n\n");
+	fprintf(OPF, "\n\n");
 
 	destroyPQExpBuffer(buf);
 }
@@ -678,7 +711,7 @@ dumpRoleMembership(PGconn *conn)
 					   "ORDER BY 1,2,3");
 
 	if (PQntuples(res) > 0)
-		printf("--\n-- Role memberships\n--\n\n");
+		fprintf(OPF, "--\n-- Role memberships\n--\n\n");
 
 	for (i = 0; i < PQntuples(res); i++)
 	{
@@ -687,16 +720,16 @@ dumpRoleMembership(PGconn *conn)
 		char	   *grantor = PQgetvalue(res, i, 2);
 		char	   *option = PQgetvalue(res, i, 3);
 
-		printf("GRANT %s", fmtId(roleid));
-		printf(" TO %s", fmtId(member));
+		fprintf(OPF, "GRANT %s", fmtId(roleid));
+		fprintf(OPF, " TO %s", fmtId(member));
 		if (*option == 't')
-			printf(" WITH ADMIN OPTION");
-		printf(" GRANTED BY %s;\n", fmtId(grantor));
+			fprintf(OPF, " WITH ADMIN OPTION");
+		fprintf(OPF, " GRANTED BY %s;\n", fmtId(grantor));
 	}
 
 	PQclear(res);
 
-	printf("\n\n");
+	fprintf(OPF, "\n\n");
 }
 
 /*
@@ -718,7 +751,7 @@ dumpGroups(PGconn *conn)
 					   "SELECT groname, grolist FROM pg_group ORDER BY 1");
 
 	if (PQntuples(res) > 0)
-		printf("--\n-- Role memberships\n--\n\n");
+		fprintf(OPF, "--\n-- Role memberships\n--\n\n");
 
 	for (i = 0; i < PQntuples(res); i++)
 	{
@@ -755,8 +788,8 @@ dumpGroups(PGconn *conn)
 			if (strcmp(groname, usename) == 0)
 				continue;
 
-			printf("GRANT %s", fmtId(groname));
-			printf(" TO %s;\n", fmtId(usename));
+			fprintf(OPF, "GRANT %s", fmtId(groname));
+			fprintf(OPF, " TO %s;\n", fmtId(usename));
 		}
 
 		PQclear(res2);
@@ -765,7 +798,7 @@ dumpGroups(PGconn *conn)
 	PQclear(res);
 	destroyPQExpBuffer(buf);
 
-	printf("\n\n");
+	fprintf(OPF, "\n\n");
 }
 
 /*
@@ -799,7 +832,7 @@ dumpTablespaces(PGconn *conn)
 						   "ORDER BY 1");
 
 	if (PQntuples(res) > 0)
-		printf("--\n-- Tablespaces\n--\n\n");
+		fprintf(OPF, "--\n-- Tablespaces\n--\n\n");
 
 	for (i = 0; i < PQntuples(res); i++)
 	{
@@ -841,14 +874,14 @@ dumpTablespaces(PGconn *conn)
 			appendPQExpBuffer(buf, ";\n");
 		}
 
-		printf("%s", buf->data);
+		fprintf(OPF, "%s", buf->data);
 
 		free(fspcname);
 		destroyPQExpBuffer(buf);
 	}
 
 	PQclear(res);
-	printf("\n\n");
+	fprintf(OPF, "\n\n");
 }
 
 /*
@@ -869,7 +902,7 @@ dumpCreateDB(PGconn *conn)
 	PGresult   *res;
 	int			i;
 
-	printf("--\n-- Database creation\n--\n\n");
+	fprintf(OPF, "--\n-- Database creation\n--\n\n");
 
 	if (server_version >= 80100)
 		res = executeQuery(conn,
@@ -998,7 +1031,7 @@ dumpCreateDB(PGconn *conn)
 			exit(1);
 		}
 
-		printf("%s", buf->data);
+		fprintf(OPF, "%s", buf->data);
 
 		if (server_version >= 70300)
 			dumpDatabaseConfig(conn, dbname);
@@ -1009,7 +1042,7 @@ dumpCreateDB(PGconn *conn)
 	PQclear(res);
 	destroyPQExpBuffer(buf);
 
-	printf("\n\n");
+	fprintf(OPF, "\n\n");
 }
 
 
@@ -1121,7 +1154,7 @@ makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
 		appendStringLiteralConn(buf, pos + 1, conn);
 	appendPQExpBuffer(buf, ";\n");
 
-	printf("%s", buf->data);
+	fprintf(OPF, "%s", buf->data);
 	destroyPQExpBuffer(buf);
 	free(mine);
 }
@@ -1151,13 +1184,29 @@ dumpDatabases(PGconn *conn)
 		if (verbose)
 			fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname);
 
-		printf("\\connect %s\n\n", fmtId(dbname));
+		fprintf(OPF, "\\connect %s\n\n", fmtId(dbname));
+		
+		if (filename)
+			fclose(OPF);
+			
 		ret = runPgDump(dbname);
 		if (ret != 0)
 		{
 			fprintf(stderr, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname, dbname);
 			exit(1);
 		}
+		
+		if (filename)
+		{
+			OPF = fopen(filename, PG_BINARY_A);
+			if (!OPF)
+			{
+				fprintf(stderr, _("%s: could not re-open the output file \"%s\"\n"),
+						progname, filename);
+				exit(1);
+			}
+		}
+		
 	}
 
 	PQclear(res);
@@ -1179,13 +1228,28 @@ runPgDump(const char *dbname)
 	 * 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 "postgres" which doesn't need quoting.
+	 *
+	 * If we have a filename, use the undocumented plain-append pg_dump format.
 	 */
+	if (filename)
+	{
+#ifndef WIN32
+	appendPQExpBuffer(cmd, "%s\"%s\" %s -Fa '", SYSTEMQUOTE, pg_dump_bin,
+#else
+	appendPQExpBuffer(cmd, "%s\"%s\" %s -Fa \"", SYSTEMQUOTE, pg_dump_bin,
+#endif
+					  pgdumpopts->data);
+	}
+	else
+	{
 #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++)
@@ -1413,5 +1477,5 @@ dumpTimestamp(char *msg)
 				 "%Y-%m-%d %H:%M:%S",
 #endif
 				 localtime(&now)) != 0)
-		printf("-- %s %s\n\n", msg, buf);
+		fprintf(OPF, "-- %s %s\n\n", msg, buf);
 }
diff --git a/src/include/c.h b/src/include/c.h
index dab8dc2e68c2c411207c853df6dd2226713ea227..9daa9e4c0eb00a149f0c9aa29510c2a533b34827 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/c.h,v 1.216 2007/01/11 02:39:52 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/c.h,v 1.217 2007/01/25 03:30:43 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -736,10 +736,12 @@ typedef NameData *Name;
  */
 #if defined(WIN32) || defined(__CYGWIN__)
 #define PG_BINARY	O_BINARY
+#define PG_BINARY_A "ab"
 #define PG_BINARY_R "rb"
 #define PG_BINARY_W "wb"
 #else
 #define PG_BINARY	0
+#define PG_BINARY_A "a"
 #define PG_BINARY_R "r"
 #define PG_BINARY_W "w"
 #endif