Re: PostgreSQL virtual hosting support - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: PostgreSQL virtual hosting support
Date
Msg-id 200011130533.AAA19565@candle.pha.pa.us
Whole thread Raw
In response to PostgreSQL virtual hosting support  ("David J. MacKenzie" <djm@web.us.uu.net>)
List pgsql-patches
I have finally merged this patch into our current tree, and have created
a diff file that I have attached to this email.  If no one objects, I
will apply this change to the current tree tomorrow.  It allows the
postmaster to listen to only certain hosts and to place the socket file
in a certain directory.

The only item not done is that PQsetdbLogin() does not have a parameter
to accept the unix socket path.  Not sure we want to change that API
just to allow unix socket path specification.

> Your name        :    David MacKenzie
> Your email address    :    djm@web.us.uu.net
>
>
> System Configuration
> ---------------------
>   Architecture (example: Intel Pentium)      : Intel x86
>
>   Operating System (example: Linux 2.0.26 ELF)     : BSD/OS 4.0.1
>
>   PostgreSQL version (example: PostgreSQL-7.0):   PostgreSQL-7.0.2
>
>   Compiler used (example:  gcc 2.8.0)        : gcc version 2.7.2.1
>
>
> Please enter a FULL description of your problem:
> ------------------------------------------------
>
> UUNET is looking into offering PostgreSQL as a part of a managed web
> hosting product, on both shared and dedicated machines.  We currently
> offer Oracle and MySQL, and it would be a nice middle-ground.
> However, as shipped, PostgreSQL lacks the following features we need
> that MySQL has:
>
> 1. The ability to listen only on a particular IP address.  Each
>    hosting customer has their own IP address, on which all of their
>    servers (http, ftp, real media, etc.) run.
> 2. The ability to place the Unix-domain socket in a mode 700 directory.
>    This allows us to automatically create an empty database, with an
>    empty DBA password, for new or upgrading customers without having
>    to interactively set a DBA password and communicate it to (or from)
>    the customer.  This in turn cuts down our install and upgrade times.
> 3. The ability to connect to the Unix-domain socket from within a
>    change-rooted environment.  We run CGI programs chrooted to the
>    user's home directory, which is another reason why we need to be
>    able to specify where the Unix-domain socket is, instead of /tmp.
> 4. The ability to, if run as root, open a pid file in /var/run as
>    root, and then setuid to the desired user.  (mysqld -u can almost
>    do this; I had to patch it, too).
>
> The patch below fixes problem 1-3.  I plan to address #4, also, but
> haven't done so yet.  These diffs are big enough that they should give
> the PG development team something to think about in the meantime :-)
> Also, I'm about to leave for 2 weeks' vacation, so I thought I'd get
> out what I have, which works (for the problems it tackles), now.
>
> With these changes, we can set up and run PostgreSQL with scripts the
> same way we can with apache or proftpd or mysql.
>
> In summary, this patch makes the following enhancements:
>
> 1. Adds an environment variable PGUNIXSOCKET, analogous to MYSQL_UNIX_PORT,
>    and command line options -k --unix-socket to the relevant programs.
> 2. Adds a -h option to postmaster to set the hostname or IP address to
>    listen on instead of the default INADDR_ANY.
> 3. Extends some library interfaces to support the above.
> 4. Fixes a few memory leaks in PQconnectdb().
>
> The default behavior is unchanged from stock 7.0.2; if you don't use
> any of these new features, they don't change the operation.
>
> Index: doc/src/sgml/layout.sgml
> *** doc/src/sgml/layout.sgml    2000/06/30 21:15:36    1.1
> --- doc/src/sgml/layout.sgml    2000/07/02 03:56:05    1.2
> ***************
> *** 55,61 ****
>   For example, if the database server machine is a remote machine, you
>   will need to set the <envar>PGHOST</envar> environment variable to the name
>   of the database server machine.   The  environment  variable
> ! <envar>PGPORT</envar> 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 <Application>postmaster</Application>,
>   you must go back and make sure that your
> --- 55,62 ----
>   For example, if the database server machine is a remote machine, you
>   will need to set the <envar>PGHOST</envar> environment variable to the name
>   of the database server machine.   The  environment  variable
> ! <envar>PGPORT</envar> or <envar>PGUNIXSOCKET</envar> 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 <Application>postmaster</Application>,
>   you must go back and make sure that your
> Index: doc/src/sgml/libpq++.sgml
> *** doc/src/sgml/libpq++.sgml    2000/06/30 21:15:36    1.1
> --- doc/src/sgml/libpq++.sgml    2000/07/02 03:56:05    1.2
> ***************
> *** 93,98 ****
> --- 93,105 ----
>         </listitem>
>         <listitem>
>          <para>
> +     <envar>PGUNIXSOCKET</envar>  sets the full Unix domain socket
> +     file name for communicating with the <productname>Postgres</productname>
> +     backend.
> +        </para>
> +       </listitem>
> +       <listitem>
> +        <para>
>       <envar>PGDATABASE</envar>  sets the default
>       <productname>Postgres</productname> database name.
>          </para>
> Index: doc/src/sgml/libpq.sgml
> *** doc/src/sgml/libpq.sgml    2000/06/30 21:15:36    1.1
> --- doc/src/sgml/libpq.sgml    2000/07/02 03:56:05    1.2
> ***************
> *** 134,139 ****
> --- 134,148 ----
>       </varlistentry>
>
>       <varlistentry>
> +      <term><literal>unixsocket</literal></term>
> +      <listitem>
> +      <para>
> +       Full path to Unix-domain socket file to connect to at the server host.
> +      </para>
> +      </listitem>
> +     </varlistentry>
> +
> +     <varlistentry>
>        <term><literal>dbname</literal></term>
>        <listitem>
>        <para>
> ***************
> *** 545,550 ****
> --- 554,569 ----
>
>   <listitem>
>   <para>
> + <function>PQunixsocket</function>
> +          Returns the name of the Unix-domain socket of the connection.
> + <synopsis>
> + char *PQunixsocket(const PGconn *conn)
> + </synopsis>
> + </para>
> + </listitem>
> +
> + <listitem>
> + <para>
>   <function>PQtty</function>
>            Returns the debug tty of the connection.
>   <synopsis>
> ***************
> *** 1772,1777 ****
> --- 1791,1803 ----
>   <envar>PGHOST</envar> sets the default server name.
>   If a non-zero-length string is specified, TCP/IP communication is used.
>   Without a host name, libpq will connect using a local Unix domain socket.
> + </para>
> + </listitem>
> + <listitem>
> + <para>
> + <envar>PGPORT</envar>  sets the default port or local Unix domain socket
> + file extension for communicating with the <productname>Postgres</productname>
> + backend.
>   </para>
>   </listitem>
>   <listitem>
> Index: doc/src/sgml/start.sgml
> *** doc/src/sgml/start.sgml    2000/06/30 21:15:37    1.1
> --- doc/src/sgml/start.sgml    2000/07/02 03:56:05    1.2
> ***************
> *** 110,117 ****
>       will need to set the <acronym>PGHOST</acronym> environment
>       variable to the name
>       of the database server machine.   The  environment  variable
> !     <acronym>PGPORT</acronym> 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 <application>postmaster</application>,
>       you should immediately consult your site administrator to make
> --- 110,117 ----
>       will need to set the <acronym>PGHOST</acronym> environment
>       variable to the name
>       of the database server machine.   The  environment  variable
> !     <acronym>PGPORT</acronym> or <acronym>PGUNIXSOCKET</acronym> 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 <application>postmaster</application>,
>       you should immediately consult your site administrator to make
> Index: doc/src/sgml/ref/createdb.sgml
> *** doc/src/sgml/ref/createdb.sgml    2000/06/30 21:15:37    1.1
> --- doc/src/sgml/ref/createdb.sgml    2000/07/04 04:46:45    1.2
> ***************
> *** 58,63 ****
> --- 58,75 ----
>         </listitem>
>        </varlistentry>
>
> +     <varlistentry>
> +       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
> +       <listitem>
> +       <para>
> +       Specifies the Unix-domain socket on which the
> +       <application>postmaster</application> is running.
> +       Without this option, the socket is created in <filename>/tmp</filename>
> +       based on the port number.
> +       </para>
> +       </listitem>
> +     </varlistentry>
> +
>        <varlistentry>
>         <term>-U, --username <replaceable class="parameter">username</replaceable></term>
>         <listitem>
> Index: doc/src/sgml/ref/createlang.sgml
> *** doc/src/sgml/ref/createlang.sgml    2000/06/30 21:15:37    1.1
> --- doc/src/sgml/ref/createlang.sgml    2000/07/04 04:46:45    1.2
> ***************
> *** 96,101 ****
> --- 96,113 ----
>         </listitem>
>        </varlistentry>
>
> +     <varlistentry>
> +       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
> +       <listitem>
> +       <para>
> +       Specifies the Unix-domain socket on which the
> +       <application>postmaster</application> is running.
> +       Without this option, the socket is created in <filename>/tmp</filename>
> +       based on the port number.
> +       </para>
> +       </listitem>
> +     </varlistentry>
> +
>        <varlistentry>
>         <term>-U, --username <replaceable class="parameter">username</replaceable></term>
>         <listitem>
> Index: doc/src/sgml/ref/createuser.sgml
> *** doc/src/sgml/ref/createuser.sgml    2000/06/30 21:15:37    1.1
> --- doc/src/sgml/ref/createuser.sgml    2000/07/04 04:46:45    1.2
> ***************
> *** 59,64 ****
> --- 59,76 ----
>         </listitem>
>        </varlistentry>
>
> +     <varlistentry>
> +       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
> +       <listitem>
> +       <para>
> +       Specifies the Unix-domain socket on which the
> +       <application>postmaster</application> is running.
> +       Without this option, the socket is created in <filename>/tmp</filename>
> +       based on the port number.
> +       </para>
> +       </listitem>
> +     </varlistentry>
> +
>        <varlistentry>
>         <term>-e, --echo</term>
>         <listitem>
> Index: doc/src/sgml/ref/dropdb.sgml
> *** doc/src/sgml/ref/dropdb.sgml    2000/06/30 21:15:38    1.1
> --- doc/src/sgml/ref/dropdb.sgml    2000/07/04 04:46:45    1.2
> ***************
> *** 58,63 ****
> --- 58,75 ----
>         </listitem>
>        </varlistentry>
>
> +     <varlistentry>
> +       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
> +       <listitem>
> +       <para>
> +       Specifies the Unix-domain socket on which the
> +       <application>postmaster</application> is running.
> +       Without this option, the socket is created in <filename>/tmp</filename>
> +       based on the port number.
> +       </para>
> +       </listitem>
> +     </varlistentry>
> +
>        <varlistentry>
>         <term>-U, --username <replaceable class="parameter">username</replaceable></term>
>         <listitem>
> Index: doc/src/sgml/ref/droplang.sgml
> *** doc/src/sgml/ref/droplang.sgml    2000/06/30 21:15:38    1.1
> --- doc/src/sgml/ref/droplang.sgml    2000/07/04 04:46:45    1.2
> ***************
> *** 96,101 ****
> --- 96,113 ----
>         </listitem>
>        </varlistentry>
>
> +     <varlistentry>
> +       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
> +       <listitem>
> +       <para>
> +       Specifies the Unix-domain socket on which the
> +       <application>postmaster</application> is running.
> +       Without this option, the socket is created in <filename>/tmp</filename>
> +       based on the port number.
> +       </para>
> +       </listitem>
> +     </varlistentry>
> +
>        <varlistentry>
>         <term>-U, --username <replaceable class="parameter">username</replaceable></term>
>         <listitem>
> Index: doc/src/sgml/ref/dropuser.sgml
> *** doc/src/sgml/ref/dropuser.sgml    2000/06/30 21:15:38    1.1
> --- doc/src/sgml/ref/dropuser.sgml    2000/07/04 04:46:45    1.2
> ***************
> *** 58,63 ****
> --- 58,75 ----
>         </listitem>
>        </varlistentry>
>
> +     <varlistentry>
> +       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
> +       <listitem>
> +       <para>
> +       Specifies the Unix-domain socket on which the
> +       <application>postmaster</application> is running.
> +       Without this option, the socket is created in <filename>/tmp</filename>
> +       based on the port number.
> +       </para>
> +       </listitem>
> +     </varlistentry>
> +
>        <varlistentry>
>         <term>-e, --echo</term>
>         <listitem>
> Index: doc/src/sgml/ref/pg_dump.sgml
> *** doc/src/sgml/ref/pg_dump.sgml    2000/06/30 21:15:38    1.1
> --- doc/src/sgml/ref/pg_dump.sgml    2000/07/01 18:41:22    1.2
> ***************
> *** 24,30 ****
>     </refsynopsisdivinfo>
>     <synopsis>
>   pg_dump [ <replaceable class="parameter">dbname</replaceable> ]
> ! pg_dump [ -h <replaceable class="parameter">host</replaceable> ] [ -p <replaceable
class="parameter">port</replaceable>] 
>       [ -t <replaceable class="parameter">table</replaceable> ]
>       [ -a ] [ -c ] [ -d ] [ -D ] [ -i ] [ -n ] [ -N ]
>       [ -o ] [ -s ] [ -u ] [ -v ] [ -x ]
> --- 24,32 ----
>     </refsynopsisdivinfo>
>     <synopsis>
>   pg_dump [ <replaceable class="parameter">dbname</replaceable> ]
> ! pg_dump [ -h <replaceable class="parameter">host</replaceable> ]
> !     [ -k <replaceable class="parameter">path</replaceable> ]
> !     [ -p <replaceable class="parameter">port</replaceable> ]
>       [ -t <replaceable class="parameter">table</replaceable> ]
>       [ -a ] [ -c ] [ -d ] [ -D ] [ -i ] [ -n ] [ -N ]
>       [ -o ] [ -s ] [ -u ] [ -v ] [ -x ]
> ***************
> *** 200,205 ****
> --- 202,222 ----
>       <application>postmaster</application>
>       is running.  Defaults to using a local Unix domain socket
>       rather than an IP connection..
> +        </para>
> +       </listitem>
> +      </varlistentry>
> +
> +      <varlistentry>
> +       <term>-k <replaceable class="parameter">path</replaceable></term>
> +       <listitem>
> +        <para>
> +     Specifies the local Unix domain socket file path
> +     on which the <application>postmaster</application>
> +     is listening for connections.
> +         Without this option, the socket path name defaults to
> +         the value of the <envar>PGUNIXSOCKET</envar> environment
> +     variable (if set), otherwise it is constructed
> +         from the port number.
>          </para>
>         </listitem>
>        </varlistentry>
> Index: doc/src/sgml/ref/pg_dumpall.sgml
> *** doc/src/sgml/ref/pg_dumpall.sgml    2000/06/30 21:15:38    1.1
> --- doc/src/sgml/ref/pg_dumpall.sgml    2000/07/01 18:41:22    1.2
> ***************
> *** 24,30 ****
>     </refsynopsisdivinfo>
>     <synopsis>
>   pg_dumpall
> ! pg_dumpall [ -h <replaceable class="parameter">host</replaceable> ] [ -p <replaceable
class="parameter">port</replaceable>] [ -a ] [ -d ] [ -D ] [ -O ] [ -s ] [ -u ] [ -v ] [ -x ] 
>     </synopsis>
>
>     <refsect2 id="R2-APP-PG-DUMPALL-1">
> --- 24,33 ----
>     </refsynopsisdivinfo>
>     <synopsis>
>   pg_dumpall
> ! pg_dumpall [ -h <replaceable class="parameter">host</replaceable> ]
> !      [ -k <replaceable class="parameter">path</replaceable> ]
> !      [ -p <replaceable class="parameter">port</replaceable> ]
> !      [ -a ] [ -d ] [ -D ] [ -O ] [ -s ] [ -u ] [ -v ] [ -x ]
>     </synopsis>
>
>     <refsect2 id="R2-APP-PG-DUMPALL-1">
> ***************
> *** 137,142 ****
> --- 140,160 ----
>       <application>postmaster</application>
>       is running.  Defaults to using a local Unix domain socket
>       rather than an IP connection..
> +        </para>
> +       </listitem>
> +      </varlistentry>
> +
> +      <varlistentry>
> +       <term>-k <replaceable class="parameter">path</replaceable></term>
> +       <listitem>
> +        <para>
> +     Specifies the local Unix domain socket file path
> +     on which the <application>postmaster</application>
> +     is listening for connections.
> +         Without this option, the socket path name defaults to
> +         the value of the <envar>PGUNIXSOCKET</envar> environment
> +     variable (if set), otherwise it is constructed
> +         from the port number.
>          </para>
>         </listitem>
>        </varlistentry>
> Index: doc/src/sgml/ref/postmaster.sgml
> *** doc/src/sgml/ref/postmaster.sgml    2000/06/30 21:15:38    1.1
> --- doc/src/sgml/ref/postmaster.sgml    2000/07/06 07:48:31    1.7
> ***************
> *** 24,30 ****
>     </refsynopsisdivinfo>
>     <synopsis>
>   postmaster [ -B <replaceable class="parameter">nBuffers</replaceable> ] [ -D <replaceable
class="parameter">DataDir</replaceable>] [ -N <replaceable class="parameter">maxBackends</replaceable> ] [ -S ] 
> !     [ -d <replaceable class="parameter">DebugLevel</replaceable> ] [ -i ] [ -l ]
>       [ -o <replaceable class="parameter">BackendOptions</replaceable> ] [ -p <replaceable
class="parameter">port</replaceable>] [ -n | -s ] 
>     </synopsis>
>
> --- 24,32 ----
>     </refsynopsisdivinfo>
>     <synopsis>
>   postmaster [ -B <replaceable class="parameter">nBuffers</replaceable> ] [ -D <replaceable
class="parameter">DataDir</replaceable>] [ -N <replaceable class="parameter">maxBackends</replaceable> ] [ -S ] 
> !     [ -d <replaceable class="parameter">DebugLevel</replaceable> ]
> !     [ -h <replaceable class="parameter">hostname</replaceable> ] [ -i ]
> !     [ -k <replaceable class="parameter">path</replaceable> ] [ -l ]
>       [ -o <replaceable class="parameter">BackendOptions</replaceable> ] [ -p <replaceable
class="parameter">port</replaceable>] [ -n | -s ] 
>     </synopsis>
>
> ***************
> *** 124,129 ****
> --- 126,161 ----
>        </varlistentry>
>
>        <varlistentry>
> +       <term>-h <replaceable class="parameter">hostName</replaceable></term>
> +       <listitem>
> +        <para>
> +     Specifies the TCP/IP hostname or address
> +     on which the <application>postmaster</application>
> +     is to listen for connections from frontend applications.  Defaults to
> +     the value of the
> +     <envar>PGHOST</envar>
> +     environment variable, or if <envar>PGHOST</envar>
> +     is not set, then defaults to "all", meaning listen on all configured addresses
> +     (including localhost).
> +        </para>
> +        <para>
> +     If you use a hostname or address other than "all", do not try to run
> +     multiple instances of <application>postmaster</application> 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 <application>postmaster</application> instances are
> +     listening must be distinct in the two last octets.
> +        </para>
> +        <para>
> +     If you do use "all" (the default), then each instance must listen on a
> +     different port (via -p or <envar>PGPORT</envar>).  And, of course, do
> +     not try to use both approaches on one host.
> +        </para>
> +       </listitem>
> +      </varlistentry>
> +
> +      <varlistentry>
>         <term>-i</term>
>         <listitem>
>          <para>
> ***************
> *** 135,140 ****
> --- 167,201 ----
>        </varlistentry>
>
>        <varlistentry>
> +       <term>-k <replaceable class="parameter">path</replaceable></term>
> +       <listitem>
> +        <para>
> +     Specifies the local Unix domain socket path name
> +     on which the <application>postmaster</application>
> +     is to listen for connections from frontend applications.  Defaults to
> +     the value of the
> +     <envar>PGUNIXSOCKET</envar>
> +     environment variable, or if <envar>PGUNIXSOCKET</envar>
> +     is not set, then defaults to a file in <filename>/tmp</filename>
> +     constructed from the port number.
> +        </para>
> +        <para>
> +         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 <filename>pg_hba.conf</filename>.
> +     If you specify a socket path other than the
> +     default then all frontend applications (including
> +     <application>psql</application>) must specify the same
> +     socket path using either command-line options or
> +     <envar>PGUNIXSOCKET</envar>.
> +        </para>
> +       </listitem>
> +      </varlistentry>
> +
> +      <varlistentry>
>         <term>-l</term>
>         <listitem>
>          <para>
> Index: doc/src/sgml/ref/psql-ref.sgml
> *** doc/src/sgml/ref/psql-ref.sgml    2000/06/30 21:15:38    1.1
> --- doc/src/sgml/ref/psql-ref.sgml    2000/07/02 03:56:05    1.3
> ***************
> *** 1329,1334 ****
> --- 1329,1347 ----
>
>
>       <varlistentry>
> +       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
> +       <listitem>
> +       <para>
> +       Specifies the Unix-domain socket on which the
> +       <application>postmaster</application> is running.
> +       Without this option, the socket is created in <filename>/tmp</filename>
> +       based on the port number.
> +       </para>
> +       </listitem>
> +     </varlistentry>
> +
> +
> +     <varlistentry>
>         <term>-H, --html</term>
>         <listitem>
>         <para>
> Index: doc/src/sgml/ref/vacuumdb.sgml
> *** doc/src/sgml/ref/vacuumdb.sgml    2000/06/30 21:15:38    1.1
> --- doc/src/sgml/ref/vacuumdb.sgml    2000/07/04 04:46:45    1.2
> ***************
> *** 24,30 ****
>     </refsynopsisdivinfo>
>     <synopsis>
>   vacuumdb [ <replaceable class="parameter">options</replaceable> ] [ --analyze | -z ]
> !     [ --alldb | -a ] [ --verbose | -v ]
>       [ --table '<replaceable class="parameter">table</replaceable> [ ( <replaceable
class="parameter">column</replaceable>[,...] ) ]' ] [ [-d] <replaceable class="parameter">dbname</replaceable> ] 
>     </synopsis>
>
> --- 24,30 ----
>     </refsynopsisdivinfo>
>     <synopsis>
>   vacuumdb [ <replaceable class="parameter">options</replaceable> ] [ --analyze | -z ]
> !     [ --all | -a ] [ --verbose | -v ]
>       [ --table '<replaceable class="parameter">table</replaceable> [ ( <replaceable
class="parameter">column</replaceable>[,...] ) ]' ] [ [-d] <replaceable class="parameter">dbname</replaceable> ] 
>     </synopsis>
>
> ***************
> *** 128,133 ****
> --- 128,145 ----
>          </para>
>         </listitem>
>        </varlistentry>
> +
> +     <varlistentry>
> +       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
> +       <listitem>
> +       <para>
> +       Specifies the Unix-domain socket on which the
> +       <application>postmaster</application> is running.
> +       Without this option, the socket is created in <filename>/tmp</filename>
> +       based on the port number.
> +       </para>
> +       </listitem>
> +     </varlistentry>
>
>        <varlistentry>
>         <term>-U <replaceable class="parameter">username</replaceable></term>
> Index: src/backend/libpq/pqcomm.c
> *** src/backend/libpq/pqcomm.c    2000/06/30 21:15:40    1.1
> --- src/backend/libpq/pqcomm.c    2000/07/01 18:50:46    1.3
> ***************
> *** 42,47 ****
> --- 42,48 ----
>    *        StreamConnection    - Create new connection with client
>    *        StreamClose            - Close a client/backend connection
>    *        pq_getport        - return the PGPORT setting
> +  *        pq_getunixsocket    - return the PGUNIXSOCKET setting
>    *        pq_init            - initialize libpq at backend startup
>    *        pq_close        - shutdown libpq at backend exit
>    *
> ***************
> *** 134,139 ****
> --- 135,151 ----
>   }
>
>   /* --------------------------------
> +  *        pq_getunixsocket - return the PGUNIXSOCKET setting.
> +  *        If NULL, default to computing it based on the port.
> +  * --------------------------------
> +  */
> + char *
> + pq_getunixsocket(void)
> + {
> +     return getenv("PGUNIXSOCKET");
> + }
> +
> + /* --------------------------------
>    *        pq_close - shutdown libpq at backend exit
>    *
>    * Note: in a standalone backend MyProcPort will be null,
> ***************
> *** 177,189 ****
>   /*
>    * StreamServerPort -- open a sock stream "listening" port.
>    *
> !  * This initializes the Postmaster's connection-accepting port.
>    *
>    * RETURNS: STATUS_OK or STATUS_ERROR
>    */
>
>   int
> ! StreamServerPort(char *hostName, unsigned short portName, int *fdP)
>   {
>       SockAddr    saddr;
>       int            fd,
> --- 189,205 ----
>   /*
>    * StreamServerPort -- open a sock stream "listening" port.
>    *
> !  * This initializes the Postmaster's connection-accepting port fdP.
> !  * If hostName is "any", listen on all configured IP addresses.
> !  * If hostName is NULL, listen on a Unix-domain socket instead of TCP;
> !  * if unixSocketName is NULL, a default path (constructed in UNIX_SOCK_PATH
> !  * in include/libpq/pqcomm.h) based on portName is used.
>    *
>    * RETURNS: STATUS_OK or STATUS_ERROR
>    */
>
>   int
> ! StreamServerPort(char *hostName, unsigned short portNumber, char *unixSocketName, int *fdP)
>   {
>       SockAddr    saddr;
>       int            fd,
> ***************
> *** 227,233 ****
>       saddr.sa.sa_family = family;
>       if (family == AF_UNIX)
>       {
> !         len = UNIXSOCK_PATH(saddr.un, portName);
>           strcpy(sock_path, saddr.un.sun_path);
>
>           /*
> --- 243,250 ----
>       saddr.sa.sa_family = family;
>       if (family == AF_UNIX)
>       {
> !         UNIXSOCK_PATH(saddr.un, portNumber, unixSocketName);
> !         len = UNIXSOCK_LEN(saddr.un);
>           strcpy(sock_path, saddr.un.sun_path);
>
>           /*
> ***************
> *** 259,267 ****
>       }
>       else
>       {
> !         saddr.in.sin_addr.s_addr = htonl(INADDR_ANY);
> !         saddr.in.sin_port = htons(portName);
> !         len = sizeof(struct sockaddr_in);
>       }
>       err = bind(fd, &saddr.sa, len);
>       if (err < 0)
> --- 276,305 ----
>       }
>       else
>       {
> !       /* TCP/IP socket */
> !       if (!strcmp(hostName, "all")) /* like for databases in pg_hba.conf.  */
> !         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(portNumber);
> !       len = sizeof(struct sockaddr_in);
>       }
>       err = bind(fd, &saddr.sa, len);
>       if (err < 0)
> Index: src/backend/postmaster/postmaster.c
> *** src/backend/postmaster/postmaster.c    2000/06/30 21:15:42    1.1
> --- src/backend/postmaster/postmaster.c    2000/07/06 07:38:21    1.5
> ***************
> *** 136,143 ****
>   /* list of ports associated with still open, but incomplete connections */
>   static Dllist *PortList;
>
> ! static unsigned short PostPortName = 0;
>
>    /*
>     * This is a boolean indicating that there is at least one backend that
>     * is accessing the current shared memory and semaphores. Between the
> --- 136,150 ----
>   /* list of ports associated with still open, but incomplete connections */
>   static Dllist *PortList;
>
> ! /* Hostname of interface to listen on, or 'any'. */
> ! static char *HostName = NULL;
>
> + /* TCP/IP port number to listen on.  Also used to default the Unix-domain socket name.  */
> + static unsigned short PostPortNumber = 0;
> +
> + /* Override of the default Unix-domain socket name to listen on, if non-NULL.  */
> + static char *UnixSocketName = NULL;
> +
>    /*
>     * This is a boolean indicating that there is at least one backend that
>     * is accessing the current shared memory and semaphores. Between the
> ***************
> *** 274,280 ****
>   static void SignalChildren(SIGNAL_ARGS);
>   static int    CountChildren(void);
>   static int
> ! SetOptsFile(char *progname, int port, char *datadir,
>               int assert, int nbuf, char *execfile,
>               int debuglvl, int netserver,
>   #ifdef USE_SSL
> --- 281,287 ----
>   static void SignalChildren(SIGNAL_ARGS);
>   static int    CountChildren(void);
>   static int
> ! SetOptsFile(char *progname, char *hostname, int port, char *unixsocket, char *datadir,
>               int assert, int nbuf, char *execfile,
>               int debuglvl, int netserver,
>   #ifdef USE_SSL
> ***************
> *** 370,380 ****
>   {
>       extern int    NBuffers;        /* from buffer/bufmgr.c */
>       int            opt;
> -     char       *hostName;
>       int            status;
>       int            silentflag = 0;
>       bool        DataDirOK;        /* We have a usable PGDATA value */
> -     char        hostbuf[MAXHOSTNAMELEN];
>       int            nonblank_argc;
>       char        original_extraoptions[MAXPGPATH];
>
> --- 377,385 ----
> ***************
> *** 431,449 ****
>        */
>       umask((mode_t) 0077);
>
> -     if (!(hostName = getenv("PGHOST")))
> -     {
> -         if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
> -             strcpy(hostbuf, "localhost");
> -         hostName = hostbuf;
> -     }
> -
>       MyProcPid = getpid();
>       DataDir = getenv("PGDATA"); /* default value */
>
>       opterr = 0;
>       IgnoreSystemIndexes(false);
> !     while ((opt = getopt(nonblank_argc, argv, "A:a:B:b:D:d:ilm:MN:no:p:Ss")) != EOF)
>       {
>           switch (opt)
>           {
> --- 436,447 ----
>        */
>       umask((mode_t) 0077);
>
>       MyProcPid = getpid();
>       DataDir = getenv("PGDATA"); /* default value */
>
>       opterr = 0;
>       IgnoreSystemIndexes(false);
> !     while ((opt = getopt(nonblank_argc, argv, "A:a:B:b:D:d:h:ik:lm:MN:no:p:Ss")) != EOF)
>       {
>           switch (opt)
>           {
> ***************
> *** 498,506 ****
> --- 496,511 ----
>                   DebugLvl = atoi(optarg);
>                   pg_options[TRACE_VERBOSE] = DebugLvl;
>                   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':
>                   SecureNetServer = true;
> ***************
> *** 545,551 ****
>                   break;
>               case 'p':
>                   /* Set PGPORT by hand. */
> !                 PostPortName = (unsigned short) atoi(optarg);
>                   break;
>               case 'S':
>
> --- 550,556 ----
>                   break;
>               case 'p':
>                   /* Set PGPORT by hand. */
> !                 PostPortNumber = (unsigned short) atoi(optarg);
>                   break;
>               case 'S':
>
> ***************
> *** 577,584 ****
>       /*
>        * Select default values for switches where needed
>        */
> !     if (PostPortName == 0)
> !         PostPortName = (unsigned short) pq_getport();
>
>       /*
>        * Check for invalid combinations of switches
> --- 582,603 ----
>       /*
>        * Select default values for switches where needed
>        */
> !     if (HostName == NULL)
> !     {
> !         if (!(HostName = getenv("PGHOST")))
> !         {
> !             HostName = "any";
> !         }
> !     }
> !     else if (!NetServer)
> !     {
> !         fprintf(stderr, "%s: -h requires -i.\n", progname);
> !         exit(1);
> !     }
> !     if (PostPortNumber == 0)
> !         PostPortNumber = (unsigned short) pq_getport();
> !     if (UnixSocketName == NULL)
> !         UnixSocketName = pq_getunixsocket();
>
>       /*
>        * Check for invalid combinations of switches
> ***************
> *** 622,628 ****
>
>       if (NetServer)
>       {
> !         status = StreamServerPort(hostName, PostPortName, &ServerSock_INET);
>           if (status != STATUS_OK)
>           {
>               fprintf(stderr, "%s: cannot create INET stream port\n",
> --- 641,647 ----
>
>       if (NetServer)
>       {
> !         status = StreamServerPort(HostName, PostPortNumber, NULL, &ServerSock_INET);
>           if (status != STATUS_OK)
>           {
>               fprintf(stderr, "%s: cannot create INET stream port\n",
> ***************
> *** 632,638 ****
>       }
>
>   #if !defined(__CYGWIN32__) && !defined(__QNX__)
> !     status = StreamServerPort(NULL, PostPortName, &ServerSock_UNIX);
>       if (status != STATUS_OK)
>       {
>           fprintf(stderr, "%s: cannot create UNIX stream port\n",
> --- 651,657 ----
>       }
>
>   #if !defined(__CYGWIN32__) && !defined(__QNX__)
> !     status = StreamServerPort(NULL, PostPortNumber, UnixSocketName, &ServerSock_UNIX);
>       if (status != STATUS_OK)
>       {
>           fprintf(stderr, "%s: cannot create UNIX stream port\n",
> ***************
> *** 642,648 ****
>   #endif
>       /* set up shared memory and semaphores */
>       EnableMemoryContext(TRUE);
> !     reset_shared(PostPortName);
>
>       /*
>        * Initialize the list of active backends.    This list is only used for
> --- 661,667 ----
>   #endif
>       /* set up shared memory and semaphores */
>       EnableMemoryContext(TRUE);
> !     reset_shared(PostPortNumber);
>
>       /*
>        * Initialize the list of active backends.    This list is only used for
> ***************
> *** 664,670 ****
>           {
>               if (SetOptsFile(
>                               progname,    /* postmaster executable file */
> !                             PostPortName,        /* port number */
>                               DataDir,    /* PGDATA */
>                               assert_enabled,        /* whether -A is specified
>                                                    * or not */
> --- 683,691 ----
>           {
>               if (SetOptsFile(
>                               progname,    /* postmaster executable file */
> !                             HostName, /* IP address to bind to */
> !                             PostPortNumber,        /* port number */
> !                             UnixSocketName,    /* PGUNIXSOCKET */
>                               DataDir,    /* PGDATA */
>                               assert_enabled,        /* whether -A is specified
>                                                    * or not */
> ***************
> *** 753,759 ****
>           {
>               if (SetOptsFile(
>                               progname,    /* postmaster executable file */
> !                             PostPortName,        /* port number */
>                               DataDir,    /* PGDATA */
>                               assert_enabled,        /* whether -A is specified
>                                                    * or not */
> --- 774,782 ----
>           {
>               if (SetOptsFile(
>                               progname,    /* postmaster executable file */
> !                             HostName, /* IP address to bind to */
> !                             PostPortNumber,        /* port number */
> !                             UnixSocketName,    /* PGUNIXSOCKET */
>                               DataDir,    /* PGDATA */
>                               assert_enabled,        /* whether -A is specified
>                                                    * or not */
> ***************
> *** 837,843 ****
> --- 860,868 ----
>       fprintf(stderr, "\t-a system\tuse this authentication system\n");
>       fprintf(stderr, "\t-b backend\tuse a specific backend server executable\n");
>       fprintf(stderr, "\t-d [1-5]\tset debugging level\n");
> +     fprintf(stderr, "\t-h hostname\tspecify hostname or IP address or 'any' for postmaster to listen on (also use
-i)\n");
>       fprintf(stderr, "\t-i \t\tlisten on TCP/IP sockets as well as Unix domain socket\n");
> +     fprintf(stderr, "\t-k path\tspecify Unix-domain socket name for postmaster to listen on\n");
>   #ifdef USE_SSL
>       fprintf(stderr, " \t-l \t\tfor TCP/IP sockets, listen only on SSL connections\n");
>   #endif
> ***************
> *** 1318,1328 ****
> --- 1343,1417 ----
>   }
>
>   /*
> +  * 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(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 of "any".
> +      *
> +      * If HostName is not "any", 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 (strcmp(HostName, "any"))
> +         port = get_host_port();
> +
>       ipc_key = port * 1000 + shmem_seq * 100;
>       CreateSharedMemoryAndSemaphores(ipc_key, MaxBackends);
>       shmem_seq += 1;
> ***************
> *** 1540,1546 ****
>                   ctime(&tnow));
>           fflush(stderr);
>           shmem_exit(0);
> !         reset_shared(PostPortName);
>           StartupPID = StartupDataBase();
>           return;
>       }
> --- 1629,1635 ----
>                   ctime(&tnow));
>           fflush(stderr);
>           shmem_exit(0);
> !         reset_shared(PostPortNumber);
>           StartupPID = StartupDataBase();
>           return;
>       }
> ***************
> *** 1720,1726 ****
>        * Set up the necessary environment variables for the backend This
>        * should really be some sort of message....
>        */
> !     sprintf(envEntry[0], "POSTPORT=%d", PostPortName);
>       putenv(envEntry[0]);
>       sprintf(envEntry[1], "POSTID=%d", NextBackendTag);
>       putenv(envEntry[1]);
> --- 1809,1815 ----
>        * Set up the necessary environment variables for the backend This
>        * should really be some sort of message....
>        */
> !     sprintf(envEntry[0], "POSTPORT=%d", PostPortNumber);
>       putenv(envEntry[0]);
>       sprintf(envEntry[1], "POSTID=%d", NextBackendTag);
>       putenv(envEntry[1]);
> ***************
> *** 2174,2180 ****
>       for (i = 0; i < 4; ++i)
>           MemSet(ssEntry[i], 0, 2 * ARGV_SIZE);
>
> !     sprintf(ssEntry[0], "POSTPORT=%d", PostPortName);
>       putenv(ssEntry[0]);
>       sprintf(ssEntry[1], "POSTID=%d", NextBackendTag);
>       putenv(ssEntry[1]);
> --- 2263,2269 ----
>       for (i = 0; i < 4; ++i)
>           MemSet(ssEntry[i], 0, 2 * ARGV_SIZE);
>
> !     sprintf(ssEntry[0], "POSTPORT=%d", PostPortNumber);
>       putenv(ssEntry[0]);
>       sprintf(ssEntry[1], "POSTID=%d", NextBackendTag);
>       putenv(ssEntry[1]);
> ***************
> *** 2254,2260 ****
>    * Create the opts file
>    */
>   static int
> ! SetOptsFile(char *progname, int port, char *datadir,
>               int assert, int nbuf, char *execfile,
>               int debuglvl, int netserver,
>   #ifdef USE_SSL
> --- 2343,2349 ----
>    * Create the opts file
>    */
>   static int
> ! SetOptsFile(char *progname, char *hostname, int port, char *unixsocket, char *datadir,
>               int assert, int nbuf, char *execfile,
>               int debuglvl, int netserver,
>   #ifdef USE_SSL
> ***************
> *** 2279,2284 ****
> --- 2368,2383 ----
>           return (-1);
>       }
>       snprintf(opts, sizeof(opts), "%s\n-p %d\n-D %s\n", progname, port, datadir);
> +     if (netserver)
> +     {
> +         sprintf(buf, "-h %s\n", hostname);
> +         strcat(opts, buf);
> +     }
> +     if (unixsocket)
> +     {
> +         sprintf(buf, "-k %s\n", unixsocket);
> +         strcat(opts, buf);
> +     }
>       if (assert)
>       {
>           sprintf(buf, "-A %d\n", assert);
> Index: src/bin/pg_dump/pg_dump.c
> *** src/bin/pg_dump/pg_dump.c    2000/06/30 21:15:44    1.1
> --- src/bin/pg_dump/pg_dump.c    2000/07/01 18:41:22    1.2
> ***************
> *** 140,145 ****
> --- 140,146 ----
>            "  -D, --attribute-inserts  dump data as INSERT commands with attribute names\n"
>            "  -h, --host <hostname>    server host name\n"
>            "  -i, --ignore-version     proceed when database version != pg_dump version\n"
> +          "  -k, --unixsocket <path>  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"
> ***************
> *** 158,163 ****
> --- 159,165 ----
>            "  -D                       dump data as INSERT commands with attribute names\n"
>            "  -h <hostname>            server host name\n"
>            "  -i                       proceed when database version != pg_dump version\n"
> +          "  -k <path>                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"
> ***************
> *** 579,584 ****
> --- 581,587 ----
>       const char *dbname = NULL;
>       const char *pghost = NULL;
>       const char *pgport = NULL;
> +     const char *pgunixsocket = NULL;
>       char       *tablename = NULL;
>       bool        oids = false;
>       TableInfo  *tblinfo;
> ***************
> *** 598,603 ****
> --- 601,607 ----
>           {"attribute-inserts", no_argument, NULL, 'D'},
>           {"host", required_argument, NULL, 'h'},
>           {"ignore-version", no_argument, NULL, 'i'},
> +         {"unixsocket", required_argument, NULL, 'k'},
>           {"no-quotes", no_argument, NULL, 'n'},
>           {"quotes", no_argument, NULL, 'N'},
>           {"oids", no_argument, NULL, 'o'},
> ***************
> *** 662,667 ****
> --- 666,674 ----
>               case 'i':            /* ignore database version mismatch */
>                   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;
> ***************
> *** 782,788 ****
>           exit(1);
>       }
>
> -     /* g_conn = PQsetdb(pghost, pgport, NULL, NULL, dbname); */
>       if (pghost != NULL)
>       {
>           sprintf(tmp_string, "host=%s ", pghost);
> --- 789,794 ----
> ***************
> *** 791,796 ****
> --- 797,807 ----
>       if (pgport != NULL)
>       {
>           sprintf(tmp_string, "port=%s ", pgport);
> +         strcat(connect_string, tmp_string);
> +     }
> +     if (pgunixsocket != NULL)
> +     {
> +         sprintf(tmp_string, "unixsocket=%s ", pgunixsocket);
>           strcat(connect_string, tmp_string);
>       }
>       if (dbname != NULL)
> Index: src/bin/psql/command.c
> *** src/bin/psql/command.c    2000/06/30 21:15:46    1.1
> --- src/bin/psql/command.c    2000/07/01 18:20:40    1.2
> ***************
> *** 1199,1204 ****
> --- 1199,1205 ----
>       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) */
> ***************
> *** 1228,1233 ****
> --- 1229,1235 ----
>       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);
>
> ***************
> *** 1303,1308 ****
> --- 1305,1311 ----
>       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));
> Index: src/bin/psql/command.h
> Index: src/bin/psql/common.c
> *** src/bin/psql/common.c    2000/06/30 21:15:46    1.1
> --- src/bin/psql/common.c    2000/07/01 18:20:40    1.2
> ***************
> *** 330,335 ****
> --- 330,336 ----
>               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;
> ***************
> *** 509,514 ****
> --- 510,516 ----
>                   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;
> Index: src/bin/psql/help.c
> *** src/bin/psql/help.c    2000/06/30 21:15:46    1.1
> --- src/bin/psql/help.c    2000/07/01 18:20:40    1.2
> ***************
> *** 103,108 ****
> --- 103,118 ----
>       puts(")");
>
>       puts("  -H              HTML table output mode (-P format=html)");
> +
> +     /* Display default Unix-domain socket */
> +     env = getenv("PGUNIXSOCKET");
> +     printf("  -k <path>       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 <filename>   Send query output to filename (or |pipe)");
> Index: src/bin/psql/prompt.c
> *** src/bin/psql/prompt.c    2000/06/30 21:15:46    1.1
> --- src/bin/psql/prompt.c    2000/07/01 18:20:40    1.2
> ***************
> *** 189,194 ****
> --- 189,199 ----
>                       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)
> Index: src/bin/psql/prompt.h
> Index: src/bin/psql/settings.h
> Index: src/bin/psql/startup.c
> *** src/bin/psql/startup.c    2000/06/30 21:15:46    1.1
> --- src/bin/psql/startup.c    2000/07/01 18:20:40    1.2
> ***************
> *** 66,71 ****
> --- 66,72 ----
>       char       *dbname;
>       char       *host;
>       char       *port;
> +     char       *unixsocket;
>       char       *username;
>       enum _actions action;
>       char       *action_string;
> ***************
> *** 158,163 ****
> --- 159,165 ----
>       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);
> ***************
> *** 202,207 ****
> --- 204,210 ----
>       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
> ***************
> *** 313,318 ****
> --- 316,322 ----
>           {"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'},
> ***************
> *** 346,359 ****
>       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)
>   #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)
>   #endif     /* not HAVE_GETOPT_LONG */
>       {
>           switch (c)
> --- 350,363 ----
>       memset(options, 0, sizeof *options);
>
>   #ifdef HAVE_GETOPT_LONG
> !     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:Hk:no:p:P:qRsStT:uU:v:VWxX?-")) != -1)
>   #endif     /* not HAVE_GETOPT_LONG */
>       {
>           switch (c)
> ***************
> *** 398,403 ****
> --- 402,410 ----
>                   break;
>               case 'l':
>                   options->action = ACT_LIST_DB;
> +                 break;
> +             case 'k':
> +                 options->unixsocket = optarg;
>                   break;
>               case 'n':
>                   options->no_readline = true;
> Index: src/bin/scripts/createdb
> *** src/bin/scripts/createdb    2000/06/30 21:15:46    1.1
> --- src/bin/scripts/createdb    2000/07/04 04:46:45    1.2
> ***************
> *** 50,55 ****
> --- 50,64 ----
>           --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,119 ****
> --- 123,129 ----
>       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"
> Index: src/bin/scripts/createlang.sh
> *** src/bin/scripts/createlang.sh    2000/06/30 21:15:46    1.1
> --- src/bin/scripts/createlang.sh    2000/07/04 04:46:45    1.2
> ***************
> *** 65,70 ****
> --- 65,79 ----
>           --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,131 ****
> --- 135,141 ----
>       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"
> Index: src/bin/scripts/createuser
> *** src/bin/scripts/createuser    2000/06/30 21:15:46    1.1
> --- src/bin/scripts/createuser    2000/07/04 04:46:45    1.2
> ***************
> *** 63,68 ****
> --- 63,77 ----
>           --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,140 ****
> --- 144,150 ----
>       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"
> Index: src/bin/scripts/dropdb
> *** src/bin/scripts/dropdb    2000/06/30 21:15:46    1.1
> --- src/bin/scripts/dropdb    2000/07/04 04:46:45    1.2
> ***************
> *** 59,64 ****
> --- 59,73 ----
>           --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,108 ****
> --- 112,118 ----
>       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"
> Index: src/bin/scripts/droplang
> *** src/bin/scripts/droplang    2000/06/30 21:15:46    1.1
> --- src/bin/scripts/droplang    2000/07/04 04:46:45    1.2
> ***************
> *** 65,70 ****
> --- 65,79 ----
>           --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,118 ****
> --- 122,128 ----
>       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"
> Index: src/bin/scripts/dropuser
> *** src/bin/scripts/dropuser    2000/06/30 21:15:46    1.1
> --- src/bin/scripts/dropuser    2000/07/04 04:46:45    1.2
> ***************
> *** 59,64 ****
> --- 59,73 ----
>           --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,110 ****
> --- 114,120 ----
>       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"
> Index: src/bin/scripts/vacuumdb
> *** src/bin/scripts/vacuumdb    2000/06/30 21:15:46    1.1
> --- src/bin/scripts/vacuumdb    2000/07/04 04:46:45    1.2
> ***************
> *** 52,57 ****
> --- 52,66 ----
>           --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,126 ****
> --- 130,136 ----
>           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"
> Index: src/include/libpq/libpq.h
> *** src/include/libpq/libpq.h    2000/06/30 21:15:47    1.1
> --- src/include/libpq/libpq.h    2000/07/01 18:20:40    1.2
> ***************
> *** 236,246 ****
>   /*
>    * prototypes for functions in pqcomm.c
>    */
> ! extern int    StreamServerPort(char *hostName, unsigned short portName, int *fdP);
>   extern int    StreamConnection(int server_fd, Port *port);
>   extern void StreamClose(int sock);
>   extern void pq_init(void);
>   extern int    pq_getport(void);
>   extern void pq_close(void);
>   extern int    pq_getbytes(char *s, size_t len);
>   extern int    pq_getstring(StringInfo s);
> --- 236,247 ----
>   /*
>    * prototypes for functions in pqcomm.c
>    */
> ! extern int    StreamServerPort(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);
>   extern int    pq_getport(void);
> + extern char    *pq_getunixsocket(void);
>   extern void pq_close(void);
>   extern int    pq_getbytes(char *s, size_t len);
>   extern int    pq_getstring(StringInfo s);
> Index: src/include/libpq/password.h
> Index: src/include/libpq/pqcomm.h
> *** src/include/libpq/pqcomm.h    2000/06/30 21:15:47    1.1
> --- src/include/libpq/pqcomm.h    2000/07/01 18:59:33    1.6
> ***************
> *** 42,53 ****
>   /* 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)))
>   #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))
>   #endif
>
>   /*
> --- 42,56 ----
>   /* Configure the UNIX socket address for the well known port. */
>
>   #if defined(SUN_LEN)
> ! #define UNIXSOCK_PATH(sun,port,defpath) \
> !         (defpath ? (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,defpath) \
> !         (defpath ? (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
>
>   /*
> Index: src/interfaces/libpq/fe-connect.c
> *** src/interfaces/libpq/fe-connect.c    2000/06/30 21:15:51    1.1
> --- src/interfaces/libpq/fe-connect.c    2000/07/01 18:50:47    1.3
> ***************
> *** 125,130 ****
> --- 125,133 ----
>       {"port", "PGPORT", DEF_PGPORT, NULL,
>       "Database-Port", "", 6},
>
> +     {"unixsocket", "PGUNIXSOCKET", NULL, NULL,
> +     "Unix-Socket", "", 80},
> +
>       {"tty", "PGTTY", DefaultTty, NULL,
>       "Backend-Debug-TTY", "D", 40},
>
> ***************
> *** 293,298 ****
> --- 296,303 ----
>       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");
> ***************
> *** 369,374 ****
> --- 374,382 ----
>    *      PGPORT       identifies TCP port to which to connect if <pgport> 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 <pgtty> argument
>    *                   is NULL or a null string.
>    *
> ***************
> *** 422,427 ****
> --- 430,439 ----
>       else
>           conn->pgport = strdup(pgport);
>
> +     conn->pgunixsocket = getenv("PGUNIXSOCKET");
> +     if (conn->pgunixsocket)
> +         conn->pgunixsocket = strdup(conn->pgunixsocket);
> +
>       if ((pgtty == NULL) || pgtty[0] == '\0')
>       {
>           if ((tmp = getenv("PGTTY")) == NULL)
> ***************
> *** 489,501 ****
>
>   /*
>    * update_db_info -
> !  * get all additional infos out of dbName
>    *
>    */
>   static int
>   update_db_info(PGconn *conn)
>   {
> !     char       *tmp,
>                  *old = conn->dbName;
>
>       if (strchr(conn->dbName, '@') != NULL)
> --- 501,513 ----
>
>   /*
>    * update_db_info -
> !  * get all additional info out of dbName
>    *
>    */
>   static int
>   update_db_info(PGconn *conn)
>   {
> !     char       *tmp, *tmp2,
>                  *old = conn->dbName;
>
>       if (strchr(conn->dbName, '@') != NULL)
> ***************
> *** 504,509 ****
> --- 516,523 ----
>           tmp = strrchr(conn->dbName, ':');
>           if (tmp != NULL)        /* port number given */
>           {
> +             if (conn->pgport)
> +                 free(conn->pgport);
>               conn->pgport = strdup(tmp + 1);
>               *tmp = '\0';
>           }
> ***************
> *** 511,516 ****
> --- 525,532 ----
>           tmp = strrchr(conn->dbName, '@');
>           if (tmp != NULL)        /* host name given */
>           {
> +             if (conn->pghost)
> +                 free(conn->pghost);
>               conn->pghost = strdup(tmp + 1);
>               *tmp = '\0';
>           }
> ***************
> *** 537,549 ****
>
>               /*
>                * new style:
> !              * <tcp|unix>:postgresql://server[:port][/dbname][?options]
>                */
>               offset += strlen("postgresql://");
>
>               tmp = strrchr(conn->dbName + offset, '?');
>               if (tmp != NULL)    /* options given */
>               {
>                   conn->pgoptions = strdup(tmp + 1);
>                   *tmp = '\0';
>               }
> --- 553,567 ----
>
>               /*
>                * new style:
> !              * <tcp|unix>: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';
>               }
> ***************
> *** 551,576 ****
>               tmp = strrchr(conn->dbName + offset, '/');
>               if (tmp != NULL)    /* database name given */
>               {
>                   conn->dbName = strdup(tmp + 1);
>                   *tmp = '\0';
>               }
>               else
>               {
>                   if ((tmp = getenv("PGDATABASE")) != NULL)
>                       conn->dbName = strdup(tmp);
>                   else if (conn->pguser)
>                       conn->dbName = strdup(conn->pguser);
>               }
>
>               tmp = strrchr(old + offset, ':');
> !             if (tmp != NULL)    /* port number given */
>               {
> -                 conn->pgport = strdup(tmp + 1);
>                   *tmp = '\0';
>               }
>
>               if (strncmp(old, "unix:", 5) == 0)
>               {
>                   conn->pghost = NULL;
>                   if (strcmp(old + offset, "localhost") != 0)
>                   {
> --- 569,630 ----
>               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 or Unix socket path given */
>               {
>                   *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)
>                   {
> ***************
> *** 582,589 ****
>                   }
>               }
>               else
>                   conn->pghost = strdup(old + offset);
> !
>               free(old);
>           }
>       }
> --- 636,646 ----
>                   }
>               }
>               else
> +             {
> +                 if (conn->pghost)
> +                     free(conn->pghost);
>                   conn->pghost = strdup(old + offset);
> !             }
>               free(old);
>           }
>       }
> ***************
> *** 743,749 ****
>       }
>   #if !defined(WIN32) && !defined(__CYGWIN32__)
>       else
> !         conn->raddr_len = UNIXSOCK_PATH(conn->raddr.un, portno);
>   #endif
>
>
> --- 800,809 ----
>       }
>   #if !defined(WIN32) && !defined(__CYGWIN32__)
>       else
> !     {
> !         UNIXSOCK_PATH(conn->raddr.un, portno, conn->pgunixsocket);
> !         conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un);
> !     }
>   #endif
>
>
> ***************
> *** 892,898 ****
>                                 conn->pghost ? conn->pghost : "localhost",
>                                 (family == AF_INET) ?
>                                 "TCP/IP port" : "Unix socket",
> !                               conn->pgport);
>               goto connect_errReturn;
>           }
>       }
> --- 952,959 ----
>                                 conn->pghost ? conn->pghost : "localhost",
>                                 (family == AF_INET) ?
>                                 "TCP/IP port" : "Unix socket",
> !                               (family == AF_UNIX && conn->pgunixsocket) ?
> !                               conn->pgunixsocket : conn->pgport);
>               goto connect_errReturn;
>           }
>       }
> ***************
> *** 1123,1129 ****
>                                  conn->pghost ? conn->pghost : "localhost",
>                                     (conn->raddr.sa.sa_family == AF_INET) ?
>                                         "TCP/IP port" : "Unix socket",
> !                                       conn->pgport);
>                       goto error_return;
>                   }
>
> --- 1184,1191 ----
>                                  conn->pghost ? conn->pghost : "localhost",
>                                     (conn->raddr.sa.sa_family == AF_INET) ?
>                                         "TCP/IP port" : "Unix socket",
> !                               (conn->raddr.sa.sa_family == AF_UNIX && conn->pgunixsocket) ?
> !                                       conn->pgunixsocket : conn->pgport);
>                       goto error_return;
>                   }
>
> ***************
> *** 1799,1804 ****
> --- 1861,1868 ----
>           free(conn->pghostaddr);
>       if (conn->pgport)
>           free(conn->pgport);
> +     if (conn->pgunixsocket)
> +         free(conn->pgunixsocket);
>       if (conn->pgtty)
>           free(conn->pgtty);
>       if (conn->pgoptions)
> ***************
> *** 2383,2388 ****
> --- 2447,2460 ----
>       if (!conn)
>           return (char *) NULL;
>       return conn->pgport;
> + }
> +
> + char *
> + PQunixsocket(const PGconn *conn)
> + {
> +     if (!conn)
> +         return (char *) NULL;
> +     return conn->pgunixsocket;
>   }
>
>   char *
> Index: src/interfaces/libpq/libpq-fe.h
> *** src/interfaces/libpq/libpq-fe.h    2000/06/30 21:15:51    1.1
> --- src/interfaces/libpq/libpq-fe.h    2000/07/01 18:20:40    1.2
> ***************
> *** 214,219 ****
> --- 214,220 ----
>       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);
> Index: src/interfaces/libpq/libpq-int.h
> *** src/interfaces/libpq/libpq-int.h    2000/06/30 21:15:51    1.1
> --- src/interfaces/libpq/libpq-int.h    2000/07/01 18:20:40    1.2
> ***************
> *** 202,207 ****
> --- 202,209 ----
>                                    * 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 */
> Index: src/interfaces/libpq/libpqdll.def
> *** src/interfaces/libpq/libpqdll.def    2000/06/30 21:15:51    1.1
> --- src/interfaces/libpq/libpqdll.def    2000/07/01 18:20:40    1.2
> ***************
> *** 79,81 ****
> --- 79,82 ----
>       destroyPQExpBuffer    @ 76
>       createPQExpBuffer    @ 77
>       PQconninfoFree        @ 78
> +     PQunixsocket        @ 79
>


