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 #include #include +#include +#include +#include #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