]> granicus.if.org Git - postgresql/blob - src/interfaces/libpq/fe-connect.c
From: t-ishii@sra.co.jp
[postgresql] / src / interfaces / libpq / fe-connect.c
1 /*-------------------------------------------------------------------------
2  *
3  * fe-connect.c--
4  *        functions related to setting up a connection to the backend
5  *
6  * Copyright (c) 1994, Regents of the University of California
7  *
8  *
9  * IDENTIFICATION
10  *        $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.77 1998/07/26 04:31:36 scrappy Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14
15 #include <stdlib.h>
16 #include <sys/types.h>
17 #ifdef WIN32
18 #include "win32.h"
19 #else
20 #include <sys/socket.h>
21 #include <unistd.h>
22 #include <netdb.h>
23 #include <sys/un.h>
24 #include <netinet/in.h>
25 #include <netinet/tcp.h>
26 #endif
27 #include <fcntl.h>
28 #include <stdio.h>
29 #include <ctype.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <signal.h>
33 #include <ctype.h>                              /* for isspace() */
34
35 #include "postgres.h"
36 #include "fe-auth.h"
37 #include "fe-connect.h"
38 #include "libpq-fe.h"
39
40 #ifndef HAVE_STRDUP
41 #include "strdup.h"
42 #endif
43 #ifdef HAVE_CRYPT_H
44 #include <crypt.h>
45 #endif
46
47 #ifdef MULTIBYTE
48 #include "mb/pg_wchar.h"
49 #endif
50
51 static ConnStatusType connectDB(PGconn *conn);
52 static PGconn *makeEmptyPGconn(void);
53 static void freePGconn(PGconn *conn);
54 static void closePGconn(PGconn *conn);
55 static int      conninfo_parse(const char *conninfo, char *errorMessage);
56 static char *conninfo_getval(char *keyword);
57 static void conninfo_free(void);
58 /* XXX Why is this not static? */
59 void            PQsetenv(PGconn *conn);
60
61 #define NOTIFYLIST_INITIAL_SIZE 10
62 #define NOTIFYLIST_GROWBY 10
63
64
65 /* ----------
66  * Definition of the conninfo parameters and their fallback resources.
67  * If Environment-Var and Compiled-in are specified as NULL, no
68  * fallback is available. If after all no value can be determined
69  * for an option, an error is returned.
70  *
71  * The values for dbname and user are treated special in conninfo_parse.
72  * If the Compiled-in resource is specified as a NULL value, the
73  * user is determined by fe_getauthname() and for dbname the user
74  * name is copied.
75  *
76  * The Label and Disp-Char entries are provided for applications that
77  * want to use PQconndefaults() to create a generic database connection
78  * dialog. Disp-Char is defined as follows:
79  *         ""           Normal input field
80  * ----------
81  */
82 static PQconninfoOption PQconninfoOptions[] = {
83 /* ----------------------------------------------------------------- */
84 /*        Option-name           Environment-Var Compiled-in             Current value   */
85 /*                                              Label                                                   Disp-Char               */
86 /* ----------------- --------------- --------------- --------------- */
87         /* "authtype" is ignored as it is no longer used. */
88         {"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
89         "Database-Authtype", "", 20},
90
91         {"user", "PGUSER", NULL, NULL,
92         "Database-User", "", 20},
93
94         {"password", "PGPASSWORD", DefaultPassword, NULL,
95         "Database-Password", "", 20},
96
97         {"dbname", "PGDATABASE", NULL, NULL,
98         "Database-Name", "", 20},
99
100         {"host", "PGHOST", NULL, NULL,
101         "Database-Host", "", 40},
102
103         {"port", "PGPORT", DEF_PGPORT, NULL,
104         "Database-Port", "", 6},
105
106         {"tty", "PGTTY", DefaultTty, NULL,
107         "Backend-Debug-TTY", "D", 40},
108
109         {"options", "PGOPTIONS", DefaultOption, NULL,
110         "Backend-Debug-Options", "D", 40},
111 /* ----------------- --------------- --------------- --------------- */
112         {NULL, NULL, NULL, NULL,
113         NULL, NULL, 0}
114 };
115
116 struct EnvironmentOptions
117 {
118         const char *envName,
119                            *pgName;
120 }                       EnvironmentOptions[] =
121
122 {
123         /* common user-interface settings */
124         {
125                 "PGDATESTYLE", "datestyle"
126         },
127         {
128                 "PGTZ", "timezone"
129         },
130 #ifdef MULTIBYTE
131         {
132                 "PGCLIENTENCODING", "client_encoding"
133         },
134 #endif
135         /* internal performance-related settings */
136         {
137                 "PGCOSTHEAP", "cost_heap"
138         },
139         {
140                 "PGCOSTINDEX", "cost_index"
141         },
142         {
143                 "PGRPLANS", "r_plans"
144         },
145         {
146                 "PGGEQO", "geqo"
147         },
148         {
149                 NULL
150         }
151 };
152
153 /* ----------------
154  *              PQconnectdb
155  *
156  * establishes a connection to a postgres backend through the postmaster
157  * using connection information in a string.
158  *
159  * The conninfo string is a list of
160  *
161  *         option = value
162  *
163  * definitions. Value might be a single value containing no whitespaces
164  * or a single quoted string. If a single quote should appear everywhere
165  * in the value, it must be escaped with a backslash like \'
166  *
167  * Returns a PGconn* which is needed for all subsequent libpq calls
168  * if the status field of the connection returned is CONNECTION_BAD,
169  * then some fields may be null'ed out instead of having valid values
170  * ----------------
171  */
172 PGconn *
173 PQconnectdb(const char *conninfo)
174 {
175         PGconn     *conn;
176         char       *tmp;
177
178         /* ----------
179          * Allocate memory for the conn structure
180          * ----------
181          */
182         conn = makeEmptyPGconn();
183         if (conn == NULL)
184         {
185                 fprintf(stderr,
186                    "FATAL: PQconnectdb() -- unable to allocate memory for a PGconn");
187                 return (PGconn *) NULL;
188         }
189
190         /* ----------
191          * Parse the conninfo string and save settings in conn structure
192          * ----------
193          */
194         if (conninfo_parse(conninfo, conn->errorMessage) < 0)
195         {
196                 conn->status = CONNECTION_BAD;
197                 conninfo_free();
198                 return conn;
199         }
200         tmp = conninfo_getval("host");
201         conn->pghost = tmp ? strdup(tmp) : NULL;
202         tmp = conninfo_getval("port");
203         conn->pgport = tmp ? strdup(tmp) : NULL;
204         tmp = conninfo_getval("tty");
205         conn->pgtty = tmp ? strdup(tmp) : NULL;
206         tmp = conninfo_getval("options");
207         conn->pgoptions = tmp ? strdup(tmp) : NULL;
208         tmp = conninfo_getval("dbname");
209         conn->dbName = tmp ? strdup(tmp) : NULL;
210         tmp = conninfo_getval("user");
211         conn->pguser = tmp ? strdup(tmp) : NULL;
212         tmp = conninfo_getval("password");
213         conn->pgpass = tmp ? strdup(tmp) : NULL;
214
215         /* ----------
216          * Free the connection info - all is in conn now
217          * ----------
218          */
219         conninfo_free();
220
221         /* ----------
222          * Connect to the database
223          * ----------
224          */
225         conn->status = connectDB(conn);
226
227         return conn;
228 }
229
230 /* ----------------
231  *              PQconndefaults
232  *
233  * Parse an empty string like PQconnectdb() would do and return the
234  * address of the connection options structure. Using this function
235  * an application might determine all possible options and their
236  * current default values.
237  * ----------------
238  */
239 PQconninfoOption *
240 PQconndefaults(void)
241 {
242         char            errorMessage[ERROR_MSG_LENGTH];
243
244         conninfo_parse("", errorMessage);
245         return PQconninfoOptions;
246 }
247
248 /* ----------------
249  *              PQsetdbLogin
250  *
251  * establishes a connection to a postgres backend through the postmaster
252  * at the specified host and port.
253  *
254  * returns a PGconn* which is needed for all subsequent libpq calls
255  * if the status field of the connection returned is CONNECTION_BAD,
256  * then some fields may be null'ed out instead of having valid values
257  *
258  *      Uses these environment variables:
259  *
260  *        PGHOST           identifies host to which to connect if <pghost> argument
261  *                                 is NULL or a null string.
262  *
263  *        PGPORT           identifies TCP port to which to connect if <pgport> argument
264  *                                 is NULL or a null string.
265  *
266  *        PGTTY            identifies tty to which to send messages if <pgtty> argument
267  *                                 is NULL or a null string.
268  *
269  *        PGOPTIONS    identifies connection options if <pgoptions> argument is
270  *                                 NULL or a null string.
271  *
272  *        PGUSER           Postgres username to associate with the connection.
273  *
274  *        PGPASSWORD   The user's password.
275  *
276  *        PGDATABASE   name of database to which to connect if <pgdatabase>
277  *                                 argument is NULL or a null string
278  *
279  *        None of the above need be defined.  There are defaults for all of them.
280  *
281  * To support "delimited identifiers" for database names, only convert
282  * the database name to lower case if it is not surrounded by double quotes.
283  * Otherwise, strip the double quotes but leave the reset of the string intact.
284  * - thomas 1997-11-08
285  *
286  * ----------------
287  */
288 PGconn *
289 PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd)
290 {
291         PGconn     *conn;
292         char       *tmp;
293         /* An error message from some service we call. */
294         bool            error = FALSE;
295         /* We encountered an error that prevents successful completion */
296         int                     i;
297
298         conn = makeEmptyPGconn();
299         if (conn == NULL)
300         {
301                 fprintf(stderr,
302                    "FATAL: PQsetdbLogin() -- unable to allocate memory for a PGconn");
303                 return (PGconn *) NULL;
304         }
305
306         if ((pghost == NULL) || pghost[0] == '\0')
307         {
308                 if ((tmp = getenv("PGHOST")) != NULL)
309                         conn->pghost = strdup(tmp);
310         }
311         else
312                 conn->pghost = strdup(pghost);
313
314         if ((pgport == NULL) || pgport[0] == '\0')
315         {
316                 if ((tmp = getenv("PGPORT")) == NULL)
317                         tmp = DEF_PGPORT;
318                 conn->pgport = strdup(tmp);
319         }
320         else
321                 conn->pgport = strdup(pgport);
322
323         if ((pgtty == NULL) || pgtty[0] == '\0')
324         {
325                 if ((tmp = getenv("PGTTY")) == NULL)
326                         tmp = DefaultTty;
327                 conn->pgtty = strdup(tmp);
328         }
329         else
330                 conn->pgtty = strdup(pgtty);
331
332         if ((pgoptions == NULL) || pgoptions[0] == '\0')
333         {
334                 if ((tmp = getenv("PGOPTIONS")) == NULL)
335                         tmp = DefaultOption;
336                 conn->pgoptions = strdup(tmp);
337         }
338         else
339                 conn->pgoptions = strdup(pgoptions);
340
341         if (login)
342                 conn->pguser = strdup(login);
343         else if ((tmp = getenv("PGUSER")) != NULL)
344                 conn->pguser = strdup(tmp);
345         else
346                 conn->pguser = fe_getauthname(conn->errorMessage);
347
348         if (conn->pguser == NULL)
349         {
350                 error = TRUE;
351                 sprintf(conn->errorMessage,
352                                 "FATAL: PQsetdbLogin(): Unable to determine a Postgres username!\n");
353         }
354
355         if (pwd)
356                 conn->pgpass = strdup(pwd);
357         else if ((tmp = getenv("PGPASSWORD")) != NULL)
358                 conn->pgpass = strdup(tmp);
359         else
360                 conn->pgpass = strdup(DefaultPassword);
361
362         if ((dbName == NULL) || dbName[0] == '\0')
363         {
364                 if ((tmp = getenv("PGDATABASE")) != NULL)
365                         conn->dbName = strdup(tmp);
366                 else if (conn->pguser)
367                         conn->dbName = strdup(conn->pguser);
368         }
369         else
370                 conn->dbName = strdup(dbName);
371
372         if (conn->dbName)
373         {
374                 /*
375                  * if the database name is surrounded by double-quotes, then
376                  * don't convert case
377                  */
378                 if (*conn->dbName == '"')
379                 {
380                         strcpy(conn->dbName, conn->dbName + 1);
381                         conn->dbName[strlen(conn->dbName) - 1] = '\0';
382                 }
383                 else
384                         for (i = 0; conn->dbName[i]; i++)
385                                 if (isascii((unsigned char)conn->dbName[i]) &&
386                                     isupper(conn->dbName[i]))
387                                         conn->dbName[i] = tolower(conn->dbName[i]);
388         }
389
390         if (error)
391                 conn->status = CONNECTION_BAD;
392         else
393                 conn->status = connectDB(conn);
394
395         return conn;
396 }
397
398
399 /*
400  * update_db_info -
401  * get all additional infos out of dbName
402  *
403  */
404 static int
405 update_db_info(PGconn *conn)
406 {
407         char *tmp, *old = conn->dbName;
408         
409         if (strchr(conn->dbName, '@') != NULL)
410         {
411                 /* old style: dbname[@server][:port] */
412                 tmp = strrchr(conn->dbName, ':');
413                 if (tmp != NULL) /* port number given */
414                 {
415                         conn->pgport = strdup(tmp + 1);
416                         *tmp = '\0';
417                 }
418                 
419                 tmp = strrchr(conn->dbName, '@');
420                 if (tmp != NULL) /* host name given */
421                 {
422                         conn->pghost = strdup(tmp + 1);
423                         *tmp = '\0';
424                 }
425         
426                 conn->dbName = strdup(old);
427                 free(old);
428         }
429         else
430         {
431                 int offset;
432                 
433                 /*
434                * only allow protocols tcp and unix
435                */
436                 if (strncmp(conn->dbName, "tcp:", 4) == 0)
437                         offset = 4;
438                 else if (strncmp(conn->dbName, "unix:", 5) == 0)
439                         offset = 5;
440                 else return 0;
441                         
442                 if (strncmp(conn->dbName + offset, "postgresql://", strlen("postgresql://")) == 0)
443                 {
444                         /* new style: <tcp|unix>:postgresql://server[:port][/dbname][?options] */
445                         offset += strlen("postgresql://");
446                         
447                         tmp = strrchr(conn->dbName + offset, '?');
448                         if (tmp != NULL) /* options given */
449                         {
450                                 conn->pgoptions = strdup(tmp + 1);
451                                 *tmp = '\0';
452                         }
453                 
454                         tmp = strrchr(conn->dbName + offset, '/');
455                         if (tmp != NULL) /* database name given */
456                         {
457                                 conn->dbName = strdup(tmp + 1);
458                                 *tmp = '\0';
459                         }
460                         else
461                         {
462                                 if ((tmp = getenv("PGDATABASE")) != NULL)
463                                         conn->dbName = strdup(tmp);
464                                 else if (conn->pguser)
465                                         conn->dbName = strdup(conn->pguser);
466                         }
467                 
468                         tmp = strrchr(old + offset, ':');
469                         if (tmp != NULL) /* port number given */
470                         {
471                                 conn->pgport = strdup(tmp + 1);
472                                 *tmp = '\0';
473                         }
474                 
475                         if (strncmp(old, "unix:", 5) == 0)
476                         {
477                                 conn->pghost = NULL;
478                                 if (strcmp(old + offset, "localhost") != 0)
479                                 {
480                                         (void) sprintf(conn->errorMessage,
481                                            "connectDB() -- non-tcp access only possible on localhost\n");
482                                          return 1;
483                                 }
484                         }
485                         else conn->pghost = strdup(old + offset);
486         
487                         free(old);
488                 }
489         }
490         
491         return 0;
492 }
493
494 /*
495  * connectDB -
496  * make a connection to the backend so it is ready to receive queries.
497  * return CONNECTION_OK if successful, CONNECTION_BAD if not.
498  *
499  */
500 static ConnStatusType
501 connectDB(PGconn *conn)
502 {
503         PGresult   *res;
504         struct hostent *hp;
505         StartupPacket sp;
506         AuthRequest areq;
507         int                     laddrlen = sizeof(SockAddr);
508         int                     portno,
509                                 family;
510         char            beresp;
511         int                     on = 1;
512
513         /* 
514         * parse dbName to get all additional info in it, if any
515         */
516         if (update_db_info(conn) != 0)
517                 goto connect_errReturn;
518                 
519         /*
520          * Initialize the startup packet.
521          */
522
523         MemSet((char *) &sp, 0, sizeof(StartupPacket));
524
525         sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LATEST);
526
527         strncpy(sp.user, conn->pguser, SM_USER);
528         strncpy(sp.database, conn->dbName, SM_DATABASE);
529         strncpy(sp.tty, conn->pgtty, SM_TTY);
530
531         if (conn->pgoptions)
532                 strncpy(sp.options, conn->pgoptions, SM_OPTIONS);
533
534         /*
535          * Open a connection to postmaster/backend.
536          */
537
538         if (conn->pghost != NULL)
539         {
540                 hp = gethostbyname(conn->pghost);
541                 if ((hp == NULL) || (hp->h_addrtype != AF_INET))
542                 {
543                         (void) sprintf(conn->errorMessage,
544                                                    "connectDB() --  unknown hostname: %s\n",
545                                                    conn->pghost);
546                         goto connect_errReturn;
547                 }
548                 family = AF_INET;
549         }
550         else {
551                 hp = NULL;
552                 family = AF_UNIX;
553         }
554
555         MemSet((char *) &conn->raddr, 0, sizeof(conn->raddr));
556         conn->raddr.sa.sa_family = family;
557
558         portno = atoi(conn->pgport);
559         if (family == AF_INET)
560         {
561                 memmove((char *) &(conn->raddr.in.sin_addr),
562                                 (char *) hp->h_addr,
563                                 hp->h_length);
564                 conn->raddr.in.sin_port = htons((unsigned short) (portno));
565                 conn->raddr_len = sizeof(struct sockaddr_in);
566         }
567 #ifndef WIN32
568         else
569                 conn->raddr_len = UNIXSOCK_PATH(conn->raddr.un, portno);
570 #endif
571         
572
573         /* Connect to the server  */
574         if ((conn->sock = socket(family, SOCK_STREAM, 0)) < 0)
575         {
576                 (void) sprintf(conn->errorMessage,
577                                            "connectDB() -- socket() failed: errno=%d\n%s\n",
578                                            errno, strerror(errno));
579                 goto connect_errReturn;
580         }
581         if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
582         {
583                 (void) sprintf(conn->errorMessage,
584                                            "connectDB() failed: Is the postmaster running and accepting%s connections at '%s' on port '%s'?\n",
585                                            conn->pghost ? " TCP/IP(with -i)" : "",
586                                            conn->pghost ? conn->pghost : "UNIX Socket",
587                                            conn->pgport);
588                 goto connect_errReturn;
589         }
590
591         /*
592          * Set the right options.
593          * We need nonblocking I/O, and we don't want delay of outgoing data.
594          */
595
596 #ifndef WIN32
597         if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) < 0)
598 #else
599         if (ioctlsocket(conn->sock,FIONBIO, &on) != 0) 
600 #endif
601         {
602                 (void) sprintf(conn->errorMessage,
603                                            "connectDB() -- fcntl() failed: errno=%d\n%s\n",
604                                            errno, strerror(errno));
605                 goto connect_errReturn;
606         }
607
608         if (family == AF_INET)
609         {
610                 struct protoent *pe;
611
612                 pe = getprotobyname("TCP");
613                 if (pe == NULL)
614                 {
615                         (void) sprintf(conn->errorMessage,
616                                                    "connectDB(): getprotobyname failed\n");
617                         goto connect_errReturn;
618                 }
619                 if (setsockopt(conn->sock, pe->p_proto, TCP_NODELAY,
620 #ifdef WIN32
621                         (char *)
622 #endif
623                                            &on, 
624                                            sizeof(on)) < 0)
625                 {
626                         (void) sprintf(conn->errorMessage,
627                                                    "connectDB() -- setsockopt failed: errno=%d\n%s\n",
628                                                    errno, strerror(errno));
629 #ifdef WIN32
630                         printf("Winsock error: %i\n",WSAGetLastError());
631 #endif
632                         goto connect_errReturn;
633                 }
634         }
635
636         /* Fill in the client address */
637         if (getsockname(conn->sock, &conn->laddr.sa, &laddrlen) < 0)
638         {
639                 (void) sprintf(conn->errorMessage,
640                                            "connectDB() -- getsockname() failed: errno=%d\n%s\n",
641                                            errno, strerror(errno));
642                 goto connect_errReturn;
643         }
644
645         /* Ensure our buffers are empty */
646         conn->inStart = conn->inCursor = conn->inEnd = 0;
647         conn->outCount = 0;
648
649         /* Send the startup packet. */
650
651         if (packetSend(conn, (char *) &sp, sizeof(StartupPacket)) != STATUS_OK)
652         {
653                 sprintf(conn->errorMessage,
654                                 "connectDB() --  couldn't send startup packet: errno=%d\n%s\n",
655                                 errno, strerror(errno));
656                 goto connect_errReturn;
657         }
658
659         /*
660          * Perform the authentication exchange:
661          * wait for backend messages and respond as necessary.
662          * We fall out of this loop when done talking to the postmaster.
663          */
664
665         for (;;)
666         {
667                 /* Wait for some data to arrive (or for the channel to close) */
668                 if (pqWait(TRUE, FALSE, conn))
669                         goto connect_errReturn;
670                 /* Load data, or detect EOF */
671                 if (pqReadData(conn) < 0)
672                         goto connect_errReturn;
673                 /* Scan the message.
674                  * If we run out of data, loop around to try again.
675                  */
676                 conn->inCursor = conn->inStart;
677
678                 if (pqGetc(&beresp, conn))
679                         continue;                       /* no data yet */
680
681                 /* Handle errors. */
682                 if (beresp == 'E')
683                 {
684                         if (pqGets(conn->errorMessage, sizeof(conn->errorMessage), conn))
685                                 continue;
686                         goto connect_errReturn;
687                 }
688
689                 /* Otherwise it should be an authentication request. */
690                 if (beresp != 'R')
691                 {
692                         (void) sprintf(conn->errorMessage,
693                                                    "connectDB() -- expected authentication request\n");
694                         goto connect_errReturn;
695                 }
696
697                 /* Get the type of request. */
698                 if (pqGetInt((int *) &areq, 4, conn))
699                         continue;
700
701                 /* Get the password salt if there is one. */
702                 if (areq == AUTH_REQ_CRYPT)
703                 {
704                         if (pqGetnchar(conn->salt, sizeof(conn->salt), conn))
705                                 continue;
706                 }
707
708                 /* OK, we successfully read the message; mark data consumed */
709                 conn->inStart = conn->inCursor;
710
711                 /* Respond to the request if necessary. */
712                 if (fe_sendauth(areq, conn, conn->pghost, conn->pgpass,
713                                                 conn->errorMessage) != STATUS_OK)
714                         goto connect_errReturn;
715                 if (pqFlush(conn))
716                         goto connect_errReturn;
717
718                 /* Are we done? */
719                 if (areq == AUTH_REQ_OK)
720                         break;
721         }
722
723         /*
724          * Now we expect to hear from the backend.
725          * A ReadyForQuery message indicates that startup is successful,
726          * but we might also get an Error message indicating failure.
727          * (Notice messages indicating nonfatal warnings are also allowed
728          * by the protocol, as is a BackendKeyData message.)
729          * Easiest way to handle this is to let PQgetResult() read the messages.
730          * We just have to fake it out about the state of the connection.
731          */
732
733         conn->status = CONNECTION_OK;
734         conn->asyncStatus = PGASYNC_BUSY;
735         res = PQgetResult(conn);
736         /* NULL return indicating we have gone to IDLE state is expected */
737         if (res) {
738                 if (res->resultStatus != PGRES_FATAL_ERROR)
739                         sprintf(conn->errorMessage,
740                                         "connectDB() -- unexpected message during startup\n");
741                 PQclear(res);
742                 goto connect_errReturn;
743         }
744
745         /* Given the new protocol that sends a ReadyForQuery message
746          * after successful backend startup, it should no longer be
747          * necessary to send an empty query to test for startup.
748          */
749
750 #if 0
751
752         /*
753          * Send a blank query to make sure everything works; in
754          * particular, that the database exists.
755          */
756         res = PQexec(conn, " ");
757         if (res == NULL || res->resultStatus != PGRES_EMPTY_QUERY)
758         {
759                 /* PQexec has put error message in conn->errorMessage */
760                 closePGconn(conn);
761                 PQclear(res);
762                 goto connect_errReturn;
763         }
764         PQclear(res);
765
766 #endif
767
768         /* Post-connection housekeeping.
769          * Send environment variables to server
770          */
771
772         PQsetenv(conn);
773
774         return CONNECTION_OK;
775
776 connect_errReturn:
777         if (conn->sock >= 0)
778         {
779 #ifdef WIN32
780                 closesocket(conn->sock);
781 #else
782                 close(conn->sock);
783 #endif
784                 conn->sock = -1;
785         }
786         return CONNECTION_BAD;
787
788 }
789
790 void
791 PQsetenv(PGconn *conn)
792 {
793         struct EnvironmentOptions *eo;
794         char            setQuery[80];   /* mjl: size okay? XXX */
795 #ifdef MULTIBYTE
796         char    *envname = "PGCLIENTENCODING";
797         char    envbuf[64];
798         char    *env;
799         char    *encoding = 0;
800         PGresult   *rtn;
801 #endif
802
803 #ifdef MULTIBYTE
804         /* query server encoding */
805         env = getenv(envname);
806         if (!env) {
807           rtn = PQexec(conn, "select getdatabaseencoding()");
808           if (rtn && PQresultStatus(rtn) == PGRES_TUPLES_OK) {
809             encoding = PQgetvalue(rtn,0,0);
810             if (encoding) {
811               /* set client encoding */
812               sprintf(envbuf,"%s=%s",envname,encoding);
813               putenv(envbuf);
814             }
815             PQclear(rtn);
816           }
817           if (!encoding) {      /* this should not happen */
818             sprintf(envbuf,"%s=%s",envname,pg_encoding_to_char(MULTIBYTE));
819             putenv(envbuf);
820           }
821         }
822 #endif
823
824         for (eo = EnvironmentOptions; eo->envName; eo++)
825         {
826                 const char *val;
827
828                 if ((val = getenv(eo->envName)))
829                 {
830                         PGresult   *res;
831
832                         if (strcasecmp(val, "default") == 0)
833                                 sprintf(setQuery, "SET %s = %.60s", eo->pgName, val);
834                         else
835                                 sprintf(setQuery, "SET %s = '%.60s'", eo->pgName, val);
836 #ifdef CONNECTDEBUG
837                         printf("Use environment variable %s to send %s\n", eo->envName, setQuery);
838 #endif
839                         res = PQexec(conn, setQuery);
840                         PQclear(res);           /* Don't care? */
841                 }
842         }
843 }       /* PQsetenv() */
844
845 /*
846  * makeEmptyPGconn
847  *   - create a PGconn data structure with (as yet) no interesting data
848  */
849 static PGconn *
850 makeEmptyPGconn(void)
851 {
852         PGconn  *conn = (PGconn *) malloc(sizeof(PGconn));
853         if (conn == NULL)
854                 return conn;
855
856         /* Zero all pointers */
857         MemSet((char *) conn, 0, sizeof(PGconn));
858
859         conn->status = CONNECTION_BAD;
860         conn->asyncStatus = PGASYNC_IDLE;
861         conn->notifyList = DLNewList();
862         conn->sock = -1;
863         conn->inBufSize = 8192;
864         conn->inBuffer = (char *) malloc(conn->inBufSize);
865         conn->outBufSize = 8192;
866         conn->outBuffer = (char *) malloc(conn->outBufSize);
867         if (conn->inBuffer == NULL || conn->outBuffer == NULL)
868         {
869                 freePGconn(conn);
870                 conn = NULL;
871         }
872         return conn;
873 }
874
875 /*
876  * freePGconn
877  *       - free the PGconn data structure
878  *
879  */
880 static void
881 freePGconn(PGconn *conn)
882 {
883         if (!conn)
884                 return;
885         PQclearAsyncResult(conn);       /* deallocate result and curTuple */
886         if (conn->sock >= 0)
887 #ifdef WIN32
888                 closesocket(conn->sock);
889 #else
890                 close(conn->sock);
891 #endif
892         if (conn->pghost)
893                 free(conn->pghost);
894         if (conn->pgport)
895                 free(conn->pgport);
896         if (conn->pgtty)
897                 free(conn->pgtty);
898         if (conn->pgoptions)
899                 free(conn->pgoptions);
900         if (conn->dbName)
901                 free(conn->dbName);
902         if (conn->pguser)
903                 free(conn->pguser);
904         if (conn->pgpass)
905                 free(conn->pgpass);
906         /* Note that conn->Pfdebug is not ours to close or free */
907         if (conn->notifyList)
908                 DLFreeList(conn->notifyList);
909         if (conn->lobjfuncs)
910                 free(conn->lobjfuncs);
911         if (conn->inBuffer)
912                 free(conn->inBuffer);
913         if (conn->outBuffer)
914                 free(conn->outBuffer);
915         free(conn);
916 }
917
918 /*
919    closePGconn
920          - properly close a connection to the backend
921 */
922 static void
923 closePGconn(PGconn *conn)
924 {
925         if (conn->sock >= 0)
926         {
927                 /*
928                  * Try to send close message.
929                  * If connection is already gone, that's cool.  No reason for kernel
930                  * to kill us when we try to write to it.  So ignore SIGPIPE signals.
931                  */
932 #ifndef WIN32
933 #if defined(USE_POSIX_SIGNALS)
934                 struct sigaction ignore_action;
935                 struct sigaction oldaction;
936
937                 ignore_action.sa_handler = SIG_IGN;
938                 sigemptyset(&ignore_action.sa_mask);
939                 ignore_action.sa_flags = 0;
940                 sigaction(SIGPIPE, (struct sigaction *) & ignore_action, &oldaction);
941
942                 (void) pqPuts("X", conn);
943                 (void) pqFlush(conn);
944
945                 sigaction(SIGPIPE, &oldaction, NULL);
946 #else
947                 void (*oldsignal)(int);
948
949                 oldsignal = signal(SIGPIPE, SIG_IGN);
950
951                 (void) pqPuts("X", conn);
952                 (void) pqFlush(conn);
953
954                 signal(SIGPIPE, oldsignal);
955 #endif
956 #endif /* Win32 uses no signals at all */
957         }
958
959         /*
960          * Close the connection, reset all transient state, flush I/O buffers.
961          */
962         if (conn->sock >= 0)
963 #ifdef WIN32
964                 closesocket(conn->sock);
965 #else
966                 close(conn->sock);
967 #endif
968         conn->sock = -1;
969         conn->status = CONNECTION_BAD;          /* Well, not really _bad_ - just
970                                                                                  * absent */
971         conn->asyncStatus = PGASYNC_IDLE;
972         PQclearAsyncResult(conn);       /* deallocate result and curTuple */
973         if (conn->lobjfuncs)
974                 free(conn->lobjfuncs);
975         conn->lobjfuncs = NULL;
976         conn->inStart = conn->inCursor = conn->inEnd = 0;
977         conn->outCount = 0;
978
979 }
980
981 /*
982    PQfinish:
983           properly close a connection to the backend
984           also frees the PGconn data structure so it shouldn't be re-used
985           after this
986 */
987 void
988 PQfinish(PGconn *conn)
989 {
990         if (!conn)
991                 fprintf(stderr, "PQfinish() -- pointer to PGconn is null\n");
992         else
993         {
994                 closePGconn(conn);
995                 freePGconn(conn);
996         }
997 }
998
999 /* PQreset :
1000    resets the connection to the backend
1001    closes the existing connection and makes a new one
1002 */
1003 void
1004 PQreset(PGconn *conn)
1005 {
1006         if (!conn)
1007                 fprintf(stderr, "PQreset() -- pointer to PGconn is null\n");
1008         else
1009         {
1010                 closePGconn(conn);
1011                 conn->status = connectDB(conn);
1012         }
1013 }
1014
1015
1016 /*
1017  * PQrequestCancel: attempt to request cancellation of the current operation.
1018  *
1019  * The return value is TRUE if the cancel request was successfully
1020  * dispatched, FALSE if not (in which case errorMessage is set).
1021  * Note: successful dispatch is no guarantee that there will be any effect at
1022  * the backend.  The application must read the operation result as usual.
1023  *
1024  * CAUTION: we want this routine to be safely callable from a signal handler
1025  * (for example, an application might want to call it in a SIGINT handler).
1026  * This means we cannot use any C library routine that might be non-reentrant.
1027  * malloc/free are often non-reentrant, and anything that might call them is
1028  * just as dangerous.  We avoid sprintf here for that reason.  Building up
1029  * error messages with strcpy/strcat is tedious but should be quite safe.
1030  */
1031
1032 int
1033 PQrequestCancel(PGconn *conn)
1034 {
1035         int                     tmpsock = -1;
1036         struct {
1037                 uint32                          packetlen;
1038                 CancelRequestPacket     cp;
1039         }                       crp;
1040
1041         /* Check we have an open connection */
1042         if (!conn)
1043                 return FALSE;
1044
1045         if (conn->sock < 0)
1046         {
1047                 strcpy(conn->errorMessage,
1048                            "PQrequestCancel() -- connection is not open\n");
1049                 return FALSE;
1050         }
1051
1052         /*
1053          * We need to open a temporary connection to the postmaster.
1054          * Use the information saved by connectDB to do this with
1055          * only kernel calls.
1056          */
1057         if ((tmpsock = socket(conn->raddr.sa.sa_family, SOCK_STREAM, 0)) < 0)
1058         {
1059                 strcpy(conn->errorMessage, "PQrequestCancel() -- socket() failed: ");
1060                 goto cancel_errReturn;
1061         }
1062         if (connect(tmpsock, &conn->raddr.sa, conn->raddr_len) < 0)
1063         {
1064                 strcpy(conn->errorMessage, "PQrequestCancel() -- connect() failed: ");
1065                 goto cancel_errReturn;
1066         }
1067         /*
1068          * We needn't set nonblocking I/O or NODELAY options here.
1069          */
1070
1071         /* Create and send the cancel request packet. */
1072
1073         crp.packetlen = htonl((uint32) sizeof(crp));
1074         crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE);
1075         crp.cp.backendPID = htonl(conn->be_pid);
1076         crp.cp.cancelAuthCode = htonl(conn->be_key);
1077
1078         if (send(tmpsock, (char*) &crp, sizeof(crp), 0) != (int) sizeof(crp))
1079         {
1080                 strcpy(conn->errorMessage, "PQrequestCancel() -- send() failed: ");
1081                 goto cancel_errReturn;
1082         }
1083
1084         /* Sent it, done */
1085 #ifdef WIN32
1086         closesocket(tmpsock);
1087 #else
1088         close(tmpsock);
1089 #endif
1090
1091         return TRUE;
1092
1093 cancel_errReturn:
1094         strcat(conn->errorMessage, strerror(errno));
1095         strcat(conn->errorMessage, "\n");
1096         if (tmpsock >= 0)
1097         {
1098 #ifdef WIN32
1099                 closesocket(tmpsock);
1100 #else
1101                 close(tmpsock);
1102 #endif
1103         }
1104         return FALSE;
1105 }
1106
1107
1108 /*
1109  * PacketSend() -- send a single-packet message.
1110  * this is like PacketSend(), defined in backend/libpq/pqpacket.c
1111  *
1112  * RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
1113  * SIDE_EFFECTS: may block.
1114 */
1115 int
1116 packetSend(PGconn *conn, const char *buf, size_t len)
1117 {
1118         /* Send the total packet size. */
1119
1120         if (pqPutInt(4 + len, 4, conn))
1121                 return STATUS_ERROR;
1122
1123         /* Send the packet itself. */
1124
1125         if (pqPutnchar(buf, len, conn))
1126                 return STATUS_ERROR;
1127
1128         if (pqFlush(conn))
1129                 return STATUS_ERROR;
1130
1131         return STATUS_OK;
1132 }
1133
1134
1135 /* ----------------
1136  * Conninfo parser routine
1137  * ----------------
1138  */
1139 static int
1140 conninfo_parse(const char *conninfo, char *errorMessage)
1141 {
1142         char       *pname;
1143         char       *pval;
1144         char       *buf;
1145         char       *tmp;
1146         char       *cp;
1147         char       *cp2;
1148         PQconninfoOption *option;
1149         char            errortmp[ERROR_MSG_LENGTH];
1150
1151         conninfo_free();
1152
1153         if ((buf = strdup(conninfo)) == NULL)
1154         {
1155                 strcpy(errorMessage,
1156                   "FATAL: cannot allocate memory for copy of conninfo string\n");
1157                 return -1;
1158         }
1159         cp = buf;
1160
1161         while (*cp)
1162         {
1163                 /* Skip blanks before the parameter name */
1164                 if (isspace(*cp))
1165                 {
1166                         cp++;
1167                         continue;
1168                 }
1169
1170                 /* Get the parameter name */
1171                 pname = cp;
1172                 while (*cp)
1173                 {
1174                         if (*cp == '=')
1175                                 break;
1176                         if (isspace(*cp))
1177                         {
1178                                 *cp++ = '\0';
1179                                 while (*cp)
1180                                 {
1181                                         if (!isspace(*cp))
1182                                                 break;
1183                                         cp++;
1184                                 }
1185                                 break;
1186                         }
1187                         cp++;
1188                 }
1189
1190                 /* Check that there is a following '=' */
1191                 if (*cp != '=')
1192                 {
1193                         sprintf(errorMessage,
1194                         "ERROR: PQconnectdb() - Missing '=' after '%s' in conninfo\n",
1195                                         pname);
1196                         free(buf);
1197                         return -1;
1198                 }
1199                 *cp++ = '\0';
1200
1201                 /* Skip blanks after the '=' */
1202                 while (*cp)
1203                 {
1204                         if (!isspace(*cp))
1205                                 break;
1206                         cp++;
1207                 }
1208
1209                 pval = cp;
1210
1211                 if (*cp != '\'')
1212                 {
1213                         cp2 = pval;
1214                         while (*cp)
1215                         {
1216                                 if (isspace(*cp))
1217                                 {
1218                                         *cp++ = '\0';
1219                                         break;
1220                                 }
1221                                 if (*cp == '\\')
1222                                 {
1223                                         cp++;
1224                                         if (*cp != '\0')
1225                                                 *cp2++ = *cp++;
1226                                 }
1227                                 else
1228                                         *cp2++ = *cp++;
1229                         }
1230                         *cp2 = '\0';
1231                 }
1232                 else
1233                 {
1234                         cp2 = pval;
1235                         cp++;
1236                         for (;;)
1237                         {
1238                                 if (*cp == '\0')
1239                                 {
1240                                         sprintf(errorMessage,
1241                                                         "ERROR: PQconnectdb() - unterminated quoted string in conninfo\n");
1242                                         free(buf);
1243                                         return -1;
1244                                 }
1245                                 if (*cp == '\\')
1246                                 {
1247                                         cp++;
1248                                         if (*cp != '\0')
1249                                                 *cp2++ = *cp++;
1250                                         continue;
1251                                 }
1252                                 if (*cp == '\'')
1253                                 {
1254                                         *cp2 = '\0';
1255                                         cp++;
1256                                         break;
1257                                 }
1258                                 *cp2++ = *cp++;
1259                         }
1260                 }
1261
1262                 /* ----------
1263                  * Now we have the name and the value. Search
1264                  * for the param record.
1265                  * ----------
1266                  */
1267                 for (option = PQconninfoOptions; option->keyword != NULL; option++)
1268                 {
1269                         if (!strcmp(option->keyword, pname))
1270                                 break;
1271                 }
1272                 if (option->keyword == NULL)
1273                 {
1274                         sprintf(errorMessage,
1275                                         "ERROR: PQconnectdb() - unknown option '%s'\n",
1276                                         pname);
1277                         free(buf);
1278                         return -1;
1279                 }
1280
1281                 /* ----------
1282                  * Store the value
1283                  * ----------
1284                  */
1285                 option->val = strdup(pval);
1286         }
1287
1288         free(buf);
1289
1290         /* ----------
1291          * Get the fallback resources for parameters not specified
1292          * in the conninfo string.
1293          * ----------
1294          */
1295         for (option = PQconninfoOptions; option->keyword != NULL; option++)
1296         {
1297                 if (option->val != NULL)
1298                         continue;                       /* Value was in conninfo */
1299
1300                 /* ----------
1301                  * Try to get the environment variable fallback
1302                  * ----------
1303                  */
1304                 if (option->environ != NULL)
1305                 {
1306                         if ((tmp = getenv(option->environ)) != NULL)
1307                         {
1308                                 option->val = strdup(tmp);
1309                                 continue;
1310                         }
1311                 }
1312
1313                 /* ----------
1314                  * No environment variable specified or this one isn't set -
1315                  * try compiled in
1316                  * ----------
1317                  */
1318                 if (option->compiled != NULL)
1319                 {
1320                         option->val = strdup(option->compiled);
1321                         continue;
1322                 }
1323
1324                 /* ----------
1325                  * Special handling for user
1326                  * ----------
1327                  */
1328                 if (!strcmp(option->keyword, "user"))
1329                 {
1330                         tmp = fe_getauthname(errortmp);
1331                         if (tmp)
1332                                 option->val = strdup(tmp);
1333                 }
1334
1335                 /* ----------
1336                  * Special handling for dbname
1337                  * ----------
1338                  */
1339                 if (!strcmp(option->keyword, "dbname"))
1340                 {
1341                         tmp = conninfo_getval("user");
1342                         if (tmp)
1343                                 option->val = strdup(tmp);
1344                 }
1345         }
1346
1347         return 0;
1348 }
1349
1350
1351 static char *
1352 conninfo_getval(char *keyword)
1353 {
1354         PQconninfoOption *option;
1355
1356         for (option = PQconninfoOptions; option->keyword != NULL; option++)
1357         {
1358                 if (!strcmp(option->keyword, keyword))
1359                         return option->val;
1360         }
1361
1362         return NULL;
1363 }
1364
1365
1366 static void
1367 conninfo_free()
1368 {
1369         PQconninfoOption *option;
1370
1371         for (option = PQconninfoOptions; option->keyword != NULL; option++)
1372         {
1373                 if (option->val != NULL)
1374                 {
1375                         free(option->val);
1376                         option->val = NULL;
1377                 }
1378         }
1379 }
1380
1381 /* =========== accessor functions for PGconn ========= */
1382 char *
1383 PQdb(PGconn *conn)
1384 {
1385         if (!conn)
1386         {
1387                 fprintf(stderr, "PQdb() -- pointer to PGconn is null\n");
1388                 return (char *) NULL;
1389         }
1390         return conn->dbName;
1391 }
1392
1393 char *
1394 PQuser(PGconn *conn)
1395 {
1396         if (!conn)
1397         {
1398                 fprintf(stderr, "PQuser() -- pointer to PGconn is null\n");
1399                 return (char *) NULL;
1400         }
1401         return conn->pguser;
1402 }
1403
1404 char *
1405 PQhost(PGconn *conn)
1406 {
1407         if (!conn)
1408         {
1409                 fprintf(stderr, "PQhost() -- pointer to PGconn is null\n");
1410                 return (char *) NULL;
1411         }
1412
1413         return conn->pghost;
1414 }
1415
1416 char *
1417 PQoptions(PGconn *conn)
1418 {
1419         if (!conn)
1420         {
1421                 fprintf(stderr, "PQoptions() -- pointer to PGconn is null\n");
1422                 return (char *) NULL;
1423         }
1424         return conn->pgoptions;
1425 }
1426
1427 char *
1428 PQtty(PGconn *conn)
1429 {
1430         if (!conn)
1431         {
1432                 fprintf(stderr, "PQtty() -- pointer to PGconn is null\n");
1433                 return (char *) NULL;
1434         }
1435         return conn->pgtty;
1436 }
1437
1438 char *
1439 PQport(PGconn *conn)
1440 {
1441         if (!conn)
1442         {
1443                 fprintf(stderr, "PQport() -- pointer to PGconn is null\n");
1444                 return (char *) NULL;
1445         }
1446         return conn->pgport;
1447 }
1448
1449 ConnStatusType
1450 PQstatus(PGconn *conn)
1451 {
1452         if (!conn)
1453         {
1454                 fprintf(stderr, "PQstatus() -- pointer to PGconn is null\n");
1455                 return CONNECTION_BAD;
1456         }
1457         return conn->status;
1458 }
1459
1460 char *
1461 PQerrorMessage(PGconn *conn)
1462 {
1463         if (!conn)
1464         {
1465                 fprintf(stderr, "PQerrorMessage() -- pointer to PGconn is null\n");
1466                 return (char *) NULL;
1467         }
1468         return conn->errorMessage;
1469 }
1470
1471 int
1472 PQsocket(PGconn *conn)
1473 {
1474         if (!conn)
1475         {
1476                 fprintf(stderr, "PQsocket() -- pointer to PGconn is null\n");
1477                 return -1;
1478         }
1479         return conn->sock;
1480 }
1481
1482 void
1483 PQtrace(PGconn *conn, FILE *debug_port)
1484 {
1485         if (conn == NULL ||
1486                 conn->status == CONNECTION_BAD)
1487                 return;
1488         PQuntrace(conn);
1489         conn->Pfdebug = debug_port;
1490 }
1491
1492 void
1493 PQuntrace(PGconn *conn)
1494 {
1495         /* note: better allow untrace even when connection bad */
1496         if (conn == NULL)
1497                 return;
1498         if (conn->Pfdebug)
1499         {
1500                 fflush(conn->Pfdebug);
1501                 conn->Pfdebug = NULL;
1502         }
1503 }