--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
? config.log
? config.cache
? config.status
? GNUmakefile
? src/Makefile.custom
? src/GNUmakefile
? src/Makefile.global
? src/log
? src/crtags
? src/backend/postgres
? src/backend/catalog/global.description
? src/backend/catalog/global.bki
? src/backend/catalog/template1.bki
? src/backend/catalog/template1.description
? src/backend/port/Makefile
? src/bin/initdb/initdb
? src/bin/initlocation/initlocation
? src/bin/ipcclean/ipcclean
? src/bin/pg_config/pg_config
? src/bin/pg_ctl/pg_ctl
? src/bin/pg_dump/pg_dump
? src/bin/pg_dump/pg_restore
? src/bin/pg_dump/pg_dumpall
? src/bin/pg_id/pg_id
? src/bin/pg_passwd/pg_passwd
? src/bin/pgaccess/pgaccess
? src/bin/pgtclsh/Makefile.tkdefs
? src/bin/pgtclsh/Makefile.tcldefs
? src/bin/pgtclsh/pgtclsh
? src/bin/pgtclsh/pgtksh
? src/bin/psql/psql
? src/bin/scripts/createlang
? src/include/config.h
? src/include/stamp-h
? src/interfaces/ecpg/lib/libecpg.so.3.2.0
? src/interfaces/ecpg/preproc/ecpg
? src/interfaces/libpgeasy/libpgeasy.so.2.1
? src/interfaces/libpgtcl/libpgtcl.so.2.1
? src/interfaces/libpq/libpq.so.2.1
? src/interfaces/perl5/blib
? src/interfaces/perl5/Makefile
? src/interfaces/perl5/pm_to_blib
? src/interfaces/perl5/Pg.c
? src/interfaces/perl5/Pg.bs
? src/pl/plperl/blib
? src/pl/plperl/Makefile
? src/pl/plperl/pm_to_blib
? src/pl/plperl/SPI.c
? src/pl/plperl/plperl.bs
? src/pl/plpgsql/src/libplpgsql.so.1.0
? src/pl/tcl/Makefile.tcldefs
? src/test/regress/pg_regress
? src/test/regress/regress.out
? src/test/regress/results
? src/test/regress/regression.diffs
? src/test/regress/expected/copy.out
? src/test/regress/expected/create_function_1.out
? src/test/regress/expected/create_function_2.out
? src/test/regress/expected/misc.out
? src/test/regress/expected/constraints.out
? src/test/regress/sql/copy.sql
? src/test/regress/sql/misc.sql
? src/test/regress/sql/create_function_1.sql
? src/test/regress/sql/create_function_2.sql
? src/test/regress/sql/constraints.sql
Index: doc/src/sgml/environ.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/environ.sgml,v
retrieving revision 1.5
diff -c -r1.5 environ.sgml
*** doc/src/sgml/environ.sgml    2000/05/02 20:01:51    1.5
--- doc/src/sgml/environ.sgml    2000/11/13 05:26:14
***************
*** 47,62 ****
  </Para>

  <Para>
