Re: PostgreSQL virtual hosting support
От | Bruce Momjian |
---|---|
Тема | Re: PostgreSQL virtual hosting support |
Дата | |
Msg-id | 200011130533.AAA19565@candle.pha.pa.us обсуждение исходный текст |
Ответ на | PostgreSQL virtual hosting support ("David J. MacKenzie" <djm@web.us.uu.net>) |
Список | 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 по дате отправления: