diff --git a/doc/src/sgml/environ.sgml b/doc/src/sgml/environ.sgml index dc5741a95d..830502a696 100644 --- a/doc/src/sgml/environ.sgml +++ b/doc/src/sgml/environ.sgml @@ -47,16 +47,17 @@ $ export PATH -If your site administrator has not set things up in the -default way, you may have some more work to do. For example, if the database - server machine is a remote machine, you -will need to set the PGHOST environment variable to the name -of the database server machine. The environment variable -PGPORT may also have to be set. The bottom line is this: if -you try to start an application program and it complains -that it cannot connect to the postmaster, - you should immediately consult your site administrator to make sure that your -environment is properly set up. - + +If your site administrator has not set things up in the default way, +you may have some more work to do. For example, if the database server +machine is a remote machine, you will need to set the +PGHOST environment variable to the name of the +database server machine. The environment variable +PGPORT or PGUNIXSOCKET may also have +to be set. The bottom line is this: if you try to start an application +program and it complains that it cannot connect to the +postmaster, you should immediately consult +your site administrator to make sure that your environment is properly +set up. diff --git a/doc/src/sgml/libpq++.sgml b/doc/src/sgml/libpq++.sgml index 44f7f97dcd..a3b045e219 100644 --- a/doc/src/sgml/libpq++.sgml +++ b/doc/src/sgml/libpq++.sgml @@ -1,5 +1,5 @@ @@ -91,6 +91,13 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.17 2000/09/29 20:21: backend. + + + PGUNIXSOCKET sets the full Unix domain socket + file name for communicating with the Postgres + backend. + + PGDATABASE sets the default diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index a23ef89546..d9b96b8620 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -1,5 +1,5 @@ @@ -133,6 +133,15 @@ PGconn *PQconnectdb(const char *conninfo) + + unixsocket + + + Full path to Unix-domain socket file to connect to at the server host. + + + + dbname @@ -554,6 +563,16 @@ char *PQport(const PGconn *conn) + + +PQunixsocket + Returns the name of the Unix-domain socket of the connection. + +char *PQunixsocket(const PGconn *conn) + + + + PQtty @@ -1832,6 +1851,13 @@ backend. +PGPORT sets the default port or local Unix domain socket +file extension for communicating with the Postgres +backend. + + + + PGDATABASE sets the default Postgres database name. diff --git a/doc/src/sgml/ref/createdb.sgml b/doc/src/sgml/ref/createdb.sgml index 3d1aca17bb..d5199e307a 100644 --- a/doc/src/sgml/ref/createdb.sgml +++ b/doc/src/sgml/ref/createdb.sgml @@ -1,5 +1,5 @@ @@ -56,6 +56,18 @@ Postgres documentation + + -k, --unixsocket path + + + Specifies the Unix-domain socket on which the + postmaster is running. + Without this option, the socket is created in /tmp + based on the port number. + + + + -U, --username username diff --git a/doc/src/sgml/ref/createlang.sgml b/doc/src/sgml/ref/createlang.sgml index f7c0540eac..0258646ad7 100644 --- a/doc/src/sgml/ref/createlang.sgml +++ b/doc/src/sgml/ref/createlang.sgml @@ -1,5 +1,5 @@ @@ -101,6 +101,18 @@ Postgres documentation + + -k, --unixsocket path + + + Specifies the Unix-domain socket on which the + postmaster is running. + Without this option, the socket is created in /tmp + based on the port number. + + + + -U, --username username diff --git a/doc/src/sgml/ref/createuser.sgml b/doc/src/sgml/ref/createuser.sgml index 5f3db58159..9845fcba1e 100644 --- a/doc/src/sgml/ref/createuser.sgml +++ b/doc/src/sgml/ref/createuser.sgml @@ -1,5 +1,5 @@ @@ -55,6 +55,18 @@ Postgres documentation + + -k, --unixsocket path + + + Specifies the Unix-domain socket on which the + postmaster is running. + Without this option, the socket is created in /tmp + based on the port number. + + + + -e, --echo diff --git a/doc/src/sgml/ref/dropdb.sgml b/doc/src/sgml/ref/dropdb.sgml index 5e28c4d528..c265c016e9 100644 --- a/doc/src/sgml/ref/dropdb.sgml +++ b/doc/src/sgml/ref/dropdb.sgml @@ -1,5 +1,5 @@ @@ -55,6 +55,18 @@ Postgres documentation + + -k, --unixsocket path + + + Specifies the Unix-domain socket on which the + postmaster is running. + Without this option, the socket is created in /tmp + based on the port number. + + + + -U, --username username diff --git a/doc/src/sgml/ref/droplang.sgml b/doc/src/sgml/ref/droplang.sgml index 48645d78a5..5d75a89fde 100644 --- a/doc/src/sgml/ref/droplang.sgml +++ b/doc/src/sgml/ref/droplang.sgml @@ -1,5 +1,5 @@ @@ -101,6 +101,18 @@ Postgres documentation + + -k, --unixsocket path + + + Specifies the Unix-domain socket on which the + postmaster is running. + Without this option, the socket is created in /tmp + based on the port number. + + + + -U, --username username diff --git a/doc/src/sgml/ref/dropuser.sgml b/doc/src/sgml/ref/dropuser.sgml index b72c5d865f..a2b1e537e5 100644 --- a/doc/src/sgml/ref/dropuser.sgml +++ b/doc/src/sgml/ref/dropuser.sgml @@ -1,5 +1,5 @@ @@ -55,6 +55,18 @@ Postgres documentation + + -k, --unixsocket path + + + Specifies the Unix-domain socket on which the + postmaster is running. + Without this option, the socket is created in /tmp + based on the port number. + + + + -e, --echo diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index f0d1facfca..b0ad3e49cf 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -1,5 +1,5 @@ @@ -24,7 +24,9 @@ Postgres documentation pg_dump [ dbname ] -pg_dump [ -h host ] [ -p port ] +pg_dump [ -h host ] + [ -k path ] + [ -p port ] [ -t table ] [ -a ] [ -c ] [ -d ] [ -D ] [ -i ] [ -n ] [ -N ] [ -o ] [ -s ] [ -u ] [ -v ] [ -x ] @@ -204,6 +206,21 @@ pg_dump [ -h host ] [ -p + + -k path + + + Specifies the local Unix domain socket file path + on which the postmaster + is listening for connections. + Without this option, the socket path name defaults to + the value of the PGUNIXSOCKET environment + variable (if set), otherwise it is constructed + from the port number. + + + + -p port diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml index a4d5c8d45a..1d78b9008c 100644 --- a/doc/src/sgml/ref/pg_dumpall.sgml +++ b/doc/src/sgml/ref/pg_dumpall.sgml @@ -1,5 +1,5 @@ @@ -23,7 +23,7 @@ Postgres documentation 1999-07-20 -pg_dumpall [ -h host ] [ -p port ] [ -a ] [ -d ] [ -D ] [ -O ] [ -s ] [ -u ] [ -v ] [ -x ] [ --accounts-only ] +pg_dumpall [ -h host ] [ -k path ] [ -p port ] [ -a ] [ -d ] [ -D ] [ -O ] [ -s ] [ -u ] [ -v ] [ -x ] [ --accounts-only ] @@ -149,6 +149,21 @@ pg_dumpall [ -h host ] [ -p + + -k path + + + Specifies the local Unix domain socket file path + on which the postmaster + is listening for connections. + Without this option, the socket path name defaults to + the value of the PGUNIXSOCKET environment + variable (if set), otherwise it is constructed + from the port number. + + + + -p port diff --git a/doc/src/sgml/ref/postmaster.sgml b/doc/src/sgml/ref/postmaster.sgml index eba01b30d4..e8e34c739f 100644 --- a/doc/src/sgml/ref/postmaster.sgml +++ b/doc/src/sgml/ref/postmaster.sgml @@ -1,5 +1,5 @@ @@ -24,7 +24,9 @@ Postgres documentation postmaster [ -B nBuffers ] [ -D DataDir ] [ -N maxBackends ] [ -S ] - [ -d DebugLevel ] [ -i ] [ -l ] + [ -d DebugLevel ] + [ -h hostname ] [ -i ] + [ -k path ] [ -l ] [ -o BackendOptions ] [ -p port ] [ -n | -s ] @@ -123,6 +125,36 @@ postmaster [ -B nBuffers ] [ -D + + -h hostName + + + Specifies the TCP/IP hostname or address + on which the postmaster + is to listen for connections from frontend applications. Defaults to + the value of the + PGHOST + environment variable, or if PGHOST + is not set, then defaults to "all", meaning listen on all configured addresses + (including localhost). + + + If you use a hostname or address other than "all", do not try to run + multiple instances of postmaster on the + same IP address but different ports. Doing so will result in them + attempting (incorrectly) to use the same shared memory segments. + Also, if you use a hostname other than "all", all of the host's IP addresses + on which postmaster instances are + listening must be distinct in the two last octets. + + + If you do use "all" (the default), then each instance must listen on a + different port (via -p or PGPORT). And, of course, do + not try to use both approaches on one host. + + + + -i @@ -134,6 +166,35 @@ postmaster [ -B nBuffers ] [ -D + + -k path + + + Specifies the local Unix domain socket path name + on which the postmaster + is to listen for connections from frontend applications. Defaults to + the value of the + PGUNIXSOCKET + environment variable, or if PGUNIXSOCKET + is not set, then defaults to a file in /tmp + constructed from the port number. + + + You can use this option to put the Unix-domain socket in a + directory that is private to one or more users using Unix + directory permissions. This is necessary for securely + creating databases automatically on shared machines. + In that situation, also disallow all TCP/IP connections + initially in pg_hba.conf. + If you specify a socket path other than the + default then all frontend applications (including + psql) must specify the same + socket path using either command-line options or + PGUNIXSOCKET. + + + + -l diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 446449d95e..ca8d14f6de 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1,5 +1,5 @@ @@ -1329,6 +1329,19 @@ Access permissions for database "test" + + -k, --unixsocket path + + + Specifies the Unix-domain socket on which the + postmaster is running. + Without this option, the socket is created in /tmp + based on the port number. + + + + + -H, --html diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml index 1417ac55f9..7a701f216d 100644 --- a/doc/src/sgml/ref/vacuumdb.sgml +++ b/doc/src/sgml/ref/vacuumdb.sgml @@ -1,5 +1,5 @@ @@ -136,6 +136,18 @@ Postgres documentation + + -k, --unixsocket path + + + Specifies the Unix-domain socket on which the + postmaster is running. + Without this option, the socket is created in /tmp + based on the port number. + + + + -U username --username username diff --git a/doc/src/sgml/start.sgml b/doc/src/sgml/start.sgml index b5093ffed1..3b484f50f9 100644 --- a/doc/src/sgml/start.sgml +++ b/doc/src/sgml/start.sgml @@ -1,5 +1,5 @@ @@ -110,8 +110,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/start.sgml,v 1.13 2000/09/29 20:21:34 peter will need to set the PGHOST environment variable to the name of the database server machine. The environment variable - PGPORT may also have to be set. The bottom - line is this: if + PGPORT or PGUNIXSOCKET may also have to be set. + The bottom line is this: if you try to start an application program and it complains that it cannot connect to the postmaster, you should immediately consult your site administrator to make diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 355144937a..2434d6ff16 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -29,7 +29,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pqcomm.c,v 1.109 2000/11/01 21:14:01 petere Exp $ + * $Id: pqcomm.c,v 1.110 2000/11/13 15:18:09 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -169,13 +169,14 @@ StreamDoUnlink(void) /* * StreamServerPort -- open a sock stream "listening" port. * - * This initializes the Postmaster's connection-accepting port. + * This initializes the Postmaster's connection-accepting port fdP. * * RETURNS: STATUS_OK or STATUS_ERROR */ int -StreamServerPort(int family, unsigned short portName, int *fdP) +StreamServerPort(int family, char *hostName, unsigned short portName, + char *unixSocketName, int *fdP) { SockAddr saddr; int fd, @@ -218,7 +219,8 @@ StreamServerPort(int family, unsigned short portName, int *fdP) #ifdef HAVE_UNIX_SOCKETS if (family == AF_UNIX) { - len = UNIXSOCK_PATH(saddr.un, portName); + UNIXSOCK_PATH(saddr.un, portName, unixSocketName); + len = UNIXSOCK_LEN(saddr.un); strcpy(sock_path, saddr.un.sun_path); /* * If the socket exists but nobody has an advisory lock on it we @@ -242,7 +244,27 @@ StreamServerPort(int family, unsigned short portName, int *fdP) if (family == AF_INET) { - saddr.in.sin_addr.s_addr = htonl(INADDR_ANY); + /* TCP/IP socket */ + if (hostName[0] == '\0') + saddr.in.sin_addr.s_addr = htonl(INADDR_ANY); + else + { + struct hostent *hp; + + hp = gethostbyname(hostName); + if ((hp == NULL) || (hp->h_addrtype != AF_INET)) + { + snprintf(PQerrormsg, PQERRORMSG_LENGTH, + "FATAL: StreamServerPort: gethostbyname(%s) failed: %s\n", + hostName, hstrerror(h_errno)); + fputs(PQerrormsg, stderr); + pqdebug("%s", PQerrormsg); + return STATUS_ERROR; + } + memmove((char *) &(saddr.in.sin_addr), (char *) hp->h_addr, + hp->h_length); + } + saddr.in.sin_port = htons(portName); len = sizeof(struct sockaddr_in); } diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index e50c0ee4d0..c6b645b15b 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.182 2000/11/12 20:51:51 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.183 2000/11/13 15:18:11 momjian Exp $ * * NOTES * @@ -114,6 +114,8 @@ static Dllist *PortList; /* The socket number we are listening for connections on */ int PostPortName; +char * UnixSocketName; +char * HostName; /* * This is a sequence number that indicates how many times we've had to @@ -224,7 +226,7 @@ extern void SetThisStartUpID(void); static void pmdaemonize(int argc, char *argv[]); static Port *ConnCreate(int serverFd); static void ConnFree(Port *port); -static void reset_shared(int port); +static void reset_shared(unsigned short port); static void SIGHUP_handler(SIGNAL_ARGS); static void pmdie(SIGNAL_ARGS); static void reaper(SIGNAL_ARGS); @@ -366,7 +368,7 @@ PostmasterMain(int argc, char *argv[]) * will occur. */ opterr = 1; - while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Film:MN:no:p:SsV-:?")) != EOF) + while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Fh:ik:lm:MN:no:p:SsV-:?")) != EOF) { switch(opt) { @@ -422,7 +424,7 @@ PostmasterMain(int argc, char *argv[]) #ifdef HAVE_INT_OPTRESET optreset = 1; #endif - while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Film:MN:no:p:SsV-:?")) != EOF) + while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Fh:ik:lm:MN:no:p:SsV-:?")) != EOF) { switch (opt) { @@ -456,9 +458,16 @@ PostmasterMain(int argc, char *argv[]) case 'F': enableFsync = false; break; + case 'h': + HostName = optarg; + break; case 'i': NetServer = true; break; + case 'k': + /* Set PGUNIXSOCKET by hand. */ + UnixSocketName = optarg; + break; #ifdef USE_SSL case 'l': EnableSSL = true; @@ -606,8 +615,9 @@ PostmasterMain(int argc, char *argv[]) if (NetServer) { - status = StreamServerPort(AF_INET, (unsigned short) PostPortName, - &ServerSock_INET); + status = StreamServerPort(AF_INET, HostName, + (unsigned short) PostPortName, UnixSocketName, + &ServerSock_INET); if (status != STATUS_OK) { fprintf(stderr, "%s: cannot create INET stream port\n", @@ -617,8 +627,9 @@ PostmasterMain(int argc, char *argv[]) } #ifdef HAVE_UNIX_SOCKETS - status = StreamServerPort(AF_UNIX, (unsigned short) PostPortName, - &ServerSock_UNIX); + status = StreamServerPort(AF_UNIX, HostName, + (unsigned short) PostPortName, UnixSocketName, + &ServerSock_UNIX); if (status != STATUS_OK) { fprintf(stderr, "%s: cannot create UNIX stream port\n", @@ -789,7 +800,9 @@ usage(const char *progname) printf(" -d 1-5 debugging level\n"); printf(" -D database directory\n"); printf(" -F turn fsync off\n"); + printf(" -h hostname specify hostname or IP address\n"); printf(" -i enable TCP/IP connections\n"); + printf(" -k path specify Unix-domain socket name\n"); #ifdef USE_SSL printf(" -l enable SSL connections\n"); #endif @@ -1302,12 +1315,76 @@ ConnFree(Port *conn) free(conn); } +/* + * get_host_port -- return a pseudo port number (16 bits) + * derived from the primary IP address of HostName. + */ +static unsigned short +get_host_port(void) +{ + static unsigned short hostPort = 0; + + if (hostPort == 0) + { + SockAddr saddr; + struct hostent *hp; + + hp = gethostbyname(HostName); + if ((hp == NULL) || (hp->h_addrtype != AF_INET)) + { + char msg[1024]; + snprintf(msg, sizeof(msg), + "FATAL: get_host_port: gethostbyname(%s) failed: %s\n", + HostName, hstrerror(h_errno)); + fputs(msg, stderr); + pqdebug("%s", msg); + exit(1); + } + memmove((char *) &(saddr.in.sin_addr), + (char *) hp->h_addr, + hp->h_length); + hostPort = ntohl(saddr.in.sin_addr.s_addr) & 0xFFFF; + } + + return hostPort; +} + /* * reset_shared -- reset shared memory and semaphores */ static void -reset_shared(int port) +reset_shared(unsigned short port) { + /* + * A typical ipc_key is 5432001, which is port 5432, sequence + * number 0, and 01 as the index in IPCKeyGetBufferMemoryKey(). + * The 32-bit INT_MAX is 2147483 6 47. + * + * The default algorithm for calculating the IPC keys assumes that all + * instances of postmaster on a given host are listening on different + * ports. In order to work (prevent shared memory collisions) if you + * run multiple PostgreSQL instances on the same port and different IP + * addresses on a host, we change the algorithm if you give postmaster + * the -h option, or set PGHOST, to a value other than the internal + * default. + * + * If HostName is set, then we generate the IPC keys using the + * last two octets of the IP address instead of the port number. + * This algorithm assumes that no one will run multiple PostgreSQL + * instances on one host using two IP addresses that have the same two + * last octets in different class C networks. If anyone does, it + * would be rare. + * + * So, if you use -h or PGHOST, don't try to run two instances of + * PostgreSQL on the same IP address but different ports. If you + * don't use them, then you must use different ports (via -p or + * PGPORT). And, of course, don't try to use both approaches on one + * host. + */ + + if (HostName[0] != '\0') + port = get_host_port(); + ipc_key = port * 1000 + shmem_seq * 100; CreateSharedMemoryAndSemaphores(ipc_key, MaxBackends); shmem_seq += 1; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 8fe7bd36fa..ecdc1d1a75 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -4,7 +4,7 @@ * Support for grand unified configuration scheme, including SET * command, configuration file, and command line options. * - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.16 2000/11/09 11:25:59 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.17 2000/11/13 15:18:12 momjian Exp $ * * Copyright 2000 by PostgreSQL Global Development Group * Written by Peter Eisentraut . @@ -304,6 +304,12 @@ ConfigureNamesString[] = {"unix_socket_group", PGC_POSTMASTER, &Unix_socket_group, "", NULL}, + {"unixsocket", PGC_POSTMASTER, &UnixSocketName, + "", NULL}, + + {"hostname", PGC_POSTMASTER, &HostName, + "", NULL}, + {NULL, 0, NULL, NULL, NULL} }; diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h index 8fceb26c8e..ffe071a665 100644 --- a/src/bin/pg_dump/pg_backup.h +++ b/src/bin/pg_dump/pg_backup.h @@ -99,8 +99,9 @@ typedef struct _restoreOptions { int useDB; char *dbname; - char *pgport; char *pghost; + char *pgport; + char *pgunixsocket; int ignoreVersion; int requirePassword; @@ -122,6 +123,7 @@ PGconn* ConnectDatabase(Archive *AH, const char* dbname, const char* pghost, const char* pgport, + const char* pgunixsocket, const int reqPwd, const int ignoreVersion); diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index d8a969b41e..085a2eb329 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -131,8 +131,9 @@ void RestoreArchive(Archive* AHX, RestoreOptions *ropt) if (AH->version < K_VERS_1_3) die_horribly(AH, "Direct database connections are not supported in pre-1.3 archives"); - ConnectDatabase(AHX, ropt->dbname, ropt->pghost, ropt->pgport, - ropt->requirePassword, ropt->ignoreVersion); + ConnectDatabase(AHX, ropt->dbname, ropt->pghost, ropt->pgport, + ropt->pgunixsocket, ropt->requirePassword, + ropt->ignoreVersion); /* * If no superuser was specified then see if the current user will do... diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h index 2c7291e6c6..a938f5e339 100644 --- a/src/bin/pg_dump/pg_backup_archiver.h +++ b/src/bin/pg_dump/pg_backup_archiver.h @@ -187,6 +187,7 @@ typedef struct _archiveHandle { char *archdbname; /* DB name *read* from archive */ char *pghost; char *pgport; + char *pgunixsocket; PGconn *connection; PGconn *blobConnection; /* Connection for BLOB xref */ int txActive; /* Flag set if TX active on connection */ diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c index 4b8873c3a2..082edd5824 100644 --- a/src/bin/pg_dump/pg_backup_db.c +++ b/src/bin/pg_dump/pg_backup_db.c @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * -*------------------------------------------------------------------------- + *------------------------------------------------------------------------- */ #include /* for getopt() */ @@ -273,6 +273,7 @@ PGconn* ConnectDatabase(Archive *AHX, const char* dbname, const char* pghost, const char* pgport, + const char* pgunixsocket, const int reqPwd, const int ignoreVersion) { @@ -307,6 +308,15 @@ PGconn* ConnectDatabase(Archive *AHX, else AH->pgport = NULL; + if (pgunixsocket != NULL) + { + AH->pgport = strdup(pgunixsocket); + sprintf(tmp_string, "unixsocket=%s ", AH->pgunixsocket); + strcat(connect_string, tmp_string); + } + else + AH->pgunixsocket = NULL; + sprintf(tmp_string, "dbname=%s ", AH->dbname); strcat(connect_string, tmp_string); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 4b765f5288..738425a3eb 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -22,7 +22,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.177 2000/10/31 14:20:30 pjw Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.178 2000/11/13 15:18:13 momjian Exp $ * * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb * @@ -200,6 +200,7 @@ help(const char *progname) " -F, --format {c|f|p} output file format (custom, files, plain text)\n" " -h, --host server host name\n" " -i, --ignore-version proceed when database version != pg_dump version\n" + " -k, --unixsocket server Unix-domain socket name\n" " -n, --no-quotes suppress most quotes around identifiers\n" " -N, --quotes enable most quotes around identifiers\n" " -o, --oids dump object ids (oids)\n" @@ -226,6 +227,7 @@ help(const char *progname) " -F {c|f|p} output file format (custom, files, plain text)\n" " -h server host name\n" " -i proceed when database version != pg_dump version\n" + " -k server Unix-domain socket name\n" " -n suppress most quotes around identifiers\n" " -N enable most quotes around identifiers\n" " -o dump object ids (oids)\n" @@ -629,6 +631,7 @@ main(int argc, char **argv) const char *dbname = NULL; const char *pghost = NULL; const char *pgport = NULL; + const char *pgunixsocket = NULL; char *tablename = NULL; bool oids = false; TableInfo *tblinfo; @@ -658,6 +661,7 @@ main(int argc, char **argv) {"attribute-inserts", no_argument, NULL, 'D'}, {"host", required_argument, NULL, 'h'}, {"ignore-version", no_argument, NULL, 'i'}, + {"unixsocket", required_argument, NULL, 'k'}, {"no-reconnect", no_argument, NULL, 'R'}, {"no-quotes", no_argument, NULL, 'n'}, {"quotes", no_argument, NULL, 'N'}, @@ -752,6 +756,10 @@ main(int argc, char **argv) ignore_version = true; break; + case 'k': /* server Unix-domain socket */ + pgunixsocket = optarg; + break; + case 'n': /* Do not force double-quotes on * identifiers */ force_quotes = false; @@ -948,7 +956,8 @@ main(int argc, char **argv) dbname = argv[optind]; /* Open the database using the Archiver, so it knows about it. Errors mean death */ - g_conn = ConnectDatabase(g_fout, dbname, pghost, pgport, use_password, ignore_version); + g_conn = ConnectDatabase(g_fout, dbname, pghost, pgport, pgunixsocket, + use_password, ignore_version); /* * Start serializable transaction to dump consistent data diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index 458482ed51..cafb7e9df6 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -101,6 +101,7 @@ struct option cmdopts[] = { { "ignore-version", 0, NULL, 'i'}, { "index", 2, NULL, 'I'}, { "list", 0, NULL, 'l'}, + { "unixsocket", 1, NULL, 'k' }, { "no-acl", 0, NULL, 'x' }, { "no-owner", 0, NULL, 'O'}, { "no-reconnect", 0, NULL, 'R' }, @@ -132,9 +133,9 @@ int main(int argc, char **argv) progname = *argv; #ifdef HAVE_GETOPT_LONG - while ((c = getopt_long(argc, argv, "acCd:f:F:h:i:lNoOp:P:rRsS:t:T:uU:vx", cmdopts, NULL)) != EOF) + while ((c = getopt_long(argc, argv, "acCd:f:F:h:i:k:lNoOp:P:rRsS:t:T:uU:vx", cmdopts, NULL)) != EOF) #else - while ((c = getopt(argc, argv, "acCd:f:F:h:i:lNoOp:P:rRsS:t:T:uU:vx")) != -1) + while ((c = getopt(argc, argv, "acCd:f:F:h:i:k:lNoOp:P:rRsS:t:T:uU:vx")) != -1) #endif { switch (c) @@ -170,6 +171,10 @@ int main(int argc, char **argv) case 'i': opts->ignoreVersion = 1; break; + case 'k': + if (strlen(optarg) != 0) + opts->pgunixsocket = strdup(optarg); + break; case 'N': opts->origOrder = 1; break; diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index d563070ae6..65c05a4ac9 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.36 2000/09/17 20:33:45 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.37 2000/11/13 15:18:14 momjian Exp $ */ #include "postgres.h" #include "command.h" @@ -1202,6 +1202,7 @@ do_connect(const char *new_dbname, const char *new_user) SetVariable(pset.vars, "USER", NULL); SetVariable(pset.vars, "HOST", NULL); SetVariable(pset.vars, "PORT", NULL); + SetVariable(pset.vars, "UNIXSOCKET", NULL); SetVariable(pset.vars, "ENCODING", NULL); /* If dbname is "" then use old name, else new one (even if NULL) */ @@ -1231,6 +1232,7 @@ do_connect(const char *new_dbname, const char *new_user) do { need_pass = false; + /* FIXME use PQconnectdb to support passing the Unix socket */ pset.db = PQsetdbLogin(PQhost(oldconn), PQport(oldconn), NULL, NULL, dbparam, userparam, pwparam); @@ -1307,6 +1309,7 @@ do_connect(const char *new_dbname, const char *new_user) SetVariable(pset.vars, "USER", PQuser(pset.db)); SetVariable(pset.vars, "HOST", PQhost(pset.db)); SetVariable(pset.vars, "PORT", PQport(pset.db)); + SetVariable(pset.vars, "UNIXSOCKET", PQunixsocket(pset.db)); SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding)); pset.issuper = test_superuser(PQuser(pset.db)); diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index ddc2be3c4f..da0542df59 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.23 2000/08/29 09:36:48 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.24 2000/11/13 15:18:14 momjian Exp $ */ #include "postgres.h" #include "common.h" @@ -329,6 +329,7 @@ PSQLexec(const char *query) SetVariable(pset.vars, "DBNAME", NULL); SetVariable(pset.vars, "HOST", NULL); SetVariable(pset.vars, "PORT", NULL); + SetVariable(pset.vars, "UNIXSOCKET", NULL); SetVariable(pset.vars, "USER", NULL); SetVariable(pset.vars, "ENCODING", NULL); return NULL; @@ -508,6 +509,7 @@ SendQuery(const char *query) SetVariable(pset.vars, "DBNAME", NULL); SetVariable(pset.vars, "HOST", NULL); SetVariable(pset.vars, "PORT", NULL); + SetVariable(pset.vars, "UNIXSOCKET", NULL); SetVariable(pset.vars, "USER", NULL); SetVariable(pset.vars, "ENCODING", NULL); return false; diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 3dfd7d8e8d..b9ee9caa67 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.32 2000/09/22 23:02:00 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.33 2000/11/13 15:18:14 momjian Exp $ */ #include "postgres.h" #include "help.h" @@ -103,6 +103,16 @@ usage(void) puts(")"); puts(" -H HTML table output mode (-P format=html)"); + + /* Display default Unix-domain socket */ + env = getenv("PGUNIXSOCKET"); + printf(" -k Specify Unix domain socket name (default: "); + if (env) + fputs(env, stdout); + else + fputs("computed from the port", stdout); + puts(")"); + puts(" -l List available databases, then exit"); puts(" -n Disable readline"); puts(" -o Send query output to filename (or |pipe)"); diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c index 1177c6f3f3..d29bc12ddb 100644 --- a/src/bin/psql/prompt.c +++ b/src/bin/psql/prompt.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/prompt.c,v 1.13 2000/08/20 10:55:34 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/prompt.c,v 1.14 2000/11/13 15:18:14 momjian Exp $ */ #include "postgres.h" #include "prompt.h" @@ -190,6 +190,11 @@ get_prompt(promptStatus_t status) if (pset.db && PQport(pset.db)) strncpy(buf, PQport(pset.db), MAX_PROMPT_SIZE); break; + /* DB server Unix-domain socket */ + case '<': + if (pset.db && PQunixsocket(pset.db)) + strncpy(buf, PQunixsocket(pset.db), MAX_PROMPT_SIZE); + break; /* DB server user name */ case 'n': if (pset.db) diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index f96cc7980b..9b0e60f0a3 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.37 2000/09/17 20:33:45 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.38 2000/11/13 15:18:14 momjian Exp $ */ #include "postgres.h" @@ -65,6 +65,7 @@ struct adhoc_opts char *dbname; char *host; char *port; + char *unixsocket; char *username; enum _actions action; char *action_string; @@ -161,6 +162,7 @@ main(int argc, char *argv[]) do { need_pass = false; + /* FIXME use PQconnectdb to allow setting the unix socket */ pset.db = PQsetdbLogin(options.host, options.port, NULL, NULL, options.action == ACT_LIST_DB ? "template1" : options.dbname, username, password); @@ -206,6 +208,7 @@ main(int argc, char *argv[]) SetVariable(pset.vars, "USER", PQuser(pset.db)); SetVariable(pset.vars, "HOST", PQhost(pset.db)); SetVariable(pset.vars, "PORT", PQport(pset.db)); + SetVariable(pset.vars, "UNIXSOCKET", PQunixsocket(pset.db)); SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding)); #ifndef WIN32 @@ -320,6 +323,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) {"field-separator", required_argument, NULL, 'F'}, {"host", required_argument, NULL, 'h'}, {"html", no_argument, NULL, 'H'}, + {"unixsocket", required_argument, NULL, 'k'}, {"list", no_argument, NULL, 'l'}, {"no-readline", no_argument, NULL, 'n'}, {"output", required_argument, NULL, 'o'}, @@ -353,14 +357,14 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) memset(options, 0, sizeof *options); #ifdef HAVE_GETOPT_LONG - while ((c = getopt_long(argc, argv, "aAc:d:eEf:F:lh:Hno:p:P:qRsStT:uU:v:VWxX?", long_options, &optindex)) != -1) + while ((c = getopt_long(argc, argv, "aAc:d:eEf:F:lh:Hk:no:p:P:qRsStT:uU:v:VWxX?", long_options, &optindex)) != -1) #else /* not HAVE_GETOPT_LONG */ /* * Be sure to leave the '-' in here, so we can catch accidental long * options. */ - while ((c = getopt(argc, argv, "aAc:d:eEf:F:lh:Hno:p:P:qRsStT:uU:v:VWxX?-")) != -1) + while ((c = getopt(argc, argv, "aAc:d:eEf:F:lh:Hk:no:p:P:qRsStT:uU:v:VWxX?-")) != -1) #endif /* not HAVE_GETOPT_LONG */ { switch (c) @@ -406,6 +410,9 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) case 'l': options->action = ACT_LIST_DB; break; + case 'k': + options->unixsocket = optarg; + break; case 'n': options->no_readline = true; break; diff --git a/src/bin/scripts/createdb b/src/bin/scripts/createdb index 3601811b24..213913ba89 100644 --- a/src/bin/scripts/createdb +++ b/src/bin/scripts/createdb @@ -11,7 +11,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createdb,v 1.9 2000/11/11 22:59:48 petere Exp $ +# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createdb,v 1.10 2000/11/13 15:18:14 momjian Exp $ # #------------------------------------------------------------------------- @@ -50,6 +50,15 @@ do --port=*) PSQLOPT="$PSQLOPT -p "`echo $1 | sed 's/^--port=//'` ;; + --unixsocket|-k) + PSQLOPT="$PSQLOPT -k $2" + shift;; + -k*) + PSQLOPT="$PSQLOPT $1" + ;; + --unixsocket=*) + PSQLOPT="$PSQLOPT -k "`echo $1 | sed 's/^--unixsocket=//'` + ;; --username|-U) PSQLOPT="$PSQLOPT -U $2" shift;; @@ -114,6 +123,7 @@ if [ "$usage" ]; then echo " -E, --encoding=ENCODING Multibyte encoding for the database" echo " -h, --host=HOSTNAME Database server host" echo " -p, --port=PORT Database server port" + echo " -k, --unixsocket=PATH Database server Unix-domain socket name" echo " -U, --username=USERNAME Username to connect as" echo " -W, --password Prompt for password" echo " -e, --echo Show the query being sent to the backend" diff --git a/src/bin/scripts/createlang.sh b/src/bin/scripts/createlang.sh index 4275dc6e93..c22dcba652 100644 --- a/src/bin/scripts/createlang.sh +++ b/src/bin/scripts/createlang.sh @@ -8,7 +8,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.17 2000/11/11 22:59:48 petere Exp $ +# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.18 2000/11/13 15:18:14 momjian Exp $ # #------------------------------------------------------------------------- @@ -65,6 +65,15 @@ do --port=*) PSQLOPT="$PSQLOPT -p "`echo $1 | sed 's/^--port=//'` ;; + --unixsocket|-k) + PSQLOPT="$PSQLOPT -k $2" + shift;; + -k*) + PSQLOPT="$PSQLOPT $1" + ;; + --unixsocket=*) + PSQLOPT="$PSQLOPT -k "`echo $1 | sed 's/^--unixsocket=//'` + ;; --username|-U) PSQLOPT="$PSQLOPT -U $2" shift;; @@ -126,6 +135,7 @@ if [ "$usage" ]; then echo "Options:" echo " -h, --host=HOSTNAME Database server host" echo " -p, --port=PORT Database server port" + echo " -k, --unixsocket=PATH Database server Unix-domain socket name" echo " -U, --username=USERNAME Username to connect as" echo " -W, --password Prompt for password" echo " -d, --dbname=DBNAME Database to install language in" diff --git a/src/bin/scripts/createuser b/src/bin/scripts/createuser index 62c674d99e..198e4b81cf 100644 --- a/src/bin/scripts/createuser +++ b/src/bin/scripts/createuser @@ -8,7 +8,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createuser,v 1.12 2000/11/11 22:59:48 petere Exp $ +# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createuser,v 1.13 2000/11/13 15:18:14 momjian Exp $ # # Note - this should NOT be setuid. # @@ -63,6 +63,15 @@ do --port=*) PSQLOPT="$PSQLOPT -p "`echo $1 | sed 's/^--port=//'` ;; + --unixsocket|-k) + PSQLOPT="$PSQLOPT -k $2" + shift;; + -k*) + PSQLOPT="$PSQLOPT $1" + ;; + --unixsocket=*) + PSQLOPT="$PSQLOPT -k "`echo $1 | sed 's/^--unixsocket=//'` + ;; # Note: These two specify the user to connect as (like in psql), # not the user you're creating. --username|-U) @@ -135,6 +144,7 @@ if [ "$usage" ]; then echo " -P, --pwprompt Assign a password to new user" echo " -h, --host=HOSTNAME Database server host" echo " -p, --port=PORT Database server port" + echo " -k, --unixsocket=PATH Database server Unix-domain socket name" echo " -U, --username=USERNAME Username to connect as (not the one to create)" echo " -W, --password Prompt for password to connect" echo " -e, --echo Show the query being sent to the backend" diff --git a/src/bin/scripts/dropdb b/src/bin/scripts/dropdb index 1bb6f10f25..586b62ac7f 100644 --- a/src/bin/scripts/dropdb +++ b/src/bin/scripts/dropdb @@ -10,7 +10,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/dropdb,v 1.7 2000/11/11 22:59:48 petere Exp $ +# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/dropdb,v 1.8 2000/11/13 15:18:14 momjian Exp $ # #------------------------------------------------------------------------- @@ -59,6 +59,15 @@ do --port=*) PSQLOPT="$PSQLOPT -p "`echo $1 | sed 's/^--port=//'` ;; + --unixsocket|-k) + PSQLOPT="$PSQLOPT -k $2" + shift;; + -k*) + PSQLOPT="$PSQLOPT $1" + ;; + --unixsocket=*) + PSQLOPT="$PSQLOPT -k "`echo $1 | sed 's/^--unixsocket=//'` + ;; --username|-U) PSQLOPT="$PSQLOPT -U $2" shift;; @@ -103,6 +112,7 @@ if [ "$usage" ]; then echo "Options:" echo " -h, --host=HOSTNAME Database server host" echo " -p, --port=PORT Database server port" + echo " -k, --unixsocket=PATH Database server Unix-domain socket name" echo " -U, --username=USERNAME Username to connect as" echo " -W, --password Prompt for password" echo " -i, --interactive Prompt before deleting anything" diff --git a/src/bin/scripts/droplang b/src/bin/scripts/droplang index 3205ad3577..46856e4241 100644 --- a/src/bin/scripts/droplang +++ b/src/bin/scripts/droplang @@ -8,7 +8,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/droplang,v 1.8 2000/11/11 22:59:48 petere Exp $ +# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/droplang,v 1.9 2000/11/13 15:18:14 momjian Exp $ # #------------------------------------------------------------------------- @@ -65,6 +65,15 @@ do --port=*) PSQLOPT="$PSQLOPT -p "`echo $1 | sed 's/^--port=//'` ;; + --unixsocket|-k) + PSQLOPT="$PSQLOPT -k $2" + shift;; + -k*) + PSQLOPT="$PSQLOPT $1" + ;; + --unixsocket=*) + PSQLOPT="$PSQLOPT -k "`echo $1 | sed 's/^--unixsocket=//'` + ;; --username|-U) PSQLOPT="$PSQLOPT -U $2" shift;; @@ -113,6 +122,7 @@ if [ "$usage" ]; then echo "Options:" echo " -h, --host=HOSTNAME Database server host" echo " -p, --port=PORT Database server port" + echo " -k, --unixsocket=PATH Database server Unix-domain socket name" echo " -U, --username=USERNAME Username to connect as" echo " -W, --password Prompt for password" echo " -d, --dbname=DBNAME Database to remove language from" diff --git a/src/bin/scripts/dropuser b/src/bin/scripts/dropuser index 81a00f9c1c..4aa858124b 100644 --- a/src/bin/scripts/dropuser +++ b/src/bin/scripts/dropuser @@ -8,7 +8,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/dropuser,v 1.7 2000/11/11 22:59:48 petere Exp $ +# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/dropuser,v 1.8 2000/11/13 15:18:14 momjian Exp $ # # Note - this should NOT be setuid. # @@ -59,6 +59,15 @@ do --port=*) PSQLOPT="$PSQLOPT -p "`echo $1 | sed 's/^--port=//'` ;; + --unixsocket|-k) + PSQLOPT="$PSQLOPT -k $2" + shift;; + -k*) + PSQLOPT="$PSQLOPT $1" + ;; + --unixsocket=*) + PSQLOPT="$PSQLOPT -k "`echo $1 | sed 's/^--unixsocket=//'` + ;; # Note: These two specify the user to connect as (like in psql), # not the user you're dropping. --username|-U) @@ -105,6 +114,7 @@ if [ "$usage" ]; then echo "Options:" echo " -h, --host=HOSTNAME Database server host" echo " -p, --port=PORT Database server port" + echo " -k, --unixsocket=PATH Database server Unix-domain socket name" echo " -U, --username=USERNAME Username to connect as (not the one to drop)" echo " -W, --password Prompt for password to connect" echo " -i, --interactive Prompt before deleting anything" diff --git a/src/bin/scripts/vacuumdb b/src/bin/scripts/vacuumdb index af038add8a..fb1db8bfe6 100644 --- a/src/bin/scripts/vacuumdb +++ b/src/bin/scripts/vacuumdb @@ -11,7 +11,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/vacuumdb,v 1.10 2000/11/11 22:59:48 petere Exp $ +# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/vacuumdb,v 1.11 2000/11/13 15:18:14 momjian Exp $ # #------------------------------------------------------------------------- @@ -52,6 +52,15 @@ do --port=*) PSQLOPT="$PSQLOPT -p "`echo $1 | sed 's/^--port=//'` ;; + --unixsocket|-k) + PSQLOPT="$PSQLOPT -k $2" + shift;; + -k*) + PSQLOPT="$PSQLOPT $1" + ;; + --unixsocket=*) + PSQLOPT="$PSQLOPT -k "`echo $1 | sed 's/^--unixsocket=//'` + ;; --username|-U) PSQLOPT="$PSQLOPT -U $2" shift;; @@ -121,6 +130,7 @@ if [ "$usage" ]; then echo "Options:" echo " -h, --host=HOSTNAME Database server host" echo " -p, --port=PORT Database server port" + echo " -k, --unixsocket=PATH Database server Unix-domain socket name" echo " -U, --username=USERNAME Username to connect as" echo " -W, --password Prompt for password" echo " -d, --dbname=DBNAME Database to vacuum" diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h index 3632012f67..21cae47d97 100644 --- a/src/include/libpq/libpq.h +++ b/src/include/libpq/libpq.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: libpq.h,v 1.39 2000/07/08 03:04:30 tgl Exp $ + * $Id: libpq.h,v 1.40 2000/11/13 15:18:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -55,7 +55,8 @@ extern char PQerrormsg[PQERRORMSG_LENGTH]; /* in libpq/util.c */ /* * prototypes for functions in pqcomm.c */ -extern int StreamServerPort(int family, unsigned short portName, int *fdP); +extern int StreamServerPort(int family, char *hostName, + unsigned short portName, char *unixSocketName, int *fdP); extern int StreamConnection(int server_fd, Port *port); extern void StreamClose(int sock); extern void pq_init(void); diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h index bb64862922..10a798d6a6 100644 --- a/src/include/libpq/pqcomm.h +++ b/src/include/libpq/pqcomm.h @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pqcomm.h,v 1.43 2000/11/01 21:14:03 petere Exp $ + * $Id: pqcomm.h,v 1.44 2000/11/13 15:18:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -51,12 +51,15 @@ typedef union SockAddr /* Configure the UNIX socket address for the well known port. */ #if defined(SUN_LEN) -#define UNIXSOCK_PATH(sun,port) \ - (sprintf((sun).sun_path, "/tmp/.s.PGSQL.%d", (port)), SUN_LEN(&(sun))) +#define UNIXSOCK_PATH(sun,port,defpath) \ + ((defpath && defpath[0] != '\0') ? (strncpy((sun).sun_path, defpath, sizeof((sun).sun_path)), (sun).sun_path[sizeof((sun).sun_path)-1] = '\0') : sprintf((sun).sun_path, "/tmp/.s.PGSQL.%d", (port))) +#define UNIXSOCK_LEN(sun) \ + (SUN_LEN(&(sun))) #else -#define UNIXSOCK_PATH(sun,port) \ - (sprintf((sun).sun_path, "/tmp/.s.PGSQL.%d", (port)), \ - strlen((sun).sun_path)+ offsetof(struct sockaddr_un, sun_path)) +#define UNIXSOCK_PATH(sun,port,defpath) \ + ((defpath && defpath[0] != '\0') ? (strncpy((sun).sun_path, defpath, sizeof((sun).sun_path)), (sun).sun_path[sizeof((sun).sun_path)-1] = '\0') : sprintf((sun).sun_path, "/tmp/.s.PGSQL.%d", (port))) +#define UNIXSOCK_LEN(sun) \ + (strlen((sun).sun_path)+ offsetof(struct sockaddr_un, sun_path)) #endif /* @@ -176,5 +179,7 @@ typedef struct CancelRequestPacket extern int Unix_socket_permissions; extern char * Unix_socket_group; +extern char * UnixSocketName; +extern char * HostName; #endif /* PQCOMM_H */ diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 4d37a8c611..b0447285d4 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.144 2000/11/04 02:27:56 ishii Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.145 2000/11/13 15:18:15 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -130,6 +130,9 @@ static const PQconninfoOption PQconninfoOptions[] = { {"port", "PGPORT", DEF_PGPORT_STR, NULL, "Database-Port", "", 6}, + {"unixsocket", "PGUNIXSOCKET", NULL, NULL, + "Unix-Socket", "", 80}, + {"tty", "PGTTY", DefaultTty, NULL, "Backend-Debug-TTY", "D", 40}, @@ -305,6 +308,8 @@ PQconnectStart(const char *conninfo) conn->pghost = tmp ? strdup(tmp) : NULL; tmp = conninfo_getval(connOptions, "port"); conn->pgport = tmp ? strdup(tmp) : NULL; + tmp = conninfo_getval(connOptions, "unixsocket"); + conn->pgunixsocket = tmp ? strdup(tmp) : NULL; tmp = conninfo_getval(connOptions, "tty"); conn->pgtty = tmp ? strdup(tmp) : NULL; tmp = conninfo_getval(connOptions, "options"); @@ -385,6 +390,9 @@ PQconndefaults(void) * PGPORT identifies TCP port to which to connect if argument * is NULL or a null string. * + * PGUNIXSOCKET identifies Unix-domain socket to which to connect; default + * is computed from the TCP port. + * * PGTTY identifies tty to which to send messages if argument * is NULL or a null string. * @@ -435,6 +443,14 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, else conn->pgport = strdup(pgport); +#if FIX_ME + /* we need to modify the function to accept a unix socket path */ + if (pgunixsocket) + conn->pgunixsocket = strdup(pgunixsocket); + else if ((tmp = getenv("PGUNIXSOCKET")) != NULL) + conn->pgunixsocket = strdup(tmp); +#endif + if (pgtty == NULL) { if ((tmp = getenv("PGTTY")) == NULL) @@ -510,13 +526,13 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, /* * update_db_info - - * get all additional infos out of dbName + * get all additional info out of dbName * */ static int update_db_info(PGconn *conn) { - char *tmp, + char *tmp, *tmp2, *old = conn->dbName; if (strchr(conn->dbName, '@') != NULL) @@ -525,6 +541,8 @@ update_db_info(PGconn *conn) tmp = strrchr(conn->dbName, ':'); if (tmp != NULL) /* port number given */ { + if (conn->pgport) + free(conn->pgport); conn->pgport = strdup(tmp + 1); *tmp = '\0'; } @@ -532,6 +550,8 @@ update_db_info(PGconn *conn) tmp = strrchr(conn->dbName, '@'); if (tmp != NULL) /* host name given */ { + if (conn->pghost) + free(conn->pghost); conn->pghost = strdup(tmp + 1); *tmp = '\0'; } @@ -558,13 +578,15 @@ update_db_info(PGconn *conn) /* * new style: - * :postgresql://server[:port][/dbname][?options] + * :postgresql://server[:port|:/unixsocket/path:][/dbname][?options] */ offset += strlen("postgresql://"); tmp = strrchr(conn->dbName + offset, '?'); if (tmp != NULL) /* options given */ { + if (conn->pgoptions) + free(conn->pgoptions); conn->pgoptions = strdup(tmp + 1); *tmp = '\0'; } @@ -572,26 +594,62 @@ update_db_info(PGconn *conn) tmp = strrchr(conn->dbName + offset, '/'); if (tmp != NULL) /* database name given */ { + if (conn->dbName) + free(conn->dbName); conn->dbName = strdup(tmp + 1); *tmp = '\0'; } else { + /* Why do we default only this value from the environment again? */ if ((tmp = getenv("PGDATABASE")) != NULL) + { + if (conn->dbName) + free(conn->dbName); conn->dbName = strdup(tmp); + } else if (conn->pguser) + { + if (conn->dbName) + free(conn->dbName); conn->dbName = strdup(conn->pguser); + } } tmp = strrchr(old + offset, ':'); - if (tmp != NULL) /* port number given */ + if (tmp != NULL) /* port number or Unix socket path given */ { - conn->pgport = strdup(tmp + 1); *tmp = '\0'; + if ((tmp2 = strchr(tmp + 1, ':')) != NULL) + { + if (strncmp(old, "unix:", 5) != 0) + { + printfPQExpBuffer(&conn->errorMessage, + "connectDBStart() -- " + "socket name can only be specified with " + "non-TCP\n"); + return 1; + } + *tmp2 = '\0'; + if (conn->pgunixsocket) + free(conn->pgunixsocket); + conn->pgunixsocket = strdup(tmp + 1); + } + else + { + if (conn->pgport) + free(conn->pgport); + conn->pgport = strdup(tmp + 1); + if (conn->pgunixsocket) + free(conn->pgunixsocket); + conn->pgunixsocket = NULL; + } } if (strncmp(old, "unix:", 5) == 0) { + if (conn->pghost) + free(conn->pghost); conn->pghost = NULL; if (strcmp(old + offset, "localhost") != 0) { @@ -603,8 +661,11 @@ update_db_info(PGconn *conn) } } else + { + if (conn->pghost) + free(conn->pghost); conn->pghost = strdup(old + offset); - + } free(old); } } @@ -763,7 +824,10 @@ connectDBStart(PGconn *conn) } #ifdef HAVE_UNIX_SOCKETS else - conn->raddr_len = UNIXSOCK_PATH(conn->raddr.un, portno); + { + UNIXSOCK_PATH(conn->raddr.un, portno, conn->pgunixsocket); + conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un); + } #endif @@ -842,7 +906,8 @@ connectDBStart(PGconn *conn) conn->pghost ? conn->pghost : "localhost", (family == AF_INET) ? "TCP/IP port" : "Unix socket", - conn->pgport); + (family == AF_UNIX && conn->pgunixsocket) ? + conn->pgunixsocket : conn->pgport); goto connect_errReturn; } } @@ -1143,7 +1208,8 @@ keep_going: /* We will come back to here until there conn->pghost ? conn->pghost : "localhost", (conn->raddr.sa.sa_family == AF_INET) ? "TCP/IP port" : "Unix socket", - conn->pgport); + (conn->raddr.sa.sa_family == AF_UNIX && conn->pgunixsocket) ? + conn->pgunixsocket : conn->pgport); goto error_return; } @@ -1819,6 +1885,8 @@ freePGconn(PGconn *conn) free(conn->pghostaddr); if (conn->pgport) free(conn->pgport); + if (conn->pgunixsocket) + free(conn->pgunixsocket); if (conn->pgtty) free(conn->pgtty); if (conn->pgoptions) @@ -2528,6 +2596,14 @@ PQport(const PGconn *conn) return conn->pgport; } +char * +PQunixsocket(const PGconn *conn) +{ + if (!conn) + return (char *) NULL; + return conn->pgunixsocket; +} + char * PQtty(const PGconn *conn) { diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index cfca198460..0d064e1a67 100644 --- a/src/interfaces/libpq/libpq-fe.h +++ b/src/interfaces/libpq/libpq-fe.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: libpq-fe.h,v 1.67 2000/08/30 14:54:23 momjian Exp $ + * $Id: libpq-fe.h,v 1.68 2000/11/13 15:18:15 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -217,6 +217,7 @@ extern "C" extern char *PQpass(const PGconn *conn); extern char *PQhost(const PGconn *conn); extern char *PQport(const PGconn *conn); + extern char *PQunixsocket(const PGconn *conn); extern char *PQtty(const PGconn *conn); extern char *PQoptions(const PGconn *conn); extern ConnStatusType PQstatus(const PGconn *conn); diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index c640b6df9f..a7c6acb952 100644 --- a/src/interfaces/libpq/libpq-int.h +++ b/src/interfaces/libpq/libpq-int.h @@ -12,7 +12,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: libpq-int.h,v 1.27 2000/08/30 14:54:24 momjian Exp $ + * $Id: libpq-int.h,v 1.28 2000/11/13 15:18:15 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -203,6 +203,8 @@ struct pg_conn * numbers-and-dots notation. Takes * precedence over above. */ char *pgport; /* the server's communication port */ + char *pgunixsocket; /* the Unix-domain socket that the server is listening on; + * if NULL, uses a default constructed from pgport */ char *pgtty; /* tty on which the backend messages is * displayed (NOT ACTUALLY USED???) */ char *pgoptions; /* options to start the backend with */ diff --git a/src/interfaces/libpq/libpqdll.def b/src/interfaces/libpq/libpqdll.def index 32b0fa6ec3..7cf3bbc0a4 100644 --- a/src/interfaces/libpq/libpqdll.def +++ b/src/interfaces/libpq/libpqdll.def @@ -79,3 +79,4 @@ EXPORTS destroyPQExpBuffer @ 76 createPQExpBuffer @ 77 PQconninfoFree @ 78 + PQunixsocket @ 79