From 93120330713916c28f87deb3466010b1f23a213e Mon Sep 17 00:00:00 2001
From: "Marc G. Fournier" <scrappy@hub.org>
Date: Mon, 17 Aug 1998 03:50:43 +0000
Subject: [PATCH] Date: Sun, 16 Aug 1998 14:56:48 -0400 From: Tom Lane
 <tgl@sss.pgh.pa.us> Attached is a patch for this weekend's work on libpq. 
 I've dealt with several issues:

        <for details: see message, in pgsql-patches archive for above data>
---
 src/backend/parser/scan.c           |   4 +-
 src/bin/psql/psql.c                 |  29 +++---
 src/interfaces/Makefile             |  15 ++-
 src/interfaces/libpgtcl/pgtclCmds.c |  98 ++++++++++---------
 src/interfaces/libpgtcl/pgtclId.c   |  30 +++---
 src/interfaces/libpq/Makefile.in    |  27 +++---
 src/interfaces/libpq/fe-auth.c      |  22 ++---
 src/interfaces/libpq/fe-auth.h      |   7 +-
 src/interfaces/libpq/fe-connect.c   |  57 +++++------
 src/interfaces/libpq/fe-exec.c      | 111 ++++++++++++---------
 src/interfaces/libpq/fe-lobj.c      |  17 ++--
 src/interfaces/libpq/fe-misc.c      |  25 +++--
 src/interfaces/libpq/fe-print.c     |  24 ++---
 src/interfaces/libpq/libpq-fe.h     | 144 ++++++++++++----------------
 src/interfaces/libpq/libpqdll.def   | 121 +++++++++++------------
 src/interfaces/libpq/pqsignal.c     |   5 +-
 16 files changed, 373 insertions(+), 363 deletions(-)

diff --git a/src/backend/parser/scan.c b/src/backend/parser/scan.c
index 83ae575e894..cede710c44e 100644
--- a/src/backend/parser/scan.c
+++ b/src/backend/parser/scan.c
@@ -1,7 +1,7 @@
 /* A lexical scanner generated by flex */
 
 /* Scanner skeleton version:
- * $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.22 1998/06/16 07:29:25 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.23 1998/08/17 03:50:15 scrappy Exp $
  */
 
 #define FLEX_SCANNER
@@ -555,7 +555,7 @@ char *yytext;
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.22 1998/06/16 07:29:25 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.23 1998/08/17 03:50:15 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
diff --git a/src/bin/psql/psql.c b/src/bin/psql/psql.c
index 836f949b838..d4bf4cdf1e0 100644
--- a/src/bin/psql/psql.c
+++ b/src/bin/psql/psql.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.153 1998/08/10 20:31:38 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.154 1998/08/17 03:50:17 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -121,8 +121,8 @@ struct winsize
 /* declarations for functions in this file */
 static void usage(char *progname);
 static void slashUsage();
-static void handleCopyOut(PGresult *res, FILE *copystream);
-static void
+static bool handleCopyOut(PGresult *res, FILE *copystream);
+static bool
 handleCopyIn(PGresult *res, const bool mustprompt,
 			 FILE *copystream);
 static int
@@ -1103,23 +1103,23 @@ SendQuery(bool *success_p, PsqlSettings *pset, const char *query,
 					printf("%s\n", PQcmdStatus(results));
 				break;
 			case PGRES_COPY_OUT:
-				*success_p = true;
 				if (copy_out)
-					handleCopyOut(results, copystream);
+					*success_p = handleCopyOut(results, copystream);
 				else
 				{
 					if (!pset->quiet)
 						printf("Copy command returns...\n");
 
-					handleCopyOut(results, stdout);
+					*success_p = handleCopyOut(results, stdout);
 				}
 				break;
 			case PGRES_COPY_IN:
-				*success_p = true;
 				if (copy_in)
-					handleCopyIn(results, false, copystream);
+					*success_p = handleCopyIn(results, false, copystream);
 				else
-					handleCopyIn(results, !pset->quiet && !pset->notty, stdin);
+					*success_p = handleCopyIn(results,
+											  !pset->quiet && !pset->notty,
+											  stdin);
 				break;
 			case PGRES_NONFATAL_ERROR:
 			case PGRES_FATAL_ERROR:
@@ -2646,7 +2646,6 @@ main(int argc, char **argv)
 	char	   *host = NULL;
 	char	   *port = NULL;
 	char	   *qfilename = NULL;
-	char		errbuf[ERROR_MSG_LENGTH];
 
 	PsqlSettings settings;
 
@@ -2692,7 +2691,9 @@ main(int argc, char **argv)
 				settings.opt.align = 0;
 				break;
 			case 'a':
+#if 0				/* this no longer does anything */
 				fe_setauthsvc(optarg, errbuf);
+#endif
 				break;
 			case 'c':
 				singleQuery = strdup(optarg);
@@ -2875,7 +2876,7 @@ main(int argc, char **argv)
 
 #define COPYBUFSIZ	8192
 
-static void
+static bool
 handleCopyOut(PGresult *res, FILE *copystream)
 {
 	bool		copydone;
@@ -2911,12 +2912,12 @@ handleCopyOut(PGresult *res, FILE *copystream)
 		}
 	}
 	fflush(copystream);
-	PQendcopy(res->conn);
+	return ! PQendcopy(res->conn);
 }
 
 
 
-static void
+static bool
 handleCopyIn(PGresult *res, const bool mustprompt, FILE *copystream)
 {
 	bool		copydone = false;
@@ -2967,7 +2968,7 @@ handleCopyIn(PGresult *res, const bool mustprompt, FILE *copystream)
 		}
 		PQputline(res->conn, "\n");
 	}
-	PQendcopy(res->conn);
+	return ! PQendcopy(res->conn);
 }
 
 
diff --git a/src/interfaces/Makefile b/src/interfaces/Makefile
index 12b0306f08c..5cb43e2c976 100644
--- a/src/interfaces/Makefile
+++ b/src/interfaces/Makefile
@@ -7,14 +7,21 @@
 #
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/interfaces/Makefile,v 1.10 1998/05/29 17:00:29 momjian Exp $
+#    $Header: /cvsroot/pgsql/src/interfaces/Makefile,v 1.11 1998/08/17 03:50:19 scrappy Exp $
 #
 #-------------------------------------------------------------------------
 
 SRCDIR= ..
 include $(SRCDIR)/Makefile.global
 
-.DEFAULT all:
+
+perl-makefile-dep :=
+ifeq ($(USE_PERL), true)
+  perl-makefile-dep := perl5/Makefile
+endif
+
+
+.DEFAULT all: $(perl-makefile-dep)
 	$(MAKE) -C libpq $@
 #	$(MAKE) -C ecpg $@
 ifeq ($(HAVE_Cplusplus), true)
@@ -26,6 +33,8 @@ ifeq ($(USE_TCL), true)
 	$(MAKE) -C libpgtcl $@
 endif
 ifeq ($(USE_PERL), true)
-	cd perl5 && perl Makefile.PL
 	$(MAKE) -C perl5 $@
 endif
+
+perl5/Makefile: perl5/Makefile.PL
+	cd perl5 && perl Makefile.PL
diff --git a/src/interfaces/libpgtcl/pgtclCmds.c b/src/interfaces/libpgtcl/pgtclCmds.c
index ec0844d8aed..a619d6206b7 100644
--- a/src/interfaces/libpgtcl/pgtclCmds.c
+++ b/src/interfaces/libpgtcl/pgtclCmds.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.28 1998/07/09 03:32:09 scrappy Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.29 1998/08/17 03:50:22 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -485,9 +485,8 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
     char *opt;
     int i;
     int tupno;
