diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index d0734d3ea5..e78569ae2a 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.22 1997/09/08 21:43:45 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.23 1997/11/07 20:51:27 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -855,8 +855,8 @@ authident(const char DataDir[], /* The username returned by ident */ - ident(port.raddr.sin_addr, port.laddr.sin_addr, - port.raddr.sin_port, port.laddr.sin_port, + ident(port.raddr.in.sin_addr, port.laddr.in.sin_addr, + port.raddr.in.sin_port, port.laddr.in.sin_port, &ident_failed, ident_username); if (ident_failed) @@ -906,10 +906,13 @@ hba_recvauth(const Port *port, const char database[], const char user[], */ int retvalue; + /* UNIX socket always OK, for now */ + if(port->raddr.in.sin_family == AF_UNIX) + return STATUS_OK; /* Our eventual return value */ + - - find_hba_entry(DataDir, port->raddr.sin_addr, database, + find_hba_entry(DataDir, port->raddr.in.sin_addr, database, &host_ok, &userauth, usermap_name, false /* don't find password entries of type 'password' */ ); diff --git a/src/backend/libpq/password.c b/src/backend/libpq/password.c index aaa204b4db..de803905cb 100644 --- a/src/backend/libpq/password.c +++ b/src/backend/libpq/password.c @@ -26,7 +26,7 @@ verify_password(char *user, char *password, Port *port, *test_pw; char salt[3]; - find_hba_entry(DataDir, port->raddr.sin_addr, database, + find_hba_entry(DataDir, port->raddr.in.sin_addr, database, &host_ok, &userauth, pw_file_name, true); if (!host_ok) diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 40a9f32c23..a75631e5f0 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.23 1997/09/18 20:20:39 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.24 1997/11/07 20:51:34 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -571,20 +571,27 @@ pq_async_notify() * * RETURNS: STATUS_OK or STATUS_ERROR */ + +static char sock_path[100] = ""; + +static void do_unlink() +{ + if (sock_path[0]) unlink(sock_path); +} + int StreamServerPort(char *hostName, short portName, int *fdP) { struct sockaddr_in sin; - int fd; + struct sockaddr_un sun; + int fd, err, family; int one = 1; - - if (!hostName) - hostName = "localhost"; + family = hostName != NULL ? AF_INET : AF_UNIX; MemSet((char *) &sin, 0, sizeof sin); - if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + if ((fd = socket(family, SOCK_STREAM, 0)) < 0) { sprintf(PQerrormsg, "FATAL: StreamServerPort: socket() failed: errno=%d\n", @@ -593,7 +600,7 @@ StreamServerPort(char *hostName, short portName, int *fdP) pqdebug("%s", PQerrormsg); return (STATUS_ERROR); } - + if (family == AF_UNIX) on_exitpg(do_unlink, (caddr_t) 0); if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one))) == -1) { @@ -604,11 +611,24 @@ StreamServerPort(char *hostName, short portName, int *fdP) pqdebug("%s", PQerrormsg); return (STATUS_ERROR); } - - sin.sin_family = AF_INET; - sin.sin_port = htons(portName); - - if (bind(fd, (struct sockaddr *) & sin, sizeof sin) < 0) + if (family == AF_UNIX) + { + size_t len; + bzero(&sun, sizeof(sun)); + sun.sun_family = family; + len = UNIXSOCK_PATH(sun,portName); + strcpy(sock_path, sun.sun_path); + err = bind(fd, (struct sockaddr *) &sun, len); + } + else + { + bzero(&sin, sizeof(sin)); + sin.sin_family = family; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = htons(portName); + err = bind(fd, (struct sockaddr *) &sin, sizeof sin); + } + if (err < 0) { sprintf(PQerrormsg, "FATAL: StreamServerPort: bind() failed: errno=%d\n", @@ -645,26 +665,30 @@ StreamServerPort(char *hostName, short portName, int *fdP) int StreamConnection(int server_fd, Port *port) { - int addrlen; + int len, addrlen; + int family = port->raddr.in.sin_family; /* accept connection (and fill in the client (remote) address) */ - addrlen = sizeof(struct sockaddr_in); + len = family == AF_INET ? + sizeof(struct sockaddr_in) : sizeof(struct sockaddr_un); + addrlen = len; if ((port->sock = accept(server_fd, - (struct sockaddr *) & port->raddr, - &addrlen)) < 0) + (struct sockaddr *) & port->raddr, + &addrlen)) < 0) { elog(WARN, "postmaster: StreamConnection: accept: %m"); return (STATUS_ERROR); } - + /* fill in the server (local) address */ - addrlen = sizeof(struct sockaddr_in); + addrlen = len; if (getsockname(port->sock, (struct sockaddr *) & port->laddr, &addrlen) < 0) { elog(WARN, "postmaster: StreamConnection: getsockname: %m"); return (STATUS_ERROR); } + if (family == AF_INET) { struct protoent *pe; int on = 1; @@ -714,45 +738,50 @@ StreamClose(int sock) int StreamOpen(char *hostName, short portName, Port *port) { + int len, err; struct hostent *hp; - int laddrlen = sizeof(struct sockaddr_in); extern int errno; - - if (!hostName) - hostName = "localhost"; - + /* set up the server (remote) address */ - if (!(hp = gethostbyname(hostName)) || hp->h_addrtype != AF_INET) - { + MemSet((char *) &port->raddr, 0, sizeof(port->raddr)); + if (hostName) + { + if (!(hp = gethostbyname(hostName)) || hp->h_addrtype != AF_INET) + { sprintf(PQerrormsg, - "FATAL: StreamOpen: unknown hostname: %s\n", - hostName); + "FATAL: StreamOpen: unknown hostname: %s\n", + hostName); fputs(PQerrormsg, stderr); pqdebug("%s", PQerrormsg); return (STATUS_ERROR); - } - MemSet((char *) &port->raddr, 0, sizeof(port->raddr)); - memmove((char *) &(port->raddr.sin_addr), - (char *) hp->h_addr, - hp->h_length); - port->raddr.sin_family = AF_INET; - port->raddr.sin_port = htons(portName); - + } + memmove((char *) &(port->raddr.in.sin_addr), + (char *) hp->h_addr, + hp->h_length); + port->raddr.in.sin_family = AF_INET; + port->raddr.in.sin_port = htons(portName); + len = sizeof(struct sockaddr_in); + } + else + { + port->raddr.un.sun_family = AF_UNIX; + len = UNIXSOCK_PATH(port->raddr.un,portName); + } /* connect to the server */ - if ((port->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + if ((port->sock=socket(port->raddr.in.sin_family, SOCK_STREAM, 0)) < 0) { sprintf(PQerrormsg, - "FATAL: StreamOpen: socket() failed: errno=%d\n", + "FATAL: StreamOpen: socket() failed: errno=%d\n", errno); fputs(PQerrormsg, stderr); pqdebug("%s", PQerrormsg); return (STATUS_ERROR); } - if (connect(port->sock, (struct sockaddr *) & port->raddr, - sizeof(port->raddr)) < 0) + err = connect(port->sock, (struct sockaddr*) &port->raddr, len); + if (err < 0) { sprintf(PQerrormsg, - "FATAL: StreamOpen: connect() failed: errno=%d\n", + "FATAL: StreamOpen: connect() failed: errno=%d\n", errno); fputs(PQerrormsg, stderr); pqdebug("%s", PQerrormsg); @@ -761,7 +790,7 @@ StreamOpen(char *hostName, short portName, Port *port) /* fill in the client address */ if (getsockname(port->sock, (struct sockaddr *) & port->laddr, - &laddrlen) < 0) + &len) < 0) { sprintf(PQerrormsg, "FATAL: StreamOpen: getsockname() failed: errno=%d\n", diff --git a/src/backend/libpq/pqpacket.c b/src/backend/libpq/pqpacket.c index 1e95794c85..d699f00d0f 100644 --- a/src/backend/libpq/pqpacket.c +++ b/src/backend/libpq/pqpacket.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.8 1997/09/08 21:43:52 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.9 1997/11/07 20:51:36 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -85,7 +85,7 @@ PacketReceive(Port *port, /* receive port */ /* * Assume port->nBytes is zero unless we were interrupted during - * non-blocking I/O. This first recvfrom() is to get the hdr + * non-blocking I/O. This first recv() is to get the hdr * information so we know how many bytes to read. Life would be very * complicated if we read too much data (buffering). */ @@ -98,8 +98,7 @@ PacketReceive(Port *port, /* receive port */ else { /* peeking into the incoming message */ - cc = recvfrom(port->sock, (char *) &(buf->len), hdrLen, flag, - (struct sockaddr *) & (port->raddr), &addrLen); + cc = recv(port->sock, (char *) &(buf->len), hdrLen, flag); if (cc < hdrLen) { /* if cc is negative, the system call failed */ @@ -179,8 +178,7 @@ PacketReceive(Port *port, /* receive port */ */ while (packetLen) { - cc = recvfrom(port->sock, tmp, packetLen, 0, - (struct sockaddr *) & (port->raddr), &addrLen); + cc = read(port->sock, tmp, packetLen); if (cc < 0) return (STATUS_ERROR); @@ -224,18 +222,13 @@ PacketSend(Port *port, PacketLen len, bool nonBlocking) { - PacketLen totalLen; - int addrLen = sizeof(struct sockaddr_in); + PacketLen doneLen; Assert(!nonBlocking); Assert(buf); - totalLen = len; - - len = sendto(port->sock, (Addr) buf, totalLen, /* flags */ 0, - (struct sockaddr *) & (port->raddr), addrLen); - - if (len < totalLen) + doneLen = write(port->sock, buf, len); + if (doneLen < len) { sprintf(PQerrormsg, "FATAL: PacketSend: couldn't send complete packet: errno=%d\n", diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index a936fff9eb..2eef75ca5e 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.59 1997/10/25 01:09:55 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.60 1997/11/07 20:51:47 momjian Exp $ * * NOTES * @@ -131,7 +131,8 @@ static char *progname = (char *) NULL; */ static char Execfile[MAXPATHLEN] = ""; -static int ServerSock = INVALID_SOCK; /* stream socket server */ +static int ServerSock_INET = INVALID_SOCK; /* stream socket server */ +static int ServerSock_UNIX = INVALID_SOCK; /* stream socket server */ /* * Set by the -o option @@ -148,6 +149,8 @@ static char ExtraOptions[ARGV_SIZE] = ""; static int Reinit = 1; static int SendStop = 0; +static int NetServer = 0; /* if not zero, postmaster listen for + non-local connections */ static int MultiplexedBackends = 0; static int MultiplexedBackendPort; @@ -244,8 +247,8 @@ PostmasterMain(int argc, char *argv[]) char *hostName; int status; int silentflag = 0; - char hostbuf[MAXHOSTNAMELEN]; bool DataDirOK; /* We have a usable PGDATA value */ + char hostbuf[MAXHOSTNAMELEN]; progname = argv[0]; @@ -267,7 +270,7 @@ PostmasterMain(int argc, char *argv[]) DataDir = getenv("PGDATA"); /* default value */ opterr = 0; - while ((opt = getopt(argc, argv, "a:B:b:D:dm:Mno:p:Ss")) != EOF) + while ((opt = getopt(argc, argv, "a:B:b:D:dim:Mno:p:Ss")) != EOF) { switch (opt) { @@ -315,6 +318,9 @@ PostmasterMain(int argc, char *argv[]) else DebugLvl = 1; break; + case 'i': + NetServer = 1; + break; case 'm': MultiplexedBackends = 1; MultiplexedBackendPort = atoi(optarg); @@ -387,11 +393,20 @@ PostmasterMain(int argc, char *argv[]) exit(1); } - - status = StreamServerPort(hostName, PostPortName, &ServerSock); + if (NetServer) + { + status = StreamServerPort(hostName, PostPortName, &ServerSock_INET); + if (status != STATUS_OK) + { + fprintf(stderr, "%s: cannot create INET stream port\n", + progname); + exit(1); + } + } + status = StreamServerPort(NULL, PostPortName, &ServerSock_UNIX); if (status != STATUS_OK) { - fprintf(stderr, "%s: cannot create stream port\n", + fprintf(stderr, "%s: cannot create UNIX stream port\n", progname); exit(1); } @@ -459,6 +474,7 @@ usage(const char *progname) fprintf(stderr, "\t-b backend\tuse a specific backend server executable\n"); fprintf(stderr, "\t-d [1|2|3]\tset debugging level\n"); fprintf(stderr, "\t-D datadir\tset data directory\n"); + fprintf(stderr, "\t-i \tlisten on TCP/IP sockets as well as Unix domain socket\n"); fprintf(stderr, "\t-m \tstart up multiplexing backends\n"); fprintf(stderr, "\t-n\t\tdon't reinitialize shared memory after abnormal exit\n"); fprintf(stderr, "\t-o option\tpass 'option' to each backend servers\n"); @@ -471,13 +487,11 @@ usage(const char *progname) static int ServerLoop(void) { - int serverFd = ServerSock; - fd_set rmask, - basemask; + fd_set rmask, basemask; int nSockets, nSelected, status, - newFd; + oldFd, newFd; Dlelem *next, *curr; @@ -493,10 +507,16 @@ ServerLoop(void) int orgsigmask = sigblock(0); #endif - - nSockets = ServerSock + 1; FD_ZERO(&basemask); - FD_SET(ServerSock, &basemask); + FD_SET(ServerSock_UNIX, &basemask); + nSockets = ServerSock_UNIX; + if (ServerSock_INET != INVALID_SOCK) + { + FD_SET(ServerSock_INET, &basemask); + if (ServerSock_INET > ServerSock_UNIX) + nSockets = ServerSock_INET; + } + nSockets++; #ifdef HAVE_SIGPROCMASK sigprocmask(0, 0, &oldsigmask); @@ -542,15 +562,21 @@ ServerLoop(void) } /* new connection pending on our well-known port's socket */ - if (FD_ISSET(ServerSock, &rmask)) + oldFd = -1; + if (FD_ISSET(ServerSock_UNIX, &rmask)) + oldFd = ServerSock_UNIX; + else if (ServerSock_INET != INVALID_SOCK && + FD_ISSET(ServerSock_INET, &rmask)) + oldFd = ServerSock_INET; + if (oldFd >= 0) { - + /* * connect and make an addition to PortList. If the * connection dies and we notice it, just forget about the * whole thing. */ - if (ConnCreate(serverFd, &newFd) == STATUS_OK) + if (ConnCreate(oldFd, &newFd) == STATUS_OK) { if (newFd >= nSockets) nSockets = newFd + 1; @@ -560,8 +586,12 @@ ServerLoop(void) fprintf(stderr, "%s: ServerLoop: connect on %d\n", progname, newFd); } + else if (DebugLvl) + fprintf(stderr, + "%s: ServerLoop: connect failed: (%d) %s\n", + progname, errno, strerror(errno)); --nSelected; - FD_CLR(ServerSock, &rmask); + FD_CLR(oldFd, &rmask); } if (DebugLvl > 1) @@ -793,7 +823,7 @@ ConnStartup(Port *port, int *status, static void send_error_reply(Port *port, const char *errormsg) { - int rc; /* return code from sendto */ + int rc; /* return code from write */ char *reply; /* @@ -812,7 +842,7 @@ send_error_reply(Port *port, const char *errormsg) sprintf(reply, "E%s", errormsg); - rc = send(port->sock, (Addr) reply, strlen(reply) + 1, /* flags */ 0); + rc = write(port->sock, (Addr) reply, strlen(reply) + 1); if (rc < 0) fprintf(stderr, "%s: ServerLoop:\t\t" @@ -1269,8 +1299,8 @@ ExitPostmaster(int status) * Not sure of the semantics here. When the Postmaster dies, should * the backends all be killed? probably not. */ - if (ServerSock != INVALID_SOCK) - close(ServerSock); + if (ServerSock_INET != INVALID_SOCK) close(ServerSock_INET); + if (ServerSock_UNIX != INVALID_SOCK) close(ServerSock_UNIX); exitpg(status); } @@ -1285,9 +1315,10 @@ dumpstatus(SIGNAL_ARGS) fprintf(stderr, "%s: dumpstatus:\n", progname); fprintf(stderr, "\tsock %d: nBytes=%d, laddr=0x%lx, raddr=0x%lx\n", - port->sock, port->nBytes, - (long int) port->laddr.sin_addr.s_addr, - (long int) port->raddr.sin_addr.s_addr); + port->sock, port->nBytes, + (long int) port->laddr.in.sin_addr.s_addr, + (long int) port->raddr.in.sin_addr.s_addr); curr = DLGetSucc(curr); } } + diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 8654c11ad8..729f9a0003 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.51 1997/11/02 15:25:45 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.52 1997/11/07 20:51:54 momjian Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -832,7 +832,6 @@ PostgresMain(int argc, char *argv[]) bool multiplexedBackend; char *hostName; /* the host name of the backend server */ - char hostbuf[MAXHOSTNAMELEN]; int serverSock; int serverPortnum = 0; int nSelected; /* number of descriptors ready from @@ -884,15 +883,10 @@ PostgresMain(int argc, char *argv[]) #endif /* - * get hostname is either the environment variable PGHOST or - * 'localhost' + * get hostname is either the environment variable PGHOST or NULL + * NULL means Unix-socket only */ - if (!(hostName = getenv("PGHOST"))) - { - if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0) - strcpy(hostbuf, "localhost"); - hostName = hostbuf; - } + hostName = getenv("PGHOST"); DataDir = getenv("PGDATA"); /* default */ multiplexedBackend = false; /* default */ @@ -1252,7 +1246,7 @@ PostgresMain(int argc, char *argv[]) if (multiplexedBackend) { if (serverPortnum == 0 || - StreamServerPort(hostName, serverPortnum, &serverSock) != STATUS_OK) + StreamServerPort(hostName, serverPortnum, &serverSock) != STATUS_OK) { fprintf(stderr, "Postgres: cannot create stream port %d\n", serverPortnum); exit(1); @@ -1343,7 +1337,7 @@ PostgresMain(int argc, char *argv[]) if (IsUnderPostmaster == false) { puts("\nPOSTGRES backend interactive interface"); - puts("$Revision: 1.51 $ $Date: 1997/11/02 15:25:45 $"); + puts("$Revision: 1.52 $ $Date: 1997/11/07 20:51:54 $"); } /* ---------------- diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index a6e670e5f6..1589c83dce 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.15 1997/11/07 06:38:46 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.16 1997/11/07 20:51:58 momjian Exp $ * * NOTES * InitPostgres() is the function called from PostgresMain @@ -310,9 +310,6 @@ InitCommunication() { SystemPortAddress address = atoi(postport); - if (address == 0) - elog(FATAL, "InitCommunication: invalid POSTPORT"); - if (MyBackendTag == -1) elog(FATAL, "InitCommunication: missing POSTID"); diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h index 65892b8a81..399e3231b6 100644 --- a/src/include/libpq/pqcomm.h +++ b/src/include/libpq/pqcomm.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: pqcomm.h,v 1.15 1997/09/12 22:26:13 momjian Exp $ + * $Id: pqcomm.h,v 1.16 1997/11/07 20:52:06 momjian Exp $ * * NOTES * Some of this should move to libpq.h @@ -19,6 +19,7 @@ #include #include #include +#include /* @@ -27,6 +28,10 @@ #define PATH_SIZE 64 #define ARGV_SIZE 64 +#define UNIXSOCK_PATH(sun,port) \ + sprintf(sun.sun_path,"/tmp/.s.PGSQL.%d",port) + sizeof(sun.sun_family) + 1; + + /* The various kinds of startup messages are for the various kinds of user authentication systems. In the beginning, there was only STARTUP_MSG and all connections were unauthenticated. Now, there are @@ -106,9 +111,10 @@ typedef struct Port int sock; /* file descriptor */ int mask; /* select mask */ int nBytes; /* nBytes read in so far */ - struct sockaddr_in laddr; /* local addr (us) */ - struct sockaddr_in raddr; /* remote addr (them) */ - + /* local addr (us) */ + union { struct sockaddr_in in; struct sockaddr_un un; } laddr; + /* remote addr (them) */ + union { struct sockaddr_in in; struct sockaddr_un un; } raddr; /* * PacketBufId id; *//* id of packet buf currently in use */ diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 942082b0d0..f5ace69dc0 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.42 1997/09/18 20:22:46 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.43 1997/11/07 20:52:15 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -86,7 +86,7 @@ static PQconninfoOption PQconninfoOptions[] = { {"dbname", "PGDATABASE", NULL, NULL, "Database-Name", "", 20}, - {"host", "PGHOST", DefaultHost, NULL, + {"host", "PGHOST", NULL, NULL, "Database-Host", "", 40}, {"port", "PGPORT", DEF_PGPORT, NULL, @@ -340,11 +340,8 @@ PQsetdb(const char *pghost, const char *pgport, const char *pgoptions, const cha if (!pghost || pghost[0] == '\0') { - if (!(tmp = getenv("PGHOST"))) - { - tmp = DefaultHost; - } - conn->pghost = strdup(tmp); + conn->pghost = NULL; + if (tmp = getenv("PGHOST")) conn->pghost = strdup(tmp); } else conn->pghost = strdup(pghost); @@ -473,7 +470,7 @@ connectDB(PGconn *conn) MsgType msgtype; int laddrlen = sizeof(struct sockaddr); Port *port = conn->port; - int portno; + int portno, family, len; /* * Initialize the startup packet. @@ -501,7 +498,8 @@ connectDB(PGconn *conn) port = (Port *) malloc(sizeof(Port)); MemSet((char *) port, 0, sizeof(Port)); - if (!(hp = gethostbyname(conn->pghost)) || hp->h_addrtype != AF_INET) + if (conn->pghost && + (!(hp = gethostbyname(conn->pghost)) || hp->h_addrtype != AF_INET)) { (void) sprintf(conn->errorMessage, "connectDB() -- unknown hostname: %s\n", @@ -509,29 +507,37 @@ connectDB(PGconn *conn) goto connect_errReturn; } MemSet((char *) &port->raddr, 0, sizeof(port->raddr)); - memmove((char *) &(port->raddr.sin_addr), - (char *) hp->h_addr, - hp->h_length); - port->raddr.sin_family = AF_INET; portno = atoi(conn->pgport); - port->raddr.sin_port = htons((unsigned short) (portno)); - + port->raddr.in.sin_family = family = conn->pghost ? AF_INET : AF_UNIX; + if (family == AF_INET) + { + memmove((char *) &(port->raddr.in.sin_addr), + (char *) hp->h_addr, + hp->h_length); + port->raddr.in.sin_port = htons((unsigned short) (portno)); + len = sizeof(struct sockaddr_in); + } + else + { + len = UNIXSOCK_PATH(port->raddr.un,portno); + } /* connect to the server */ - if ((port->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + if ((port->sock = socket(family, SOCK_STREAM, 0)) < 0) { (void) sprintf(conn->errorMessage, "connectDB() -- socket() failed: errno=%d\n%s\n", errno, strerror(errno)); goto connect_errReturn; } - if (connect(port->sock, (struct sockaddr *) & port->raddr, - sizeof(port->raddr)) < 0) + if (connect(port->sock, (struct sockaddr *) &port->raddr, len) < 0) { (void) sprintf(conn->errorMessage, - "connectDB() failed: Is the postmaster running at '%s' on port '%s'?\n", - conn->pghost, conn->pgport); + "connectDB() failed: Is the postmaster running at '%s' on port '%s'?\n", + conn->pghost ? conn->pghost : "UNIX Socket", + conn->pgport); goto connect_errReturn; } + if (family == AF_INET) { struct protoent *pe; int on = 1; @@ -773,19 +779,11 @@ packetSend(Port *port, PacketLen len, bool nonBlocking) { - PacketLen totalLen; - int addrLen = sizeof(struct sockaddr_in); - - totalLen = len; - - len = sendto(port->sock, (Addr) buf, totalLen, /* flags */ 0, - (struct sockaddr *) & (port->raddr), addrLen); - - if (len < totalLen) + PacketLen doneLen = write(port->sock, buf, len); + if (doneLen < len) { return (STATUS_ERROR); } - return (STATUS_OK); }