Index: fe-connect.c
===================================================================
RCS file: /home/ncvs/pgsql/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.250
diff -u -r1.250 fe-connect.c
--- fe-connect.c	21 Jun 2003 21:51:33 -0000	1.250
+++ fe-connect.c	23 Jun 2003 07:06:56 -0000
@@ -21,6 +21,9 @@
 #include <errno.h>
 #include <ctype.h>
 #include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
 
 #ifndef HAVE_STRDUP
 #include "strdup.h"
@@ -178,11 +181,11 @@
 				const char *keyword);
 static void defaultNoticeReceiver(void *arg, const PGresult *res);
 static void defaultNoticeProcessor(void *arg, const char *message);
+static void defaultfNoticeProcessor(void *arg, const char *fmt, ...);
 static int parseServiceInfo(PQconninfoOption *options,
 				 PQExpBuffer errorMessage);
 static char *pwdfMatchesString(char *buf, char *token);
-static char *PasswordFromFile(char *hostname, char *port, char *dbname,
-							  char *username);
+static char *PasswordFromFile(PGconn *conn);
 
 /*
  *		Connecting to a Database
@@ -386,8 +389,7 @@
 	{
 		if (conn->pgpass)
 			free(conn->pgpass);
-		conn->pgpass = PasswordFromFile(conn->pghost, conn->pgport,
-										conn->dbName, conn->pguser);
+		conn->pgpass = PasswordFromFile(conn);
 		if (conn->pgpass == NULL)
 			conn->pgpass = strdup(DefaultPassword);
 	}
@@ -1805,6 +1807,7 @@
 	/* Zero all pointers and booleans */
 	MemSet((char *) conn, 0, sizeof(PGconn));
 
+	conn->noticeHooks.fnoticeProc = defaultfNoticeProcessor;
 	conn->noticeHooks.noticeRec = defaultNoticeReceiver;
 	conn->noticeHooks.noticeProc = defaultNoticeProcessor;
 	conn->status = CONNECTION_BAD;
@@ -2836,6 +2839,23 @@
 	return old;
 }
 
+PQfnoticeProcessor
+PQsetfNoticeProcessor(PGconn *conn, PQfnoticeProcessor proc, void *arg)
+{
+	PQfnoticeProcessor old;
+
+	if (conn == NULL)
+		return NULL;
+
+	old = conn->noticeHooks.fnoticeProc;
+	if (proc)
+	{
+		conn->noticeHooks.fnoticeProc = proc;
+		conn->noticeHooks.fnoticeProcArg = arg;
+	}
+	return old;
+}
+
 /*
  * The default notice message receiver just gets the standard notice text
  * and sends it to the notice processor.  This two-level setup exists
@@ -2860,8 +2880,25 @@
 defaultNoticeProcessor(void *arg, const char *message)
 {
 	(void) arg;					/* not used */
-	/* Note: we expect the supplied string to end with a newline already. */
-	fprintf(stderr, "%s", message);
+	defaultfNoticeProcessor(NULL, "%s", message);
+}
+
+/*
+ * This is the same as the defaultNoticeProcessor, however it takes a
+ * format as its 2nd argument and has a variable length function
+ * argument.  Applications can override this if they want the messages
+ * to go elsewhere (a window, for example).  Note that simply
+ * discarding notices is probably a bad idea.
+ */
+static void
+defaultfNoticeProcessor(void *arg, const char *fmt, ...)
+{
+	va_list ap;
+	(void) arg;					/* not used */
+
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
 }
 
 /*
@@ -2906,27 +2943,36 @@
 
 /* Get a password from the password file. Return value is malloc'd. */
 static char *
-PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
+PasswordFromFile(PGconn *conn)
 {
 	FILE	   *fp;
 	char	   *pgpassfile;
 	char	   *home;
+	char	   *hostname;
+	char	   *port;
 	struct stat stat_buf;
 
 #define LINELEN NAMEDATALEN*5
 	char		buf[LINELEN];
 
-	if (dbname == NULL || strlen(dbname) == 0)
+	if (conn == NULL)
+		return NULL;
+
+	if (conn->dbName == NULL || strlen(conn->dbName) == 0)
 		return NULL;
 
-	if (username == NULL || strlen(username) == 0)
+	if (conn->pguser == NULL || strlen(conn->pguser) == 0)
 		return NULL;
 
-	if (hostname == NULL)
+	if (conn->pghost == NULL)
 		hostname = DefaultHost;
+	else
+		hostname = conn->pghost;
 
-	if (port == NULL)
+	if (conn->pgport == NULL)
 		port = DEF_PGPORT_STR;
+	else
+		port = conn->pgport;
 
 	/* Look for it in the home dir */
 	home = getenv("HOME");
@@ -2936,7 +2982,7 @@
 	pgpassfile = malloc(strlen(home) + 1 + strlen(PGPASSFILE) + 1);
 	if (!pgpassfile)
 	{
-		fprintf(stderr, libpq_gettext("out of memory\n"));
+		conn->noticeHooks.fnoticeProc(NULL, libpq_gettext("out of memory\n"));
 		return NULL;
 	}
 
@@ -2953,8 +2999,8 @@
 	/* If password file is insecure, alert the user and ignore it. */
 	if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
 	{
-		fprintf(stderr,
-				libpq_gettext("WARNING: Password file %s has world or group read access; permission should be u=rw (0600)\n"),
+		conn->noticeHooks.fnoticeProc(NULL,
+                                libpq_gettext("WARNING: Password file %s has world or group read access; permission should be u=rw (0600)\n"),
 				pgpassfile);
 		free(pgpassfile);
 		return NULL;
@@ -2962,9 +3008,14 @@
 #endif
 
 	fp = fopen(pgpassfile, "r");
-	free(pgpassfile);
-	if (fp == NULL)
+	if (fp == NULL) {
+		conn->noticeHooks.fnoticeProc(NULL,
+					libpq_gettext("WARNING: Unable to read password file %s: %s\n"),
+					pgpassfile, strerror(errno));
+		free(pgpassfile);
 		return NULL;
+	}
+	free(pgpassfile);
 
 	while (!feof(fp))
 	{
@@ -2982,10 +3033,10 @@
 		if (buf[len - 1] == '\n')
 			buf[len - 1] = 0;
 
-		if ((t = pwdfMatchesString(t, hostname)) == NULL ||
-			(t = pwdfMatchesString(t, port)) == NULL ||
-			(t = pwdfMatchesString(t, dbname)) == NULL ||
-			(t = pwdfMatchesString(t, username)) == NULL)
+		if ((t = pwdfMatchesString(t, conn->pghost)) == NULL ||
+			(t = pwdfMatchesString(t, conn->pgport)) == NULL ||
+			(t = pwdfMatchesString(t, conn->dbName)) == NULL ||
+			(t = pwdfMatchesString(t, conn->pguser)) == NULL)
 			continue;
 		ret = strdup(t);
 		fclose(fp);
Index: fe-exec.c
===================================================================
RCS file: /home/ncvs/pgsql/pgsql-server/src/interfaces/libpq/fe-exec.c,v
retrieving revision 1.139
diff -u -r1.139 fe-exec.c
--- fe-exec.c	21 Jun 2003 21:51:34 -0000	1.139
+++ fe-exec.c	23 Jun 2003 07:02:49 -0000
@@ -170,6 +170,8 @@
 	else
 	{
 		/* defaults... */
+		result->noticeHooks.fnoticeProc = NULL;
+		result->noticeHooks.fnoticeProcArg = NULL;
 		result->noticeHooks.noticeRec = NULL;
 		result->noticeHooks.noticeRecArg = NULL;
 		result->noticeHooks.noticeProc = NULL;
Index: libpq-fe.h
===================================================================
RCS file: /home/ncvs/pgsql/pgsql-server/src/interfaces/libpq/libpq-fe.h,v
retrieving revision 1.94
diff -u -r1.94 libpq-fe.h
--- libpq-fe.h	21 Jun 2003 21:51:34 -0000	1.94
+++ libpq-fe.h	23 Jun 2003 07:07:31 -0000
@@ -132,6 +132,7 @@
 /* Function types for notice-handling callbacks */
 typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res);
 typedef void (*PQnoticeProcessor) (void *arg, const char *message);
+typedef void (*PQfnoticeProcessor) (void *arg, const char *fmt, ...);
 
 /* Print options for PQprint() */
 typedef char pqbool;
@@ -272,6 +273,10 @@
 											void *arg);
 extern PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn,
 					 PQnoticeProcessor proc,
+					 void *arg);
+
+extern PQfnoticeProcessor PQsetfNoticeProcessor(PGconn *conn,
+					 PQfnoticeProcessor proc,
 					 void *arg);
 
 /* === in fe-exec.c === */
Index: libpq-int.h
===================================================================
RCS file: /home/ncvs/pgsql/pgsql-server/src/interfaces/libpq/libpq-int.h,v
retrieving revision 1.75
diff -u -r1.75 libpq-int.h
--- libpq-int.h	21 Jun 2003 21:51:34 -0000	1.75
+++ libpq-int.h	23 Jun 2003 07:01:58 -0000
@@ -129,6 +129,8 @@
 	void	   *noticeRecArg;
 	PQnoticeProcessor noticeProc;	/* notice message processor */
 	void	   *noticeProcArg;
+	PQfnoticeProcessor fnoticeProc;	/* notice message processor */
+	void	   *fnoticeProcArg;
 } PGNoticeHooks;
 
 struct pg_result