-    char prearrayInd[MAX_MESSAGE_LEN];
-    char arrayInd[MAX_MESSAGE_LEN];
     char *arrVar;
+    char nameBuffer[256];
 
     if (argc < 3 || argc > 5) {
 	Tcl_AppendResult(interp, "Wrong # of arguments\n",0);
@@ -522,6 +521,10 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
 	sprintf(interp->result, "%d", PQntuples(result));
 	return TCL_OK;
     }
+    else if (strcmp(opt, "-numAttrs") == 0) {
+	sprintf(interp->result, "%d", PQnfields(result));
+	return TCL_OK;
+    }
     else if (strcmp(opt, "-assign") == 0) {
 	if (argc != 4) {
 	    Tcl_AppendResult(interp, "-assign option must be followed by a variable name",0);
@@ -530,17 +533,21 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
 	arrVar = argv[3];
 	/* this assignment assigns the table of result tuples into a giant
 	   array with the name given in the argument,
-	   the indices of the array or (tupno,attrName)*/
+	   the indices of the array or (tupno,attrName).
+	   Note we expect field names not to exceed a few dozen characters,
+	   so truncating to prevent buffer overflow shouldn't be a problem.
+	   */
 	for (tupno = 0; tupno<PQntuples(result); tupno++) {
 	    for (i=0;i<PQnfields(result);i++) {
-		sprintf(arrayInd, "%d,%s", tupno, PQfname(result,i));
-		Tcl_SetVar2(interp, arrVar, arrayInd, 
+		sprintf(nameBuffer, "%d,%.200s", tupno, PQfname(result,i));
+		if (Tcl_SetVar2(interp, arrVar, nameBuffer, 
 #ifdef TCL_ARRAYS
-			    tcl_value(PQgetvalue(result,tupno,i)),
+				tcl_value(PQgetvalue(result,tupno,i)),
 #else
-			    PQgetvalue(result,tupno,i),
+				PQgetvalue(result,tupno,i),
 #endif
-			    TCL_LEAVE_ERR_MSG);
+				TCL_LEAVE_ERR_MSG) == NULL)
+		  return TCL_ERROR;
 	    }
 	}
 	Tcl_AppendResult(interp, arrVar, 0);
@@ -554,15 +561,23 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
       arrVar = argv[3];
       /* this assignment assigns the table of result tuples into a giant
          array with the name given in the argument,
-         the indices of the array or (tupno,attrName)*/
+         the indices of the array or (tupno,attrName).
+	 Here, we still assume PQfname won't exceed 200 characters,
+	 but we dare not make the same assumption about the data in field 0.
+	 */
       for (tupno = 0; tupno<PQntuples(result); tupno++) {
-          sprintf(prearrayInd,"%s",PQgetvalue(result,tupno,0));
+	  const char *field0 = PQgetvalue(result,tupno,0);
+	  char * workspace = malloc(strlen(field0) + 210);
           for (i=1;i<PQnfields(result);i++) {
-              sprintf(arrayInd, "%s,%s", prearrayInd, PQfname(result,i));
-              Tcl_SetVar2(interp, arrVar, arrayInd,
-                          PQgetvalue(result,tupno,i),
-                          TCL_LEAVE_ERR_MSG);
+              sprintf(workspace, "%s,%.200s", field0, PQfname(result,i));
+              if (Tcl_SetVar2(interp, arrVar, workspace,
+			      PQgetvalue(result,tupno,i),
+			      TCL_LEAVE_ERR_MSG) == NULL) {
+		free(workspace);
+		return TCL_ERROR;
+	      }
           }
+	  free(workspace);
       }
       Tcl_AppendResult(interp, arrVar, 0);
       return TCL_OK;
@@ -573,25 +588,13 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
 	    return TCL_ERROR;
 	}
 	tupno = atoi(argv[3]);
-	
-	if (tupno >= PQntuples(result)) {
+	if (tupno < 0 || tupno >= PQntuples(result)) {
 	    Tcl_AppendResult(interp, "argument to getTuple cannot exceed number of tuples - 1",0);
 	    return TCL_ERROR;
 	}
-
-#ifdef TCL_ARRAYS
 	for (i=0; i<PQnfields(result); i++) {
-	    Tcl_AppendElement(interp, tcl_value(PQgetvalue(result,tupno,i)));
-	}
-#else
-/*	Tcl_AppendResult(interp, PQgetvalue(result,tupno,0),NULL); */
-        Tcl_AppendElement(interp, PQgetvalue(result,tupno,0));
-	for (i=1;i<PQnfields(result);i++) {
-/*	  Tcl_AppendResult(interp, " ", PQgetvalue(result,tupno,i),NULL);*/
-         Tcl_AppendElement(interp, PQgetvalue(result,tupno,i));
+	    Tcl_AppendElement(interp, PQgetvalue(result,tupno,i));
 	}
-#endif
-
 	return TCL_OK;
     }
     else if (strcmp(opt, "-tupleArray") == 0) {
@@ -600,41 +603,42 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
 	    return TCL_ERROR;
 	}
 	tupno = atoi(argv[3]);
-	
-	if (tupno >= PQntuples(result)) {
+	if (tupno < 0 || tupno >= PQntuples(result)) {
 	    Tcl_AppendResult(interp, "argument to tupleArray cannot exceed number of tuples - 1",0);
 	    return TCL_ERROR;
 	}
-
 	for ( i = 0; i < PQnfields(result); i++) {
-	   if (Tcl_SetVar2(interp, argv[4], PQfname(result, i), PQgetvalue(result, tupno, i), TCL_LEAVE_ERR_MSG) == NULL) {
+	   if (Tcl_SetVar2(interp, argv[4], PQfname(result, i),
+			   PQgetvalue(result, tupno, i),
+			   TCL_LEAVE_ERR_MSG) == NULL) {
 	       return TCL_ERROR;
 	   }
 	}
 	return TCL_OK;
     }
     else if (strcmp(opt, "-attributes") == 0) {
-      Tcl_AppendResult(interp, PQfname(result,0),NULL);
-      for (i=1;i<PQnfields(result);i++) {
-	Tcl_AppendResult(interp, " ", PQfname(result,i), NULL);
+      for (i=0;i<PQnfields(result);i++) {
+	Tcl_AppendElement(interp, PQfname(result,i));
       }
       return TCL_OK;
     }
     else if (strcmp(opt, "-lAttributes") == 0) {
-      char buf[512];
-      Tcl_ResetResult(interp);
       for (i = 0; i < PQnfields(result); i++) {
-          sprintf(buf, "{%s} %ld %d", PQfname(result, i),
-	  			      (long) PQftype(result, i),
-				      PQfsize(result, i));
-          Tcl_AppendElement(interp, buf);
+	/* start a sublist */
+	if (i > 0)
+	  Tcl_AppendResult(interp, " {", 0);
+	else
+	  Tcl_AppendResult(interp, "{", 0);
+	Tcl_AppendElement(interp, PQfname(result, i));
+	sprintf(nameBuffer, "%ld", (long) PQftype(result, i));
+	Tcl_AppendElement(interp, nameBuffer);
+	sprintf(nameBuffer, "%ld", (long) PQfsize(result, i));
+	Tcl_AppendElement(interp, nameBuffer);
+	/* end the sublist */
+	Tcl_AppendResult(interp, "}", 0);
       }
       return TCL_OK;
     }
-    else if (strcmp(opt, "-numAttrs") == 0) {
-      sprintf(interp->result, "%d", PQnfields(result));
-      return TCL_OK;
-    }
     else   { 
 	Tcl_AppendResult(interp, "Invalid option",0);
 	goto Pg_result_errReturn;
@@ -649,9 +653,9 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
 		     "\t-assign arrayVarName\n",
 		     "\t-assignbyidx arrayVarName\n",
 		     "\t-numTuples\n",
+		     "\t-numAttrs\n"
 		     "\t-attributes\n"
 		     "\t-lAttributes\n"
-		     "\t-numAttrs\n"
 		     "\t-getTuple tupleNumber\n",
 		     "\t-tupleArray tupleNumber arrayVarName\n",
 		     "\t-clear\n",
diff --git a/src/interfaces/libpgtcl/pgtclId.c b/src/interfaces/libpgtcl/pgtclId.c
index 4ed8f58d57f..05dfb19b6de 100644
--- a/src/interfaces/libpgtcl/pgtclId.c
+++ b/src/interfaces/libpgtcl/pgtclId.c
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.11 1998/06/16 04:10:17 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.12 1998/08/17 03:50:26 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -43,7 +43,10 @@ static int PgEndCopy(Pg_ConnectionId *connid, int *errorCodePtr)
 }
 
 /*
- *  Called when reading data (via gets) for a copy <rel> to stdout
+ *  Called when reading data (via gets) for a copy <rel> to stdout.
+ *
+ *  NOTE: this routine knows way more than it ought to about libpq's
+ *  internal buffering mechanisms.
  */
 int PgInputProc(DRIVER_INPUT_PROTO)
 {
@@ -62,10 +65,10 @@ int PgInputProc(DRIVER_INPUT_PROTO)
     }
 
     /* Try to load any newly arrived data */
-    errno = 0;
-
-    if (pqReadData(conn) < 0) {
-	*errorCodePtr = errno ? errno : EIO;
+    conn->errorMessage[0] = '\0';
+    PQconsumeInput(conn);
+    if (conn->errorMessage[0]) {
+	*errorCodePtr = EIO;
 	return -1;
     }
 
@@ -80,8 +83,8 @@ int PgInputProc(DRIVER_INPUT_PROTO)
     conn->inCursor = conn->inStart;
 
     avail = bufSize;
-    while (avail > 0 &&
-	   pqGetc(&c, conn) == 0) {
+    while (avail > 0 && conn->inCursor < conn->inEnd) {
+	c = conn->inBuffer[conn->inCursor++];
 	*buf++ = c;
 	--avail;
 	if (c == '\n') {
@@ -130,10 +133,12 @@ int PgOutputProc(DRIVER_OUTPUT_PROTO)
 	return -1;
     }
 
-    errno = 0;
+    conn->errorMessage[0] = '\0';
 
-    if (pqPutnchar(buf, bufSize, conn)) {
-	*errorCodePtr = errno ? errno : EIO;
+    PQputnbytes(conn, buf, bufSize);
+
+    if (conn->errorMessage[0]) {
+	*errorCodePtr = EIO;
 	return -1;
     }
 
@@ -141,7 +146,6 @@ int PgOutputProc(DRIVER_OUTPUT_PROTO)
      * in a single operation; maybe not such a good assumption?
      */
     if (bufSize >= 3 && strncmp(&buf[bufSize-3], "\\.\n", 3) == 0) {
-	(void) pqFlush(conn);
 	if (PgEndCopy(connid, errorCodePtr) == -1)
 	    return -1;
     }
@@ -423,7 +427,7 @@ PgGetConnByResultId(Tcl_Interp *interp, char *resid_c)
     *mark = '\0';
     conn_chan = Tcl_GetChannel(interp, resid_c, 0);
     *mark = '.';
-    if(conn_chan && Tcl_GetChannelType(conn_chan) != &Pg_ConnType) {
+    if(conn_chan && Tcl_GetChannelType(conn_chan) == &Pg_ConnType) {
 	Tcl_SetResult(interp, Tcl_GetChannelName(conn_chan), TCL_VOLATILE);
 	return TCL_OK;
     }
diff --git a/src/interfaces/libpq/Makefile.in b/src/interfaces/libpq/Makefile.in
index 7dbe54f1469..b13e7753c17 100644
--- a/src/interfaces/libpq/Makefile.in
+++ b/src/interfaces/libpq/Makefile.in
@@ -7,7 +7,7 @@
 #
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/interfaces/libpq/Attic/Makefile.in,v 1.25 1998/07/26 04:31:35 scrappy Exp $
+#    $Header: /cvsroot/pgsql/src/interfaces/libpq/Attic/Makefile.in,v 1.26 1998/08/17 03:50:29 scrappy Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -87,7 +87,7 @@ ifeq ($(PORTNAME), hpux)
   CFLAGS += $(CFLAGS_SL)
 endif
 
-all: libpq.a $(shlib) c.h
+all: libpq.a $(shlib)
 
 libpq.a: $(OBJS)
 ifdef MK_NO_LORDER
@@ -97,8 +97,6 @@ else
 endif
 	$(RANLIB) libpq.a
 
-fe-lobj.o: $(SRCDIR)/backend/fmgr.h
-
 # We need to compile this with special options for shared libs,
 # so we can't use the object in $(SRCDIR)/backend
 dllist.c:	$(SRCDIR)/backend/lib/dllist.c
@@ -120,6 +118,8 @@ endif
 # The following rules cause dependencies in the backend directory to 
 # get made if they don't exist, but don't cause them to get remade if they
 # are out of date.
+fe-lobj.o: $(SRCDIR)/backend/fmgr.h
+
 $(SRCDIR)/backend/fmgr.h:
 	$(MAKE) -C $(SRCDIR)/backend fmgr.h
 
@@ -128,12 +128,6 @@ $(shlib): $(OBJS)
 	ln -sf $@ libpq.so
 
 
-c.h: $(SRCDIR)/include/c.h
-	rm -f c.h
-	echo "#undef PORTNAME" >  c.h
-	echo "#define PORTNAME $(PORTNAME)" >> c.h
-	cat $(SRCDIR)/include/c.h >> c.h
-
 .PHONY: beforeinstall-headers install-headers
 .PHONY: install install-libpq install-shlib-dep 
 
@@ -142,15 +136,17 @@ install: install-headers install-libpq $(install-shlib-dep)
 # Many of the headers we install below have nothing to do with libpq,
 # so should be installed by someone else.
 #
-install-headers: beforeinstall-headers c.h \
+install-headers: beforeinstall-headers $(SRCDIR)/include/c.h \
                  $(SRCDIR)/include/postgres.h $(SRCDIR)/include/postgres_ext.h \
                  $(SRCDIR)/include/config.h $(SRCDIR)/include/libpq/pqcomm.h \
                  $(SRCDIR)/include/libpq/libpq-fs.h $(SRCDIR)/include/lib/dllist.h \
-                 $(SRCDIR)/include/utils/geo_decls.h libpq-fe.h
+                 $(SRCDIR)/include/utils/geo_decls.h libpq-fe.h libpq-int.h
 	$(INSTALL) $(INSTLOPTS) $(SRCDIR)/include/os.h \
           $(HEADERDIR)/os.h
 	$(INSTALL) $(INSTLOPTS) $(SRCDIR)/include/config.h \
           $(HEADERDIR)/config.h
+	$(INSTALL) $(INSTLOPTS) $(SRCDIR)/include/c.h \
+          $(HEADERDIR)/c.h
 	$(INSTALL) $(INSTLOPTS) $(SRCDIR)/include/postgres.h \
           $(HEADERDIR)/postgres.h
 	$(INSTALL) $(INSTLOPTS) $(SRCDIR)/include/postgres_ext.h \
@@ -174,19 +170,17 @@ install-headers: beforeinstall-headers c.h \
 	$(INSTALL) $(INSTLOPTS) $(SRCDIR)/include/commands/trigger.h \
           $(HEADERDIR)/commands/trigger.h
 	$(INSTALL) $(INSTLOPTS) libpq-fe.h $(HEADERDIR)/libpq-fe.h
+	$(INSTALL) $(INSTLOPTS) libpq-int.h $(HEADERDIR)/libpq-int.h
 ifeq ($(PORTNAME), hpux)
 	$(INSTALL) $(INSTLOPTS) $(SRCDIR)/backend/port/hpux/fixade.h \
           $(HEADERDIR)/port/hpux/fixade.h
 endif
-	$(INSTALL) $(INSTLOPTS) c.h $(HEADERDIR)/c.h
 
 beforeinstall-headers:
 	@if [ ! -d $(HEADERDIR) ]; then mkdir $(HEADERDIR); fi
 	@if [ ! -d $(HEADERDIR)/port ]; then mkdir $(HEADERDIR)/port; fi
 	@if [ ! -d $(HEADERDIR)/port/$(PORTNAME) ]; \
 		then mkdir $(HEADERDIR)/port/$(PORTNAME); fi
-	@if [ ! -d $(HEADERDIR)/include ]; \
-		then mkdir $(HEADERDIR)/include; fi
 	@if [ ! -d $(HEADERDIR)/lib ]; \
 		then mkdir $(HEADERDIR)/lib; fi
 	@if [ ! -d $(HEADERDIR)/libpq ]; \
@@ -213,7 +207,8 @@ depend dep:
 
 .PHONY: clean
 clean:
-	rm -f libpq.a $(shlib) $(OBJS) c.h dllist.c libpq.so
+	rm -f libpq.a $(shlib) libpq.so $(OBJS)
+	rm -f dllist.c common.c wchar.c conv.c
 
 ifeq (depend,$(wildcard depend))
 include depend
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 8d96a1af8cc..5d137afe6de 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.21 1998/08/09 02:59:25 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.22 1998/08/17 03:50:31 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -24,28 +24,26 @@
  *
  *
  */
+
+#include "libpq-fe.h"
+#include "libpq-int.h"
+#include "fe-auth.h"
+#include "postgres.h"
+
 #ifdef WIN32
 #include "win32.h"
 #else
-#include <stdio.h>
 #include <string.h>
 #include <sys/param.h>			/* for MAXHOSTNAMELEN on most */
-#include <sys/types.h>
 #ifndef  MAXHOSTNAMELEN
 #include <netdb.h>				/* for MAXHOSTNAMELEN on some */
 #endif
+#if !defined(NO_UNISTD_H)
 #include <unistd.h>
+#endif
 #include <pwd.h>
 #endif /* WIN32 */
 
-#include "postgres.h"
-
-#include "libpq/pqcomm.h"
-
-#include "libpq-fe.h"
-#include "fe-auth.h"
-#include "fe-connect.h"
-
 #ifdef HAVE_CRYPT_H
 #include <crypt.h>
 #endif
@@ -469,7 +467,7 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
 	if (areq == AUTH_REQ_CRYPT)
 		password = crypt(password, conn->salt);
 
-	return packetSend(conn, password, strlen(password) + 1);
+	return pqPacketSend(conn, password, strlen(password) + 1);
 }
 
 /*
diff --git a/src/interfaces/libpq/fe-auth.h b/src/interfaces/libpq/fe-auth.h
index ebbca5dfb3e..c014204722e 100644
--- a/src/interfaces/libpq/fe-auth.h
+++ b/src/interfaces/libpq/fe-auth.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: fe-auth.h,v 1.8 1998/01/29 03:24:21 scrappy Exp $
+ * $Id: fe-auth.h,v 1.9 1998/08/17 03:50:33 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -14,6 +14,7 @@
 #define FE_AUTH_H
 
 #include "libpq-fe.h"
+#include "libpq-int.h"
 
 
 /*----------------------------------------------------------------
@@ -33,8 +34,10 @@
 
 extern int
 fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
-			const char *password, char *PQerromsg);
+			const char *password, char *PQerrormsg);
+extern MsgType fe_getauthsvc(char *PQerrormsg);
 extern void fe_setauthsvc(const char *name, char *PQerrormsg);
+extern char *fe_getauthname(char *PQerrormsg);
 
 #define PG_KRB4_VERSION "PGVER4.1"		/* at most KRB_SENDAUTH_VLEN chars */
 #define PG_KRB5_VERSION "PGVER5.1"
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index cc8af6d6acf..30f9933950c 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -7,35 +7,31 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.78 1998/08/09 02:59:26 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.79 1998/08/17 03:50:34 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
 
+#include "libpq-fe.h"
+#include "libpq-int.h"
+#include "fe-auth.h"
+#include "postgres.h"
+
 #include <stdlib.h>
-#include <sys/types.h>
 #ifdef WIN32
 #include "win32.h"
 #else
-#include <sys/socket.h>
+#if !defined(NO_UNISTD_H)
 #include <unistd.h>
+#endif
 #include <netdb.h>
-#include <sys/un.h>
-#include <netinet/in.h>
 #include <netinet/tcp.h>
 #endif
 #include <fcntl.h>
-#include <stdio.h>
-#include <ctype.h>
 #include <string.h>
 #include <errno.h>
 #include <ctype.h>				/* for isspace() */
 
-#include "postgres.h"
-#include "fe-auth.h"
-#include "fe-connect.h"
-#include "libpq-fe.h"
-
 #ifndef HAVE_STRDUP
 #include "strdup.h"
 #endif
@@ -113,7 +109,7 @@ static PQconninfoOption PQconninfoOptions[] = {
 	NULL, NULL, 0}
 };
 
-struct EnvironmentOptions
+static struct EnvironmentOptions
 {
 	const char *envName,
 			   *pgName;
@@ -496,7 +492,7 @@ connectDB(PGconn *conn)
 	struct hostent *hp;
 	StartupPacket sp;
 	AuthRequest areq;
-	int			laddrlen = sizeof(SockAddr);
+	int			laddrlen;
 	int			portno,
 				family;
 	char		beresp;
@@ -514,7 +510,7 @@ connectDB(PGconn *conn)
 
 	MemSet((char *) &sp, 0, sizeof(StartupPacket));
 
-	sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LATEST);
+	sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LIBPQ);
 
 	strncpy(sp.user, conn->pguser, SM_USER);
 	strncpy(sp.database, conn->dbName, SM_DATABASE);
@@ -626,6 +622,7 @@ connectDB(PGconn *conn)
 	}
 
 	/* Fill in the client address */
+	laddrlen = sizeof(conn->laddr);
 	if (getsockname(conn->sock, &conn->laddr.sa, &laddrlen) < 0)
 	{
 		(void) sprintf(conn->errorMessage,
@@ -640,7 +637,7 @@ connectDB(PGconn *conn)
 
 	/* Send the startup packet. */
 
-	if (packetSend(conn, (char *) &sp, sizeof(StartupPacket)) != STATUS_OK)
+	if (pqPacketSend(conn, (char *) &sp, sizeof(StartupPacket)) != STATUS_OK)
 	{
 		sprintf(conn->errorMessage,
 				"connectDB() --  couldn't send startup packet: errno=%d\n%s\n",
@@ -786,7 +783,7 @@ PQsetenv(PGconn *conn)
 	char		setQuery[80];	/* mjl: size okay? XXX */
 #ifdef MULTIBYTE
 	char	*envname = "PGCLIENTENCODING";
-	char	envbuf[64];
+	static char	envbuf[64];		/* big enough? */
 	char	*env;
 	char	*encoding = 0;
 	PGresult   *rtn;
@@ -875,7 +872,7 @@ freePGconn(PGconn *conn)
 {
 	if (!conn)
 		return;
-	PQclearAsyncResult(conn);	/* deallocate result and curTuple */
+	pqClearAsyncResult(conn);	/* deallocate result and curTuple */
 	if (conn->sock >= 0)
 #ifdef WIN32
 		closesocket(conn->sock);
@@ -919,19 +916,13 @@ closePGconn(PGconn *conn)
 	{
 		/*
 		 * Try to send "close connection" message to backend.
-		 * BUT: backend might have already closed connection.
-		 * To avoid being killed by SIGPIPE, we need to detect this before
-		 * writing.  Check for "read ready" condition which indicates EOF.
+		 * Ignore any error.
+		 * Note: this routine used to go to substantial lengths to avoid
+		 * getting SIGPIPE'd if the connection were already closed.
+		 * Now we rely on pqFlush to avoid the signal.
 		 */
-		while (pqReadReady(conn)) {
-			if (pqReadData(conn) < 0)
-				break;
-		}
-		if (conn->sock >= 0) {
-			/* Should be safe now... */
-			(void) pqPuts("X", conn);
-			(void) pqFlush(conn);
-		}
+		(void) pqPuts("X", conn);
+		(void) pqFlush(conn);
 	}
 
 	/*
@@ -947,7 +938,7 @@ closePGconn(PGconn *conn)
 	conn->status = CONNECTION_BAD;		/* Well, not really _bad_ - just
 										 * absent */
 	conn->asyncStatus = PGASYNC_IDLE;
-	PQclearAsyncResult(conn);	/* deallocate result and curTuple */
+	pqClearAsyncResult(conn);	/* deallocate result and curTuple */
 	if (conn->lobjfuncs)
 		free(conn->lobjfuncs);
 	conn->lobjfuncs = NULL;
@@ -1080,14 +1071,14 @@ cancel_errReturn:
 
 
 /*
- * PacketSend() -- send a single-packet message.
+ * pqPacketSend() -- send a single-packet message.
  * this is like PacketSend(), defined in backend/libpq/pqpacket.c
  *
  * RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
  * SIDE_EFFECTS: may block.
 */
 int
-packetSend(PGconn *conn, const char *buf, size_t len)
+pqPacketSend(PGconn *conn, const char *buf, size_t len)
 {
 	/* Send the total packet size. */
 
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 89790183144..c909c424468 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -7,24 +7,25 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.61 1998/08/09 02:59:27 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.62 1998/08/17 03:50:35 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
+#include "libpq-fe.h"
+#include "libpq-int.h"
+#include "postgres.h"
+
 #ifdef WIN32
 #include "win32.h"
+#else
+#if !defined(NO_UNISTD_H)
+#include <unistd.h>
+#endif
 #endif
 #include <stdlib.h>
-#include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include <ctype.h>
-#if !defined(NO_UNISTD_H)
-#include <unistd.h>
-#endif
-#include "postgres.h"
-#include "libpq/pqcomm.h"
-#include "libpq-fe.h"
 
 
 /* the rows array in a PGresGroup  has to grow to accommodate the rows */
@@ -32,7 +33,7 @@
 #define TUPARR_GROW_BY 100
 
 /* keep this in same order as ExecStatusType in libpq-fe.h */
-const char *pgresStatus[] = {
+const char * const pgresStatus[] = {
 	"PGRES_EMPTY_QUERY",
 	"PGRES_COMMAND_OK",
 	"PGRES_TUPLES_OK",
@@ -144,7 +145,7 @@ freeTuple(PGresAttValue *tuple, int numAttributes)
  */
 
 void
-PQclearAsyncResult(PGconn *conn)
+pqClearAsyncResult(PGconn *conn)
 {
 	/* Get rid of incomplete result and any not-yet-added tuple */
 	if (conn->result)
@@ -210,25 +211,6 @@ PQsendQuery(PGconn *conn, const char *query)
 		return 0;
 	}
 
-	if (conn->asyncStatus != PGASYNC_IDLE)
-	{
-		sprintf(conn->errorMessage,
-				"PQsendQuery() -- another query already in progress.");
-		return 0;
-	}
-
-	/* Check for pending input (asynchronous Notice or Notify messages);
-	 * also detect the case that the backend just closed the connection.
-	 * Note: we have to loop if the first call to pqReadData successfully
-	 * reads some data, since in that case pqReadData won't notice whether
-	 * the connection is now closed.
-	 */
-	while (pqReadReady(conn)) {
-		if (pqReadData(conn) < 0)
-			return 0;			/* errorMessage already set */
-		parseInput(conn);		/* deal with Notice or Notify, if any */
-	}
-
 	/* Don't try to send if we know there's no live connection. */
 	if (conn->status != CONNECTION_OK)
 	{
@@ -236,6 +218,13 @@ PQsendQuery(PGconn *conn, const char *query)
 				"to the backend.\n");
 		return 0;
 	}
+	/* Can't send while already busy, either. */
+	if (conn->asyncStatus != PGASYNC_IDLE)
+	{
+		sprintf(conn->errorMessage,
+				"PQsendQuery() -- another query already in progress.");
+		return 0;
+	}
 
 	/* clear the error string */
 	conn->errorMessage[0] = '\0';
@@ -361,7 +350,7 @@ parseInput(PGconn *conn)
 					if (pqGets(conn->asyncErrorMessage,ERROR_MSG_LENGTH,conn))
 						return;
 					/* delete any partially constructed result */
-					PQclearAsyncResult(conn);
+					pqClearAsyncResult(conn);
 					/* we leave result NULL while setting asyncStatus=READY;
 					 * this signals an error condition to PQgetResult.
 					 */
@@ -468,7 +457,7 @@ parseInput(PGconn *conn)
 					/* Discard the unexpected message; good idea?? */
 					conn->inStart = conn->inEnd;
 					/* delete any partially constructed result */
-					PQclearAsyncResult(conn);
+					pqClearAsyncResult(conn);
 					conn->asyncStatus = PGASYNC_READY;
 					return;
 			}					/* switch on protocol character */
@@ -583,7 +572,7 @@ getAnotherTuple(PGconn *conn, int binary)
 	{
 		sprintf(conn->asyncErrorMessage,
 				"getAnotherTuple() -- null-values bitmap is too large\n");
-		PQclearAsyncResult(conn);
+		pqClearAsyncResult(conn);
 		conn->asyncStatus = PGASYNC_READY;
 		/* Discard the broken message */
 		conn->inStart = conn->inEnd;
@@ -688,7 +677,7 @@ PQgetResult(PGconn *conn)
 		if (pqWait(TRUE, FALSE, conn) ||
 			pqReadData(conn) < 0)
 		{
-			PQclearAsyncResult(conn);
+			pqClearAsyncResult(conn);
 			conn->asyncStatus = PGASYNC_IDLE;
 			/* conn->errorMessage has been set by pqWait or pqReadData. */
 			return makeEmptyPGresult(conn, PGRES_FATAL_ERROR);
@@ -939,6 +928,16 @@ PQputline(PGconn *conn, const char *s)
 		(void) pqPutnchar(s, strlen(s), conn);
 }
 
+/*
+ * PQputnbytes -- like PQputline, but buffer need not be null-terminated.
+ */
+void
+PQputnbytes(PGconn *conn, const char *buffer, int nbytes)
+{
+	if (conn && conn->sock >= 0)
+		(void) pqPutnchar(buffer, nbytes, conn);
+}
+
 /*
  * PQendcopy
  *		After completing the data transfer portion of a copy in/out,
@@ -968,6 +967,7 @@ PQendcopy(PGconn *conn)
 
 	/* Return to active duty */
 	conn->asyncStatus = PGASYNC_BUSY;
+	conn->errorMessage[0] = '\0';
 
 	/* Wait for the completion response */
 	result = PQgetResult(conn);
@@ -986,8 +986,10 @@ PQendcopy(PGconn *conn)
 	 */
 	PQclear(result);
 
-	sprintf(conn->errorMessage, "PQendcopy: resetting connection\n");
-	DONOTICE(conn, conn->errorMessage);
+	if (conn->errorMessage[0])
+		DONOTICE(conn, conn->errorMessage);
+
+	DONOTICE(conn, "PQendcopy: resetting connection\n");
 
 	PQreset(conn);
 
@@ -1344,23 +1346,40 @@ PQcmdStatus(PGresult *res)
 const char *
 PQoidStatus(PGresult *res)
 {
-	static char oidStatus[32] = {0};
+	char	*p, *e, *scan;
+	int		slen, olen;
 
 	if (!res)
 		return "";
 
-	oidStatus[0] = 0;
+	if (strncmp(res->cmdStatus, "INSERT ", 7) != 0)
+		return "";
 
-	if (strncmp(res->cmdStatus, "INSERT ", 7) == 0)
-	{
-		char	   *p = res->cmdStatus + 7;
-		char	   *e;
+	/* The cmdStatus string looks like
+	 *     INSERT oid count\0
+	 * In order to be able to return an ordinary C string without
+	 * damaging the result for PQcmdStatus or PQcmdTuples, we copy
+	 * the oid part of the string to just after the null, so that
+	 * cmdStatus looks like
+	 *     INSERT oid count\0oid\0
+	 *                       ^ our return value points here
+	 * Pretty klugy eh?  This routine should've just returned an Oid value.
+	 */
 
-		for (e = p; *e != ' ' && *e;)
-			e++;
-		sprintf(oidStatus, "%.*s", e - p, p);
-	}
-	return oidStatus;
+	slen = strlen(res->cmdStatus);
+	p = res->cmdStatus + 7;			/* where oid is now */
+	e = res->cmdStatus + slen + 1; 	/* where to put the oid string */
+
+	for (scan = p; *scan && *scan != ' '; )
+		scan++;
+	olen = scan - p;
+	if (slen + olen + 2 > sizeof(res->cmdStatus))
+		return "";				/* something very wrong if it doesn't fit */
+
+	strncpy(e, p, olen);
+	e[olen] = '\0';
+
+	return e;
 }
 
 /*
diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c
index a59815fc529..8b89e940f2e 100644
--- a/src/interfaces/libpq/fe-lobj.c
+++ b/src/interfaces/libpq/fe-lobj.c
@@ -7,24 +7,29 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.14 1998/07/03 04:24:14 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.15 1998/08/17 03:50:37 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
+
+#include "libpq-fe.h"
+#include "libpq-int.h"
+#include "postgres.h"
+
 #ifdef WIN32
 #include "win32.h"
 #include <io.h>
 #else
+#if !defined(NO_UNISTD_H)
 #include <unistd.h>
 #endif
-#include <stdio.h>
+#endif
 #include <string.h>
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <sys/types.h>
-#include "postgres.h"
-#include "libpq-fe.h"
-#include "libpq/libpq-fs.h"
+
+#include "libpq/libpq-fs.h"	/* must come after sys/stat.h */
+
 
 #define LO_BUFSIZE		  1024
 
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index 512633ca0fc..5608a0de2f8 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -24,15 +24,20 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.17 1998/08/09 02:59:29 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.18 1998/08/17 03:50:38 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
 
+#include "libpq-fe.h"
+#include "libpq-int.h"
+#include "postgres.h"
+#include "pqsignal.h"
+
 #include <stdlib.h>
-#include <stdio.h>
 #include <string.h>
 #include <errno.h>
+#include <signal.h>
 #include <time.h>
 #ifdef WIN32
 #include "win32.h"
@@ -42,13 +47,11 @@
 #include <unistd.h>
 #endif
 #endif /* WIN32 */
-#include <sys/types.h>			/* for fd_set stuff */
+
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #endif
 
-#include "postgres.h"
-#include "libpq-fe.h"
 
 #define DONOTICE(conn,message) \
 	((*(conn)->noticeHook) ((conn)->noticeArg, (message)))
@@ -273,7 +276,7 @@ pqPutInt(int value, int bytes, PGconn *conn)
 /* --------------------------------------------------------------------- */
 /* pqReadReady: is select() saying the file is ready to read?
  */
-int
+static int
 pqReadReady(PGconn *conn)
 {
 	fd_set			input_mask;
@@ -451,7 +454,17 @@ pqFlush(PGconn *conn)
 
 	while (len > 0)
 	{
+		/* Prevent being SIGPIPEd if backend has closed the connection. */
+#ifndef WIN32
+		pqsigfunc oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
+#endif
+
 		int sent = send(conn->sock, ptr, len, 0);
+
+#ifndef WIN32
+		pqsignal(SIGPIPE, oldsighandler);
+#endif
+
 		if (sent < 0)
 		{
 			/* Anything except EAGAIN or EWOULDBLOCK is trouble */
diff --git a/src/interfaces/libpq/fe-print.c b/src/interfaces/libpq/fe-print.c
index f60231be699..4671373090d 100644
--- a/src/interfaces/libpq/fe-print.c
+++ b/src/interfaces/libpq/fe-print.c
@@ -9,31 +9,31 @@
  * didn't really belong there.
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.9 1998/08/09 02:59:30 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.10 1998/08/17 03:50:39 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
+#include "libpq-fe.h"
+#include "libpq-int.h"
+#include "postgres.h"
+#include "pqsignal.h"
+
 #ifdef WIN32
 #include "win32.h"
-#endif
-#include <postgres.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <string.h>
-#ifndef WIN32
+#else
+#if !defined(NO_UNISTD_H)
 #include <unistd.h>
-#include <sys/ioctl.h>
 #endif
-#include "libpq/pqsignal.h"
-#include "libpq-fe.h"
-#ifndef WIN32
+#include <sys/ioctl.h>
 #ifndef HAVE_TERMIOS_H
 #include <sys/termios.h>
 #else
 #include <termios.h>
 #endif
 #endif /* WIN32 */
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
 
 #ifdef MULTIBYTE
 #include "mb/pg_wchar.h"
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index 7e6660c83db..4cd45fca6c3 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: libpq-fe.h,v 1.37 1998/08/09 02:59:31 momjian Exp $
+ * $Id: libpq-fe.h,v 1.38 1998/08/17 03:50:40 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,12 +20,15 @@ extern		"C"
 #endif
 
 #include <stdio.h>
+/* these wouldn't need to be included if PGSockAddr weren't exported: */
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
 /* ----------------
  *		include stuff common to fe and be
  * ----------------
  */
 #include "postgres_ext.h"
-#include "libpq/pqcomm.h"
 #include "lib/dllist.h"
 
 /* Application-visible enum types */
@@ -53,7 +56,7 @@ extern		"C"
 	} ExecStatusType;
 
 /* string descriptions of the ExecStatusTypes */
-	extern const char *pgresStatus[];
+	extern const char * const pgresStatus[];
 
 /*
  * POSTGRES backend dependent Constants.
@@ -61,9 +64,6 @@ extern		"C"
 
 /* ERROR_MSG_LENGTH should really be the same as ELOG_MAXLEN in utils/elog.h*/
 #define ERROR_MSG_LENGTH 4096
-#define COMMAND_LENGTH 20
-#define REMARK_LENGTH 80
-#define PORTAL_NAME_LENGTH 16
 #define CMDSTATUS_LEN 40
 
 /* PGresult and the subsidiary types PGresAttDesc, PGresAttValue
@@ -85,7 +85,8 @@ extern		"C"
    ASCII tuples are guaranteed to be null-terminated
    For binary tuples, the first four bytes of the value is the size,
    and the bytes afterwards are the value.	The binary value is
-   not guaranteed to be null-terminated.  In fact, it can have embedded nulls*/
+   not guaranteed to be null-terminated.  In fact, it can have embedded nulls
+ */
 
 #define NULL_LEN		(-1)	/* pg_result len for NULL value */
 
@@ -134,6 +135,15 @@ extern		"C"
 		PGASYNC_COPY_OUT		/* Copy Out data transfer in progress */
 	} PGAsyncStatusType;
 
+/* generic socket address type for PGconn connection information.
+ * Really shouldn't be visible to users */
+	typedef union PGSockAddr
+	{
+		struct sockaddr sa;
+		struct sockaddr_in in;
+		struct sockaddr_un un;
+	} PGSockAddr;
+
 /* large-object-access data ... allocated only if large-object code is used.
  * Really shouldn't be visible to users */
 	typedef struct pgLobjfuncs
@@ -150,7 +160,9 @@ extern		"C"
 	} PGlobjfuncs;
 
 /* PGconn encapsulates a connection to the backend.
- * XXX contents of this struct really shouldn't be visible to applications
+ * XXX contents of this struct really shouldn't be visible to applications,
+ * but we might break some existing applications if we tried to make it
+ * completely opaque.
  */
 	typedef struct pg_conn
 	{
@@ -179,8 +191,8 @@ extern		"C"
 
 		/* Connection data */
 		int			sock;		/* Unix FD for socket, -1 if not connected */
-		SockAddr	laddr;		/* Local address */
-		SockAddr	raddr;		/* Remote address */
+		PGSockAddr	laddr;		/* Local address */
+		PGSockAddr	raddr;		/* Remote address */
 		int			raddr_len;	/* Length of remote address */
 
 		/* Miscellaneous stuff */
@@ -213,14 +225,14 @@ extern		"C"
 		char		asyncErrorMessage[ERROR_MSG_LENGTH];
 	} PGconn;
 
-	typedef char pqbool;
-
 	/*
 	 * We can't use the conventional "bool", because we are designed to be
 	 * included in a user's program, and user may already have that type
 	 * defined.  Pqbool, on the other hand, is unlikely to be used.
 	 */
 
+	typedef char pqbool;
+
 /* Print options for PQprint() */
 
 	typedef struct _PQprintOpt
@@ -255,7 +267,7 @@ extern		"C"
 	} PQArgBlock;
 
 /* ----------------
- * Structure for the conninfo parameter definitions of PQconnectdb()
+ * Structure for the conninfo parameter definitions returned by PQconndefaults
  * ----------------
  */
 	typedef struct _PQconninfoOption
@@ -274,24 +286,36 @@ extern		"C"
 		int			dispsize;	/* Field size in characters for dialog	*/
 	} PQconninfoOption;
 
+/* ----------------
+ * Exported functions of libpq
+ * ----------------
+ */
+
 /* ===	in fe-connect.c === */
+
 	/* make a new client connection to the backend */
 	extern PGconn *PQconnectdb(const char *conninfo);
+	extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport,
+								const char *pgoptions, const char *pgtty,
+								const char *dbName,
+								const char *login, const char *pwd);
+#define PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME)  \
+	PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL)
+
+	/* get info about connection options known to PQconnectdb */
 	extern PQconninfoOption *PQconndefaults(void);
-	extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
-											const char *pgtty, const char *dbName, const char *login, const char *pwd);
-#define PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME)   PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL)
+
 	/* close the current connection and free the PGconn data structure */
 	extern void PQfinish(PGconn *conn);
-	/* issue a cancel request */
-	extern int	PQrequestCancel(PGconn *conn);
-
 	/*
 	 * close the current connection and restablish a new one with the same
 	 * parameters
 	 */
 	extern void PQreset(PGconn *conn);
 
+	/* issue a cancel request */
+	extern int	PQrequestCancel(PGconn *conn);
+
 	/* Accessor functions for PGconn objects */
 	extern char *PQdb(PGconn *conn);
 	extern char *PQuser(PGconn *conn);
@@ -313,28 +337,33 @@ extern		"C"
 									  void *arg);
 
 /* === in fe-exec.c === */
+
 	/* Simple synchronous query */
 	extern PGresult *PQexec(PGconn *conn, const char *query);
 	extern PGnotify *PQnotifies(PGconn *conn);
+
 	/* Interface for multiple-result or asynchronous queries */
 	extern int  PQsendQuery(PGconn *conn, const char *query);
 	extern PGresult *PQgetResult(PGconn *conn);
+
 	/* Routines for managing an asychronous query */
 	extern int	PQisBusy(PGconn *conn);
 	extern void PQconsumeInput(PGconn *conn);
+
 	/* Routines for copy in/out */
 	extern int	PQgetline(PGconn *conn, char *string, int length);
 	extern void PQputline(PGconn *conn, const char *string);
+	extern void PQputnbytes(PGconn *conn, const char *buffer, int nbytes);
 	extern int	PQendcopy(PGconn *conn);
-	/* Not really meant for application use: */
+
+	/* "Fast path" interface --- not really recommended for application use */
 	extern PGresult *PQfn(PGconn *conn,
-									  int fnid,
-									  int *result_buf,
-									  int *result_len,
-									  int result_is_int,
-									  PQArgBlock *args,
-									  int nargs);
-	extern void PQclearAsyncResult(PGconn *conn);
+						  int fnid,
+						  int *result_buf,
+						  int *result_len,
+						  int result_is_int,
+						  PQArgBlock *args,
+						  int nargs);
 
 	/* Accessor functions for PGresult objects */
 	extern ExecStatusType PQresultStatus(PGresult *res);
@@ -351,14 +380,16 @@ extern		"C"
 	extern char *PQgetvalue(PGresult *res, int tup_num, int field_num);
 	extern int	PQgetlength(PGresult *res, int tup_num, int field_num);
 	extern int	PQgetisnull(PGresult *res, int tup_num, int field_num);
+
 	/* Delete a PGresult */
 	extern void PQclear(PGresult *res);
 
 /* === in fe-print.c === */
+
 	extern void PQprint(FILE *fout,		/* output stream */
 						PGresult *res,
-						PQprintOpt *ps /* option structure */
-		);
+						PQprintOpt *ps); /* option structure */
+
 	/* PQdisplayTuples() is a better version of PQprintTuples(),
 	 * but both are obsoleted by PQprint().
 	 */
@@ -376,37 +407,16 @@ extern		"C"
 													 * or not */
 							  int terseOutput,		/* delimiter bars or
 													 * not? */
-							  int width		/* width of column, if
+							  int width);	/* width of column, if
 											 * 0, use variable width */
-		);
 
 #ifdef MULTIBYTE
 	extern int PQmblen(unsigned char *s);
 #endif
 
-/* === in fe-auth.c === */
-	extern MsgType fe_getauthsvc(char *PQerrormsg);
-	extern void fe_setauthsvc(const char *name, char *PQerrormsg);
-	extern char *fe_getauthname(char *PQerrormsg);
-
-/* === in fe-misc.c === */
-	/* "Get" and "Put" routines return 0 if successful, EOF if not.
-	 * Note that for Get, EOF merely means the buffer is exhausted,
-	 * not that there is necessarily any error.
-	 */
-	extern int	pqGetc(char *result, PGconn *conn);
-	extern int	pqGets(char *s, int maxlen, PGconn *conn);
-	extern int	pqPuts(const char *s, PGconn *conn);
-	extern int	pqGetnchar(char *s, int len, PGconn *conn);
-	extern int	pqPutnchar(const char *s, int len, PGconn *conn);
-	extern int	pqGetInt(int *result, int bytes, PGconn *conn);
-	extern int	pqPutInt(int value, int bytes, PGconn *conn);
-	extern int	pqReadData(PGconn *conn);
-	extern int	pqReadReady(PGconn *conn);
-	extern int	pqFlush(PGconn *conn);
-	extern int	pqWait(int forRead, int forWrite, PGconn *conn);
-
 /* === in fe-lobj.c === */
+
+	/* Large-object access routines */
 	extern int	lo_open(PGconn *conn, Oid lobjId, int mode);
 	extern int	lo_close(PGconn *conn, int fd);
 	extern int	lo_read(PGconn *conn, int fd, char *buf, int len);
@@ -418,36 +428,8 @@ extern		"C"
 	extern Oid	lo_import(PGconn *conn, char *filename);
 	extern int	lo_export(PGconn *conn, Oid lobjId, char *filename);
 
-/* max length of message to send  */
-#define MAX_MESSAGE_LEN 8193
-
-/* maximum number of fields in a tuple */
-#define MAX_FIELDS 512
-
-/* bits in a byte */
-#define BYTELEN 8
-
-/* fall back options if they are not specified by arguments or defined
-   by environment variables */
-#define DefaultHost		"localhost"
-#define DefaultTty		""
-#define DefaultOption	""
-#define DefaultAuthtype		  ""
-#define DefaultPassword		  ""
-
-
-	typedef void *TUPLE;
-#define palloc malloc
-#define pfree free
-
-#if defined(sun) && defined(sparc) && !defined(__SVR4)
-	extern char *sys_errlist[];
-#define strerror(A) (sys_errlist[(A)])
-#endif							/* sunos4 */
-
 #ifdef __cplusplus
 };
-
 #endif
 
 #endif							/* LIBPQ_FE_H */
diff --git a/src/interfaces/libpq/libpqdll.def b/src/interfaces/libpq/libpqdll.def
index 0a46f8273c7..f1a0b324d1a 100644
--- a/src/interfaces/libpq/libpqdll.def
+++ b/src/interfaces/libpq/libpqdll.def
@@ -2,72 +2,59 @@ LIBRARY LIBPQ
 DESCRIPTION "Postgres Client Access Library"
 EXPORTS
 	PQconnectdb 		@ 1
-	PQconndefaults 		@ 2
-	PQsetdbLogin 		@ 3
+	PQsetdbLogin 		@ 2
+	PQconndefaults 		@ 3
 	PQfinish 		@ 4
 	PQreset			@ 5
-	PQdb			@ 6
-	PQuser			@ 7
-	PQhost			@ 8
-	PQoptions		@ 9
-	PQport			@ 10
-	PQtty			@ 11
-	PQstatus		@ 12
-	PQerrorMessage		@ 13
-	PQsocket		@ 14
-	PQtrace			@ 15
-	PQuntrace		@ 16
-	PQexec			@ 17
-	PQnotifies		@ 18
-	PQsendQuery		@ 19
-	PQgetResult		@ 20
-	PQisBusy		@ 21
-	PQconsumeInput		@ 22
-	PQrequestCancel		@ 23
-	PQgetline		@ 24
-	PQputline		@ 25
-	PQendcopy		@ 26
-	PQfn			@ 27
-	PQclearAsyncResult	@ 28
-	PQresultStatus		@ 29
-	PQntuples		@ 30
-	PQnfields		@ 31
-	PQfname			@ 32
-	PQfnumber		@ 33
-	PQftype			@ 34
-	PQfsize			@ 35
-	PQfmod			@ 36
-	PQcmdStatus		@ 37
-	PQoidStatus		@ 38
-	PQcmdTuples		@ 39
-	PQgetvalue		@ 40
-	PQgetlength		@ 41
-	PQgetisnull		@ 42
-	PQclear			@ 43
-	PQprint			@ 44
-	PQdisplayTuples		@ 45
-	PQprintTuples		@ 46
-	fe_getauthsvc		@ 47
-	fe_setauthsvc		@ 48
-	fe_getauthname		@ 49
-	pqGetc			@ 50
-	pqGets			@ 51
-	pqPuts			@ 52
-	pqGetnchar		@ 53
-	pqPutnchar		@ 54
-	pqGetInt		@ 55
-	pqPutInt		@ 56
-	pqReadData		@ 57
-	pqFlush			@ 58
-	pqWait			@ 59
-	lo_open			@ 60
-	lo_close		@ 61
-	lo_read			@ 62
-	lo_write		@ 63
-	lo_lseek		@ 64
-	lo_creat		@ 65
-	lo_tell			@ 66
-	lo_unlink		@ 67
-	lo_import		@ 68
-	lo_export		@ 69
-		
+	PQrequestCancel		@ 6
+	PQdb			@ 7
+	PQuser			@ 8
+	PQhost			@ 9
+	PQoptions		@ 10
+	PQport			@ 11
+	PQtty			@ 12
+	PQstatus		@ 13
+	PQerrorMessage		@ 14
+	PQsocket		@ 15
+	PQtrace			@ 16
+	PQuntrace		@ 17
+	PQsetNoticeProcessor	@ 18
+	PQexec			@ 19
+	PQnotifies		@ 20
+	PQsendQuery		@ 21
+	PQgetResult		@ 22
+	PQisBusy		@ 23
+	PQconsumeInput		@ 24
+	PQgetline		@ 25
+	PQputline		@ 26
+	PQputnbytes		@ 27
+	PQendcopy		@ 28
+	PQfn			@ 29
+	PQresultStatus		@ 30
+	PQntuples		@ 31
+	PQnfields		@ 32
+	PQfname			@ 33
+	PQfnumber		@ 34
+	PQftype			@ 35
+	PQfsize			@ 36
+	PQfmod			@ 37
+	PQcmdStatus		@ 38
+	PQoidStatus		@ 39
+	PQcmdTuples		@ 40
+	PQgetvalue		@ 41
+	PQgetlength		@ 42
+	PQgetisnull		@ 43
+	PQclear			@ 44
+	PQprint			@ 45
+	PQdisplayTuples		@ 46
+	PQprintTuples		@ 47
+	lo_open			@ 48
+	lo_close		@ 49
+	lo_read			@ 50
+	lo_write		@ 51
+	lo_lseek		@ 52
+	lo_creat		@ 53
+	lo_tell			@ 54
+	lo_unlink		@ 55
+	lo_import		@ 56
+	lo_export		@ 57
diff --git a/src/interfaces/libpq/pqsignal.c b/src/interfaces/libpq/pqsignal.c
index 815c00f343d..58de98b450c 100644
--- a/src/interfaces/libpq/pqsignal.c
+++ b/src/interfaces/libpq/pqsignal.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/pqsignal.c,v 1.6 1998/06/15 19:30:26 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/libpq/pqsignal.c,v 1.7 1998/08/17 03:50:43 scrappy Exp $
  *
  * NOTES
  *		This shouldn't be in libpq, but the monitor and some other
@@ -17,10 +17,9 @@
  *-------------------------------------------------------------------------
  */
 #include <stdlib.h>
-
 #include <signal.h>
 
-#include "libpq/pqsignal.h"
+#include "pqsignal.h"
 
 pqsigfunc
 pqsignal(int signo, pqsigfunc func)
-- 
GitLab