! 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 <Acronym>PGHOST</Acronym> environment variable to the name
! of the database server machine.   The  environment  variable
! <Acronym>PGPORT</Acronym> 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 <Application>postmaster</Application>,
!  you should immediately consult your site administrator to make sure that your
! environment is properly set up.
! </Para>

  </Chapter>
--- 47,63 ----
  </Para>

  <Para>
!
! 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
! <Acronym>PGHOST</Acronym> environment variable to the name of the
! database server machine.   The  environment  variable
! <Acronym>PGPORT</Acronym> or <envar>PGUNIXSOCKET</envar> 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
! <Application>postmaster</Application>, you should immediately consult
! your site administrator to make sure that your environment is properly
! set up. </Para>

  </Chapter>
Index: doc/src/sgml/libpq++.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/libpq++.sgml,v
retrieving revision 1.17
diff -c -r1.17 libpq++.sgml
*** doc/src/sgml/libpq++.sgml    2000/09/29 20:21:34    1.17
--- doc/src/sgml/libpq++.sgml    2000/11/13 05:26:14
***************
*** 93,98 ****
--- 93,105 ----
        </listitem>
        <listitem>
         <para>
+     <envar>PGUNIXSOCKET</envar>  sets the full Unix domain socket
+     file name for communicating with the <productname>Postgres</productname>
+     backend.
+        </para>
+       </listitem>
+       <listitem>
+        <para>
      <envar>PGDATABASE</envar>  sets the default
      <productname>Postgres</productname> database name.
         </para>
