diff --git a/src/backend/libpq/Makefile b/src/backend/libpq/Makefile index a7c7f13704..84b2b9a3a3 100644 --- a/src/backend/libpq/Makefile +++ b/src/backend/libpq/Makefile @@ -4,7 +4,7 @@ # Makefile for libpq subsystem (backend half of libpq interface) # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.5 1997/03/12 21:17:45 scrappy Exp $ +# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.6 1997/03/18 20:14:32 scrappy Exp $ # #------------------------------------------------------------------------- @@ -23,7 +23,7 @@ CFLAGS+= $(KRBFLAGS) LDADD+= $(KRBLIBS) endif -OBJS = be-dumpdata.o be-fsstubs.o be-pqexec.o \ +OBJS = be-dumpdata.o be-fsstubs.o be-pqexec.o pqcomprim.o\ auth.o hba.o pqcomm.o portal.o util.o portalbuf.o pqpacket.o pqsignal.o \ password.o diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 6b8ecdac28..10fa738c0f 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -1,4 +1,4 @@ -/*------------------------------------------------------------------------- + /*------------------------------------------------------------------------- * * pqcomm.c-- * Communication functions between the Frontend and the Backend @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.12 1997/03/12 21:17:58 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.13 1997/03/18 20:14:33 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -206,26 +206,29 @@ pq_getstr(char *s, int maxlen) * the line ended within maxlen bytes.) * 1 in other cases */ -int -PQgetline(char *s, int maxlen) -{ - int c = '\0'; - +int PQgetline(char *s, int maxlen) + { if (!Pfin || !s || maxlen <= 1) return(EOF); - for (; maxlen > 1 && (c = pq_getc(Pfin)) != '\n' && c != EOF; --maxlen) { - *s++ = c; - } + if(fgets(s, maxlen - 1, Pfin) == NULL) + { + return feof(Pfin) ? EOF : 1; + } + else + { + for( ; *s; *s++) + { + if(*s == '\n') + { *s = '\0'; + break; + } + } + } - if (c == EOF) { - return(EOF); /* error -- reached EOF before \n */ - } else if (c == '\n') { - return(0); /* done with this line */ + return 0; } - return(1); /* returning a full buffer */ -} /* * USER FUNCTION - sends a string to the backend. @@ -252,6 +255,9 @@ PQputline(char *s) int pq_getnchar(char *s, int off, int maxlen) { + return pqGetNBytes(s + off, maxlen, Pfin); + +#if 0 int c = '\0'; if (Pfin == (FILE *) NULL) { @@ -270,6 +276,7 @@ pq_getnchar(char *s, int off, int maxlen) if (c == EOF) return(EOF); return(!EOF); +#endif } /* -------------------------------- @@ -282,20 +289,38 @@ pq_getnchar(char *s, int off, int maxlen) int pq_getint(int b) { - int n, c, p; + int n, status = 1; - if (Pfin == (FILE *) NULL) { -/* elog(DEBUG, "pq_getint: Input descriptor is null"); */ - return(EOF); + if(!Pfin) + return EOF; + /* mjl: Seems inconsisten w/ return value of pq_putint (void). Also, + EOF is a valid return value for an int! XXX */ + + switch(b) + { + case 1: + status = ((n = fgetc(Pfin)) == EOF); + break; + case 2: + pqGetShort(&n, Pfin); + break; + case 4: + pqGetLong(&n, Pfin); + break; + default: + fprintf(stderr, "** Unsupported size %d\n", b); } - n = p = 0; - while (b-- && (c = pq_getc(Pfin)) != EOF && p < 32) { - n |= (c & 0xff) << p; - p += 8; + if(status) + { + (void) sprintf(PQerrormsg, + "FATAL: pq_getint failed: errno=%d\n", errno); + fputs(PQerrormsg, stderr); + pqdebug("%s", PQerrormsg); + n = 0; } - return(n); + return n; } /* -------------------------------- @@ -305,26 +330,13 @@ pq_getint(int b) void pq_putstr(char *s) { - int status; - - if (Pfout) { - status = fputs(s, Pfout); - if (status == EOF) { + if(pqPutString(s, Pfout)) + { (void) sprintf(PQerrormsg, - "FATAL: pq_putstr: fputs() failed: errno=%d\n", - errno); + "FATAL: pq_putstr: fputs() failed: errno=%d\n", errno); fputs(PQerrormsg, stderr); pqdebug("%s", PQerrormsg); } - status = fputc('\0', Pfout); - if (status == EOF) { - (void) sprintf(PQerrormsg, - "FATAL: pq_putstr: fputc() failed: errno=%d\n", - errno); - fputs(PQerrormsg, stderr); - pqdebug("%s", PQerrormsg); - } - } } /* -------------------------------- @@ -333,13 +345,9 @@ pq_putstr(char *s) */ void pq_putnchar(char *s, int n) -{ - int status; - - if (Pfout) { - while (n--) { - status = fputc(*s++, Pfout); - if (status == EOF) { + { + if(pqPutNBytes(s, n, Pfout)) + { (void) sprintf(PQerrormsg, "FATAL: pq_putnchar: fputc() failed: errno=%d\n", errno); @@ -347,8 +355,6 @@ pq_putnchar(char *s, int n) pqdebug("%s", PQerrormsg); } } - } -} /* -------------------------------- * pq_putint - send an integer to connection @@ -362,22 +368,31 @@ pq_putint(int i, int b) { int status; - if (b > 4) - b = 4; + if(!Pfout) return; - if (Pfout) { - while (b--) { - status = fputc(i & 0xff, Pfout); - i >>= 8; - if (status == EOF) { + status = 1; + switch(b) + { + case 1: + status = (fputc(i, Pfout) == EOF); + break; + case 2: + status = pqPutShort(i, Pfout); + break; + case 4: + status = pqPutLong(i, Pfout); + break; + default: + fprintf(stderr, "** Unsupported size %d\n", b); + } + + if(status) + { (void) sprintf(PQerrormsg, - "FATAL: pq_putint: fputc() failed: errno=%d\n", - errno); + "FATAL: pq_putint failed: errno=%d\n", errno); fputs(PQerrormsg, stderr); pqdebug("%s", PQerrormsg); } - } - } } /* --- diff --git a/src/backend/libpq/pqcomprim.c b/src/backend/libpq/pqcomprim.c index fa1fc866b8..abb634b536 100644 --- a/src/backend/libpq/pqcomprim.c +++ b/src/backend/libpq/pqcomprim.c @@ -27,6 +27,164 @@ #error Please write byte order macros #endif +/* --------------------------------------------------------------------- */ +int pqPutShort(const int integer, FILE *f) + { + int retval = 0; + u_short n; + + n = hton_s(integer); + if(fwrite(&n, sizeof(u_short), 1, f) != 1) + retval = EOF; + + return retval; + } + +/* --------------------------------------------------------------------- */ +int pqPutLong(const int integer, FILE *f) + { + int retval = 0; + u_long n; + + n = hton_l(integer); + if(fwrite(&n, sizeof(u_long), 1, f) != 1) + retval = EOF; + + return retval; + } + +/* --------------------------------------------------------------------- */ +int pqGetShort(int *result, FILE *f) + { + int retval = 0; + u_short n; + + if(fread(&n, sizeof(u_short), 1, f) != 1) + retval = EOF; + + *result = ntoh_s(n); + return retval; + } + +/* --------------------------------------------------------------------- */ +int pqGetLong(int *result, FILE *f) + { + int retval = 0; + u_long n; + + if(fread(&n, sizeof(u_long), 1, f) != 1) + retval = EOF; + + *result = ntoh_l(n); + return retval; + } + +/* --------------------------------------------------------------------- */ +/* pqGetNBytes: Read a chunk of exactly len bytes in buffer s. + Return 0 if ok. +*/ +int pqGetNBytes(char* s, const int len, FILE *f) + { + int cnt; + + if (f == NULL) + return EOF; + + cnt = fread(s, 1, len, f); + s[cnt] = '\0'; + /* mjl: actually needs up to len+1 bytes, is this okay? XXX */ + + return (cnt == len) ? 0 : EOF; + } + +/* --------------------------------------------------------------------- */ +int pqPutNBytes(const char *s, const int len, FILE *f) + { + if (f == NULL) + return 0; + + if(fwrite(s, 1, len, f) != len) + return EOF; + + return 0; + } + +/* --------------------------------------------------------------------- */ +int pqGetString(char *s, int len, FILE *f) + { + int c; + + if (f == NULL) + return EOF; + + while (len-- && (c = getc(f)) != EOF && c) + *s++ = c; + *s = '\0'; + /* mjl: actually needs up to len+1 bytes, is this okay? XXX */ + + return 0; + } + +/* --------------------------------------------------------------------- */ +int pqPutString(const char *s, FILE *f) + { + if (f == NULL) + return 0; + + if (fputs(s, f) == EOF) + return EOF; + + fputc('\0', f); /* important to send an ending \0 since backend expects it */ + fflush(f); + + return 0; + } + +/* --------------------------------------------------------------------- */ +int pqGetByte(FILE *f) + { + return getc(f); + } + +/* --------------------------------------------------------------------- */ +int pqPutByte(const int c, FILE *f) + { + if(!f) return 0; + + return (putc(c, f) == c) ? 0 : EOF; + } + +/* --------------------------------------------------------------------- */ + +#include +#include + +#include "postgres.h" +#include "libpq/pqcomm.h" + +/* --------------------------------------------------------------------- */ +/* Is the other way around than system ntoh/hton, so we roll our own + here */ + +#if BYTE_ORDER == LITTLE_ENDIAN +#define ntoh_s(n) n +#define ntoh_l(n) n +#define hton_s(n) n +#define hton_l(n) n +#endif +#if BYTE_ORDER == BIG_ENDIAN +#define ntoh_s(n) (u_short)(((u_char *) &n)[0] << 8 | ((u_char *) &n)[1]); +#define ntoh_l(n) (u_long)(((u_char *)&n)[0] << 24 | ((u_char *)&n)[1] << 16 |\ + ((u_char *)&n)[2] << 8 | ((u_char *)&n)[3]); +#define hton_s(n) (ntoh_s(n)) +#define hton_l(n) (ntoh_l(n)) +#endif +#if BYTE_ORDER == PDP_ENDIAN +#endif +#ifndef ntoh_s +#error Please write byte order macros +#endif + /* --------------------------------------------------------------------- */ int pqPutShort(const int integer, FILE *f) { diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c index 65ea4b10dd..d5fa06071f 100644 --- a/src/backend/utils/init/globals.c +++ b/src/backend/utils/init/globals.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.6 1997/03/18 16:35:46 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.7 1997/03/18 20:14:46 scrappy Exp $ * * NOTES * Globals used all over the place should be declared here and not @@ -71,6 +71,9 @@ bool CDayLight = false; int CTimeZone = 0; char CTZName[8] = ""; +char DateFormat[20] = "%d-%m-%Y"; /* mjl: sizes! or better malloc? XXX */ +char FloatFormat[20] = "%f"; + char *IndexedCatalogNames[] = { AttributeRelationName, ProcedureRelationName, diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 81fcece346..a7648feb99 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -11,7 +11,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: miscadmin.h,v 1.6 1997/03/18 16:36:23 scrappy Exp $ + * $Id: miscadmin.h,v 1.7 1997/03/18 20:15:19 scrappy Exp $ * * NOTES * some of the information in this file will be moved to @@ -70,6 +70,9 @@ extern bool CDayLight; extern int CTimeZone; extern char CTZName[]; +extern char FloatFormat[]; +extern char DateFormat[]; + extern Oid LastOidProcessed; /* for query rewrite */ #define MAX_PARSE_BUFFER 8192 diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 60f55ae599..4b3a8630a5 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.24 1997/03/12 21:23:09 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.25 1997/03/18 20:15:39 scrappy Exp $ * *------------------------------------------------------------------------- */ @@ -100,6 +100,16 @@ static PQconninfoOption PQconninfoOptions[] = { NULL, NULL, 0 } }; +struct EnvironmentOptions + { + const char *envName, *pgName; + } EnvironmentOptions[] = + { + { "PG_DATEFORMAT", "pg_dateformat" }, + { "PG_FLOATFORMAT", "pg_floatformat" }, + { NULL } + }; + /* ---------------- * PQconnectdb * @@ -514,6 +524,24 @@ connectDB(PGconn *conn) conn->port = port; + { + struct EnvironmentOptions *eo; + char setQuery[80]; /* mjl: size okay? XXX */ + + for(eo = EnvironmentOptions; eo->envName; eo++) + { + const char *val; + + if(val = getenv(eo->envName)) + { + PGresult *res; + + sprintf(setQuery, "SET %s TO \".60%s\"", eo->pgName, val); + res = PQexec(conn, setQuery); + PQclear(res); /* Don't care? */ + } + } + } return CONNECTION_OK; connect_errReturn: