Skip site navigation (1) Skip section navigation (2)

Re: PostgreSQL virtual hosting support

From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: "David J(dot) MacKenzie" <djm(at)web(dot)us(dot)uu(dot)net>
Cc: pgsql-patches(at)postgresql(dot)org
Subject: Re: PostgreSQL virtual hosting support
Date: 2000-11-13 15:03:17
Message-ID: 200011131503.KAA18115@candle.pha.pa.us (view raw or flat)
Thread:
Lists: pgsql-hackerspgsql-patches
OK, I have applied my version of patch.  The only change is that '-h
any' is not supported.  If you use -h, you must use an IP address.  Not
using -h is the same as -h any.


;> Your name		:	David MacKenzie
> Your email address	:	djm(at)web(dot)us(dot)uu(dot)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(at)candle(dot)pha(dot)pa(dot)us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

In response to

pgsql-hackers by date

Next:From: Bruce MomjianDate: 2000-11-13 15:04:31
Subject: Re: Re: [PATCHES] PostgreSQL virtual hosting support
Previous:From: Bruce MomjianDate: 2000-11-13 14:57:37
Subject: Re: AW: AW: RE: [COMMITTERS] pgsql/src/backend/access/trans am ( xact.c xlog.c)

pgsql-patches by date

Next:From: Bruce MomjianDate: 2000-11-13 15:04:31
Subject: Re: Re: [PATCHES] PostgreSQL virtual hosting support
Previous:From: Bruce MomjianDate: 2000-11-13 05:33:46
Subject: Re: PostgreSQL virtual hosting support

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group