Index: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/libpq.sgml,v
retrieving revision 1.44
diff -c -r1.44 libpq.sgml
*** doc/src/sgml/libpq.sgml    2000/10/17 14:27:50    1.44
--- doc/src/sgml/libpq.sgml    2000/11/13 05:26:16
***************
*** 134,139 ****
--- 134,148 ----
      </varlistentry>

      <varlistentry>
+      <term><literal>unixsocket</literal></term>
+      <listitem>
+      <para>
+       Full path to Unix-domain socket file to connect to at the server host.
+      </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
       <term><literal>dbname</literal></term>
       <listitem>
       <para>
***************
*** 556,561 ****
--- 565,580 ----

  <listitem>
  <para>
+ <function>PQunixsocket</function>
+          Returns the name of the Unix-domain socket of the connection.
+ <synopsis>
+ char *PQunixsocket(const PGconn *conn)
+ </synopsis>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
  <function>PQtty</function>
           Returns the debug tty of the connection.
  <synopsis>
***************
*** 1821,1826 ****
--- 1840,1852 ----
  <envar>PGHOST</envar> sets the default server name.
  If a non-zero-length string is specified, TCP/IP communication is used.
  Without a host name, libpq will connect using a local Unix domain socket.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <envar>PGPORT</envar>  sets the default port or local Unix domain socket
