*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/* 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)
*/
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' */ );
*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)
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
*
* 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",
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)
{
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",
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;
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);
/* 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",
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/*
* 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).
*/
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 */
*/
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);
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",
*
*
* 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
*
*/
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
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;
char *hostName;
int status;
int silentflag = 0;
- char hostbuf[MAXHOSTNAMELEN];
bool DataDirOK; /* We have a usable PGDATA value */
+ char hostbuf[MAXHOSTNAMELEN];
progname = argv[0];
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)
{
else
DebugLvl = 1;
break;
+ case 'i':
+ NetServer = 1;
+ break;
case 'm':
MultiplexedBackends = 1;
MultiplexedBackendPort = atoi(optarg);
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);
}
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");
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;
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);
}
/* 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;
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)
static void
send_error_reply(Port *port, const char *errormsg)
{
- int rc; /* return code from sendto */
+ int rc; /* return code from write */
char *reply;
/*
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"
* 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);
}
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);
}
}
+
*
*
* 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
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
#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 */
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);
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 $");
}
/* ----------------
*
*
* 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
{
SystemPortAddress address = atoi(postport);
- if (address == 0)
- elog(FATAL, "InitCommunication: invalid POSTPORT");
-
if (MyBackendTag == -1)
elog(FATAL, "InitCommunication: missing POSTID");
*
* 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
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
+#include <sys/un.h>
/*
#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
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 */
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{"dbname", "PGDATABASE", NULL, NULL,
"Database-Name", "", 20},
- {"host", "PGHOST", DefaultHost, NULL,
+ {"host", "PGHOST", NULL, NULL,
"Database-Host", "", 40},
{"port", "PGPORT", DEF_PGPORT, NULL,
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);
MsgType msgtype;
int laddrlen = sizeof(struct sockaddr);
Port *port = conn->port;
- int portno;
+ int portno, family, len;
/*
* Initialize the startup packet.
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",
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;
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);
}