+ file extension for communicating with the <productname>Postgres</productname>
+ backend.
  </para>
  </listitem>
  <listitem>
Index: doc/src/sgml/start.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/start.sgml,v
retrieving revision 1.13
diff -c -r1.13 start.sgml
*** doc/src/sgml/start.sgml    2000/09/29 20:21:34    1.13
--- doc/src/sgml/start.sgml    2000/11/13 05:26:16
***************
*** 110,117 ****
      will need to set the <acronym>PGHOST</acronym> environment
      variable to the name
      of the database server machine.   The  environment  variable
!     <acronym>PGPORT</acronym> 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 <application>postmaster</application>,
      you should immediately consult your site administrator to make
--- 110,117 ----
      will need to set the <acronym>PGHOST</acronym> environment
      variable to the name
      of the database server machine.   The  environment  variable
!     <acronym>PGPORT</acronym> or <acronym>PGUNIXSOCKET</acronym> 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 <application>postmaster</application>,
      you should immediately consult your site administrator to make
Index: doc/src/sgml/ref/createdb.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/createdb.sgml,v
retrieving revision 1.11
diff -c -r1.11 createdb.sgml
*** doc/src/sgml/ref/createdb.sgml    2000/11/11 23:01:38    1.11
--- doc/src/sgml/ref/createdb.sgml    2000/11/13 05:26:16
***************
*** 56,61 ****
--- 56,73 ----
        </listitem>
       </varlistentry>

+     <varlistentry>
+       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
+       <listitem>
+       <para>
+       Specifies the Unix-domain socket on which the
+       <application>postmaster</application> is running.
+       Without this option, the socket is created in <filename>/tmp</filename>
+       based on the port number.
+       </para>
+       </listitem>
+     </varlistentry>
+
       <varlistentry>
        <term>-U, --username <replaceable class="parameter">username</replaceable></term>
        <listitem>
Index: doc/src/sgml/ref/createlang.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/createlang.sgml,v
retrieving revision 1.10
diff -c -r1.10 createlang.sgml
*** doc/src/sgml/ref/createlang.sgml    2000/11/11 23:01:38    1.10
--- doc/src/sgml/ref/createlang.sgml    2000/11/13 05:26:16
***************
*** 101,106 ****
--- 101,118 ----
        </listitem>
       </varlistentry>

+     <varlistentry>
+       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
+       <listitem>
+       <para>
+       Specifies the Unix-domain socket on which the
+       <application>postmaster</application> is running.
+       Without this option, the socket is created in <filename>/tmp</filename>
+       based on the port number.
+       </para>
+       </listitem>
+     </varlistentry>
+
       <varlistentry>
        <term>-U, --username <replaceable class="parameter">username</replaceable></term>
        <listitem>
Index: doc/src/sgml/ref/createuser.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/createuser.sgml,v
retrieving revision 1.10
diff -c -r1.10 createuser.sgml
*** doc/src/sgml/ref/createuser.sgml    2000/11/11 23:01:40    1.10
--- doc/src/sgml/ref/createuser.sgml    2000/11/13 05:26:16
***************
*** 55,60 ****
--- 55,72 ----
        </listitem>
       </varlistentry>

+     <varlistentry>
+       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
+       <listitem>
+       <para>
+       Specifies the Unix-domain socket on which the
+       <application>postmaster</application> is running.
+       Without this option, the socket is created in <filename>/tmp</filename>
+       based on the port number.
+       </para>
+       </listitem>
+     </varlistentry>
+
       <varlistentry>
        <term>-e, --echo</term>
        <listitem>
Index: doc/src/sgml/ref/dropdb.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/dropdb.sgml,v
retrieving revision 1.4
diff -c -r1.4 dropdb.sgml
*** doc/src/sgml/ref/dropdb.sgml    2000/11/11 23:01:45    1.4
--- doc/src/sgml/ref/dropdb.sgml    2000/11/13 05:26:16
***************
*** 55,60 ****
--- 55,72 ----
        </listitem>
       </varlistentry>

+     <varlistentry>
+       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
+       <listitem>
+       <para>
+       Specifies the Unix-domain socket on which the
+       <application>postmaster</application> is running.
+       Without this option, the socket is created in <filename>/tmp</filename>
+       based on the port number.
+       </para>
+       </listitem>
+     </varlistentry>
+
       <varlistentry>
        <term>-U, --username <replaceable class="parameter">username</replaceable></term>
        <listitem>
Index: doc/src/sgml/ref/droplang.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/droplang.sgml,v
retrieving revision 1.4
diff -c -r1.4 droplang.sgml
*** doc/src/sgml/ref/droplang.sgml    2000/11/11 23:01:45    1.4
--- doc/src/sgml/ref/droplang.sgml    2000/11/13 05:26:16
***************
*** 101,106 ****
--- 101,118 ----
        </listitem>
       </varlistentry>

+     <varlistentry>
+       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
+       <listitem>
+       <para>
+       Specifies the Unix-domain socket on which the
+       <application>postmaster</application> is running.
+       Without this option, the socket is created in <filename>/tmp</filename>
+       based on the port number.
+       </para>
+       </listitem>
+     </varlistentry>
+
       <varlistentry>
        <term>-U, --username <replaceable class="parameter">username</replaceable></term>
        <listitem>
Index: doc/src/sgml/ref/dropuser.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/dropuser.sgml,v
retrieving revision 1.5
diff -c -r1.5 dropuser.sgml
*** doc/src/sgml/ref/dropuser.sgml    2000/11/11 23:01:45    1.5
--- doc/src/sgml/ref/dropuser.sgml    2000/11/13 05:26:16
***************
*** 55,60 ****
--- 55,72 ----
        </listitem>
       </varlistentry>

+     <varlistentry>
+       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
+       <listitem>
+       <para>
+       Specifies the Unix-domain socket on which the
+       <application>postmaster</application> is running.
+       Without this option, the socket is created in <filename>/tmp</filename>
+       based on the port number.
+       </para>
+       </listitem>
+     </varlistentry>
+
       <varlistentry>
        <term>-e, --echo</term>
        <listitem>
Index: doc/src/sgml/ref/pg_dump.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v
retrieving revision 1.20
diff -c -r1.20 pg_dump.sgml
*** doc/src/sgml/ref/pg_dump.sgml    2000/10/05 19:48:18    1.20
--- doc/src/sgml/ref/pg_dump.sgml    2000/11/13 05:26:17
***************
*** 24,30 ****
    </refsynopsisdivinfo>
    <synopsis>
  pg_dump [ <replaceable class="parameter">dbname</replaceable> ]
! pg_dump [ -h <replaceable class="parameter">host</replaceable> ] [ -p <replaceable
class="parameter">port</replaceable>] 
      [ -t <replaceable class="parameter">table</replaceable> ]
      [ -a ] [ -c ] [ -d ] [ -D ] [ -i ] [ -n ] [ -N ]
      [ -o ] [ -s ] [ -u ] [ -v ] [ -x ]
--- 24,32 ----
    </refsynopsisdivinfo>
    <synopsis>
  pg_dump [ <replaceable class="parameter">dbname</replaceable> ]
! pg_dump [ -h <replaceable class="parameter">host</replaceable> ]
!     [ -k <replaceable class="parameter">path</replaceable> ]
!     [ -p <replaceable class="parameter">port</replaceable> ]
      [ -t <replaceable class="parameter">table</replaceable> ]
      [ -a ] [ -c ] [ -d ] [ -D ] [ -i ] [ -n ] [ -N ]
      [ -o ] [ -s ] [ -u ] [ -v ] [ -x ]
***************
*** 200,205 ****
--- 202,222 ----
      <application>postmaster</application>
      is running.  Defaults to using a local Unix domain socket
      rather than an IP connection.
+        </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>-k <replaceable class="parameter">path</replaceable></term>
+       <listitem>
+        <para>
+     Specifies the local Unix domain socket file path
+     on which the <application>postmaster</application>
+     is listening for connections.
+         Without this option, the socket path name defaults to
+         the value of the <envar>PGUNIXSOCKET</envar> environment
+     variable (if set), otherwise it is constructed
+         from the port number.
         </para>
        </listitem>
       </varlistentry>
Index: doc/src/sgml/ref/pg_dumpall.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/pg_dumpall.sgml,v
retrieving revision 1.11
diff -c -r1.11 pg_dumpall.sgml
*** doc/src/sgml/ref/pg_dumpall.sgml    2000/11/02 21:13:31    1.11
--- doc/src/sgml/ref/pg_dumpall.sgml    2000/11/13 05:26:17
***************
*** 23,29 ****
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! pg_dumpall [ -h <replaceable class="parameter">host</replaceable> ] [ -p <replaceable
class="parameter">port</replaceable>] [ -a ] [ -d ] [ -D ] [ -O ] [ -s ] [ -u ] [ -v ] [ -x ] [ --accounts-only ] 
    </synopsis>

    <refsect2 id="R2-APP-PG-DUMPALL-1">
--- 23,29 ----
     <date>1999-07-20</date>
    </refsynopsisdivinfo>
    <synopsis>
! pg_dumpall [ -h <replaceable class="parameter">host</replaceable> ] [ -k <replaceable
class="parameter">path</replaceable>] [ -p <replaceable class="parameter">port</replaceable> ] [ -a ] [ -d ] [ -D ] [
-O] [ -s ] [ -u ] [ -v ] [ -x ] [ --accounts-only ] 
    </synopsis>

    <refsect2 id="R2-APP-PG-DUMPALL-1">
***************
*** 145,150 ****
--- 145,165 ----
      <application>postmaster</application>
      is running.  Defaults to using a local Unix domain socket
      rather than an IP connection..
+        </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>-k <replaceable class="parameter">path</replaceable></term>
+       <listitem>
+        <para>
+     Specifies the local Unix domain socket file path
+     on which the <application>postmaster</application>
+     is listening for connections.
+         Without this option, the socket path name defaults to
+         the value of the <envar>PGUNIXSOCKET</envar> environment
+     variable (if set), otherwise it is constructed
+         from the port number.
         </para>
        </listitem>
       </varlistentry>
Index: doc/src/sgml/ref/postmaster.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/postmaster.sgml,v
retrieving revision 1.12
diff -c -r1.12 postmaster.sgml
*** doc/src/sgml/ref/postmaster.sgml    2000/10/05 19:48:18    1.12
--- doc/src/sgml/ref/postmaster.sgml    2000/11/13 05:26:17
***************
*** 24,30 ****
    </refsynopsisdivinfo>
    <synopsis>
  postmaster [ -B <replaceable class="parameter">nBuffers</replaceable> ] [ -D <replaceable
class="parameter">DataDir</replaceable>] [ -N <replaceable class="parameter">maxBackends</replaceable> ] [ -S ] 
!     [ -d <replaceable class="parameter">DebugLevel</replaceable> ] [ -i ] [ -l ]
      [ -o <replaceable class="parameter">BackendOptions</replaceable> ] [ -p <replaceable
class="parameter">port</replaceable>] [ -n | -s ] 
    </synopsis>

--- 24,32 ----
    </refsynopsisdivinfo>
    <synopsis>
  postmaster [ -B <replaceable class="parameter">nBuffers</replaceable> ] [ -D <replaceable
class="parameter">DataDir</replaceable>] [ -N <replaceable class="parameter">maxBackends</replaceable> ] [ -S ] 
!     [ -d <replaceable class="parameter">DebugLevel</replaceable> ]
!     [ -h <replaceable class="parameter">hostname</replaceable> ] [ -i ]
!     [ -k <replaceable class="parameter">path</replaceable> ] [ -l ]
      [ -o <replaceable class="parameter">BackendOptions</replaceable> ] [ -p <replaceable
class="parameter">port</replaceable>] [ -n | -s ] 
    </synopsis>

***************
*** 124,135 ****
--- 126,196 ----
       </varlistentry>

       <varlistentry>
+       <term>-h <replaceable class="parameter">hostName</replaceable></term>
+       <listitem>
+        <para>
+     Specifies the TCP/IP hostname or address
+     on which the <application>postmaster</application>
+     is to listen for connections from frontend applications.  Defaults to
+     the value of the
+     <envar>PGHOST</envar>
+     environment variable, or if <envar>PGHOST</envar>
+     is not set, then defaults to "all", meaning listen on all configured addresses
+     (including localhost).
+        </para>
+        <para>
+     If you use a hostname or address other than "all", do not try to run
+     multiple instances of <application>postmaster</application> 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 <application>postmaster</application> instances are
+     listening must be distinct in the two last octets.
+        </para>
+        <para>
+     If you do use "all" (the default), then each instance must listen on a
+     different port (via -p or <envar>PGPORT</envar>).  And, of course, do
+     not try to use both approaches on one host.
+        </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
        <term>-i</term>
        <listitem>
         <para>
          Allows clients to connect via TCP/IP (Internet domain) connections.
      Without this option, only local Unix domain socket connections are
      accepted.
+        </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>-k <replaceable class="parameter">path</replaceable></term>
+       <listitem>
+        <para>
+     Specifies the local Unix domain socket path name
+     on which the <application>postmaster</application>
+     is to listen for connections from frontend applications.  Defaults to
+     the value of the
+     <envar>PGUNIXSOCKET</envar>
+     environment variable, or if <envar>PGUNIXSOCKET</envar>
+     is not set, then defaults to a file in <filename>/tmp</filename>
+     constructed from the port number.
+        </para>
+        <para>
+         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 <filename>pg_hba.conf</filename>.
+     If you specify a socket path other than the
+     default then all frontend applications (including
+     <application>psql</application>) must specify the same
+     socket path using either command-line options or
+     <envar>PGUNIXSOCKET</envar>.
         </para>
        </listitem>
       </varlistentry>
Index: doc/src/sgml/ref/psql-ref.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v
retrieving revision 1.40
diff -c -r1.40 psql-ref.sgml
*** doc/src/sgml/ref/psql-ref.sgml    2000/10/24 01:38:21    1.40
--- doc/src/sgml/ref/psql-ref.sgml    2000/11/13 05:26:22
***************
*** 1330,1335 ****
--- 1330,1348 ----


      <varlistentry>
+       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
+       <listitem>
+       <para>
+       Specifies the Unix-domain socket on which the
+       <application>postmaster</application> is running.
+       Without this option, the socket is created in <filename>/tmp</filename>
+       based on the port number.
+       </para>
+       </listitem>
+     </varlistentry>
+
+
+     <varlistentry>
        <term>-H, --html</term>
        <listitem>
        <para>
Index: doc/src/sgml/ref/vacuumdb.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/vacuumdb.sgml,v
retrieving revision 1.10
diff -c -r1.10 vacuumdb.sgml
*** doc/src/sgml/ref/vacuumdb.sgml    2000/11/11 23:01:45    1.10
--- doc/src/sgml/ref/vacuumdb.sgml    2000/11/13 05:26:22
***************
*** 136,141 ****
--- 136,153 ----
        </listitem>
       </varlistentry>

+     <varlistentry>
+       <term>-k, --unixsocket <replaceable class="parameter">path</replaceable></term>
+       <listitem>
+       <para>
+       Specifies the Unix-domain socket on which the
+       <application>postmaster</application> is running.
+       Without this option, the socket is created in <filename>/tmp</filename>
+       based on the port number.
+       </para>
+       </listitem>
+     </varlistentry>
+
       <varlistentry>
        <term>-U <replaceable class="parameter">username</replaceable></term>
        <term>--username <replaceable class="parameter">username</replaceable></term>
Index: src/backend/libpq/pqcomm.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/libpq/pqcomm.c,v
retrieving revision 1.109
diff -c -r1.109 pqcomm.c
*** src/backend/libpq/pqcomm.c    2000/11/01 21:14:01    1.109
--- src/backend/libpq/pqcomm.c    2000/11/13 05:26:22
***************
*** 169,181 ****
  /*
   * StreamServerPort -- open a sock stream "listening" port.
   *
!  * This initializes the Postmaster's connection-accepting port.
   *
   * RETURNS: STATUS_OK or STATUS_ERROR
   */

  int
! StreamServerPort(int family, unsigned short portName, int *fdP)
  {
      SockAddr    saddr;
      int            fd,
--- 169,182 ----
  /*
   * StreamServerPort -- open a sock stream "listening" port.
   *
!  * This initializes the Postmaster's connection-accepting port fdP.
   *
   * RETURNS: STATUS_OK or STATUS_ERROR
   */

  int
! StreamServerPort(int family, char *hostName, unsigned short portName,
!                  char *unixSocketName, int *fdP)
  {
      SockAddr    saddr;
      int            fd,
***************
*** 218,224 ****
  #ifdef HAVE_UNIX_SOCKETS
      if (family == AF_UNIX)
      {
!         len = UNIXSOCK_PATH(saddr.un, portName);
          strcpy(sock_path, saddr.un.sun_path);
          /*
           * If the socket exists but nobody has an advisory lock on it we
--- 219,226 ----
  #ifdef HAVE_UNIX_SOCKETS
      if (family == AF_UNIX)
      {
!         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,248 ****

      if (family == AF_INET)
      {
!         saddr.in.sin_addr.s_addr = htonl(INADDR_ANY);
          saddr.in.sin_port = htons(portName);
          len = sizeof(struct sockaddr_in);
      }
--- 244,270 ----

      if (family == AF_INET)
      {
!         /* 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);
      }
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/postmaster/postmaster.c,v
retrieving revision 1.181
diff -c -r1.181 postmaster.c
*** src/backend/postmaster/postmaster.c    2000/11/09 11:25:59    1.181
--- src/backend/postmaster/postmaster.c    2000/11/13 05:26:25
***************
*** 114,119 ****
--- 114,121 ----
  static Dllist *PortList;

  int PostPortName;
+ char * UnixSocketName;
+ char * HostName;

   /*
    * This is a boolean indicating that there is at least one backend that
***************
*** 234,240 ****
  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 SIGHUP_handler(SIGNAL_ARGS);
  static void pmdie(SIGNAL_ARGS);
  static void reaper(SIGNAL_ARGS);
--- 236,242 ----
  static void pmdaemonize(int argc, char *argv[]);
  static Port *ConnCreate(int serverFd);
  static void ConnFree(Port *port);
! static void reset_shared(unsigned short port);
  static void SIGHUP_handler(SIGNAL_ARGS);
  static void pmdie(SIGNAL_ARGS);
  static void reaper(SIGNAL_ARGS);
***************
*** 376,382 ****
       * will occur.
       */
      opterr = 1;
!     while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Film:MN:no:p:SsV-:?")) != EOF)
      {
          switch(opt)
          {
--- 378,384 ----
       * will occur.
       */
      opterr = 1;
!     while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Fh:ik:lm:MN:no:p:SsV-:?")) != EOF)
      {
          switch(opt)
          {
***************
*** 432,438 ****
  #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)
      {
          switch (opt)
          {
--- 434,440 ----
  #ifdef HAVE_INT_OPTRESET
      optreset = 1;
  #endif
!     while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Fh:ik:lm:MN:no:p:SsV-:?")) != EOF)
      {
          switch (opt)
          {
***************
*** 466,474 ****
--- 468,483 ----
              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;
***************
*** 600,606 ****

      if (NetServer)
      {
!         status = StreamServerPort(AF_INET, (unsigned short)PostPortName, &ServerSock_INET);
          if (status != STATUS_OK)
          {
              fprintf(stderr, "%s: cannot create INET stream port\n",
--- 609,616 ----

      if (NetServer)
      {
!         status = StreamServerPort(AF_INET, HostName,
!                 (unsigned short)PostPortName, UnixSocketName, &ServerSock_INET);
          if (status != STATUS_OK)
          {
              fprintf(stderr, "%s: cannot create INET stream port\n",
***************
*** 610,616 ****
      }

  #ifdef HAVE_UNIX_SOCKETS
!     status = StreamServerPort(AF_UNIX, (unsigned short)PostPortName, &ServerSock_UNIX);
      if (status != STATUS_OK)
      {
          fprintf(stderr, "%s: cannot create UNIX stream port\n",
--- 620,627 ----
      }

  #ifdef HAVE_UNIX_SOCKETS
!     status = StreamServerPort(AF_UNIX, HostName,
!             (unsigned short)PostPortName, UnixSocketName, &ServerSock_UNIX);
      if (status != STATUS_OK)
      {
          fprintf(stderr, "%s: cannot create UNIX stream port\n",
***************
*** 780,786 ****
--- 791,799 ----
      printf("  -d 1-5          debugging level\n");
      printf("  -D <directory>  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
***************
*** 1294,1304 ****
  }

  /*
   * reset_shared -- reset shared memory and semaphores
   */
  static void
! reset_shared(int port)
  {
      ipc_key = port * 1000 + shmem_seq * 100;
      CreateSharedMemoryAndSemaphores(ipc_key, MaxBackends);
      shmem_seq += 1;
--- 1307,1381 ----
  }

  /*
+  * 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(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;
***************
*** 2205,2210 ****
--- 2282,2289 ----
          char        nbbuf[ARGV_SIZE];
          char        dbbuf[ARGV_SIZE];
          char        xlbuf[ARGV_SIZE];
+         char        hsbuf[ARGV_SIZE];
+         char        skbuf[ARGV_SIZE];

          /* Lose the postmaster's on-exit routines and port connections */
          on_exit_reset();
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.16
diff -c -r1.16 guc.c
*** src/backend/utils/misc/guc.c    2000/11/09 11:25:59    1.16
--- src/backend/utils/misc/guc.c    2000/11/13 05:26:26
***************
*** 304,309 ****
--- 304,315 ----
      {"unix_socket_group",         PGC_POSTMASTER,       &Unix_socket_group,
       "", NULL},

+     {"unixsocket",                   PGC_POSTMASTER,       &UnixSocketName,
+      "", NULL},
+
+     {"hostname",                   PGC_POSTMASTER,       &HostName,
+      "", NULL},
+
      {NULL, 0, NULL, NULL, NULL}
  };

Index: src/bin/pg_dump/pg_backup.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v
retrieving revision 1.4
diff -c -r1.4 pg_backup.h
*** src/bin/pg_dump/pg_backup.h    2000/08/01 15:51:44    1.4
--- src/bin/pg_dump/pg_backup.h    2000/11/13 05:26:26
***************
*** 99,106 ****

      int            useDB;
      char        *dbname;
-     char        *pgport;
      char        *pghost;
      int            ignoreVersion;
      int            requirePassword;

--- 99,107 ----

      int            useDB;
      char        *dbname;
      char        *pghost;
+     char        *pgport;
+     char        *pgunixsocket;
      int            ignoreVersion;
      int            requirePassword;

***************
*** 122,127 ****
--- 123,129 ----
          const char*     dbname,
          const char*    pghost,
          const char*    pgport,
+         const char*    pgunixsocket,
          const int    reqPwd,
          const int    ignoreVersion);

Index: src/bin/pg_dump/pg_backup_archiver.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v
retrieving revision 1.10
diff -c -r1.10 pg_backup_archiver.c
*** src/bin/pg_dump/pg_backup_archiver.c    2000/10/31 14:20:30    1.10
--- src/bin/pg_dump/pg_backup_archiver.c    2000/11/13 05:26:27
***************
*** 131,138 ****
          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);

          /*
           * If no superuser was specified then see if the current user will do...
--- 131,139 ----
          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->pgunixsocket, ropt->requirePassword,
!                             ropt->ignoreVersion);

          /*
           * If no superuser was specified then see if the current user will do...
Index: src/bin/pg_dump/pg_backup_archiver.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v
retrieving revision 1.16
diff -c -r1.16 pg_backup_archiver.h
*** src/bin/pg_dump/pg_backup_archiver.h    2000/10/31 14:20:30    1.16
--- src/bin/pg_dump/pg_backup_archiver.h    2000/11/13 05:26:27
***************
*** 187,192 ****
--- 187,193 ----
      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 */
Index: src/bin/pg_dump/pg_backup_db.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v
retrieving revision 1.8
diff -c -r1.8 pg_backup_db.c
*** src/bin/pg_dump/pg_backup_db.c    2000/10/31 14:20:30    1.8
--- src/bin/pg_dump/pg_backup_db.c    2000/11/13 05:26:27
***************
*** 1,7 ****
  /*-------------------------------------------------------------------------
   *
   *
! *-------------------------------------------------------------------------
   */

  #include <unistd.h>                /* for getopt() */
--- 1,7 ----
  /*-------------------------------------------------------------------------
   *
   *
!  *-------------------------------------------------------------------------
   */

  #include <unistd.h>                /* for getopt() */
***************
*** 273,278 ****
--- 273,279 ----
          const char*     dbname,
          const char*     pghost,
          const char*     pgport,
+         const char*     pgunixsocket,
          const int        reqPwd,
          const int        ignoreVersion)
  {
***************
*** 306,311 ****
--- 307,321 ----
      }
      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);
Index: src/bin/pg_dump/pg_dump.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v
retrieving revision 1.177
diff -c -r1.177 pg_dump.c
*** src/bin/pg_dump/pg_dump.c    2000/10/31 14:20:30    1.177
--- src/bin/pg_dump/pg_dump.c    2000/11/13 05:26:30
***************
*** 200,205 ****
--- 200,206 ----
          "  -F, --format {c|f|p}     output file format (custom, files, plain text)\n"
          "  -h, --host <hostname>    server host name\n"
          "  -i, --ignore-version     proceed when database version != pg_dump version\n"
+         "  -k, --unixsocket <path>  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,231 ****
--- 227,233 ----
          "  -F {c|f|p}               output file format (custom, files, plain text)\n"
          "  -h <hostname>            server host name\n"
          "  -i                       proceed when database version != pg_dump version\n"
+         "  -k <path>                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,634 ****
--- 631,637 ----
      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,663 ****
--- 661,667 ----
          {"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,757 ****
--- 756,765 ----
                  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,954 ****
      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);

      /*
       * Start serializable transaction to dump consistent data
--- 956,963 ----
      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, pgunixsocket,
!                              use_password, ignore_version);

      /*
       * Start serializable transaction to dump consistent data
Index: src/bin/pg_dump/pg_restore.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v
retrieving revision 1.8
diff -c -r1.8 pg_restore.c
*** src/bin/pg_dump/pg_restore.c    2000/10/16 14:34:08    1.8
--- src/bin/pg_dump/pg_restore.c    2000/11/13 05:26:30
***************
*** 101,106 ****
--- 101,107 ----
                  { "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,140 ****
      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)
  #else
!     while ((c = getopt(argc, argv, "acCd:f:F:h:i:lNoOp:P:rRsS:t:T:uU:vx")) != -1)
  #endif
      {
          switch (c)
--- 133,141 ----
      progname = *argv;

  #ifdef HAVE_GETOPT_LONG
!     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:k:lNoOp:P:rRsS:t:T:uU:vx")) != -1)
  #endif
      {
          switch (c)
***************
*** 169,174 ****
--- 170,179 ----
                  break;
              case 'i':
                  opts->ignoreVersion = 1;
+                 break;
+             case 'k':
+                 if (strlen(optarg) != 0)
+                     opts->pgunixsocket = strdup(optarg);
                  break;
              case 'N':
                  opts->origOrder = 1;
Index: src/bin/psql/command.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/psql/command.c,v
retrieving revision 1.36
diff -c -r1.36 command.c
*** src/bin/psql/command.c    2000/09/17 20:33:45    1.36
--- src/bin/psql/command.c    2000/11/13 05:26:31
***************
*** 1202,1207 ****
--- 1202,1208 ----
      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,1236 ****
--- 1232,1238 ----
      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,1312 ****
--- 1309,1315 ----
      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));
Index: src/bin/psql/common.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/psql/common.c,v
retrieving revision 1.23
diff -c -r1.23 common.c
*** src/bin/psql/common.c    2000/08/29 09:36:48    1.23
--- src/bin/psql/common.c    2000/11/13 05:26:31
***************
*** 329,334 ****
--- 329,335 ----
              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,513 ****
--- 509,515 ----
                  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;
Index: src/bin/psql/help.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/psql/help.c,v
retrieving revision 1.32
diff -c -r1.32 help.c
*** src/bin/psql/help.c    2000/09/22 23:02:00    1.32
--- src/bin/psql/help.c    2000/11/13 05:26:33
***************
*** 103,108 ****
--- 103,118 ----
      puts(")");

      puts("  -H              HTML table output mode (-P format=html)");
+
+     /* Display default Unix-domain socket */
+     env = getenv("PGUNIXSOCKET");
+     printf("  -k <path>       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 <filename>   Send query output to filename (or |pipe)");
Index: src/bin/psql/prompt.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/psql/prompt.c,v
retrieving revision 1.13
diff -c -r1.13 prompt.c
*** src/bin/psql/prompt.c    2000/08/20 10:55:34    1.13
--- src/bin/psql/prompt.c    2000/11/13 05:26:33
***************
*** 190,195 ****
--- 190,200 ----
                      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)
Index: src/bin/psql/startup.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/psql/startup.c,v
retrieving revision 1.37
diff -c -r1.37 startup.c
*** src/bin/psql/startup.c    2000/09/17 20:33:45    1.37
--- src/bin/psql/startup.c    2000/11/13 05:26:34
***************
*** 65,70 ****
--- 65,71 ----
      char       *dbname;
      char       *host;
      char       *port;
+     char       *unixsocket;
      char       *username;
      enum _actions action;
      char       *action_string;
***************
*** 161,166 ****
--- 162,168 ----
      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,211 ****
--- 208,214 ----
      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,325 ****
--- 323,329 ----
          {"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,366 ****
      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)
  #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)
  #endif     /* not HAVE_GETOPT_LONG */
      {
          switch (c)
--- 357,370 ----
      memset(options, 0, sizeof *options);

  #ifdef HAVE_GETOPT_LONG
!     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:Hk:no:p:P:qRsStT:uU:v:VWxX?-")) != -1)
  #endif     /* not HAVE_GETOPT_LONG */
      {
          switch (c)
***************
*** 405,410 ****
--- 409,417 ----
                  break;
              case 'l':
                  options->action = ACT_LIST_DB;
+                 break;
+             case 'k':
+                 options->unixsocket = optarg;
                  break;
              case 'n':
                  options->no_readline = true;
Index: src/bin/scripts/createdb
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/scripts/createdb,v
retrieving revision 1.9
diff -c -r1.9 createdb
*** src/bin/scripts/createdb    2000/11/11 22:59:48    1.9
--- src/bin/scripts/createdb    2000/11/13 05:26:34
***************
*** 50,55 ****
--- 50,64 ----
          --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,119 ****
--- 123,129 ----
      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"
Index: src/bin/scripts/createlang.sh
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/scripts/createlang.sh,v
retrieving revision 1.17
diff -c -r1.17 createlang.sh
*** src/bin/scripts/createlang.sh    2000/11/11 22:59:48    1.17
--- src/bin/scripts/createlang.sh    2000/11/13 05:26:34
***************
*** 65,70 ****
--- 65,79 ----
          --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,131 ****
--- 135,141 ----
      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"
Index: src/bin/scripts/createuser
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/scripts/createuser,v
retrieving revision 1.12
diff -c -r1.12 createuser
*** src/bin/scripts/createuser    2000/11/11 22:59:48    1.12
--- src/bin/scripts/createuser    2000/11/13 05:26:34
***************
*** 63,68 ****
--- 63,77 ----
          --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,140 ****
--- 144,150 ----
      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"
Index: src/bin/scripts/dropdb
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/scripts/dropdb,v
retrieving revision 1.7
diff -c -r1.7 dropdb
*** src/bin/scripts/dropdb    2000/11/11 22:59:48    1.7
--- src/bin/scripts/dropdb    2000/11/13 05:26:34
***************
*** 59,64 ****
--- 59,73 ----
          --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,108 ****
--- 112,118 ----
      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"
Index: src/bin/scripts/droplang
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/scripts/droplang,v
retrieving revision 1.8
diff -c -r1.8 droplang
*** src/bin/scripts/droplang    2000/11/11 22:59:48    1.8
--- src/bin/scripts/droplang    2000/11/13 05:26:34
***************
*** 65,70 ****
--- 65,79 ----
          --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,118 ****
--- 122,128 ----
      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"
Index: src/bin/scripts/dropuser
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/scripts/dropuser,v
retrieving revision 1.7
diff -c -r1.7 dropuser
*** src/bin/scripts/dropuser    2000/11/11 22:59:48    1.7
--- src/bin/scripts/dropuser    2000/11/13 05:26:34
***************
*** 59,64 ****
--- 59,73 ----
          --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,110 ****
--- 114,120 ----
      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"
Index: src/bin/scripts/vacuumdb
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/bin/scripts/vacuumdb,v
retrieving revision 1.10
diff -c -r1.10 vacuumdb
*** src/bin/scripts/vacuumdb    2000/11/11 22:59:48    1.10
--- src/bin/scripts/vacuumdb    2000/11/13 05:26:34
***************
*** 52,57 ****
--- 52,66 ----
          --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,126 ****
--- 130,136 ----
          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"
Index: src/include/libpq/libpq.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/libpq/libpq.h,v
retrieving revision 1.39
diff -c -r1.39 libpq.h
*** src/include/libpq/libpq.h    2000/07/08 03:04:30    1.39
--- src/include/libpq/libpq.h    2000/11/13 05:26:34
***************
*** 55,61 ****
  /*
   * prototypes for functions in pqcomm.c
   */
! extern int    StreamServerPort(int family, unsigned short portName, int *fdP);
  extern int    StreamConnection(int server_fd, Port *port);
  extern void StreamClose(int sock);
  extern void pq_init(void);
--- 55,62 ----
  /*
   * prototypes for functions in pqcomm.c
   */
! 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);
Index: src/include/libpq/pqcomm.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/libpq/pqcomm.h,v
retrieving revision 1.43
diff -c -r1.43 pqcomm.h
*** src/include/libpq/pqcomm.h    2000/11/01 21:14:03    1.43
--- src/include/libpq/pqcomm.h    2000/11/13 05:26:35
***************
*** 51,62 ****
  /* 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)))
  #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))
  #endif

  /*
--- 51,65 ----
  /* Configure the UNIX socket address for the well known port. */

  #if defined(SUN_LEN)
! #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,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,180 ****
--- 179,185 ----
  extern int Unix_socket_permissions;

  extern char * Unix_socket_group;
+ extern char * UnixSocketName;
+ extern char * HostName;

  #endif     /* PQCOMM_H */
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.144
diff -c -r1.144 fe-connect.c
*** src/interfaces/libpq/fe-connect.c    2000/11/04 02:27:56    1.144
--- src/interfaces/libpq/fe-connect.c    2000/11/13 05:26:39
***************
*** 130,135 ****
--- 130,138 ----
      {"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,310 ****
--- 308,315 ----
      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,390 ****
--- 390,398 ----
   *      PGPORT       identifies TCP port to which to connect if <pgport> 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 <pgtty> argument
   *                   is NULL or a null string.
   *
***************
*** 435,440 ****
--- 443,456 ----
      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,522 ****

  /*
   * update_db_info -
!  * get all additional infos out of dbName
   *
   */
  static int
  update_db_info(PGconn *conn)
  {
!     char       *tmp,
                 *old = conn->dbName;

      if (strchr(conn->dbName, '@') != NULL)
--- 526,538 ----

  /*
   * update_db_info -
!  * get all additional info out of dbName
   *
   */
  static int
  update_db_info(PGconn *conn)
  {
!     char       *tmp, *tmp2,
                 *old = conn->dbName;

      if (strchr(conn->dbName, '@') != NULL)
***************
*** 525,530 ****
--- 541,548 ----
          tmp = strrchr(conn->dbName, ':');
          if (tmp != NULL)        /* port number given */
          {
+             if (conn->pgport)
+                 free(conn->pgport);
              conn->pgport = strdup(tmp + 1);
              *tmp = '\0';
          }
***************
*** 532,537 ****
--- 550,557 ----
          tmp = strrchr(conn->dbName, '@');
          if (tmp != NULL)        /* host name given */
          {
+             if (conn->pghost)
+                 free(conn->pghost);
              conn->pghost = strdup(tmp + 1);
              *tmp = '\0';
          }
***************
*** 558,570 ****

              /*
               * new style:
!              * <tcp|unix>:postgresql://server[:port][/dbname][?options]
               */
              offset += strlen("postgresql://");

              tmp = strrchr(conn->dbName + offset, '?');
              if (tmp != NULL)    /* options given */
              {
                  conn->pgoptions = strdup(tmp + 1);
                  *tmp = '\0';
              }
--- 578,592 ----

              /*
               * new style:
!              * <tcp|unix>: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,597 ****
              tmp = strrchr(conn->dbName + offset, '/');
              if (tmp != NULL)    /* database name given */
              {
                  conn->dbName = strdup(tmp + 1);
                  *tmp = '\0';
              }
              else
              {
                  if ((tmp = getenv("PGDATABASE")) != NULL)
                      conn->dbName = strdup(tmp);
                  else if (conn->pguser)
                      conn->dbName = strdup(conn->pguser);
              }

              tmp = strrchr(old + offset, ':');
!             if (tmp != NULL)    /* port number given */
              {
-                 conn->pgport = strdup(tmp + 1);
                  *tmp = '\0';
              }

              if (strncmp(old, "unix:", 5) == 0)
              {
                  conn->pghost = NULL;
                  if (strcmp(old + offset, "localhost") != 0)
                  {
--- 594,655 ----
              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 or Unix socket path given */
              {
                  *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,610 ****
                  }
              }
              else
                  conn->pghost = strdup(old + offset);
!
              free(old);
          }
      }
--- 661,671 ----
                  }
              }
              else
+             {
+                 if (conn->pghost)
+                     free(conn->pghost);
                  conn->pghost = strdup(old + offset);
!             }
              free(old);
          }
      }
***************
*** 763,769 ****
      }
  #ifdef HAVE_UNIX_SOCKETS
      else
!         conn->raddr_len = UNIXSOCK_PATH(conn->raddr.un, portno);
  #endif


--- 824,833 ----
      }
  #ifdef HAVE_UNIX_SOCKETS
      else
!     {
!         UNIXSOCK_PATH(conn->raddr.un, portno, conn->pgunixsocket);
!         conn->raddr_len = UNIXSOCK_LEN(conn->raddr.un);
!     }
  #endif


***************
*** 842,848 ****
                                conn->pghost ? conn->pghost : "localhost",
                                (family == AF_INET) ?
                                "TCP/IP port" : "Unix socket",
!                               conn->pgport);
              goto connect_errReturn;
          }
      }
--- 906,913 ----
                                conn->pghost ? conn->pghost : "localhost",
                                (family == AF_INET) ?
                                "TCP/IP port" : "Unix socket",
!                               (family == AF_UNIX && conn->pgunixsocket) ?
!                               conn->pgunixsocket : conn->pgport);
              goto connect_errReturn;
          }
      }
***************
*** 1143,1149 ****
                                 conn->pghost ? conn->pghost : "localhost",
                                    (conn->raddr.sa.sa_family == AF_INET) ?
                                        "TCP/IP port" : "Unix socket",
!                                       conn->pgport);
                      goto error_return;
                  }

--- 1208,1215 ----
                                 conn->pghost ? conn->pghost : "localhost",
                                    (conn->raddr.sa.sa_family == AF_INET) ?
                                        "TCP/IP port" : "Unix socket",
!                               (conn->raddr.sa.sa_family == AF_UNIX && conn->pgunixsocket) ?
!                                       conn->pgunixsocket : conn->pgport);
                      goto error_return;
                  }

***************
*** 1819,1824 ****
--- 1885,1892 ----
          free(conn->pghostaddr);
      if (conn->pgport)
          free(conn->pgport);
+     if (conn->pgunixsocket)
+         free(conn->pgunixsocket);
      if (conn->pgtty)
          free(conn->pgtty);
      if (conn->pgoptions)
***************
*** 2526,2531 ****
--- 2594,2607 ----
      if (!conn)
          return (char *) NULL;
      return conn->pgport;
+ }
+
+ char *
+ PQunixsocket(const PGconn *conn)
+ {
+     if (!conn)
+         return (char *) NULL;
+     return conn->pgunixsocket;
  }

  char *
Index: src/interfaces/libpq/libpq-fe.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/libpq-fe.h,v
retrieving revision 1.67
diff -c -r1.67 libpq-fe.h
*** src/interfaces/libpq/libpq-fe.h    2000/08/30 14:54:23    1.67
--- src/interfaces/libpq/libpq-fe.h    2000/11/13 05:26:39
***************
*** 217,222 ****
--- 217,223 ----
      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);
Index: src/interfaces/libpq/libpq-int.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/libpq-int.h,v
retrieving revision 1.27
diff -c -r1.27 libpq-int.h
*** src/interfaces/libpq/libpq-int.h    2000/08/30 14:54:24    1.27
--- src/interfaces/libpq/libpq-int.h    2000/11/13 05:26:39
***************
*** 203,208 ****
--- 203,210 ----
                                   * 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 */
Index: src/interfaces/libpq/libpqdll.def
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/libpqdll.def,v
retrieving revision 1.10
diff -c -r1.10 libpqdll.def
*** src/interfaces/libpq/libpqdll.def    2000/03/11 03:08:37    1.10
--- src/interfaces/libpq/libpqdll.def    2000/11/13 05:26:39
***************
*** 79,81 ****
--- 79,82 ----
      destroyPQExpBuffer    @ 76
      createPQExpBuffer    @ 77
      PQconninfoFree        @ 78
+     PQunixsocket        @ 79

pgsql-patches by date:

Previous
From: Peter Mount
Date:
Subject: RE: [JDBC] string conversion patch
Next
From: Bruce Momjian
Date:
Subject: Re: PostgreSQL virtual hosting support