PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
fe-connect.c File Reference
#include "postgres_fe.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <time.h>
#include <unistd.h>
#include "libpq-fe.h"
#include "libpq-int.h"
#include "fe-auth.h"
#include "pg_config_paths.h"
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "common/ip.h"
#include "mb/pg_wchar.h"
Include dependency graph for fe-connect.c:

Go to the source code of this file.

Data Structures

struct  _internalPQconninfoOption
 

Macros

#define FD_CLOEXEC   1
 
#define PGPASSFILE   ".pgpass"
 
#define ERRCODE_APPNAME_UNKNOWN   "42704"
 
#define ERRCODE_INVALID_PASSWORD   "28P01"
 
#define ERRCODE_CANNOT_CONNECT_NOW   "57P03"
 
#define DefaultHost   "localhost"
 
#define DefaultTty   ""
 
#define DefaultOption   ""
 
#define DefaultAuthtype   ""
 
#define DefaultTargetSessionAttrs   "any"
 
#define DefaultSSLMode   "disable"
 
#define MAXBUFSIZE   256
 
#define LINELEN   NAMEDATALEN*5
 

Typedefs

typedef struct
_internalPQconninfoOption 
internalPQconninfoOption
 

Functions

static bool connectOptions1 (PGconn *conn, const char *conninfo)
 
static bool connectOptions2 (PGconn *conn)
 
static int connectDBStart (PGconn *conn)
 
static int connectDBComplete (PGconn *conn)
 
static PGPing internal_ping (PGconn *conn)
 
static PGconnmakeEmptyPGconn (void)
 
static bool fillPGconn (PGconn *conn, PQconninfoOption *connOptions)
 
static void freePGconn (PGconn *conn)
 
static void closePGconn (PGconn *conn)
 
static void release_all_addrinfo (PGconn *conn)
 
static void sendTerminateConn (PGconn *conn)
 
static PQconninfoOptionconninfo_init (PQExpBuffer errorMessage)
 
static PQconninfoOptionparse_connection_string (const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
 
static int uri_prefix_length (const char *connstr)
 
static bool recognized_connection_string (const char *connstr)
 
static PQconninfoOptionconninfo_parse (const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
 
static PQconninfoOptionconninfo_array_parse (const char *const *keywords, const char *const *values, PQExpBuffer errorMessage, bool use_defaults, int expand_dbname)
 
static bool conninfo_add_defaults (PQconninfoOption *options, PQExpBuffer errorMessage)
 
static PQconninfoOptionconninfo_uri_parse (const char *uri, PQExpBuffer errorMessage, bool use_defaults)
 
static bool conninfo_uri_parse_options (PQconninfoOption *options, const char *uri, PQExpBuffer errorMessage)
 
static bool conninfo_uri_parse_params (char *params, PQconninfoOption *connOptions, PQExpBuffer errorMessage)
 
static char * conninfo_uri_decode (const char *str, PQExpBuffer errorMessage)
 
static bool get_hexdigit (char digit, int *value)
 
static const char * conninfo_getval (PQconninfoOption *connOptions, const char *keyword)
 
static PQconninfoOptionconninfo_storeval (PQconninfoOption *connOptions, const char *keyword, const char *value, PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode)
 
static PQconninfoOptionconninfo_find (PQconninfoOption *connOptions, const char *keyword)
 
static void defaultNoticeReceiver (void *arg, const PGresult *res)
 
static void defaultNoticeProcessor (void *arg, const char *message)
 
static int parseServiceInfo (PQconninfoOption *options, PQExpBuffer errorMessage)
 
static int parseServiceFile (const char *serviceFile, const char *service, PQconninfoOption *options, PQExpBuffer errorMessage, bool *group_found)
 
static char * pwdfMatchesString (char *buf, char *token)
 
static char * passwordFromFile (char *hostname, char *port, char *dbname, char *username, char *pgpassfile)
 
static void pgpassfileWarning (PGconn *conn)
 
static void default_threadlock (int acquire)
 
void pqDropConnection (PGconn *conn, bool flushInput)
 
PGconnPQconnectdbParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PGPing PQpingParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PGconnPQconnectdb (const char *conninfo)
 
PGPing PQping (const char *conninfo)
 
PGconnPQconnectStartParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PGconnPQconnectStart (const char *conninfo)
 
PQconninfoOptionPQconndefaults (void)
 
PGconnPQsetdbLogin (const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd)
 
static int connectNoDelay (PGconn *conn)
 
static void connectFailureMessage (PGconn *conn, int errorno)
 
static int useKeepalives (PGconn *conn)
 
static int setKeepalivesIdle (PGconn *conn)
 
static int setKeepalivesInterval (PGconn *conn)
 
static int setKeepalivesCount (PGconn *conn)
 
static bool saveErrorMessage (PGconn *conn, PQExpBuffer savedMessage)
 
static void restoreErrorMessage (PGconn *conn, PQExpBuffer savedMessage)
 
PostgresPollingStatusType PQconnectPoll (PGconn *conn)
 
void PQfinish (PGconn *conn)
 
void PQreset (PGconn *conn)
 
int PQresetStart (PGconn *conn)
 
PostgresPollingStatusType PQresetPoll (PGconn *conn)
 
PGcancelPQgetCancel (PGconn *conn)
 
void PQfreeCancel (PGcancel *cancel)
 
static int internal_cancel (SockAddr *raddr, int be_pid, int be_key, char *errbuf, int errbufsize)
 
int PQcancel (PGcancel *cancel, char *errbuf, int errbufsize)
 
int PQrequestCancel (PGconn *conn)
 
int pqPacketSend (PGconn *conn, char pack_type, const void *buf, size_t buf_len)
 
PQconninfoOptionPQconninfoParse (const char *conninfo, char **errmsg)
 
PQconninfoOptionPQconninfo (PGconn *conn)
 
void PQconninfoFree (PQconninfoOption *connOptions)
 
char * PQdb (const PGconn *conn)
 
char * PQuser (const PGconn *conn)
 
char * PQpass (const PGconn *conn)
 
char * PQhost (const PGconn *conn)
 
char * PQport (const PGconn *conn)
 
char * PQtty (const PGconn *conn)
 
char * PQoptions (const PGconn *conn)
 
ConnStatusType PQstatus (const PGconn *conn)
 
PGTransactionStatusType PQtransactionStatus (const PGconn *conn)
 
const char * PQparameterStatus (const PGconn *conn, const char *paramName)
 
int PQprotocolVersion (const PGconn *conn)
 
int PQserverVersion (const PGconn *conn)
 
char * PQerrorMessage (const PGconn *conn)
 
int PQsocket (const PGconn *conn)
 
int PQbackendPID (const PGconn *conn)
 
int PQconnectionNeedsPassword (const PGconn *conn)
 
int PQconnectionUsedPassword (const PGconn *conn)
 
int PQclientEncoding (const PGconn *conn)
 
int PQsetClientEncoding (PGconn *conn, const char *encoding)
 
PGVerbosity PQsetErrorVerbosity (PGconn *conn, PGVerbosity verbosity)
 
PGContextVisibility PQsetErrorContextVisibility (PGconn *conn, PGContextVisibility show_context)
 
void PQtrace (PGconn *conn, FILE *debug_port)
 
void PQuntrace (PGconn *conn)
 
PQnoticeReceiver PQsetNoticeReceiver (PGconn *conn, PQnoticeReceiver proc, void *arg)
 
PQnoticeProcessor PQsetNoticeProcessor (PGconn *conn, PQnoticeProcessor proc, void *arg)
 
bool pqGetHomeDirectory (char *buf, int bufsize)
 
pgthreadlock_t PQregisterThreadLock (pgthreadlock_t newhandler)
 

Variables

static const
internalPQconninfoOption 
PQconninfoOptions []
 
static const PQEnvironmentOption EnvironmentOptions []
 
static const char uri_designator [] = "postgresql://"
 
static const char short_uri_designator [] = "postgres://"
 
pgthreadlock_t pg_g_threadlock = default_threadlock
 

Macro Definition Documentation

#define DefaultAuthtype   ""

Definition at line 109 of file fe-connect.c.

#define DefaultHost   "localhost"

Definition at line 106 of file fe-connect.c.

Referenced by connectOptions2(), passwordFromFile(), and PQhost().

#define DefaultOption   ""

Definition at line 108 of file fe-connect.c.

#define DefaultSSLMode   "disable"

Definition at line 114 of file fe-connect.c.

Referenced by connectOptions2().

#define DefaultTargetSessionAttrs   "any"

Definition at line 110 of file fe-connect.c.

#define DefaultTty   ""

Definition at line 107 of file fe-connect.c.

#define ERRCODE_APPNAME_UNKNOWN   "42704"

Definition at line 95 of file fe-connect.c.

Referenced by PQconnectPoll().

#define ERRCODE_CANNOT_CONNECT_NOW   "57P03"

Definition at line 100 of file fe-connect.c.

Referenced by internal_ping(), and ProcessStartupPacket().

#define ERRCODE_INVALID_PASSWORD   "28P01"

Definition at line 98 of file fe-connect.c.

Referenced by auth_failed(), and pgpassfileWarning().

#define FD_CLOEXEC   1

Definition at line 79 of file fe-connect.c.

Referenced by PQconnectPoll().

#define LINELEN   NAMEDATALEN*5

Referenced by passwordFromFile().

#define MAXBUFSIZE   256

Definition at line 4357 of file fe-connect.c.

Referenced by parseServiceFile().

#define PGPASSFILE   ".pgpass"

Definition at line 84 of file fe-connect.c.

Referenced by connectOptions2().

Typedef Documentation

Function Documentation

static void closePGconn ( PGconn conn)
static

Definition at line 3428 of file fe-connect.c.

References pg_conn::asyncStatus, CONNECTION_BAD, pg_conn::errorMessage, FALSE, free, pg_conn::lobjfuncs, pgNotify::next, pgParameterStatus::next, pg_conn::nonblocking, pg_conn::notifyHead, pg_conn::notifyTail, NULL, PGASYNC_IDLE, pqClearAsyncResult(), pqDropConnection(), pg_conn::pstatus, release_all_addrinfo(), resetPQExpBuffer(), sendTerminateConn(), and pg_conn::status.

Referenced by PQfinish(), PQreset(), and PQresetStart().

3429 {
3430  PGnotify *notify;
3431  pgParameterStatus *pstatus;
3432 
3433  sendTerminateConn(conn);
3434 
3435  /*
3436  * Must reset the blocking status so a possible reconnect will work.
3437  *
3438  * Don't call PQsetnonblocking() because it will fail if it's unable to
3439  * flush the connection.
3440  */
3441  conn->nonblocking = FALSE;
3442 
3443  /*
3444  * Close the connection, reset all transient state, flush I/O buffers.
3445  */
3446  pqDropConnection(conn, true);
3447  conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just
3448  * absent */
3449  conn->asyncStatus = PGASYNC_IDLE;
3450  pqClearAsyncResult(conn); /* deallocate result */
3452  release_all_addrinfo(conn);
3453 
3454  notify = conn->notifyHead;
3455  while (notify != NULL)
3456  {
3457  PGnotify *prev = notify;
3458 
3459  notify = notify->next;
3460  free(prev);
3461  }
3462  conn->notifyHead = conn->notifyTail = NULL;
3463  pstatus = conn->pstatus;
3464  while (pstatus != NULL)
3465  {
3466  pgParameterStatus *prev = pstatus;
3467 
3468  pstatus = pstatus->next;
3469  free(prev);
3470  }
3471  conn->pstatus = NULL;
3472  if (conn->lobjfuncs)
3473  free(conn->lobjfuncs);
3474  conn->lobjfuncs = NULL;
3475 #ifdef ENABLE_GSS
3476  {
3477  OM_uint32 min_s;
3478 
3479  if (conn->gctx)
3480  gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
3481  if (conn->gtarg_nam)
3482  gss_release_name(&min_s, &conn->gtarg_nam);
3483  if (conn->ginbuf.length)
3484  gss_release_buffer(&min_s, &conn->ginbuf);
3485  if (conn->goutbuf.length)
3486  gss_release_buffer(&min_s, &conn->goutbuf);
3487  }
3488 #endif
3489 #ifdef ENABLE_SSPI
3490  if (conn->ginbuf.length)
3491  free(conn->ginbuf.value);
3492  conn->ginbuf.length = 0;
3493  conn->ginbuf.value = NULL;
3494  if (conn->sspitarget)
3495  free(conn->sspitarget);
3496  conn->sspitarget = NULL;
3497  if (conn->sspicred)
3498  {
3499  FreeCredentialsHandle(conn->sspicred);
3500  free(conn->sspicred);
3501  conn->sspicred = NULL;
3502  }
3503  if (conn->sspictx)
3504  {
3505  DeleteSecurityContext(conn->sspictx);
3506  free(conn->sspictx);
3507  conn->sspictx = NULL;
3508  }
3509 #endif
3510 }
static void release_all_addrinfo(PGconn *conn)
Definition: fe-connect.c:3373
PGnotify * notifyHead
Definition: libpq-int.h:393
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:410
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:3401
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
#define FALSE
Definition: c.h:218
pgParameterStatus * pstatus
Definition: libpq-int.h:425
struct pgNotify * next
Definition: libpq-fe.h:167
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
struct pgParameterStatus * next
Definition: libpq-int.h:260
ConnStatusType status
Definition: libpq-int.h:380
PGnotify * notifyTail
Definition: libpq-int.h:394
bool nonblocking
Definition: libpq-int.h:387
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:705
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:430
static int connectDBComplete ( PGconn conn)
static

Definition at line 1715 of file fe-connect.c.

References pg_conn::connect_timeout, CONNECTION_BAD, pg_conn::errorMessage, flag(), NULL, PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PQconnectPoll(), pqWaitTimed(), resetPQExpBuffer(), and pg_conn::status.

Referenced by internal_ping(), PQconnectdb(), PQconnectdbParams(), PQreset(), and PQsetdbLogin().

1716 {
1718  time_t finish_time = ((time_t) -1);
1719 
1720  if (conn == NULL || conn->status == CONNECTION_BAD)
1721  return 0;
1722 
1723  /*
1724  * Set up a time limit, if connect_timeout isn't zero.
1725  */
1726  if (conn->connect_timeout != NULL)
1727  {
1728  int timeout = atoi(conn->connect_timeout);
1729 
1730  if (timeout > 0)
1731  {
1732  /*
1733  * Rounding could cause connection to fail; need at least 2 secs
1734  */
1735  if (timeout < 2)
1736  timeout = 2;
1737  /* calculate the finish time based on start + timeout */
1738  finish_time = time(NULL) + timeout;
1739  }
1740  }
1741 
1742  for (;;)
1743  {
1744  /*
1745  * Wait, if necessary. Note that the initial state (just after
1746  * PQconnectStart) is to wait for the socket to select for writing.
1747  */
1748  switch (flag)
1749  {
1750  case PGRES_POLLING_OK:
1751 
1752  /*
1753  * Reset stored error messages since we now have a working
1754  * connection
1755  */
1757  return 1; /* success! */
1758 
1759  case PGRES_POLLING_READING:
1760  if (pqWaitTimed(1, 0, conn, finish_time))
1761  {
1762  conn->status = CONNECTION_BAD;
1763  return 0;
1764  }
1765  break;
1766 
1767  case PGRES_POLLING_WRITING:
1768  if (pqWaitTimed(0, 1, conn, finish_time))
1769  {
1770  conn->status = CONNECTION_BAD;
1771  return 0;
1772  }
1773  break;
1774 
1775  default:
1776  /* Just in case we failed to set it in PQconnectPoll */
1777  conn->status = CONNECTION_BAD;
1778  return 0;
1779  }
1780 
1781  /*
1782  * Now try to advance the state machine.
1783  */
1784  flag = PQconnectPoll(conn);
1785  }
1786 }
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
Definition: fe-misc.c:1004
char * connect_timeout
Definition: libpq-int.h:337
char * flag(int b)
Definition: test-ctype.c:33
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:1849
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define NULL
Definition: c.h:226
ConnStatusType status
Definition: libpq-int.h:380
PostgresPollingStatusType
Definition: libpq-fe.h:72
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
static int connectDBStart ( PGconn conn)
static

Definition at line 1574 of file fe-connect.c.

References pg_conn::addr_cur, pg_conn_host::addrlist, addrinfo::ai_family, addrinfo::ai_flags, AI_NUMERICHOST, addrinfo::ai_socktype, appendPQExpBuffer(), Assert, CHT_HOST_ADDRESS, CHT_HOST_NAME, CHT_UNIX_SOCKET, CONNECTION_BAD, CONNECTION_NEEDED, pg_conn::connhost, pg_conn::errorMessage, gai_strerror, pg_conn_host::host, i, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, libpq_gettext, MAXPGPATH, MemSet, pg_conn::nconnhost, NULL, pg_conn::options_valid, pg_conn::outCount, pg_freeaddrinfo_all(), pg_getaddrinfo_all(), PG_PROTOCOL, PGRES_POLLING_WRITING, pg_conn_host::port, PQconnectPoll(), pqDropConnection(), pg_conn::pversion, pg_conn::send_appname, snprintf(), pg_conn::sslmode, pg_conn::status, pg_conn_host::type, UNIXSOCK_PATH, UNIXSOCK_PATH_BUFLEN, and pg_conn::whichhost.

Referenced by PQconnectStart(), PQconnectStartParams(), PQreset(), PQresetStart(), and PQsetdbLogin().

1575 {
1576  char portstr[MAXPGPATH];
1577  int ret;
1578  int i;
1579 
1580  if (!conn)
1581  return 0;
1582 
1583  if (!conn->options_valid)
1584  goto connect_errReturn;
1585 
1586  /* Ensure our buffers are empty */
1587  conn->inStart = conn->inCursor = conn->inEnd = 0;
1588  conn->outCount = 0;
1589 
1590  /*
1591  * Look up socket addresses for each possible host using
1592  * pg_getaddrinfo_all.
1593  */
1594  for (i = 0; i < conn->nconnhost; ++i)
1595  {
1596  pg_conn_host *ch = &conn->connhost[i];
1597  char *node = ch->host;
1598  struct addrinfo hint;
1599  int thisport;
1600 
1601  /* Initialize hint structure */
1602  MemSet(&hint, 0, sizeof(hint));
1603  hint.ai_socktype = SOCK_STREAM;
1604  hint.ai_family = AF_UNSPEC;
1605 
1606  /* Figure out the port number we're going to use. */
1607  if (ch->port == NULL)
1608  thisport = DEF_PGPORT;
1609  else
1610  {
1611  thisport = atoi(ch->port);
1612  if (thisport < 1 || thisport > 65535)
1613  {
1615  libpq_gettext("invalid port number: \"%s\"\n"),
1616  ch->port);
1617  conn->options_valid = false;
1618  goto connect_errReturn;
1619  }
1620  }
1621  snprintf(portstr, sizeof(portstr), "%d", thisport);
1622 
1623  /* Set up for name resolution. */
1624  switch (ch->type)
1625  {
1626  case CHT_HOST_NAME:
1627  break;
1628  case CHT_HOST_ADDRESS:
1629  hint.ai_flags = AI_NUMERICHOST;
1630  break;
1631  case CHT_UNIX_SOCKET:
1632 #ifdef HAVE_UNIX_SOCKETS
1633  node = NULL;
1634  hint.ai_family = AF_UNIX;
1635  UNIXSOCK_PATH(portstr, thisport, ch->host);
1636  if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
1637  {
1639  libpq_gettext("Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n"),
1640  portstr,
1641  (int) (UNIXSOCK_PATH_BUFLEN - 1));
1642  conn->options_valid = false;
1643  goto connect_errReturn;
1644  }
1645 #else
1646  Assert(false);
1647 #endif
1648  break;
1649  }
1650 
1651  /* Use pg_getaddrinfo_all() to resolve the address */
1652  ret = pg_getaddrinfo_all(node, portstr, &hint, &ch->addrlist);
1653  if (ret || !ch->addrlist)
1654  {
1655  if (node)
1657  libpq_gettext("could not translate host name \"%s\" to address: %s\n"),
1658  node, gai_strerror(ret));
1659  else
1661  libpq_gettext("could not translate Unix-domain socket path \"%s\" to address: %s\n"),
1662  portstr, gai_strerror(ret));
1663  if (ch->addrlist)
1664  {
1665  pg_freeaddrinfo_all(hint.ai_family, ch->addrlist);
1666  ch->addrlist = NULL;
1667  }
1668  conn->options_valid = false;
1669  goto connect_errReturn;
1670  }
1671  }
1672 
1673 #ifdef USE_SSL
1674  /* setup values based on SSL mode */
1675  if (conn->sslmode[0] == 'd') /* "disable" */
1676  conn->allow_ssl_try = false;
1677  else if (conn->sslmode[0] == 'a') /* "allow" */
1678  conn->wait_ssl_try = true;
1679 #endif
1680 
1681  /*
1682  * Set up to try to connect, with protocol 3.0 as the first attempt.
1683  */
1684  conn->whichhost = 0;
1685  conn->addr_cur = conn->connhost[0].addrlist;
1686  conn->pversion = PG_PROTOCOL(3, 0);
1687  conn->send_appname = true;
1688  conn->status = CONNECTION_NEEDED;
1689 
1690  /*
1691  * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
1692  * so that it can easily be re-executed if needed again during the
1693  * asynchronous startup process. However, we must run it once here,
1694  * because callers expect a success return from this routine to mean that
1695  * we are in PGRES_POLLING_WRITING connection state.
1696  */
1697  if (PQconnectPoll(conn) == PGRES_POLLING_WRITING)
1698  return 1;
1699 
1700 connect_errReturn:
1701  pqDropConnection(conn, true);
1702  conn->status = CONNECTION_BAD;
1703  return 0;
1704 }
int inEnd
Definition: libpq-int.h:437
void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
Definition: ip.c:89
#define UNIXSOCK_PATH(path, port, sockdir)
Definition: pqcomm.h:70
int inStart
Definition: libpq-int.h:435
struct addrinfo * addr_cur
Definition: libpq-int.h:416
#define UNIXSOCK_PATH_BUFLEN
Definition: pqcomm.h:86
int outCount
Definition: libpq-int.h:442
char * host
Definition: libpq-int.h:309
#define MemSet(start, val, len)
Definition: c.h:853
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:410
#define AI_NUMERICHOST
Definition: getaddrinfo.h:75
pg_conn_host_type type
Definition: libpq-int.h:310
#define gai_strerror
Definition: getaddrinfo.h:148
int pg_getaddrinfo_all(const char *hostname, const char *servname, const struct addrinfo *hintp, struct addrinfo **result)
Definition: ip.c:58
#define MAXPGPATH
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
pg_conn_host * connhost
Definition: libpq-int.h:399
char * sslmode
Definition: libpq-int.h:353
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:1849
PQExpBufferData errorMessage
Definition: libpq-int.h:498
bool options_valid
Definition: libpq-int.h:386
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
struct addrinfo * addrlist
Definition: libpq-int.h:316
ProtocolVersion pversion
Definition: libpq-int.h:406
ConnStatusType status
Definition: libpq-int.h:380
int i
int inCursor
Definition: libpq-int.h:436
char * port
Definition: libpq-int.h:311
int nconnhost
Definition: libpq-int.h:397
#define PG_PROTOCOL(m, n)
Definition: pqcomm.h:106
int whichhost
Definition: libpq-int.h:398
#define libpq_gettext(x)
Definition: libpq-int.h:689
bool send_appname
Definition: libpq-int.h:419
static void connectFailureMessage ( PGconn conn,
int  errorno 
)
static

Definition at line 1303 of file fe-connect.c.

References SockAddr::addr, appendPQExpBuffer(), pg_conn::connhost, pg_conn::errorMessage, pg_conn_host::host, inet_net_ntop(), IS_AF_UNIX, libpq_gettext, NI_MAXHOST, NI_NUMERICSERV, NULL, pg_getnameinfo_all(), pg_conn::pghost, pg_conn::pghostaddr, pg_conn_host::port, pg_conn::raddr, SockAddr::salen, SOCK_STRERROR, strlcpy(), and pg_conn::whichhost.

Referenced by PQconnectPoll().

1304 {
1305  char sebuf[256];
1306 
1307 #ifdef HAVE_UNIX_SOCKETS
1308  if (IS_AF_UNIX(conn->raddr.addr.ss_family))
1309  {
1310  char service[NI_MAXHOST];
1311 
1312  pg_getnameinfo_all(&conn->raddr.addr, conn->raddr.salen,
1313  NULL, 0,
1314  service, sizeof(service),
1315  NI_NUMERICSERV);
1317  libpq_gettext("could not connect to server: %s\n"
1318  "\tIs the server running locally and accepting\n"
1319  "\tconnections on Unix domain socket \"%s\"?\n"),
1320  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1321  service);
1322  }
1323  else
1324 #endif /* HAVE_UNIX_SOCKETS */
1325  {
1326  char host_addr[NI_MAXHOST];
1327  const char *displayed_host;
1328  const char *displayed_port;
1329  struct sockaddr_storage *addr = &conn->raddr.addr;
1330 
1331  /*
1332  * Optionally display the network address with the hostname. This is
1333  * useful to distinguish between IPv4 and IPv6 connections.
1334  */
1335  if (conn->pghostaddr != NULL)
1336  strlcpy(host_addr, conn->pghostaddr, NI_MAXHOST);
1337  else if (addr->ss_family == AF_INET)
1338  {
1339  if (inet_net_ntop(AF_INET,
1340  &((struct sockaddr_in *) addr)->sin_addr.s_addr,
1341  32,
1342  host_addr, sizeof(host_addr)) == NULL)
1343  strcpy(host_addr, "???");
1344  }
1345 #ifdef HAVE_IPV6
1346  else if (addr->ss_family == AF_INET6)
1347  {
1348  if (inet_net_ntop(AF_INET6,
1349  &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
1350  128,
1351  host_addr, sizeof(host_addr)) == NULL)
1352  strcpy(host_addr, "???");
1353  }
1354 #endif
1355  else
1356  strcpy(host_addr, "???");
1357 
1358  /* To which host and port were we actually connecting? */
1359  displayed_host = conn->connhost[conn->whichhost].host;
1360  displayed_port = conn->connhost[conn->whichhost].port;
1361  if (displayed_port == NULL || displayed_port[0] == '\0')
1362  displayed_port = DEF_PGPORT_STR;
1363 
1364  /*
1365  * If the user did not supply an IP address using 'hostaddr', and
1366  * 'host' was missing or does not match our lookup, display the
1367  * looked-up IP address.
1368  */
1369  if ((conn->pghostaddr == NULL) &&
1370  (conn->pghost == NULL || strcmp(conn->pghost, host_addr) != 0))
1372  libpq_gettext("could not connect to server: %s\n"
1373  "\tIs the server running on host \"%s\" (%s) and accepting\n"
1374  "\tTCP/IP connections on port %s?\n"),
1375  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1376  displayed_host,
1377  host_addr,
1378  displayed_port);
1379  else
1381  libpq_gettext("could not connect to server: %s\n"
1382  "\tIs the server running on host \"%s\" and accepting\n"
1383  "\tTCP/IP connections on port %s?\n"),
1384  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1385  displayed_host,
1386  displayed_port);
1387  }
1388 }
char * host
Definition: libpq-int.h:309
struct sockaddr_storage addr
Definition: pqcomm.h:64
#define SOCK_STRERROR
Definition: libpq-int.h:703
#define NI_MAXHOST
Definition: getaddrinfo.h:90
#define IS_AF_UNIX(fam)
Definition: ip.h:24
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
pg_conn_host * connhost
Definition: libpq-int.h:399
ACCEPT_TYPE_ARG3 salen
Definition: pqcomm.h:65
char * inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
Definition: inet_net_ntop.c:78
SockAddr raddr
Definition: libpq-int.h:405
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define NI_NUMERICSERV
Definition: getaddrinfo.h:83
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:226
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:123
char * pghostaddr
Definition: libpq-int.h:331
char * port
Definition: libpq-int.h:311
int whichhost
Definition: libpq-int.h:398
#define libpq_gettext(x)
Definition: libpq-int.h:689
char * pghost
Definition: libpq-int.h:326
static int connectNoDelay ( PGconn conn)
static

Definition at line 1275 of file fe-connect.c.

References appendPQExpBuffer(), pg_conn::errorMessage, libpq_gettext, pg_conn::sock, SOCK_ERRNO, and SOCK_STRERROR.

Referenced by PQconnectPoll().

1276 {
1277 #ifdef TCP_NODELAY
1278  int on = 1;
1279 
1280  if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
1281  (char *) &on,
1282  sizeof(on)) < 0)
1283  {
1284  char sebuf[256];
1285 
1287  libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
1288  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1289  return 0;
1290  }
1291 #endif
1292 
1293  return 1;
1294 }
#define SOCK_STRERROR
Definition: libpq-int.h:703
#define SOCK_ERRNO
Definition: libpq-int.h:702
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
pgsocket sock
Definition: libpq-int.h:402
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define libpq_gettext(x)
Definition: libpq-int.h:689
static bool connectOptions1 ( PGconn conn,
const char *  conninfo 
)
static

Definition at line 739 of file fe-connect.c.

References CONNECTION_BAD, pg_conn::errorMessage, fillPGconn(), NULL, parse_connection_string(), PQconninfoFree(), and pg_conn::status.

Referenced by PQconnectStart(), and PQsetdbLogin().

740 {
741  PQconninfoOption *connOptions;
742 
743  /*
744  * Parse the conninfo string
745  */
746  connOptions = parse_connection_string(conninfo, &conn->errorMessage, true);
747  if (connOptions == NULL)
748  {
749  conn->status = CONNECTION_BAD;
750  /* errorMessage is already set */
751  return false;
752  }
753 
754  /*
755  * Move option values into conn structure
756  */
757  if (!fillPGconn(conn, connOptions))
758  {
759  conn->status = CONNECTION_BAD;
760  PQconninfoFree(connOptions);
761  return false;
762  }
763 
764  /*
765  * Free the option info - all is in conn now
766  */
767  PQconninfoFree(connOptions);
768 
769  return true;
770 }
static PQconninfoOption * parse_connection_string(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4666
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5810
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define NULL
Definition: c.h:226
static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
Definition: fe-connect.c:697
ConnStatusType status
Definition: libpq-int.h:380
static bool connectOptions2 ( PGconn conn)
static

Definition at line 781 of file fe-connect.c.

References calloc, CHT_HOST_ADDRESS, CHT_HOST_NAME, CHT_UNIX_SOCKET, pg_conn::client_encoding_initial, CONNECTION_BAD, pg_conn::connhost, pg_conn::dbName, DEFAULT_PGSOCKET_DIR, DefaultHost, DefaultSSLMode, pg_conn::errorMessage, free, pg_conn_host::host, i, is_absolute_path, libpq_gettext, malloc, MAXPGPATH, pg_conn::nconnhost, NULL, pg_conn::options_valid, pg_conn_host::password, passwordFromFile(), pg_encoding_to_char(), pg_fe_getauthname(), pg_get_encoding_from_locale(), pg_conn::pghost, pg_conn::pghostaddr, pg_conn::pgpass, PGPASSFILE, pg_conn::pgpassfile, pg_conn::pgpassfile_used, pg_conn::pgport, pg_conn::pguser, pg_conn_host::port, pqGetHomeDirectory(), printfPQExpBuffer(), snprintf(), pg_conn::sslmode, pg_conn::status, pg_conn::target_session_attrs, pg_conn_host::type, and pg_conn::whichhost.

Referenced by PQconnectStart(), PQconnectStartParams(), and PQsetdbLogin().

782 {
783  /*
784  * Allocate memory for details about each host to which we might possibly
785  * try to connect. If pghostaddr is set, we're only going to try to
786  * connect to that one particular address. If it's not, we'll use pghost,
787  * which may contain multiple, comma-separated names.
788  */
789  conn->nconnhost = 1;
790  conn->whichhost = 0;
791  if ((conn->pghostaddr == NULL || conn->pghostaddr[0] == '\0')
792  && conn->pghost != NULL)
793  {
794  char *s;
795 
796  for (s = conn->pghost; *s != '\0'; ++s)
797  if (*s == ',')
798  conn->nconnhost++;
799  }
800  conn->connhost = (pg_conn_host *)
801  calloc(conn->nconnhost, sizeof(pg_conn_host));
802  if (conn->connhost == NULL)
803  goto oom_error;
804 
805  /*
806  * We now have one pg_conn_host structure per possible host. Fill in
807  * the host details for each one.
808  */
809  if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
810  {
811  conn->connhost[0].host = strdup(conn->pghostaddr);
812  if (conn->connhost[0].host == NULL)
813  goto oom_error;
814  conn->connhost[0].type = CHT_HOST_ADDRESS;
815  }
816  else if (conn->pghost != NULL && conn->pghost[0] != '\0')
817  {
818  int i = 0;
819  char *s = conn->pghost;
820 
821  while (1)
822  {
823  char *e = s;
824 
825  /*
826  * Search for the end of the current hostname; a comma or
827  * end-of-string acts as a terminator.
828  */
829  while (*e != '\0' && *e != ',')
830  ++e;
831 
832  /* Copy the hostname whose bounds we just identified. */
833  conn->connhost[i].host =
834  (char *) malloc(sizeof(char) * (e - s + 1));
835  if (conn->connhost[i].host == NULL)
836  goto oom_error;
837  memcpy(conn->connhost[i].host, s, e - s);
838  conn->connhost[i].host[e - s] = '\0';
839 
840  /* Identify the type of host. */
841  conn->connhost[i].type = CHT_HOST_NAME;
842 #ifdef HAVE_UNIX_SOCKETS
843  if (is_absolute_path(conn->connhost[i].host))
844  conn->connhost[i].type = CHT_UNIX_SOCKET;
845 #endif
846 
847  /* Prepare to find the next host (if any). */
848  if (*e == '\0')
849  break;
850  s = e + 1;
851  i++;
852  }
853  }
854  else
855  {
856 #ifdef HAVE_UNIX_SOCKETS
857  conn->connhost[0].host = strdup(DEFAULT_PGSOCKET_DIR);
858  conn->connhost[0].type = CHT_UNIX_SOCKET;
859 #else
860  conn->connhost[0].host = strdup(DefaultHost);
861  conn->connhost[0].type = CHT_HOST_NAME;
862 #endif
863  if (conn->connhost[0].host == NULL)
864  goto oom_error;
865  }
866 
867  /*
868  * Next, work out the port number corresponding to each host name.
869  */
870  if (conn->pgport != NULL && conn->pgport[0] != '\0')
871  {
872  int i = 0;
873  char *s = conn->pgport;
874  int nports = 1;
875 
876  for (i = 0; i < conn->nconnhost; ++i)
877  {
878  char *e = s;
879 
880  /* Search for the end of the current port number. */
881  while (*e != '\0' && *e != ',')
882  ++e;
883 
884  /*
885  * If we found a port number of non-zero length, copy it.
886  * Otherwise, insert the default port number.
887  */
888  if (e > s)
889  {
890  conn->connhost[i].port =
891  (char *) malloc(sizeof(char) * (e - s + 1));
892  if (conn->connhost[i].port == NULL)
893  goto oom_error;
894  memcpy(conn->connhost[i].port, s, e - s);
895  conn->connhost[i].port[e - s] = '\0';
896  }
897 
898  /*
899  * Move on to the next port number, unless there are no more.
900  * (If only one part number is specified, we reuse it for every
901  * host.)
902  */
903  if (*e != '\0')
904  {
905  s = e + 1;
906  ++nports;
907  }
908  }
909 
910  /*
911  * If multiple ports were specified, there must be exactly as many
912  * ports as there were hosts. Otherwise, we do not know how to match
913  * them up.
914  */
915  if (nports != 1 && nports != conn->nconnhost)
916  {
917  conn->status = CONNECTION_BAD;
919  libpq_gettext("could not match %d port numbers to %d hosts\n"),
920  nports, conn->nconnhost);
921  return false;
922  }
923  }
924 
925  /*
926  * If user name was not given, fetch it. (Most likely, the fetch will
927  * fail, since the only way we get here is if pg_fe_getauthname() failed
928  * during conninfo_add_defaults(). But now we want an error message.)
929  */
930  if (conn->pguser == NULL || conn->pguser[0] == '\0')
931  {
932  if (conn->pguser)
933  free(conn->pguser);
934  conn->pguser = pg_fe_getauthname(&conn->errorMessage);
935  if (!conn->pguser)
936  {
937  conn->status = CONNECTION_BAD;
938  return false;
939  }
940  }
941 
942  /*
943  * If database name was not given, default it to equal user name
944  */
945  if (conn->dbName == NULL || conn->dbName[0] == '\0')
946  {
947  if (conn->dbName)
948  free(conn->dbName);
949  conn->dbName = strdup(conn->pguser);
950  if (!conn->dbName)
951  goto oom_error;
952  }
953 
954  /*
955  * Supply default password if none given. Note that the password might
956  * be different for each host/port pair.
957  */
958  if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
959  {
960  int i;
961 
962  if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
963  {
964  /* Identify password file to use; fail if we can't */
965  char homedir[MAXPGPATH];
966 
967  if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
968  {
969  conn->status = CONNECTION_BAD;
971  libpq_gettext("could not get home directory to locate password file\n"));
972  return false;
973  }
974 
975  if (conn->pgpassfile)
976  free(conn->pgpassfile);
977  conn->pgpassfile = malloc(MAXPGPATH);
978  if (!conn->pgpassfile)
979  goto oom_error;
980 
981  snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s", homedir, PGPASSFILE);
982  }
983 
984  for (i = 0; i < conn->nconnhost; i++)
985  {
986  /* Try to get a password for this host from pgpassfile */
987  conn->connhost[i].password =
988  passwordFromFile(conn->connhost[i].host,
989  conn->connhost[i].port,
990  conn->dbName,
991  conn->pguser,
992  conn->pgpassfile);
993  /* If we got one, set pgpassfile_used */
994  if (conn->connhost[i].password != NULL)
995  conn->pgpassfile_used = true;
996  }
997  }
998 
999  /*
1000  * validate sslmode option
1001  */
1002  if (conn->sslmode)
1003  {
1004  if (strcmp(conn->sslmode, "disable") != 0
1005  && strcmp(conn->sslmode, "allow") != 0
1006  && strcmp(conn->sslmode, "prefer") != 0
1007  && strcmp(conn->sslmode, "require") != 0
1008  && strcmp(conn->sslmode, "verify-ca") != 0
1009  && strcmp(conn->sslmode, "verify-full") != 0)
1010  {
1011  conn->status = CONNECTION_BAD;
1013  libpq_gettext("invalid sslmode value: \"%s\"\n"),
1014  conn->sslmode);
1015  return false;
1016  }
1017 
1018 #ifndef USE_SSL
1019  switch (conn->sslmode[0])
1020  {
1021  case 'a': /* "allow" */
1022  case 'p': /* "prefer" */
1023 
1024  /*
1025  * warn user that an SSL connection will never be negotiated
1026  * since SSL was not compiled in?
1027  */
1028  break;
1029 
1030  case 'r': /* "require" */
1031  case 'v': /* "verify-ca" or "verify-full" */
1032  conn->status = CONNECTION_BAD;
1034  libpq_gettext("sslmode value \"%s\" invalid when SSL support is not compiled in\n"),
1035  conn->sslmode);
1036  return false;
1037  }
1038 #endif
1039  }
1040  else
1041  {
1042  conn->sslmode = strdup(DefaultSSLMode);
1043  if (!conn->sslmode)
1044  goto oom_error;
1045  }
1046 
1047  /*
1048  * Resolve special "auto" client_encoding from the locale
1049  */
1050  if (conn->client_encoding_initial &&
1051  strcmp(conn->client_encoding_initial, "auto") == 0)
1052  {
1055  if (!conn->client_encoding_initial)
1056  goto oom_error;
1057  }
1058 
1059  /*
1060  * Validate target_session_attrs option.
1061  */
1062  if (conn->target_session_attrs)
1063  {
1064  if (strcmp(conn->target_session_attrs, "any") != 0
1065  && strcmp(conn->target_session_attrs, "read-write") != 0)
1066  {
1067  conn->status = CONNECTION_BAD;
1069  libpq_gettext("invalid target_session_attrs value: \"%s\"\n"),
1070  conn->target_session_attrs);
1071  return false;
1072  }
1073  }
1074 
1075  /*
1076  * Only if we get this far is it appropriate to try to connect. (We need a
1077  * state flag, rather than just the boolean result of this function, in
1078  * case someone tries to PQreset() the PGconn.)
1079  */
1080  conn->options_valid = true;
1081 
1082  return true;
1083 
1084 oom_error:
1085  conn->status = CONNECTION_BAD;
1087  libpq_gettext("out of memory\n"));
1088  return false;
1089 }
#define calloc(a, b)
Definition: header.h:50
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * pgpassfile
Definition: libpq-int.h:346
char * host
Definition: libpq-int.h:309
char * dbName
Definition: libpq-int.h:342
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
bool pgpassfile_used
Definition: libpq-int.h:411
#define DefaultSSLMode
Definition: fe-connect.c:114
pg_conn_host_type type
Definition: libpq-int.h:310
char * client_encoding_initial
Definition: libpq-int.h:338
#define malloc(a)
Definition: header.h:45
#define PGPASSFILE
Definition: fe-connect.c:84
#define MAXPGPATH
pg_conn_host * connhost
Definition: libpq-int.h:399
#define is_absolute_path(filename)
Definition: port.h:77
char * target_session_attrs
Definition: libpq-int.h:365
char * pguser
Definition: libpq-int.h:344
char * sslmode
Definition: libpq-int.h:353
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:733
PQExpBufferData errorMessage
Definition: libpq-int.h:498
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:438
#define free(a)
Definition: header.h:60
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:531
bool options_valid
Definition: libpq-int.h:386
#define NULL
Definition: c.h:226
char * pgpass
Definition: libpq-int.h:345
ConnStatusType status
Definition: libpq-int.h:380
#define DefaultHost
Definition: fe-connect.c:106
static char * passwordFromFile(char *hostname, char *port, char *dbname, char *username, char *pgpassfile)
Definition: fe-connect.c:6223
char * pghostaddr
Definition: libpq-int.h:331
e
Definition: preproc-init.c:82
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:6379
int i
char * port
Definition: libpq-int.h:311
char * pgport
Definition: libpq-int.h:334
int nconnhost
Definition: libpq-int.h:397
int whichhost
Definition: libpq-int.h:398
#define libpq_gettext(x)
Definition: libpq-int.h:689
char * pghost
Definition: libpq-int.h:326
#define DEFAULT_PGSOCKET_DIR
char * password
Definition: libpq-int.h:313
static bool conninfo_add_defaults ( PQconninfoOption options,
PQExpBuffer  errorMessage 
)
static

Definition at line 5062 of file fe-connect.c.

References _PQconninfoOption::compiled, _PQconninfoOption::envvar, _PQconninfoOption::keyword, libpq_gettext, NULL, parseServiceInfo(), pg_fe_getauthname(), printfPQExpBuffer(), and _PQconninfoOption::val.

Referenced by conninfo_array_parse(), conninfo_parse(), conninfo_uri_parse(), and PQconndefaults().

5063 {
5065  char *tmp;
5066 
5067  /*
5068  * If there's a service spec, use it to obtain any not-explicitly-given
5069  * parameters. Ignore error if no error message buffer is passed because
5070  * there is no way to pass back the failure message.
5071  */
5072  if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
5073  return false;
5074 
5075  /*
5076  * Get the fallback resources for parameters not specified in the conninfo
5077  * string nor the service.
5078  */
5079  for (option = options; option->keyword != NULL; option++)
5080  {
5081  if (option->val != NULL)
5082  continue; /* Value was in conninfo or service */
5083 
5084  /*
5085  * Try to get the environment variable fallback
5086  */
5087  if (option->envvar != NULL)
5088  {
5089  if ((tmp = getenv(option->envvar)) != NULL)
5090  {
5091  option->val = strdup(tmp);
5092  if (!option->val)
5093  {
5094  if (errorMessage)
5095  printfPQExpBuffer(errorMessage,
5096  libpq_gettext("out of memory\n"));
5097  return false;
5098  }
5099  continue;
5100  }
5101  }
5102 
5103  /*
5104  * No environment variable specified or the variable isn't set - try
5105  * compiled-in default
5106  */
5107  if (option->compiled != NULL)
5108  {
5109  option->val = strdup(option->compiled);
5110  if (!option->val)
5111  {
5112  if (errorMessage)
5113  printfPQExpBuffer(errorMessage,
5114  libpq_gettext("out of memory\n"));
5115  return false;
5116  }
5117  continue;
5118  }
5119 
5120  /*
5121  * Special handling for "user" option. Note that if pg_fe_getauthname
5122  * fails, we just leave the value as NULL; there's no need for this to
5123  * be an error condition if the caller provides a user name. The only
5124  * reason we do this now at all is so that callers of PQconndefaults
5125  * will see a correct default (barring error, of course).
5126  */
5127  if (strcmp(option->keyword, "user") == 0)
5128  {
5129  option->val = pg_fe_getauthname(NULL);
5130  continue;
5131  }
5132  }
5133 
5134  return true;
5135 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:733
#define NULL
Definition: c.h:226
static int parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:4360
#define libpq_gettext(x)
Definition: libpq-int.h:689
static PQconninfoOption * conninfo_array_parse ( const char *const *  keywords,
const char *const *  values,
PQExpBuffer  errorMessage,
bool  use_defaults,
int  expand_dbname 
)
static

Definition at line 4898 of file fe-connect.c.

References conninfo_add_defaults(), conninfo_init(), free, i, _PQconninfoOption::keyword, libpq_gettext, NULL, options, parse_connection_string(), PQconninfoFree(), printfPQExpBuffer(), recognized_connection_string(), _PQconninfoOption::val, and val.

Referenced by PQconnectStartParams().

4901 {
4903  PQconninfoOption *dbname_options = NULL;
4905  int i = 0;
4906 
4907  /*
4908  * If expand_dbname is non-zero, check keyword "dbname" to see if val is
4909  * actually a recognized connection string.
4910  */
4911  while (expand_dbname && keywords[i])
4912  {
4913  const char *pname = keywords[i];
4914  const char *pvalue = values[i];
4915 
4916  /* first find "dbname" if any */
4917  if (strcmp(pname, "dbname") == 0 && pvalue)
4918  {
4919  /*
4920  * If value is a connection string, parse it, but do not use
4921  * defaults here -- those get picked up later. We only want to
4922  * override for those parameters actually passed.
4923  */
4924  if (recognized_connection_string(pvalue))
4925  {
4926  dbname_options = parse_connection_string(pvalue, errorMessage, false);
4927  if (dbname_options == NULL)
4928  return NULL;
4929  }
4930  break;
4931  }
4932  ++i;
4933  }
4934 
4935  /* Make a working copy of PQconninfoOptions */
4936  options = conninfo_init(errorMessage);
4937  if (options == NULL)
4938  {
4939  PQconninfoFree(dbname_options);
4940  return NULL;
4941  }
4942 
4943  /* Parse the keywords/values arrays */
4944  i = 0;
4945  while (keywords[i])
4946  {
4947  const char *pname = keywords[i];
4948  const char *pvalue = values[i];
4949 
4950  if (pvalue != NULL && pvalue[0] != '\0')
4951  {
4952  /* Search for the param record */
4953  for (option = options; option->keyword != NULL; option++)
4954  {
4955  if (strcmp(option->keyword, pname) == 0)
4956  break;
4957  }
4958 
4959  /* Check for invalid connection option */
4960  if (option->keyword == NULL)
4961  {
4962  printfPQExpBuffer(errorMessage,
4963  libpq_gettext("invalid connection option \"%s\"\n"),
4964  pname);
4965  PQconninfoFree(options);
4966  PQconninfoFree(dbname_options);
4967  return NULL;
4968  }
4969 
4970  /*
4971  * If we are on the first dbname parameter, and we have a parsed
4972  * connection string, copy those parameters across, overriding any
4973  * existing previous settings.
4974  */
4975  if (strcmp(pname, "dbname") == 0 && dbname_options)
4976  {
4977  PQconninfoOption *str_option;
4978 
4979  for (str_option = dbname_options; str_option->keyword != NULL; str_option++)
4980  {
4981  if (str_option->val != NULL)
4982  {
4983  int k;
4984 
4985  for (k = 0; options[k].keyword; k++)
4986  {
4987  if (strcmp(options[k].keyword, str_option->keyword) == 0)
4988  {
4989  if (options[k].val)
4990  free(options[k].val);
4991  options[k].val = strdup(str_option->val);
4992  if (!options[k].val)
4993  {
4994  printfPQExpBuffer(errorMessage,
4995  libpq_gettext("out of memory\n"));
4996  PQconninfoFree(options);
4997  PQconninfoFree(dbname_options);
4998  return NULL;
4999  }
5000  break;
5001  }
5002  }
5003  }
5004  }
5005 
5006  /*
5007  * Forget the parsed connection string, so that any subsequent
5008  * dbname parameters will not be expanded.
5009  */
5010  PQconninfoFree(dbname_options);
5011  dbname_options = NULL;
5012  }
5013  else
5014  {
5015  /*
5016  * Store the value, overriding previous settings
5017  */
5018  if (option->val)
5019  free(option->val);
5020  option->val = strdup(pvalue);
5021  if (!option->val)
5022  {
5023  printfPQExpBuffer(errorMessage,
5024  libpq_gettext("out of memory\n"));
5025  PQconninfoFree(options);
5026  PQconninfoFree(dbname_options);
5027  return NULL;
5028  }
5029  }
5030  }
5031  ++i;
5032  }
5033  PQconninfoFree(dbname_options);
5034 
5035  /*
5036  * Add in defaults if the caller wants that.
5037  */
5038  if (use_defaults)
5039  {
5040  if (!conninfo_add_defaults(options, errorMessage))
5041  {
5042  PQconninfoFree(options);
5043  return NULL;
5044  }
5045  }
5046 
5047  return options;
5048 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4626
static PQconninfoOption * parse_connection_string(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4666
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5810
static char ** options
static bool recognized_connection_string(const char *connstr)
Definition: fe-connect.c:4709
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5062
static Datum values[MAXATTR]
Definition: bootstrap.c:162
int i
long val
Definition: informix.c:689
#define libpq_gettext(x)
Definition: libpq-int.h:689
static PQconninfoOption * conninfo_find ( PQconninfoOption connOptions,
const char *  keyword 
)
static

Definition at line 5751 of file fe-connect.c.

References _PQconninfoOption::keyword, and NULL.

Referenced by conninfo_getval(), and conninfo_storeval().

5752 {
5754 
5755  for (option = connOptions; option->keyword != NULL; option++)
5756  {
5757  if (strcmp(option->keyword, keyword) == 0)
5758  return option;
5759  }
5760 
5761  return NULL;
5762 }
#define NULL
Definition: c.h:226
static const char * conninfo_getval ( PQconninfoOption connOptions,
const char *  keyword 
)
static

Definition at line 5660 of file fe-connect.c.

References conninfo_find(), NULL, and _PQconninfoOption::val.

Referenced by fillPGconn(), and parseServiceInfo().

5662 {
5664 
5665  option = conninfo_find(connOptions, keyword);
5666 
5667  return option ? option->val : NULL;
5668 }
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5751
#define NULL
Definition: c.h:226
static PQconninfoOption * conninfo_init ( PQExpBuffer  errorMessage)
static

Definition at line 4626 of file fe-connect.c.

References _internalPQconninfoOption::keyword, libpq_gettext, malloc, MemSet, NULL, options, PQconninfoOptions, and printfPQExpBuffer().

Referenced by conninfo_array_parse(), conninfo_parse(), conninfo_uri_parse(), PQconndefaults(), and PQconninfo().

4627 {
4629  PQconninfoOption *opt_dest;
4630  const internalPQconninfoOption *cur_opt;
4631 
4632  /*
4633  * Get enough memory for all options in PQconninfoOptions, even if some
4634  * end up being filtered out.
4635  */
4636  options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
4637  if (options == NULL)
4638  {
4639  printfPQExpBuffer(errorMessage,
4640  libpq_gettext("out of memory\n"));
4641  return NULL;
4642  }
4643  opt_dest = options;
4644 
4645  for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
4646  {
4647  /* Only copy the public part of the struct, not the full internal */
4648  memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
4649  opt_dest++;
4650  }
4651  MemSet(opt_dest, 0, sizeof(PQconninfoOption));
4652 
4653  return options;
4654 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define MemSet(start, val, len)
Definition: c.h:853
#define malloc(a)
Definition: header.h:45
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:167
static char ** options
#define NULL
Definition: c.h:226
#define libpq_gettext(x)
Definition: libpq-int.h:689
static PQconninfoOption * conninfo_parse ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

Definition at line 4720 of file fe-connect.c.

References buf, conninfo_add_defaults(), conninfo_init(), conninfo_storeval(), free, libpq_gettext, NULL, options, PQconninfoFree(), and printfPQExpBuffer().

Referenced by parse_connection_string().

4722 {
4723  char *pname;
4724  char *pval;
4725  char *buf;
4726  char *cp;
4727  char *cp2;
4729 
4730  /* Make a working copy of PQconninfoOptions */
4731  options = conninfo_init(errorMessage);
4732  if (options == NULL)
4733  return NULL;
4734 
4735  /* Need a modifiable copy of the input string */
4736  if ((buf = strdup(conninfo)) == NULL)
4737  {
4738  printfPQExpBuffer(errorMessage,
4739  libpq_gettext("out of memory\n"));
4740  PQconninfoFree(options);
4741  return NULL;
4742  }
4743  cp = buf;
4744 
4745  while (*cp)
4746  {
4747  /* Skip blanks before the parameter name */
4748  if (isspace((unsigned char) *cp))
4749  {
4750  cp++;
4751  continue;
4752  }
4753 
4754  /* Get the parameter name */
4755  pname = cp;
4756  while (*cp)
4757  {
4758  if (*cp == '=')
4759  break;
4760  if (isspace((unsigned char) *cp))
4761  {
4762  *cp++ = '\0';
4763  while (*cp)
4764  {
4765  if (!isspace((unsigned char) *cp))
4766  break;
4767  cp++;
4768  }
4769  break;
4770  }
4771  cp++;
4772  }
4773 
4774  /* Check that there is a following '=' */
4775  if (*cp != '=')
4776  {
4777  printfPQExpBuffer(errorMessage,
4778  libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
4779  pname);
4780  PQconninfoFree(options);
4781  free(buf);
4782  return NULL;
4783  }
4784  *cp++ = '\0';
4785 
4786  /* Skip blanks after the '=' */
4787  while (*cp)
4788  {
4789  if (!isspace((unsigned char) *cp))
4790  break;
4791  cp++;
4792  }
4793 
4794  /* Get the parameter value */
4795  pval = cp;
4796 
4797  if (*cp != '\'')
4798  {
4799  cp2 = pval;
4800  while (*cp)
4801  {
4802  if (isspace((unsigned char) *cp))
4803  {
4804  *cp++ = '\0';
4805  break;
4806  }
4807  if (*cp == '\\')
4808  {
4809  cp++;
4810  if (*cp != '\0')
4811  *cp2++ = *cp++;
4812  }
4813  else
4814  *cp2++ = *cp++;
4815  }
4816  *cp2 = '\0';
4817  }
4818  else
4819  {
4820  cp2 = pval;
4821  cp++;
4822  for (;;)
4823  {
4824  if (*cp == '\0')
4825  {
4826  printfPQExpBuffer(errorMessage,
4827  libpq_gettext("unterminated quoted string in connection info string\n"));
4828  PQconninfoFree(options);
4829  free(buf);
4830  return NULL;
4831  }
4832  if (*cp == '\\')
4833  {
4834  cp++;
4835  if (*cp != '\0')
4836  *cp2++ = *cp++;
4837  continue;
4838  }
4839  if (*cp == '\'')
4840  {
4841  *cp2 = '\0';
4842  cp++;
4843  break;
4844  }
4845  *cp2++ = *cp++;
4846  }
4847  }
4848 
4849  /*
4850  * Now that we have the name and the value, store the record.
4851  */
4852  if (!conninfo_storeval(options, pname, pval, errorMessage, false, false))
4853  {
4854  PQconninfoFree(options);
4855  free(buf);
4856  return NULL;
4857  }
4858  }
4859 
4860  /* Done with the modifiable input string */
4861  free(buf);
4862 
4863  /*
4864  * Add in defaults if the caller wants that.
4865  */
4866  if (use_defaults)
4867  {
4868  if (!conninfo_add_defaults(options, errorMessage))
4869  {
4870  PQconninfoFree(options);
4871  return NULL;
4872  }
4873  }
4874 
4875  return options;
4876 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_storeval(PQconninfoOption *connOptions, const char *keyword, const char *value, PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode)
Definition: fe-connect.c:5686
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4626
static char * buf
Definition: pg_test_fsync.c:65
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5810
static char ** options
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5062
#define libpq_gettext(x)
Definition: libpq-int.h:689
static PQconninfoOption * conninfo_storeval ( PQconninfoOption connOptions,
const char *  keyword,
const char *  value,
PQExpBuffer  errorMessage,
bool  ignoreMissing,
bool  uri_decode 
)
static

Definition at line 5686 of file fe-connect.c.

References conninfo_find(), conninfo_uri_decode(), free, libpq_gettext, NULL, printfPQExpBuffer(), and _PQconninfoOption::val.

Referenced by conninfo_parse(), conninfo_uri_parse_options(), conninfo_uri_parse_params(), and PQconninfo().

5690 {
5692  char *value_copy;
5693 
5694  /*
5695  * For backwards compatibility, requiressl=1 gets translated to
5696  * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
5697  * (which is the default for sslmode).
5698  */
5699  if (strcmp(keyword, "requiressl") == 0)
5700  {
5701  keyword = "sslmode";
5702  if (value[0] == '1')
5703  value = "require";
5704  else
5705  value = "prefer";
5706  }
5707 
5708  option = conninfo_find(connOptions, keyword);
5709  if (option == NULL)
5710  {
5711  if (!ignoreMissing)
5712  printfPQExpBuffer(errorMessage,
5713  libpq_gettext("invalid connection option \"%s\"\n"),
5714  keyword);
5715  return NULL;
5716  }
5717 
5718  if (uri_decode)
5719  {
5720  value_copy = conninfo_uri_decode(value, errorMessage);
5721  if (value_copy == NULL)
5722  /* conninfo_uri_decode already set an error message */
5723  return NULL;
5724  }
5725  else
5726  {
5727  value_copy = strdup(value);
5728  if (value_copy == NULL)
5729  {
5730  printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5731  return NULL;
5732  }
5733  }
5734 
5735  if (option->val)
5736  free(option->val);
5737  option->val = value_copy;
5738 
5739  return option;
5740 }
static struct @76 value
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5751
static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
Definition: fe-connect.c:5571
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
#define libpq_gettext(x)
Definition: libpq-int.h:689
static char * conninfo_uri_decode ( const char *  str,
PQExpBuffer  errorMessage 
)
static

Definition at line 5571 of file fe-connect.c.

References buf, free, get_hexdigit(), libpq_gettext, malloc, NULL, and printfPQExpBuffer().

Referenced by conninfo_storeval(), and conninfo_uri_parse_params().

5572 {
5573  char *buf;
5574  char *p;
5575  const char *q = str;
5576 
5577  buf = malloc(strlen(str) + 1);
5578  if (buf == NULL)
5579  {
5580  printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5581  return NULL;
5582  }
5583  p = buf;
5584 
5585  for (;;)
5586  {
5587  if (*q != '%')
5588  {
5589  /* copy and check for NUL terminator */
5590  if (!(*(p++) = *(q++)))
5591  break;
5592  }
5593  else
5594  {
5595  int hi;
5596  int lo;
5597  int c;
5598 
5599  ++q; /* skip the percent sign itself */
5600 
5601  /*
5602  * Possible EOL will be caught by the first call to
5603  * get_hexdigit(), so we never dereference an invalid q pointer.
5604  */
5605  if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
5606  {
5607  printfPQExpBuffer(errorMessage,
5608  libpq_gettext("invalid percent-encoded token: \"%s\"\n"),
5609  str);
5610  free(buf);
5611  return NULL;
5612  }
5613 
5614  c = (hi << 4) | lo;
5615  if (c == 0)
5616  {
5617  printfPQExpBuffer(errorMessage,
5618  libpq_gettext("forbidden value %%00 in percent-encoded value: \"%s\"\n"),
5619  str);
5620  free(buf);
5621  return NULL;
5622  }
5623  *(p++) = c;
5624  }
5625  }
5626 
5627  return buf;
5628 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define malloc(a)
Definition: header.h:45
char * c
static char * buf
Definition: pg_test_fsync.c:65
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
static bool get_hexdigit(char digit, int *value)
Definition: fe-connect.c:5639
#define libpq_gettext(x)
Definition: libpq-int.h:689
static PQconninfoOption * conninfo_uri_parse ( const char *  uri,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

Definition at line 5143 of file fe-connect.c.

References conninfo_add_defaults(), conninfo_init(), conninfo_uri_parse_options(), NULL, options, and PQconninfoFree().

Referenced by parse_connection_string().

5145 {
5147 
5148  /* Make a working copy of PQconninfoOptions */
5149  options = conninfo_init(errorMessage);
5150  if (options == NULL)
5151  return NULL;
5152 
5153  if (!conninfo_uri_parse_options(options, uri, errorMessage))
5154  {
5155  PQconninfoFree(options);
5156  return NULL;
5157  }
5158 
5159  /*
5160  * Add in defaults if the caller wants that.
5161  */
5162  if (use_defaults)
5163  {
5164  if (!conninfo_add_defaults(options, errorMessage))
5165  {
5166  PQconninfoFree(options);
5167  return NULL;
5168  }
5169  }
5170 
5171  return options;
5172 }
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4626
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5810
static bool conninfo_uri_parse_options(PQconninfoOption *options, const char *uri, PQExpBuffer errorMessage)
Definition: fe-connect.c:5196
static char ** options
#define NULL
Definition: c.h:226
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5062
static bool conninfo_uri_parse_options ( PQconninfoOption options,
const char *  uri,
PQExpBuffer  errorMessage 
)
static

Definition at line 5196 of file fe-connect.c.

References appendPQExpBufferStr(), buf, cleanup(), conninfo_storeval(), conninfo_uri_parse_params(), PQExpBufferData::data, dbname, free, initPQExpBuffer(), libpq_gettext, NULL, password, PQExpBufferDataBroken, printfPQExpBuffer(), termPQExpBuffer(), uri_prefix_length(), and user.

Referenced by conninfo_uri_parse().

5198 {
5199  int prefix_len;
5200  char *p;
5201  char *buf = NULL;
5202  char *start;
5203  char prevchar = '\0';
5204  char *user = NULL;
5205  char *host = NULL;
5206  bool retval = false;
5207  PQExpBufferData hostbuf;
5208  PQExpBufferData portbuf;
5209 
5210  initPQExpBuffer(&hostbuf);
5211  initPQExpBuffer(&portbuf);
5212  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
5213  {
5214  printfPQExpBuffer(errorMessage,
5215  libpq_gettext("out of memory\n"));
5216  goto cleanup;
5217  }
5218 
5219  /* need a modifiable copy of the input URI */
5220  buf = strdup(uri);
5221  if (buf == NULL)
5222  {
5223  printfPQExpBuffer(errorMessage,
5224  libpq_gettext("out of memory\n"));
5225  goto cleanup;
5226  }
5227  start = buf;
5228 
5229  /* Skip the URI prefix */
5230  prefix_len = uri_prefix_length(uri);
5231  if (prefix_len == 0)
5232  {
5233  /* Should never happen */
5234  printfPQExpBuffer(errorMessage,
5235  libpq_gettext("invalid URI propagated to internal parser routine: \"%s\"\n"),
5236  uri);
5237  goto cleanup;
5238  }
5239  start += prefix_len;
5240  p = start;
5241 
5242  /* Look ahead for possible user credentials designator */
5243  while (*p && *p != '@' && *p != '/')
5244  ++p;
5245  if (*p == '@')
5246  {
5247  /*
5248  * Found username/password designator, so URI should be of the form
5249  * "scheme://user[:password]@[netloc]".
5250  */
5251  user = start;
5252 
5253  p = user;
5254  while (*p != ':' && *p != '@')
5255  ++p;
5256 
5257  /* Save last char and cut off at end of user name */
5258  prevchar = *p;
5259  *p = '\0';
5260 
5261  if (*user &&
5262  !conninfo_storeval(options, "user", user,
5263  errorMessage, false, true))
5264  goto cleanup;
5265 
5266  if (prevchar == ':')
5267  {
5268  const char *password = p + 1;
5269 
5270  while (*p != '@')
5271  ++p;
5272  *p = '\0';
5273 
5274  if (*password &&
5275  !conninfo_storeval(options, "password", password,
5276  errorMessage, false, true))
5277  goto cleanup;
5278  }
5279 
5280  /* Advance past end of parsed user name or password token */
5281  ++p;
5282  }
5283  else
5284  {
5285  /*
5286  * No username/password designator found. Reset to start of URI.
5287  */
5288  p = start;
5289  }
5290 
5291  /*
5292  * There may be multiple netloc[:port] pairs, each separated from the next
5293  * by a comma. When we initially enter this loop, "p" has been
5294  * incremented past optional URI credential information at this point and
5295  * now points at the "netloc" part of the URI. On subsequent loop
5296  * iterations, "p" has been incremented past the comma separator and now
5297  * points at the start of the next "netloc".
5298  */
5299  for (;;)
5300  {
5301  /*
5302  * Look for IPv6 address.
5303  */
5304  if (*p == '[')
5305  {
5306  host = ++p;
5307  while (*p && *p != ']')
5308  ++p;
5309  if (!*p)
5310  {
5311  printfPQExpBuffer(errorMessage,
5312  libpq_gettext("end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n"),
5313  uri);
5314  goto cleanup;
5315  }
5316  if (p == host)
5317  {
5318  printfPQExpBuffer(errorMessage,
5319  libpq_gettext("IPv6 host address may not be empty in URI: \"%s\"\n"),
5320  uri);
5321  goto cleanup;
5322  }
5323 
5324  /* Cut off the bracket and advance */
5325  *(p++) = '\0';
5326 
5327  /*
5328  * The address may be followed by a port specifier or a slash or a
5329  * query or a separator comma.
5330  */
5331  if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
5332  {
5333  printfPQExpBuffer(errorMessage,
5334  libpq_gettext("unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n"),
5335  *p, (int) (p - buf + 1), uri);
5336  goto cleanup;
5337  }
5338  }
5339  else
5340  {
5341  /* not an IPv6 address: DNS-named or IPv4 netloc */
5342  host = p;
5343 
5344  /*
5345  * Look for port specifier (colon) or end of host specifier (slash)
5346  * or query (question mark) or host separator (comma).
5347  */
5348  while (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
5349  ++p;
5350  }
5351 
5352  /* Save the hostname terminator before we null it */
5353  prevchar = *p;
5354  *p = '\0';
5355 
5356  appendPQExpBufferStr(&hostbuf, host);
5357 
5358  if (prevchar == ':')
5359  {
5360  const char *port = ++p; /* advance past host terminator */
5361 
5362  while (*p && *p != '/' && *p != '?' && *p != ',')
5363  ++p;
5364 
5365  prevchar = *p;
5366  *p = '\0';
5367 
5368  appendPQExpBufferStr(&portbuf, port);
5369  }
5370 
5371  if (prevchar != ',')
5372  break;
5373  ++p; /* advance past comma separator */
5374  appendPQExpBufferStr(&hostbuf, ",");
5375  appendPQExpBufferStr(&portbuf, ",");
5376  }
5377 
5378  /* Save final values for host and port. */
5379  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
5380  goto cleanup;
5381  if (hostbuf.data[0] &&
5382  !conninfo_storeval(options, "host", hostbuf.data,
5383  errorMessage, false, true))
5384  goto cleanup;
5385  if (portbuf.data[0] &&
5386  !conninfo_storeval(options, "port", portbuf.data,
5387  errorMessage, false, true))
5388  goto cleanup;
5389 
5390  if (prevchar && prevchar != '?')
5391  {
5392  const char *dbname = ++p; /* advance past host terminator */
5393 
5394  /* Look for query parameters */
5395  while (*p && *p != '?')
5396  ++p;
5397 
5398  prevchar = *p;
5399  *p = '\0';
5400 
5401  /*
5402  * Avoid setting dbname to an empty string, as it forces the default
5403  * value (username) and ignores $PGDATABASE, as opposed to not setting
5404  * it at all.
5405  */
5406  if (*dbname &&
5407  !conninfo_storeval(options, "dbname", dbname,
5408  errorMessage, false, true))
5409  goto cleanup;
5410  }
5411 
5412  if (prevchar)
5413  {
5414  ++p; /* advance past terminator */
5415 
5416  if (!conninfo_uri_parse_params(p, options, errorMessage))
5417  goto cleanup;
5418  }
5419 
5420  /* everything parsed okay */
5421  retval = true;
5422 
5423 cleanup:
5424  termPQExpBuffer(&hostbuf);
5425  termPQExpBuffer(&portbuf);
5426  if (buf)
5427  free(buf);
5428  return retval;
5429 }
static char password[100]
Definition: streamutil.c:44
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_storeval(PQconninfoOption *connOptions, const char *keyword, const char *value, PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode)
Definition: fe-connect.c:5686
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
static char * buf
Definition: pg_test_fsync.c:65
static int port
Definition: pg_regress.c:87
static void cleanup(void)
Definition: bootstrap.c:848
static bool conninfo_uri_parse_params(char *params, PQconninfoOption *connOptions, PQExpBuffer errorMessage)
Definition: fe-connect.c:5440
#define free(a)
Definition: header.h:60
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
#define NULL
Definition: c.h:226
char * dbname
Definition: streamutil.c:41
static char * user
Definition: pg_regress.c:90
static int uri_prefix_length(const char *connstr)
Definition: fe-connect.c:4686
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
#define libpq_gettext(x)
Definition: libpq-int.h:689
static bool conninfo_uri_parse_params ( char *  params,
PQconninfoOption connOptions,
PQExpBuffer  errorMessage 
)
static

Definition at line 5440 of file fe-connect.c.

References conninfo_storeval(), conninfo_uri_decode(), free, PQExpBufferData::len, libpq_gettext, NULL, printfPQExpBuffer(), and value.

Referenced by conninfo_uri_parse_options().

5443 {
5444  while (*params)
5445  {
5446  char *keyword = params;
5447  char *value = NULL;
5448  char *p = params;
5449  bool malloced = false;
5450 
5451  /*
5452  * Scan the params string for '=' and '&', marking the end of keyword
5453  * and value respectively.
5454  */
5455  for (;;)
5456  {
5457  if (*p == '=')
5458  {
5459  /* Was there '=' already? */
5460  if (value != NULL)
5461  {
5462  printfPQExpBuffer(errorMessage,
5463  libpq_gettext("extra key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5464  keyword);
5465  return false;
5466  }
5467  /* Cut off keyword, advance to value */
5468  *p++ = '\0';
5469  value = p;
5470  }
5471  else if (*p == '&' || *p == '\0')
5472  {
5473  /*
5474  * If not at the end, cut off value and advance; leave p
5475  * pointing to start of the next parameter, if any.
5476  */
5477  if (*p != '\0')
5478  *p++ = '\0';
5479  /* Was there '=' at all? */
5480  if (value == NULL)
5481  {
5482  printfPQExpBuffer(errorMessage,
5483  libpq_gettext("missing key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5484  keyword);
5485  return false;
5486  }
5487  /* Got keyword and value, go process them. */
5488  break;
5489  }
5490  else
5491  ++p; /* Advance over all other bytes. */
5492  }
5493 
5494  keyword = conninfo_uri_decode(keyword, errorMessage);
5495  if (keyword == NULL)
5496  {
5497  /* conninfo_uri_decode already set an error message */
5498  return false;
5499  }
5500  value = conninfo_uri_decode(value, errorMessage);
5501  if (value == NULL)
5502  {
5503  /* conninfo_uri_decode already set an error message */
5504  free(keyword);
5505  return false;
5506  }
5507  malloced = true;
5508 
5509  /*
5510  * Special keyword handling for improved JDBC compatibility.
5511  */
5512  if (strcmp(keyword, "ssl") == 0 &&
5513  strcmp(value, "true") == 0)
5514  {
5515  free(keyword);
5516  free(value);
5517  malloced = false;
5518 
5519  keyword = "sslmode";
5520  value = "require";
5521  }
5522 
5523  /*
5524  * Store the value if the corresponding option exists; ignore
5525  * otherwise. At this point both keyword and value are not
5526  * URI-encoded.
5527  */
5528  if (!conninfo_storeval(connOptions, keyword, value,
5529  errorMessage, true, false))
5530  {
5531  /* Insert generic message if conninfo_storeval didn't give one. */
5532  if (errorMessage->len == 0)
5533  printfPQExpBuffer(errorMessage,
5534  libpq_gettext("invalid URI query parameter: \"%s\"\n"),
5535  keyword);
5536  /* And fail. */
5537  if (malloced)
5538  {
5539  free(keyword);
5540  free(value);
5541  }
5542  return false;
5543  }
5544 
5545  if (malloced)
5546  {
5547  free(keyword);
5548  free(value);
5549  }
5550 
5551  /* Proceed to next key=value pair, if any */
5552  params = p;
5553  }
5554 
5555  return true;
5556 }
static struct @76 value
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_storeval(PQconninfoOption *connOptions, const char *keyword, const char *value, PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode)
Definition: fe-connect.c:5686
static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
Definition: fe-connect.c:5571
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
#define libpq_gettext(x)
Definition: libpq-int.h:689
static void default_threadlock ( int  acquire)
static

Definition at line 6408 of file fe-connect.c.

References NULL, pthread_mutex_init(), pthread_mutex_lock(), and pthread_mutex_unlock().

Referenced by PQregisterThreadLock().

6409 {
6410 #ifdef ENABLE_THREAD_SAFETY
6411 #ifndef WIN32
6412  static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
6413 #else
6414  static pthread_mutex_t singlethread_lock = NULL;
6415  static long mutex_initlock = 0;
6416 
6417  if (singlethread_lock == NULL)
6418  {
6419  while (InterlockedExchange(&mutex_initlock, 1) == 1)
6420  /* loop, another thread own the lock */ ;
6421  if (singlethread_lock == NULL)
6422  {
6423  if (pthread_mutex_init(&singlethread_lock, NULL))
6424  PGTHREAD_ERROR("failed to initialize mutex");
6425  }
6426  InterlockedExchange(&mutex_initlock, 0);
6427  }
6428 #endif
6429  if (acquire)
6430  {
6431  if (pthread_mutex_lock(&singlethread_lock))
6432  PGTHREAD_ERROR("failed to lock mutex");
6433  }
6434  else
6435  {
6436  if (pthread_mutex_unlock(&singlethread_lock))
6437  PGTHREAD_ERROR("failed to unlock mutex");
6438  }
6439 #endif
6440 }
CRITICAL_SECTION * pthread_mutex_t
Definition: pthread-win32.h:8
int pthread_mutex_init(pthread_mutex_t *mp, void *attr)
Definition: pthread-win32.c:36
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:46
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:55
#define NULL
Definition: c.h:226
static void defaultNoticeProcessor ( void *  arg,
const char *  message 
)
static

Definition at line 6174 of file fe-connect.c.

Referenced by makeEmptyPGconn().

6175 {
6176  (void) arg; /* not used */
6177  /* Note: we expect the supplied string to end with a newline already. */
6178  fprintf(stderr, "%s", message);
6179 }
void * arg
static void defaultNoticeReceiver ( void *  arg,
const PGresult res 
)
static

Definition at line 6159 of file fe-connect.c.

References pg_result::noticeHooks, PGNoticeHooks::noticeProc, PGNoticeHooks::noticeProcArg, NULL, and PQresultErrorMessage().

Referenced by makeEmptyPGconn().

6160 {
6161  (void) arg; /* not used */
6162  if (res->noticeHooks.noticeProc != NULL)
6164  PQresultErrorMessage(res));
6165 }
PGNoticeHooks noticeHooks
Definition: libpq-int.h:188
void * noticeProcArg
Definition: libpq-int.h:157
PQnoticeProcessor noticeProc
Definition: libpq-int.h:156
#define NULL
Definition: c.h:226
char * PQresultErrorMessage(const PGresult *res)
Definition: fe-exec.c:2612
void * arg
static bool fillPGconn ( PGconn conn,
PQconninfoOption connOptions 
)
static

Definition at line 697 of file fe-connect.c.

References conninfo_getval(), _internalPQconninfoOption::connofs, pg_conn::errorMessage, free, _internalPQconninfoOption::keyword, libpq_gettext, NULL, and printfPQExpBuffer().

Referenced by connectOptions1(), and PQconnectStartParams().

698 {
700 
701  for (option = PQconninfoOptions; option->keyword; option++)
702  {
703  if (option->connofs >= 0)
704  {
705  const char *tmp = conninfo_getval(connOptions, option->keyword);
706 
707  if (tmp)
708  {
709  char **connmember = (char **) ((char *) conn + option->connofs);
710 
711  if (*connmember)
712  free(*connmember);
713  *connmember = strdup(tmp);
714  if (*connmember == NULL)
715  {
717  libpq_gettext("out of memory\n"));
718  return false;
719  }
720  }
721  }
722  }
723 
724  return true;
725 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:167
PQExpBufferData errorMessage
Definition: libpq-int.h:498
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
static const char * conninfo_getval(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5660
#define libpq_gettext(x)
Definition: libpq-int.h:689
static void freePGconn ( PGconn conn)
static

Definition at line 3256 of file fe-connect.c.

References pg_conn::appname, pg_conn::client_encoding_initial, conn, PGEventConnDestroy::conn, pg_conn::connect_timeout, pg_conn::connhost, pg_conn::dbName, pg_conn::errorMessage, pg_conn::events, pg_conn::fbappname, free, pg_conn_host::host, i, pg_conn::inBuffer, pg_conn::keepalives, pg_conn::keepalives_count, pg_conn::keepalives_idle, pg_conn::keepalives_interval, pg_conn::last_query, PGEvent::name, pg_conn::nconnhost, pg_conn::nEvents, NULL, pg_conn::outBuffer, PGEvent::passThrough, pg_conn_host::password, PGEVT_CONNDESTROY, pg_conn::pghost, pg_conn::pghostaddr, pg_conn::pgoptions, pg_conn::pgpass, pg_conn::pgpassfile, pg_conn::pgport, pg_conn::pgtty, pg_conn::pguser, pg_conn_host::port, PGEvent::proc, pg_conn::replication, pg_conn::requirepeer, pg_conn::rowBuf, pg_conn::sslcert, pg_conn::sslcompression, pg_conn::sslcrl, pg_conn::sslkey, pg_conn::sslmode, pg_conn::sslrootcert, pg_conn::target_session_attrs, termPQExpBuffer(), and pg_conn::workBuffer.

Referenced by makeEmptyPGconn(), and PQfinish().

3257 {
3258  int i;
3259 
3260  /* let any event procs clean up their state data */
3261  for (i = 0; i < conn->nEvents; i++)
3262  {
3263  PGEventConnDestroy evt;
3264 
3265  evt.conn = conn;
3266  (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
3267  conn->events[i].passThrough);
3268  free(conn->events[i].name);
3269  }
3270 
3271  /* clean up pg_conn_host structures */
3272  if (conn->connhost != NULL)
3273  {
3274  for (i = 0; i < conn->nconnhost; ++i)
3275  {
3276  if (conn->connhost[i].host != NULL)
3277  free(conn->connhost[i].host);
3278  if (conn->connhost[i].port != NULL)
3279  free(conn->connhost[i].port);
3280  if (conn->connhost[i].password != NULL)
3281  free(conn->connhost[i].password);
3282  }
3283  free(conn->connhost);
3284  }
3285 
3286  if (conn->client_encoding_initial)
3288  if (conn->events)
3289  free(conn->events);
3290  if (conn->pghost)
3291  free(conn->pghost);
3292  if (conn->pghostaddr)
3293  free(conn->pghostaddr);
3294  if (conn->pgport)
3295  free(conn->pgport);
3296  if (conn->pgtty)
3297  free(conn->pgtty);
3298  if (conn->connect_timeout)
3299  free(conn->connect_timeout);
3300  if (conn->pgoptions)
3301  free(conn->pgoptions);
3302  if (conn->appname)
3303  free(conn->appname);
3304  if (conn->fbappname)
3305  free(conn->fbappname);
3306  if (conn->dbName)
3307  free(conn->dbName);
3308  if (conn->replication)
3309  free(conn->replication);
3310  if (conn->pguser)
3311  free(conn->pguser);
3312  if (conn->pgpass)
3313  free(conn->pgpass);
3314  if (conn->pgpassfile)
3315  free(conn->pgpassfile);
3316  if (conn->keepalives)
3317  free(conn->keepalives);
3318  if (conn->keepalives_idle)
3319  free(conn->keepalives_idle);
3320  if (conn->keepalives_interval)
3321  free(conn->keepalives_interval);
3322  if (conn->keepalives_count)
3323  free(conn->keepalives_count);
3324  if (conn->sslmode)
3325  free(conn->sslmode);
3326  if (conn->sslcert)
3327  free(conn->sslcert);
3328  if (conn->sslkey)
3329  free(conn->sslkey);
3330  if (conn->sslrootcert)
3331  free(conn->sslrootcert);
3332  if (conn->sslcrl)
3333  free(conn->sslcrl);
3334  if (conn->sslcompression)
3335  free(conn->sslcompression);
3336  if (conn->requirepeer)
3337  free(conn->requirepeer);
3338 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
3339  if (conn->krbsrvname)
3340  free(conn->krbsrvname);
3341 #endif
3342 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
3343  if (conn->gsslib)
3344  free(conn->gsslib);
3345 #endif
3346  /* Note that conn->Pfdebug is not ours to close or free */
3347  if (conn->last_query)
3348  free(conn->last_query);
3349  if (conn->inBuffer)
3350  free(conn->inBuffer);
3351  if (conn->outBuffer)
3352  free(conn->outBuffer);
3353  if (conn->rowBuf)
3354  free(conn->rowBuf);
3355  if (conn->target_session_attrs)
3356  free(conn->target_session_attrs);
3357  termPQExpBuffer(&conn->errorMessage);
3358  termPQExpBuffer(&conn->workBuffer);
3359 
3360  free(conn);
3361 
3362 #ifdef WIN32
3363  WSACleanup();
3364 #endif
3365 }
PGEvent * events
Definition: libpq-int.h:375
char * replication
Definition: libpq-int.h:343
char * pgpassfile
Definition: libpq-int.h:346
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
PQExpBufferData workBuffer
Definition: libpq-int.h:501
char * requirepeer
Definition: libpq-int.h:359
char * host
Definition: libpq-int.h:309
char * dbName
Definition: libpq-int.h:342
char * keepalives
Definition: libpq-int.h:347
char * keepalives_idle
Definition: libpq-int.h:348
char * client_encoding_initial
Definition: libpq-int.h:338
char * sslkey
Definition: libpq-int.h:355
char * sslcompression
Definition: libpq-int.h:354
PGconn * conn
Definition: streamutil.c:45
char * connect_timeout
Definition: libpq-int.h:337
pg_conn_host * connhost
Definition: libpq-int.h:399
char * keepalives_interval
Definition: libpq-int.h:349
char * appname
Definition: libpq-int.h:340
char * target_session_attrs
Definition: libpq-int.h:365
char * last_query
Definition: libpq-int.h:384
PGdataValue * rowBuf
Definition: libpq-int.h:450
char * pguser
Definition: libpq-int.h:344
char * inBuffer
Definition: libpq-int.h:433
char * sslmode
Definition: libpq-int.h:353
PQExpBufferData errorMessage
Definition: libpq-int.h:498
char * sslcert
Definition: libpq-int.h:356
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
char * pgoptions
Definition: libpq-int.h:339
char * pgpass
Definition: libpq-int.h:345
char * sslrootcert
Definition: libpq-int.h:357
PGEventProc proc
Definition: libpq-int.h:162
char * outBuffer
Definition: libpq-int.h:440
char * pghostaddr
Definition: libpq-int.h:331
int nEvents
Definition: libpq-int.h:376
int i
void * passThrough
Definition: libpq-int.h:164
char * fbappname
Definition: libpq-int.h:341
char * port
Definition: libpq-int.h:311
char * pgport
Definition: libpq-int.h:334
int nconnhost
Definition: libpq-int.h:397
char * name
Definition: libpq-int.h:163
char * sslcrl
Definition: libpq-int.h:358
char * keepalives_count
Definition: libpq-int.h:351
char * pghost
Definition: libpq-int.h:326
char * pgtty
Definition: libpq-int.h:335
char * password
Definition: libpq-int.h:313
static bool get_hexdigit ( char  digit,
int *  value 
)
static

Definition at line 5639 of file fe-connect.c.

Referenced by conninfo_uri_decode().

5640 {
5641  if ('0' <= digit && digit <= '9')
5642  *value = digit - '0';
5643  else if ('A' <= digit && digit <= 'F')
5644  *value = digit - 'A' + 10;
5645  else if ('a' <= digit && digit <= 'f')
5646  *value = digit - 'a' + 10;
5647  else
5648  return false;
5649 
5650  return true;
5651 }
static struct @76 value
static int internal_cancel ( SockAddr raddr,
int  be_pid,
int  be_key,
char *  errbuf,
int  errbufsize 
)
static

Definition at line 3689 of file fe-connect.c.

References SockAddr::addr, CANCEL_REQUEST_CODE, closesocket, connect, EINTR, FALSE, PGINVALID_SOCKET, recv, SockAddr::salen, send, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, socket, strlcpy(), and TRUE.

Referenced by PQcancel(), and PQrequestCancel().

3691 {
3692  int save_errno = SOCK_ERRNO;
3693  pgsocket tmpsock = PGINVALID_SOCKET;
3694  char sebuf[256];
3695  int maxlen;
3696  struct
3697  {
3698  uint32 packetlen;
3700  } crp;
3701 
3702  /*
3703  * We need to open a temporary connection to the postmaster. Do this with
3704  * only kernel calls.
3705  */
3706  if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
3707  {
3708  strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
3709  goto cancel_errReturn;
3710  }
3711 retry3:
3712  if (connect(tmpsock, (struct sockaddr *) & raddr->addr,
3713  raddr->salen) < 0)
3714  {
3715  if (SOCK_ERRNO == EINTR)
3716  /* Interrupted system call - we'll just try again */
3717  goto retry3;
3718  strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
3719  goto cancel_errReturn;
3720  }
3721 
3722  /*
3723  * We needn't set nonblocking I/O or NODELAY options here.
3724  */
3725 
3726  /* Create and send the cancel request packet. */
3727 
3728  crp.packetlen = htonl((uint32) sizeof(crp));
3729  crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE);
3730  crp.cp.backendPID = htonl(be_pid);
3731  crp.cp.cancelAuthCode = htonl(be_key);
3732 
3733 retry4:
3734  if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
3735  {
3736  if (SOCK_ERRNO == EINTR)
3737  /* Interrupted system call - we'll just try again */
3738  goto retry4;
3739  strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
3740  goto cancel_errReturn;
3741  }
3742 
3743  /*
3744  * Wait for the postmaster to close the connection, which indicates that
3745  * it's processed the request. Without this delay, we might issue another
3746  * command only to find that our cancel zaps that command instead of the
3747  * one we thought we were canceling. Note we don't actually expect this
3748  * read to obtain any data, we are just waiting for EOF to be signaled.
3749  */
3750 retry5:
3751  if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
3752  {
3753  if (SOCK_ERRNO == EINTR)
3754  /* Interrupted system call - we'll just try again */
3755  goto retry5;
3756  /* we ignore other error conditions */
3757  }
3758 
3759  /* All done */
3760  closesocket(tmpsock);
3761  SOCK_ERRNO_SET(save_errno);
3762  return TRUE;
3763 
3764 cancel_errReturn:
3765 
3766  /*
3767  * Make sure we don't overflow the error buffer. Leave space for the \n at
3768  * the end, and for the terminating zero.
3769  */
3770  maxlen = errbufsize - strlen(errbuf) - 2;
3771  if (maxlen >= 0)
3772  {
3773  strncat(errbuf, SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)),
3774  maxlen);
3775  strcat(errbuf, "\n");
3776  }
3777  if (tmpsock != PGINVALID_SOCKET)
3778  closesocket(tmpsock);
3779  SOCK_ERRNO_SET(save_errno);
3780  return FALSE;
3781 }
#define send(s, buf, len, flags)
Definition: win32.h:386
#define connect(s, name, namelen)
Definition: win32.h:383
#define closesocket
Definition: port.h:328
struct sockaddr_storage addr
Definition: pqcomm.h:64
#define socket(af, type, protocol)
Definition: win32.h:379
#define recv(s, buf, len, flags)
Definition: win32.h:385
#define SOCK_STRERROR
Definition: libpq-int.h:703
#define FALSE
Definition: c.h:218
#define SOCK_ERRNO
Definition: libpq-int.h:702
unsigned int uint32
Definition: c.h:265
int pgsocket
Definition: port.h:22
ACCEPT_TYPE_ARG3 salen
Definition: pqcomm.h:65
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:704
#define PGINVALID_SOCKET
Definition: port.h:24
#define EINTR
Definition: win32.h:295
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:187
ProtocolVersion MsgType
Definition: pqcomm.h:115
#define TRUE
Definition: c.h:214
static PGPing internal_ping ( PGconn conn)
static

Definition at line 3095 of file fe-connect.c.

References pg_conn::auth_req_received, connectDBComplete(), CONNECTION_BAD, ERRCODE_CANNOT_CONNECT_NOW, pg_conn::last_sqlstate, pg_conn::options_valid, PQPING_NO_ATTEMPT, PQPING_NO_RESPONSE, PQPING_OK, PQPING_REJECT, and pg_conn::status.

Referenced by PQping(), and PQpingParams().

3096 {
3097  /* Say "no attempt" if we never got to PQconnectPoll */
3098  if (!conn || !conn->options_valid)
3099  return PQPING_NO_ATTEMPT;
3100 
3101  /* Attempt to complete the connection */
3102  if (conn->status != CONNECTION_BAD)
3103  (void) connectDBComplete(conn);
3104 
3105  /* Definitely OK if we succeeded */
3106  if (conn->status != CONNECTION_BAD)
3107  return PQPING_OK;
3108 
3109  /*
3110  * Here begins the interesting part of "ping": determine the cause of the
3111  * failure in sufficient detail to decide what to return. We do not want
3112  * to report that the server is not up just because we didn't have a valid
3113  * password, for example. In fact, any sort of authentication request
3114  * implies the server is up. (We need this check since the libpq side of
3115  * things might have pulled the plug on the connection before getting an
3116  * error as such from the postmaster.)
3117  */
3118  if (conn->auth_req_received)
3119  return PQPING_OK;
3120 
3121  /*
3122  * If we failed to get any ERROR response from the postmaster, report
3123  * PQPING_NO_RESPONSE. This result could be somewhat misleading for a
3124  * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
3125  * out of support. Another corner case where the server could return a
3126  * failure without a SQLSTATE is fork failure, but NO_RESPONSE isn't
3127  * totally unreasonable for that anyway. We expect that every other
3128  * failure case in a modern server will produce a report with a SQLSTATE.
3129  *
3130  * NOTE: whenever we get around to making libpq generate SQLSTATEs for
3131  * client-side errors, we should either not store those into
3132  * last_sqlstate, or add an extra flag so we can tell client-side errors
3133  * apart from server-side ones.
3134  */
3135  if (strlen(conn->last_sqlstate) != 5)
3136  return PQPING_NO_RESPONSE;
3137 
3138  /*
3139  * Report PQPING_REJECT if server says it's not accepting connections. (We
3140  * distinguish this case mainly for the convenience of pg_ctl.)
3141  */
3142  if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
3143  return PQPING_REJECT;
3144 
3145  /*
3146  * Any other SQLSTATE can be taken to indicate that the server is up.
3147  * Presumably it didn't like our username, password, or database name; or
3148  * perhaps it had some transient failure, but that should not be taken as
3149  * meaning "it's down".
3150  */
3151  return PQPING_OK;
3152 }
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1715
bool options_valid
Definition: libpq-int.h:386
#define ERRCODE_CANNOT_CONNECT_NOW
Definition: fe-connect.c:100
ConnStatusType status
Definition: libpq-int.h:380
bool auth_req_received
Definition: libpq-int.h:408
char last_sqlstate[6]
Definition: libpq-int.h:385
static PGconn * makeEmptyPGconn ( void  )
static

Definition at line 3160 of file fe-connect.c.

References pg_conn::asyncStatus, pg_conn::auth_req_received, pg_conn::client_encoding, conn, CONNECTION_BAD, defaultNoticeProcessor(), defaultNoticeReceiver(), pg_conn::errorMessage, freePGconn(), pg_conn::inBuffer, pg_conn::inBufSize, initPQExpBuffer(), malloc, MemSet, pg_conn::nonblocking, pg_conn::noticeHooks, PGNoticeHooks::noticeProc, PGNoticeHooks::noticeRec, NULL, pg_conn::options_valid, pg_conn::outBuffer, pg_conn::outBufSize, pg_conn::password_needed, PG_SQL_ASCII, PGASYNC_IDLE, PGINVALID_SOCKET, pg_conn::pgpassfile_used, PQERRORS_DEFAULT, PQExpBufferBroken, PQSHOW_CONTEXT_ERRORS, PQTRANS_IDLE, pg_conn::rowBuf, pg_conn::rowBufLen, pg_conn::setenv_state, SETENV_STATE_IDLE, pg_conn::show_context, pg_conn::sock, pg_conn::status, pg_conn::std_strings, pg_conn::verbosity, pg_conn::workBuffer, and pg_conn::xactStatus.

Referenced by PQconnectStart(), PQconnectStartParams(), and PQsetdbLogin().

3161 {
3162  PGconn *conn;
3163 
3164 #ifdef WIN32
3165 
3166  /*
3167  * Make sure socket support is up and running.
3168  */
3169  WSADATA wsaData;
3170 
3171  if (WSAStartup(MAKEWORD(1, 1), &wsaData))
3172  return NULL;
3173  WSASetLastError(0);
3174 #endif
3175 
3176  conn = (PGconn *) malloc(sizeof(PGconn));
3177  if (conn == NULL)
3178  {
3179 #ifdef WIN32
3180  WSACleanup();
3181 #endif
3182  return conn;
3183  }
3184 
3185  /* Zero all pointers and booleans */
3186  MemSet(conn, 0, sizeof(PGconn));
3187 
3188  /* install default notice hooks */
3191 
3192  conn->status = CONNECTION_BAD;
3193  conn->asyncStatus = PGASYNC_IDLE;
3194  conn->xactStatus = PQTRANS_IDLE;
3195  conn->options_valid = false;
3196  conn->nonblocking = false;
3198  conn->client_encoding = PG_SQL_ASCII;
3199  conn->std_strings = false; /* unless server says differently */
3200  conn->verbosity = PQERRORS_DEFAULT;
3202  conn->sock = PGINVALID_SOCKET;
3203  conn->auth_req_received = false;
3204  conn->password_needed = false;
3205  conn->pgpassfile_used = false;
3206 #ifdef USE_SSL
3207  conn->allow_ssl_try = true;
3208  conn->wait_ssl_try = false;
3209  conn->ssl_in_use = false;
3210 #endif
3211 
3212  /*
3213  * We try to send at least 8K at a time, which is the usual size of pipe
3214  * buffers on Unix systems. That way, when we are sending a large amount
3215  * of data, we avoid incurring extra kernel context swaps for partial
3216  * bufferloads. The output buffer is initially made 16K in size, and we
3217  * try to dump it after accumulating 8K.
3218  *
3219  * With the same goal of minimizing context swaps, the input buffer will
3220  * be enlarged anytime it has less than 8K free, so we initially allocate
3221  * twice that.
3222  */
3223  conn->inBufSize = 16 * 1024;
3224  conn->inBuffer = (char *) malloc(conn->inBufSize);
3225  conn->outBufSize = 16 * 1024;
3226  conn->outBuffer = (char *) malloc(conn->outBufSize);
3227  conn->rowBufLen = 32;
3228  conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
3229  initPQExpBuffer(&conn->errorMessage);
3230  initPQExpBuffer(&conn->workBuffer);
3231 
3232  if (conn->inBuffer == NULL ||
3233  conn->outBuffer == NULL ||
3234  conn->rowBuf == NULL ||
3235  PQExpBufferBroken(&conn->errorMessage) ||
3236  PQExpBufferBroken(&conn->workBuffer))
3237  {
3238  /* out of memory already :-( */
3239  freePGconn(conn);
3240  conn = NULL;
3241  }
3242 
3243  return conn;
3244 }
PGContextVisibility show_context
Definition: libpq-int.h:429
int rowBufLen
Definition: libpq-int.h:451
bool password_needed
Definition: libpq-int.h:410
PQExpBufferData workBuffer
Definition: libpq-int.h:501
#define MemSet(start, val, len)
Definition: c.h:853
bool pgpassfile_used
Definition: libpq-int.h:411
#define malloc(a)
Definition: header.h:45
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
PGSetenvStatusType setenv_state
Definition: libpq-int.h:417
PGconn * conn
Definition: streamutil.c:45
int inBufSize
Definition: libpq-int.h:434
PGNoticeHooks noticeHooks
Definition: libpq-int.h:372
PGVerbosity verbosity
Definition: libpq-int.h:428
PQnoticeReceiver noticeRec
Definition: libpq-int.h:154
PGdataValue * rowBuf
Definition: libpq-int.h:450
pgsocket sock
Definition: libpq-int.h:402
#define PGINVALID_SOCKET
Definition: port.h:24
char * inBuffer
Definition: libpq-int.h:433
PQnoticeProcessor noticeProc
Definition: libpq-int.h:156
static void freePGconn(PGconn *conn)
Definition: fe-connect.c:3256
PQExpBufferData errorMessage
Definition: libpq-int.h:498
bool std_strings
Definition: libpq-int.h:427
bool options_valid
Definition: libpq-int.h:386
int outBufSize
Definition: libpq-int.h:441
#define NULL
Definition: c.h:226
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
ConnStatusType status
Definition: libpq-int.h:380
bool auth_req_received
Definition: libpq-int.h:408
char * outBuffer
Definition: libpq-int.h:440
bool nonblocking
Definition: libpq-int.h:387
static void defaultNoticeProcessor(void *arg, const char *message)
Definition: fe-connect.c:6174
int client_encoding
Definition: libpq-int.h:426
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
static void defaultNoticeReceiver(void *arg, const PGresult *res)
Definition: fe-connect.c:6159
PGTransactionStatusType xactStatus
Definition: libpq-int.h:382
static PQconninfoOption * parse_connection_string ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

Definition at line 4666 of file fe-connect.c.

References conninfo_parse(), conninfo_uri_parse(), and uri_prefix_length().

Referenced by connectOptions1(), conninfo_array_parse(), and PQconninfoParse().

4668 {
4669  /* Parse as URI if connection string matches URI prefix */
4670  if (uri_prefix_length(connstr) != 0)
4671  return conninfo_uri_parse(connstr, errorMessage, use_defaults);
4672 
4673  /* Parse as default otherwise */
4674  return conninfo_parse(connstr, errorMessage, use_defaults);
4675 }
static PQconninfoOption * conninfo_parse(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4720
static int uri_prefix_length(const char *connstr)
Definition: fe-connect.c:4686
static PQconninfoOption * conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:5143
static char * connstr
Definition: pg_dumpall.c:67
static int parseServiceFile ( const char *  serviceFile,
const char *  service,
PQconninfoOption options,
PQExpBuffer  errorMessage,
bool group_found 
)
static

Definition at line 4429 of file fe-connect.c.

References buf, i, _PQconninfoOption::keyword, libpq_gettext, MAXBUFSIZE, NULL, printfPQExpBuffer(), _PQconninfoOption::val, and val.

Referenced by parseServiceInfo().

4434 {
4435  int linenr = 0,
4436  i;
4437  FILE *f;
4438  char buf[MAXBUFSIZE],
4439  *line;
4440 
4441  f = fopen(serviceFile, "r");
4442  if (f == NULL)
4443  {
4444  printfPQExpBuffer(errorMessage, libpq_gettext("service file \"%s\" not found\n"),
4445  serviceFile);
4446  return 1;
4447  }
4448 
4449  while ((line = fgets(buf, sizeof(buf), f)) != NULL)
4450  {
4451  linenr++;
4452 
4453  if (strlen(line) >= sizeof(buf) - 1)
4454  {
4455  fclose(f);
4456  printfPQExpBuffer(errorMessage,
4457  libpq_gettext("line %d too long in service file \"%s\"\n"),
4458  linenr,
4459  serviceFile);
4460  return 2;
4461  }
4462 
4463  /* ignore EOL at end of line */
4464  if (strlen(line) && line[strlen(line) - 1] == '\n')
4465  line[strlen(line) - 1] = 0;
4466 
4467  /* ignore leading blanks */
4468  while (*line && isspace((unsigned char) line[0]))
4469  line++;
4470 
4471  /* ignore comments and empty lines */
4472  if (strlen(line) == 0 || line[0] == '#')
4473  continue;
4474 
4475  /* Check for right groupname */
4476  if (line[0] == '[')
4477  {
4478  if (*group_found)
4479  {
4480  /* group info already read */
4481  fclose(f);
4482  return 0;
4483  }
4484 
4485  if (strncmp(line + 1, service, strlen(service)) == 0 &&
4486  line[strlen(service) + 1] == ']')
4487  *group_found = true;
4488  else
4489  *group_found = false;
4490  }
4491  else
4492  {
4493  if (*group_found)
4494  {
4495  /*
4496  * Finally, we are in the right group and can parse the line
4497  */
4498  char *key,
4499  *val;
4500  bool found_keyword;
4501 
4502 #ifdef USE_LDAP
4503  if (strncmp(line, "ldap", 4) == 0)
4504  {
4505  int rc = ldapServiceLookup(line, options, errorMessage);
4506 
4507  /* if rc = 2, go on reading for fallback */
4508  switch (rc)
4509  {
4510  case 0:
4511  fclose(f);
4512  return 0;
4513  case 1:
4514  case 3:
4515  fclose(f);
4516  return 3;
4517  case 2:
4518  continue;
4519  }
4520  }
4521 #endif
4522 
4523  key = line;
4524  val = strchr(line, '=');
4525  if (val == NULL)
4526  {
4527  printfPQExpBuffer(errorMessage,
4528  libpq_gettext("syntax error in service file \"%s\", line %d\n"),
4529  serviceFile,
4530  linenr);
4531  fclose(f);
4532  return 3;
4533  }
4534  *val++ = '\0';
4535 
4536  if (strcmp(key, "service") == 0)
4537  {
4538  printfPQExpBuffer(errorMessage,
4539  libpq_gettext("nested service specifications not supported in service file \"%s\", line %d\n"),
4540  serviceFile,
4541  linenr);
4542  fclose(f);
4543  return 3;
4544  }
4545 
4546  /*
4547  * Set the parameter --- but don't override any previous
4548  * explicit setting.
4549  */
4550  found_keyword = false;
4551  for (i = 0; options[i].keyword; i++)
4552  {
4553  if (strcmp(options[i].keyword, key) == 0)
4554  {
4555  if (options[i].val == NULL)
4556  options[i].val = strdup(val);
4557  if (!options[i].val)
4558  {
4559  printfPQExpBuffer(errorMessage,
4560  libpq_gettext("out of memory\n"));
4561  fclose(f);
4562  return 3;
4563  }
4564  found_keyword = true;
4565  break;
4566  }
4567  }
4568 
4569  if (!found_keyword)
4570  {
4571  printfPQExpBuffer(errorMessage,
4572  libpq_gettext("syntax error in service file \"%s\", line %d\n"),
4573  serviceFile,
4574  linenr);
4575  fclose(f);
4576  return 3;
4577  }
4578  }
4579  }
4580  }
4581 
4582  fclose(f);
4583 
4584  return 0;
4585 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define MAXBUFSIZE
Definition: fe-connect.c:4357
static char * buf
Definition: pg_test_fsync.c:65
#define NULL
Definition: c.h:226
int i
long val
Definition: informix.c:689
#define libpq_gettext(x)
Definition: libpq-int.h:689
static int parseServiceInfo ( PQconninfoOption options,
PQExpBuffer  errorMessage 
)
static

Definition at line 4360 of file fe-connect.c.

References conninfo_getval(), libpq_gettext, MAXPGPATH, NULL, parseServiceFile(), pqGetHomeDirectory(), printfPQExpBuffer(), snprintf(), status(), and strlcpy().

Referenced by conninfo_add_defaults().

4361 {
4362  const char *service = conninfo_getval(options, "service");
4363  char serviceFile[MAXPGPATH];
4364  char *env;
4365  bool group_found = false;
4366  int status;
4367  struct stat stat_buf;
4368 
4369  /*
4370  * We have to special-case the environment variable PGSERVICE here, since
4371  * this is and should be called before inserting environment defaults for
4372  * other connection options.
4373  */
4374  if (service == NULL)
4375  service = getenv("PGSERVICE");
4376 
4377  if (service == NULL)
4378  return 0;
4379 
4380  if ((env = getenv("PGSERVICEFILE")) != NULL)
4381  strlcpy(serviceFile, env, sizeof(serviceFile));
4382  else
4383  {
4384  char homedir[MAXPGPATH];
4385 
4386  if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
4387  {
4388  printfPQExpBuffer(errorMessage, libpq_gettext("could not get home directory to locate service definition file"));
4389  return 1;
4390  }
4391  snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
4392  errno = 0;
4393  if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4394  goto next_file;
4395  }
4396 
4397  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4398  if (group_found || status != 0)
4399  return status;
4400 
4401 next_file:
4402 
4403  /*
4404  * This could be used by any application so we can't use the binary
4405  * location to find our config files.
4406  */
4407  snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
4408  getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
4409  errno = 0;
4410  if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4411  goto last_file;
4412 
4413  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4414  if (status != 0)
4415  return status;
4416 
4417 last_file:
4418  if (!group_found)
4419  {
4420  printfPQExpBuffer(errorMessage,
4421  libpq_gettext("definition of service \"%s\" not found\n"), service);
4422  return 3;
4423  }
4424 
4425  return 0;
4426 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
struct stat stat_buf
Definition: pg_standby.c:101
#define MAXPGPATH
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:226
static int parseServiceFile(const char *serviceFile, const char *service, PQconninfoOption *options, PQExpBuffer errorMessage, bool *group_found)
Definition: fe-connect.c:4429
static const char * conninfo_getval(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5660
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:6379
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:222
#define libpq_gettext(x)
Definition: libpq-int.h:689
static char * passwordFromFile ( char *  hostname,
char *  port,
char *  dbname,
char *  username,
char *  pgpassfile 
)
static

Definition at line 6223 of file fe-connect.c.

References buf, DEFAULT_PGSOCKET_DIR, DefaultHost, is_absolute_path, libpq_gettext, LINELEN, NULL, pwdfMatchesString(), S_IRWXG, and S_IRWXO.

Referenced by connectOptions2().

6225 {
6226  FILE *fp;
6227  struct stat stat_buf;
6228 
6229 #define LINELEN NAMEDATALEN*5
6230  char buf[LINELEN];
6231 
6232  if (dbname == NULL || strlen(dbname) == 0)
6233  return NULL;
6234 
6235  if (username == NULL || strlen(username) == 0)
6236  return NULL;
6237 
6238  /* 'localhost' matches pghost of '' or the default socket directory */
6239  if (hostname == NULL)
6241  else if (is_absolute_path(hostname))
6242 
6243  /*
6244  * We should probably use canonicalize_path(), but then we have to
6245  * bring path.c into libpq, and it doesn't seem worth it.
6246  */
6247  if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
6249 
6250  if (port == NULL)
6251  port = DEF_PGPORT_STR;
6252 
6253  /* If password file cannot be opened, ignore it. */
6254  if (stat(pgpassfile, &stat_buf) != 0)
6255  return NULL;
6256 
6257 #ifndef WIN32
6258  if (!S_ISREG(stat_buf.st_mode))
6259  {
6260  fprintf(stderr,
6261  libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
6262  pgpassfile);
6263  return NULL;
6264  }
6265 
6266  /* If password file is insecure, alert the user and ignore it. */
6267  if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
6268  {
6269  fprintf(stderr,
6270  libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
6271  pgpassfile);
6272  return NULL;
6273  }
6274 #else
6275 
6276  /*
6277  * On Win32, the directory is protected, so we don't have to check the
6278  * file.
6279  */
6280 #endif
6281 
6282  fp = fopen(pgpassfile, "r");
6283  if (fp == NULL)
6284  return NULL;
6285 
6286  while (!feof(fp) && !ferror(fp))
6287  {
6288  char *t = buf,
6289  *ret,
6290  *p1,
6291  *p2;
6292  int len;
6293 
6294  if (fgets(buf, sizeof(buf), fp) == NULL)
6295  break;
6296 
6297  len = strlen(buf);
6298 
6299  /* Remove trailing newline */
6300  if (len > 0 && buf[len - 1] == '\n')
6301  {
6302  buf[--len] = '\0';
6303  /* Handle DOS-style line endings, too, even when not on Windows */
6304  if (len > 0 && buf[len - 1] == '\r')
6305  buf[--len] = '\0';
6306  }
6307 
6308  if (len == 0)
6309  continue;
6310 
6311  if ((t = pwdfMatchesString(t, hostname)) == NULL ||
6312  (t = pwdfMatchesString(t, port)) == NULL ||
6313  (t = pwdfMatchesString(t, dbname)) == NULL ||
6314  (t = pwdfMatchesString(t, username)) == NULL)
6315  continue;
6316 
6317  /* Found a match. */
6318  ret = strdup(t);
6319  fclose(fp);
6320 
6321  if (!ret)
6322  {
6323  /* Out of memory. XXX: an error message would be nice. */
6324  return NULL;
6325  }
6326 
6327  /* De-escape password. */
6328  for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
6329  {
6330  if (*p1 == '\\' && p1[1] != '\0')
6331  ++p1;
6332  *p2 = *p1;
6333  }
6334  *p2 = '\0';
6335 
6336  return ret;
6337  }
6338 
6339  fclose(fp);
6340  return NULL;
6341 
6342 #undef LINELEN
6343 }
#define LINELEN
struct stat stat_buf
Definition: pg_standby.c:101
static char * buf
Definition: pg_test_fsync.c:65
#define is_absolute_path(filename)
Definition: port.h:77
static int port
Definition: pg_regress.c:87
#define S_IRWXO
Definition: win32.h:484
static char * username
Definition: initdb.c:130
#define NULL
Definition: c.h:226
char * dbname
Definition: streamutil.c:41
#define DefaultHost
Definition: fe-connect.c:106
#define S_IRWXG
Definition: win32.h:480
static char * hostname
Definition: pg_regress.c:86
static char * pwdfMatchesString(char *buf, char *token)
Definition: fe-connect.c:6186
#define libpq_gettext(x)
Definition: libpq-int.h:689
#define DEFAULT_PGSOCKET_DIR
static void pgpassfileWarning ( PGconn conn)
static

Definition at line 6351 of file fe-connect.c.

References appendPQExpBuffer(), ERRCODE_INVALID_PASSWORD, pg_conn::errorMessage, libpq_gettext, pg_conn::password_needed, PG_DIAG_SQLSTATE, pg_conn::pgpassfile, pg_conn::pgpassfile_used, PQresultErrorField(), and pg_conn::result.

Referenced by PQconnectPoll().

6352 {
6353  /* If it was 'invalid authorization', add pgpassfile mention */
6354  /* only works with >= 9.0 servers */
6355  if (conn->pgpassfile_used && conn->password_needed && conn->result)
6356  {
6357  const char *sqlstate = PQresultErrorField(conn->result,
6359 
6360  if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
6362  libpq_gettext("password retrieved from file \"%s\"\n"),
6363  conn->pgpassfile);
6364  }
6365 }
char * pgpassfile
Definition: libpq-int.h:346
bool password_needed
Definition: libpq-int.h:410
bool pgpassfile_used
Definition: libpq-int.h:411
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:53
PGresult * result
Definition: libpq-int.h:454
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
PQExpBufferData errorMessage
Definition: libpq-int.h:498
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2658
#define ERRCODE_INVALID_PASSWORD
Definition: fe-connect.c:98
#define libpq_gettext(x)
Definition: libpq-int.h:689
int PQbackendPID ( const PGconn conn)

Definition at line 5986 of file fe-connect.c.

References pg_conn::be_pid, CONNECTION_OK, and pg_conn::status.

Referenced by get_prompt().

5987 {
5988  if (!conn || conn->status != CONNECTION_OK)
5989  return 0;
5990  return conn->be_pid;
5991 }
ConnStatusType status
Definition: libpq-int.h:380
int be_pid
Definition: libpq-int.h:422
int PQcancel ( PGcancel cancel,
char *  errbuf,
int  errbufsize 
)

Definition at line 3793 of file fe-connect.c.

References pg_cancel::be_key, pg_cancel::be_pid, FALSE, internal_cancel(), pg_cancel::raddr, and strlcpy().

Referenced by dblink_cancel_query(), DisconnectDatabase(), handle_sigint(), pgfdw_subxact_callback(), pgfdw_xact_callback(), ShutdownWorkersHard(), sigTermHandler(), and try_complete_step().

3794 {
3795  if (!cancel)
3796  {
3797  strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
3798  return FALSE;
3799  }
3800 
3801  return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
3802  errbuf, errbufsize);
3803 }
static int internal_cancel(SockAddr *raddr, int be_pid, int be_key, char *errbuf, int errbufsize)
Definition: fe-connect.c:3689
int be_pid
Definition: libpq-int.h:511
#define FALSE
Definition: c.h:218
int be_key
Definition: libpq-int.h:512
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
SockAddr raddr
Definition: libpq-int.h:510
int PQclientEncoding ( const PGconn conn)

Definition at line 6020 of file fe-connect.c.

References pg_conn::client_encoding, CONNECTION_OK, and pg_conn::status.

Referenced by appendStringLiteralConn(), dblink_connect(), exec_command(), main(), processSQLNamePattern(), SendQuery(), setup_connection(), and SyncVariables().

6021 {
6022  if (!conn || conn->status != CONNECTION_OK)
6023  return -1;
6024  return conn->client_encoding;
6025 }
ConnStatusType status
Definition: libpq-int.h:380
int client_encoding
Definition: libpq-int.h:426
PQconninfoOption* PQconndefaults ( void  )

Definition at line 1108 of file fe-connect.c.

References conninfo_add_defaults(), conninfo_init(), initPQExpBuffer(), NULL, PQconninfoFree(), PQExpBufferDataBroken, and termPQExpBuffer().

Referenced by check_pghost_envvar(), dblink_fdw_validator(), get_connect_string(), InitPgFdwOptions(), and main().

1109 {
1110  PQExpBufferData errorBuf;
1111  PQconninfoOption *connOptions;
1112 
1113  /* We don't actually report any errors here, but callees want a buffer */
1114  initPQExpBuffer(&errorBuf);
1115  if (PQExpBufferDataBroken(errorBuf))
1116  return NULL; /* out of memory already :-( */
1117 
1118  connOptions = conninfo_init(&errorBuf);
1119  if (connOptions != NULL)
1120  {
1121  /* pass NULL errorBuf to ignore errors */
1122  if (!conninfo_add_defaults(connOptions, NULL))
1123  {
1124  PQconninfoFree(connOptions);
1125  connOptions = NULL;
1126  }
1127  }
1128 
1129  termPQExpBuffer(&errorBuf);
1130  return connOptions;
1131 }
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4626
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5810
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
#define NULL
Definition: c.h:226
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5062
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGconn* PQconnectdb ( const char *  conninfo)

Definition at line 527 of file fe-connect.c.

References conn, connectDBComplete(), CONNECTION_BAD, PQconnectStart(), and pg_conn::status.

Referenced by dblink_connect(), get_db_conn(), libpqConnect(), and main().

528 {
529  PGconn *conn = PQconnectStart(conninfo);
530 
531  if (conn && conn->status != CONNECTION_BAD)
532  (void) connectDBComplete(conn);
533 
534  return conn;
535 }
PGconn * conn
Definition: streamutil.c:45
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1715
PGconn * PQconnectStart(const char *conninfo)
Definition: fe-connect.c:653
ConnStatusType status
Definition: libpq-int.h:380
PGconn* PQconnectdbParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)

Definition at line 471 of file fe-connect.c.

References conn, connectDBComplete(), CONNECTION_BAD, PQconnectStartParams(), and pg_conn::status.

Referenced by _connectDB(), connect_pg_server(), connectDatabase(), ConnectDatabase(), do_connect(), doConnect(), ECPGconnect(), GetConnection(), libpqrcv_connect(), main(), sql_conn(), and vacuumlo().

474 {
475  PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
476 
477  if (conn && conn->status != CONNECTION_BAD)
478  (void) connectDBComplete(conn);
479 
480  return conn;
481 
482 }
PGconn * conn
Definition: streamutil.c:45
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1715
ConnStatusType status
Definition: libpq-int.h:380
static Datum values[MAXATTR]
Definition: bootstrap.c:162
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:574
int PQconnectionNeedsPassword ( const PGconn conn)

Definition at line 5994 of file fe-connect.c.

References NULL, password, pg_conn::password_needed, and PQpass().

Referenced by _connectDB(), connectDatabase(), ConnectDatabase(), do_connect(), doConnect(), GetConnection(), main(), sql_conn(), and vacuumlo().

5995 {
5996  char *password;
5997 
5998  if (!conn)
5999  return false;
6000  password = PQpass(conn);
6001  if (conn->password_needed &&
6002  (password == NULL || password[0] == '\0'))
6003  return true;
6004  else
6005  return false;
6006 }
static char password[100]
Definition: streamutil.c:44
bool password_needed
Definition: libpq-int.h:410
char * PQpass(const PGconn *conn)
Definition: fe-connect.c:5844
#define NULL
Definition: c.h:226
int PQconnectionUsedPassword ( const PGconn conn)

Definition at line 6009 of file fe-connect.c.

References pg_conn::password_needed.

Referenced by _connectDB(), connect_pg_server(), ConnectDatabase(), and dblink_security_check().

6010 {
6011  if (!conn)
6012  return false;
6013  if (conn->password_needed)
6014  return true;
6015  else
6016  return false;
6017 }
bool password_needed
Definition: libpq-int.h:410
PostgresPollingStatusType PQconnectPoll ( PGconn conn)

Definition at line 1849 of file fe-connect.c.

References SockAddr::addr, pg_conn::addr_cur, pg_conn_host::addrlist, addrinfo::ai_addr, addrinfo::ai_addrlen, addrinfo::ai_family, addrinfo::ai_next, appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), pg_conn::appname, pg_conn::asyncStatus, AUTH_REQ_GSS_CONT, AUTH_REQ_MD5, AUTH_REQ_OK, pg_conn::auth_req_received, connect, connectFailureMessage(), CONNECTION_AUTH_OK, CONNECTION_AWAITING_RESPONSE, CONNECTION_BAD, CONNECTION_CHECK_WRITABLE, CONNECTION_CONSUME, CONNECTION_MADE, CONNECTION_NEEDED, CONNECTION_OK, CONNECTION_SETENV, CONNECTION_SSL_STARTUP, CONNECTION_STARTED, connectNoDelay(), pg_conn::connhost, PQExpBufferData::data, EINPROGRESS, EINTR, EnvironmentOptions, ERRCODE_APPNAME_UNKNOWN, pg_conn::errorMessage, EWOULDBLOCK, pg_conn::fbappname, FD_CLOEXEC, free, getpeereid(), pg_conn_host::host, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, IS_AF_UNIX, pg_conn::laddr, PQExpBufferData::len, libpq_gettext, malloc, pg_conn::md5Salt, pg_conn::nconnhost, NEGOTIATE_SSL_CODE, pg_conn::next_eo, NULL, PG_DIAG_SQLSTATE, pg_fe_sendauth(), PG_PROTOCOL, PG_PROTOCOL_MAJOR, pg_set_noblock(), PGASYNC_BUSY, PGINVALID_SOCKET, pgpassfileWarning(), PGRES_FATAL_ERROR, PGRES_POLLING_FAILED, PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PGRES_TUPLES_OK, pg_conn_host::port, pqBuildStartupPacket2(), pqBuildStartupPacket3(), pqCheckInBufferSpace(), PQclear(), PQconsumeInput(), pqDropConnection(), pqFlush(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGetnchar(), pqGetpwuid(), PQgetResult(), pqGets_append(), PQgetvalue(), PQisBusy(), PQntuples(), pqPacketSend(), pqReadData(), PQresultErrorField(), PQresultStatus(), pqsecure_initialize(), pqsecure_open_client(), PQsendQuery(), pqSetenvPoll(), pqStrerror(), printfPQExpBuffer(), pg_conn::pversion, pg_conn::raddr, release_all_addrinfo(), pg_conn::requirepeer, restoreErrorMessage(), pg_result::resultStatus, SockAddr::salen, saveErrorMessage(), pg_conn::send_appname, sendTerminateConn(), pg_conn::setenv_state, SETENV_STATE_CLIENT_ENCODING_SEND, setKeepalivesCount(), setKeepalivesIdle(), setKeepalivesInterval(), pg_conn::sigpipe_flag, pg_conn::sigpipe_so, pg_conn::sock, SOCK_ERRNO, SOCK_STRERROR, socket, pg_conn::sslmode, pg_conn::status, STATUS_OK, pg_conn::target_session_attrs, termPQExpBuffer(), useKeepalives(), val, and pg_conn::whichhost.

Referenced by connectDBComplete(), connectDBStart(), and PQresetPoll().

1850 {
1851  PGresult *res;
1852  char sebuf[256];
1853  int optval;
1854  PQExpBufferData savedMessage;
1855 
1856  if (conn == NULL)
1857  return PGRES_POLLING_FAILED;
1858 
1859  /* Get the new data */
1860  switch (conn->status)
1861  {
1862  /*
1863  * We really shouldn't have been polled in these two cases, but we
1864  * can handle it.
1865  */
1866  case CONNECTION_BAD:
1867  return PGRES_POLLING_FAILED;
1868  case CONNECTION_OK:
1869  return PGRES_POLLING_OK;
1870 
1871  /* These are reading states */
1873  case CONNECTION_AUTH_OK:
1874  {
1875  /* Load waiting data */
1876  int n = pqReadData(conn);
1877 
1878  if (n < 0)
1879  goto error_return;
1880  if (n == 0)
1881  return PGRES_POLLING_READING;
1882 
1883  break;
1884  }
1885 
1886  /* These are writing states, so we just proceed. */
1887  case CONNECTION_STARTED:
1888  case CONNECTION_MADE:
1889  break;
1890 
1891  /* We allow pqSetenvPoll to decide whether to proceed. */
1892  case CONNECTION_SETENV:
1893  break;
1894 
1895  /* Special cases: proceed without waiting. */
1897  case CONNECTION_NEEDED:
1899  case CONNECTION_CONSUME:
1900  break;
1901 
1902  default:
1904  libpq_gettext(
1905  "invalid connection state, "
1906  "probably indicative of memory corruption\n"
1907  ));
1908  goto error_return;
1909  }
1910 
1911 
1912 keep_going: /* We will come back to here until there is
1913  * nothing left to do. */
1914  switch (conn->status)
1915  {
1916  case CONNECTION_NEEDED:
1917  {
1918  /*
1919  * Try to initiate a connection to one of the addresses
1920  * returned by pg_getaddrinfo_all(). conn->addr_cur is the
1921  * next one to try. We fail when we run out of addresses.
1922  */
1923  for (;;)
1924  {
1925  struct addrinfo *addr_cur;
1926 
1927  /*
1928  * Advance to next possible host, if we've tried all of
1929  * the addresses for the current host.
1930  */
1931  if (conn->addr_cur == NULL)
1932  {
1933  if (++conn->whichhost >= conn->nconnhost)
1934  {
1935  conn->whichhost = 0;
1936  break;
1937  }
1938  conn->addr_cur =
1939  conn->connhost[conn->whichhost].addrlist;
1940  }
1941 
1942  /* Remember current address for possible error msg */
1943  addr_cur = conn->addr_cur;
1944  memcpy(&conn->raddr.addr, addr_cur->ai_addr,
1945  addr_cur->ai_addrlen);
1946  conn->raddr.salen = addr_cur->ai_addrlen;
1947 
1948  conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
1949  if (conn->sock == PGINVALID_SOCKET)
1950  {
1951  /*
1952  * ignore socket() failure if we have more addresses
1953  * to try
1954  */
1955  if (addr_cur->ai_next != NULL ||
1956  conn->whichhost + 1 < conn->nconnhost)
1957  {
1958  conn->addr_cur = addr_cur->ai_next;
1959  continue;
1960  }
1962  libpq_gettext("could not create socket: %s\n"),
1963  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1964  break;
1965  }
1966 
1967  /*
1968  * Select socket options: no delay of outgoing data for
1969  * TCP sockets, nonblock mode, close-on-exec. Fail if any
1970  * of this fails.
1971  */
1972  if (!IS_AF_UNIX(addr_cur->ai_family))
1973  {
1974  if (!connectNoDelay(conn))
1975  {
1976  pqDropConnection(conn, true);
1977  conn->addr_cur = addr_cur->ai_next;
1978  continue;
1979  }
1980  }
1981  if (!pg_set_noblock(conn->sock))
1982  {
1984  libpq_gettext("could not set socket to nonblocking mode: %s\n"),
1985  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1986  pqDropConnection(conn, true);
1987  conn->addr_cur = addr_cur->ai_next;
1988  continue;
1989  }
1990 
1991 #ifdef F_SETFD
1992  if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
1993  {
1995  libpq_gettext("could not set socket to close-on-exec mode: %s\n"),
1996  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1997  pqDropConnection(conn, true);
1998  conn->addr_cur = addr_cur->ai_next;
1999  continue;
2000  }
2001 #endif /* F_SETFD */
2002 
2003  if (!IS_AF_UNIX(addr_cur->ai_family))
2004  {
2005 #ifndef WIN32
2006  int on = 1;
2007 #endif
2008  int usekeepalives = useKeepalives(conn);
2009  int err = 0;
2010 
2011  if (usekeepalives < 0)
2012  {
2014  libpq_gettext("keepalives parameter must be an integer\n"));
2015  err = 1;
2016  }
2017  else if (usekeepalives == 0)
2018  {
2019  /* Do nothing */
2020  }
2021 #ifndef WIN32
2022  else if (setsockopt(conn->sock,
2023  SOL_SOCKET, SO_KEEPALIVE,
2024  (char *) &on, sizeof(on)) < 0)
2025  {
2027  libpq_gettext("setsockopt(SO_KEEPALIVE) failed: %s\n"),
2028  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2029  err = 1;
2030  }
2031  else if (!setKeepalivesIdle(conn)
2032  || !setKeepalivesInterval(conn)
2033  || !setKeepalivesCount(conn))
2034  err = 1;
2035 #else /* WIN32 */
2036 #ifdef SIO_KEEPALIVE_VALS
2037  else if (!setKeepalivesWin32(conn))
2038  err = 1;
2039 #endif /* SIO_KEEPALIVE_VALS */
2040 #endif /* WIN32 */
2041 
2042  if (err)
2043  {
2044  pqDropConnection(conn, true);
2045  conn->addr_cur = addr_cur->ai_next;
2046  continue;
2047  }
2048  }
2049 
2050  /*----------
2051  * We have three methods of blocking SIGPIPE during
2052  * send() calls to this socket:
2053  *
2054  * - setsockopt(sock, SO_NOSIGPIPE)
2055  * - send(sock, ..., MSG_NOSIGNAL)
2056  * - setting the signal mask to SIG_IGN during send()
2057  *
2058  * The third method requires three syscalls per send,
2059  * so we prefer either of the first two, but they are
2060  * less portable. The state is tracked in the following
2061  * members of PGconn:
2062  *
2063  * conn->sigpipe_so - we have set up SO_NOSIGPIPE
2064  * conn->sigpipe_flag - we're specifying MSG_NOSIGNAL
2065  *
2066  * If we can use SO_NOSIGPIPE, then set sigpipe_so here
2067  * and we're done. Otherwise, set sigpipe_flag so that
2068  * we will try MSG_NOSIGNAL on sends. If we get an error
2069  * with MSG_NOSIGNAL, we'll clear that flag and revert to
2070  * signal masking.
2071  *----------
2072  */
2073  conn->sigpipe_so = false;
2074 #ifdef MSG_NOSIGNAL
2075  conn->sigpipe_flag = true;
2076 #else
2077  conn->sigpipe_flag = false;
2078 #endif /* MSG_NOSIGNAL */
2079 
2080 #ifdef SO_NOSIGPIPE
2081  optval = 1;
2082  if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE,
2083  (char *) &optval, sizeof(optval)) == 0)
2084  {
2085  conn->sigpipe_so = true;
2086  conn->sigpipe_flag = false;
2087  }
2088 #endif /* SO_NOSIGPIPE */
2089 
2090  /*
2091  * Start/make connection. This should not block, since we
2092  * are in nonblock mode. If it does, well, too bad.
2093  */
2094  if (connect(conn->sock, addr_cur->ai_addr,
2095  addr_cur->ai_addrlen) < 0)
2096  {
2097  if (SOCK_ERRNO == EINPROGRESS ||
2098 #ifdef WIN32
2099  SOCK_ERRNO == EWOULDBLOCK ||
2100 #endif
2101  SOCK_ERRNO == EINTR)
2102  {
2103  /*
2104  * This is fine - we're in non-blocking mode, and
2105  * the connection is in progress. Tell caller to
2106  * wait for write-ready on socket.
2107  */
2108  conn->status = CONNECTION_STARTED;
2109  return PGRES_POLLING_WRITING;
2110  }
2111  /* otherwise, trouble */
2112  }
2113  else
2114  {
2115  /*
2116  * Hm, we're connected already --- seems the "nonblock
2117  * connection" wasn't. Advance the state machine and
2118  * go do the next stuff.
2119  */
2120  conn->status = CONNECTION_STARTED;
2121  goto keep_going;
2122  }
2123 
2124  /*
2125  * This connection failed --- set up error report, then
2126  * close socket (do it this way in case close() affects
2127  * the value of errno...). We will ignore the connect()
2128  * failure and keep going if there are more addresses.
2129  */
2131  pqDropConnection(conn, true);
2132 
2133  /*
2134  * Try the next address, if any.
2135  */
2136  conn->addr_cur = addr_cur->ai_next;
2137  } /* loop over addresses */
2138 
2139  /*
2140  * Ooops, no more addresses. An appropriate error message is
2141  * already set up, so just set the right status.
2142  */
2143  goto error_return;
2144  }
2145 
2146  case CONNECTION_STARTED:
2147  {
2148  ACCEPT_TYPE_ARG3 optlen = sizeof(optval);
2149 
2150  /*
2151  * Write ready, since we've made it here, so the connection
2152  * has been made ... or has failed.
2153  */
2154 
2155  /*
2156  * Now check (using getsockopt) that there is not an error
2157  * state waiting for us on the socket.
2158  */
2159 
2160  if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
2161  (char *) &optval, &optlen) == -1)
2162  {
2164  libpq_gettext("could not get socket error status: %s\n"),
2165  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2166  goto error_return;
2167  }
2168  else if (optval != 0)
2169  {
2170  /*
2171  * When using a nonblocking connect, we will typically see
2172  * connect failures at this point, so provide a friendly
2173  * error message.
2174  */
2175  connectFailureMessage(conn, optval);
2176  pqDropConnection(conn, true);
2177 
2178  /*
2179  * If more addresses remain, keep trying, just as in the
2180  * case where connect() returned failure immediately.
2181  */
2182  if (conn->addr_cur->ai_next != NULL ||
2183  conn->whichhost + 1 < conn->nconnhost)
2184  {
2185  conn->addr_cur = conn->addr_cur->ai_next;
2186  conn->status = CONNECTION_NEEDED;
2187  goto keep_going;
2188  }
2189  goto error_return;
2190  }
2191 
2192  /* Fill in the client address */
2193  conn->laddr.salen = sizeof(conn->laddr.addr);
2194  if (getsockname(conn->sock,
2195  (struct sockaddr *) & conn->laddr.addr,
2196  &conn->laddr.salen) < 0)
2197  {
2199  libpq_gettext("could not get client address from socket: %s\n"),
2200  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2201  goto error_return;
2202  }
2203 
2204  /*
2205  * Make sure we can write before advancing to next step.
2206  */
2207  conn->status = CONNECTION_MADE;
2208  return PGRES_POLLING_WRITING;
2209  }
2210 
2211  case CONNECTION_MADE:
2212  {
2213  char *startpacket;
2214  int packetlen;
2215 
2216 #ifdef HAVE_UNIX_SOCKETS
2217 
2218  /*
2219  * Implement requirepeer check, if requested and it's a
2220  * Unix-domain socket.
2221  */
2222  if (conn->requirepeer && conn->requirepeer[0] &&
2223  IS_AF_UNIX(conn->raddr.addr.ss_family))
2224  {
2225  char pwdbuf[BUFSIZ];
2226  struct passwd pass_buf;
2227  struct passwd *pass;
2228  int passerr;
2229  uid_t uid;
2230  gid_t gid;
2231 
2232  errno = 0;
2233  if (getpeereid(conn->sock, &uid, &gid) != 0)
2234  {
2235  /*
2236  * Provide special error message if getpeereid is a
2237  * stub
2238  */
2239  if (errno == ENOSYS)
2241  libpq_gettext("requirepeer parameter is not supported on this platform\n"));
2242  else
2244  libpq_gettext("could not get peer credentials: %s\n"),
2245  pqStrerror(errno, sebuf, sizeof(sebuf)));
2246  goto error_return;
2247  }
2248 
2249  passerr = pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
2250  if (pass == NULL)
2251  {
2252  if (passerr != 0)
2254  libpq_gettext("could not look up local user ID %d: %s\n"),
2255  (int) uid,
2256  pqStrerror(passerr, sebuf, sizeof(sebuf)));
2257  else
2259  libpq_gettext("local user with ID %d does not exist\n"),
2260  (int) uid);
2261  goto error_return;
2262  }
2263 
2264  if (strcmp(pass->pw_name, conn->requirepeer) != 0)
2265  {
2267  libpq_gettext("requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n"),
2268  conn->requirepeer, pass->pw_name);
2269  goto error_return;
2270  }
2271  }
2272 #endif /* HAVE_UNIX_SOCKETS */
2273 
2274 #ifdef USE_SSL
2275 
2276  /*
2277  * If SSL is enabled and we haven't already got it running,
2278  * request it instead of sending the startup message.
2279  */
2280  if (IS_AF_UNIX(conn->raddr.addr.ss_family))
2281  {
2282  /* Don't bother requesting SSL over a Unix socket */
2283  conn->allow_ssl_try = false;
2284  }
2285  if (conn->allow_ssl_try && !conn->wait_ssl_try &&
2286  !conn->ssl_in_use)
2287  {
2288  ProtocolVersion pv;
2289 
2290  /*
2291  * Send the SSL request packet.
2292  *
2293  * Theoretically, this could block, but it really
2294  * shouldn't since we only got here if the socket is
2295  * write-ready.
2296  */
2297  pv = htonl(NEGOTIATE_SSL_CODE);
2298  if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
2299  {
2301  libpq_gettext("could not send SSL negotiation packet: %s\n"),
2302  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2303  goto error_return;
2304  }
2305  /* Ok, wait for response */
2307  return PGRES_POLLING_READING;
2308  }
2309 #endif /* USE_SSL */
2310 
2311  /*
2312  * Build the startup packet.
2313  */
2314  if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2315  startpacket = pqBuildStartupPacket3(conn, &packetlen,
2317  else
2318  startpacket = pqBuildStartupPacket2(conn, &packetlen,
2320  if (!startpacket)
2321  {
2322  /*
2323  * will not appendbuffer here, since it's likely to also
2324  * run out of memory
2325  */
2327  libpq_gettext("out of memory\n"));
2328  goto error_return;
2329  }
2330 
2331  /*
2332  * Send the startup packet.
2333  *
2334  * Theoretically, this could block, but it really shouldn't
2335  * since we only got here if the socket is write-ready.
2336  */
2337  if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
2338  {
2340  libpq_gettext("could not send startup packet: %s\n"),
2341  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2342  free(startpacket);
2343  goto error_return;
2344  }
2345 
2346  free(startpacket);
2347 
2349  return PGRES_POLLING_READING;
2350  }
2351 
2352  /*
2353  * Handle SSL negotiation: wait for postmaster messages and
2354  * respond as necessary.
2355  */
2357  {
2358 #ifdef USE_SSL
2359  PostgresPollingStatusType pollres;
2360 
2361  /*
2362  * On first time through, get the postmaster's response to our
2363  * SSL negotiation packet.
2364  */
2365  if (!conn->ssl_in_use)
2366  {
2367  /*
2368  * We use pqReadData here since it has the logic to
2369  * distinguish no-data-yet from connection closure. Since
2370  * conn->ssl isn't set, a plain recv() will occur.
2371  */
2372  char SSLok;
2373  int rdresult;
2374 
2375  rdresult = pqReadData(conn);
2376  if (rdresult < 0)
2377  {
2378  /* errorMessage is already filled in */
2379  goto error_return;
2380  }
2381  if (rdresult == 0)
2382  {
2383  /* caller failed to wait for data */
2384  return PGRES_POLLING_READING;
2385  }
2386  if (pqGetc(&SSLok, conn) < 0)
2387  {
2388  /* should not happen really */
2389  return PGRES_POLLING_READING;
2390  }
2391  if (SSLok == 'S')
2392  {
2393  /* mark byte consumed */
2394  conn->inStart = conn->inCursor;
2395  /* Set up global SSL state if required */
2396  if (pqsecure_initialize(conn) != 0)
2397  goto error_return;
2398  }
2399  else if (SSLok == 'N')
2400  {
2401  /* mark byte consumed */
2402  conn->inStart = conn->inCursor;
2403  /* OK to do without SSL? */
2404  if (conn->sslmode[0] == 'r' || /* "require" */
2405  conn->sslmode[0] == 'v') /* "verify-ca" or
2406  * "verify-full" */
2407  {
2408  /* Require SSL, but server does not want it */
2410  libpq_gettext("server does not support SSL, but SSL was required\n"));
2411  goto error_return;
2412  }
2413  /* Otherwise, proceed with normal startup */
2414  conn->allow_ssl_try = false;
2415  conn->status = CONNECTION_MADE;
2416  return PGRES_POLLING_WRITING;
2417  }
2418  else if (SSLok == 'E')
2419  {
2420  /*
2421  * Server failure of some sort, such as failure to
2422  * fork a backend process. We need to process and
2423  * report the error message, which might be formatted
2424  * according to either protocol 2 or protocol 3.
2425  * Rather than duplicate the code for that, we flip
2426  * into AWAITING_RESPONSE state and let the code there
2427  * deal with it. Note we have *not* consumed the "E"
2428  * byte here.
2429  */
2431  goto keep_going;
2432  }
2433  else
2434  {
2436  libpq_gettext("received invalid response to SSL negotiation: %c\n"),
2437  SSLok);
2438  goto error_return;
2439  }
2440  }
2441 
2442  /*
2443  * Begin or continue the SSL negotiation process.
2444  */
2445  pollres = pqsecure_open_client(conn);
2446  if (pollres == PGRES_POLLING_OK)
2447  {
2448  /* SSL handshake done, ready to send startup packet */
2449  conn->status = CONNECTION_MADE;
2450  return PGRES_POLLING_WRITING;
2451  }
2452  if (pollres == PGRES_POLLING_FAILED)
2453  {
2454  /*
2455  * Failed ... if sslmode is "prefer" then do a non-SSL
2456  * retry
2457  */
2458  if (conn->sslmode[0] == 'p' /* "prefer" */
2459  && conn->allow_ssl_try /* redundant? */
2460  && !conn->wait_ssl_try) /* redundant? */
2461  {
2462  /* only retry once */
2463  conn->allow_ssl_try = false;
2464  /* Must drop the old connection */
2465  pqDropConnection(conn, true);
2466  conn->status = CONNECTION_NEEDED;
2467  goto keep_going;
2468  }
2469  }
2470  return pollres;
2471 #else /* !USE_SSL */
2472  /* can't get here */
2473  goto error_return;
2474 #endif /* USE_SSL */
2475  }
2476 
2477  /*
2478  * Handle authentication exchange: wait for postmaster messages
2479  * and respond as necessary.
2480  */
2482  {
2483  char beresp;
2484  int msgLength;
2485  int avail;
2486  AuthRequest areq;
2487 
2488  /*
2489  * Scan the message from current point (note that if we find
2490  * the message is incomplete, we will return without advancing
2491  * inStart, and resume here next time).
2492  */
2493  conn->inCursor = conn->inStart;
2494 
2495  /* Read type byte */
2496  if (pqGetc(&beresp, conn))
2497  {
2498  /* We'll come back when there is more data */
2499  return PGRES_POLLING_READING;
2500  }
2501 
2502  /*
2503  * Validate message type: we expect only an authentication
2504  * request or an error here. Anything else probably means
2505  * it's not Postgres on the other end at all.
2506  */
2507  if (!(beresp == 'R' || beresp == 'E'))
2508  {
2510  libpq_gettext(
2511  "expected authentication request from "
2512  "server, but received %c\n"),
2513  beresp);
2514  goto error_return;
2515  }
2516 
2517  if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2518  {
2519  /* Read message length word */
2520  if (pqGetInt(&msgLength, 4, conn))
2521  {
2522  /* We'll come back when there is more data */
2523  return PGRES_POLLING_READING;
2524  }
2525  }
2526  else
2527  {
2528  /* Set phony message length to disable checks below */
2529  msgLength = 8;
2530  }
2531 
2532  /*
2533  * Try to validate message length before using it.
2534  * Authentication requests can't be very large, although GSS
2535  * auth requests may not be that small. Errors can be a
2536  * little larger, but not huge. If we see a large apparent
2537  * length in an error, it means we're really talking to a
2538  * pre-3.0-protocol server; cope.
2539  */
2540  if (beresp == 'R' && (msgLength < 8 || msgLength > 2000))
2541  {
2543  libpq_gettext(
2544  "expected authentication request from "
2545  "server, but received %c\n"),
2546  beresp);
2547  goto error_return;
2548  }
2549 
2550  if (beresp == 'E' && (msgLength < 8 || msgLength > 30000))
2551  {
2552  /* Handle error from a pre-3.0 server */
2553  conn->inCursor = conn->inStart + 1; /* reread data */
2554  if (pqGets_append(&conn->errorMessage, conn))
2555  {
2556  /* We'll come back when there is more data */
2557  return PGRES_POLLING_READING;
2558  }
2559  /* OK, we read the message; mark data consumed */
2560  conn->inStart = conn->inCursor;
2561 
2562  /*
2563  * The postmaster typically won't end its message with a
2564  * newline, so add one to conform to libpq conventions.
2565  */
2566  appendPQExpBufferChar(&conn->errorMessage, '\n');
2567 
2568  /*
2569  * If we tried to open the connection in 3.0 protocol,
2570  * fall back to 2.0 protocol.
2571  */
2572  if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2573  {
2574  conn->pversion = PG_PROTOCOL(2, 0);
2575  /* Must drop the old connection */
2576  pqDropConnection(conn, true);
2577  conn->status = CONNECTION_NEEDED;
2578  goto keep_going;
2579  }
2580 
2581  goto error_return;
2582  }
2583 
2584  /*
2585  * Can't process if message body isn't all here yet.
2586  *
2587  * (In protocol 2.0 case, we are assuming messages carry at
2588  * least 4 bytes of data.)
2589  */
2590  msgLength -= 4;
2591  avail = conn->inEnd - conn->inCursor;
2592  if (avail < msgLength)
2593  {
2594  /*
2595  * Before returning, try to enlarge the input buffer if
2596  * needed to hold the whole message; see notes in
2597  * pqParseInput3.
2598  */
2599  if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
2600  conn))
2601  goto error_return;
2602  /* We'll come back when there is more data */
2603  return PGRES_POLLING_READING;
2604  }
2605 
2606  /* Handle errors. */
2607  if (beresp == 'E')
2608  {
2609  if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2610  {
2611  if (pqGetErrorNotice3(conn, true))
2612  {
2613  /* We'll come back when there is more data */
2614  return PGRES_POLLING_READING;
2615  }
2616  }
2617  else
2618  {
2619  if (pqGets_append(&conn->errorMessage, conn))
2620  {
2621  /* We'll come back when there is more data */
2622  return PGRES_POLLING_READING;
2623  }
2624  }
2625  /* OK, we read the message; mark data consumed */
2626  conn->inStart = conn->inCursor;
2627 
2628 #ifdef USE_SSL
2629 
2630  /*
2631  * if sslmode is "allow" and we haven't tried an SSL
2632  * connection already, then retry with an SSL connection
2633  */
2634  if (conn->sslmode[0] == 'a' /* "allow" */
2635  && !conn->ssl_in_use
2636  && conn->allow_ssl_try
2637  && conn->wait_ssl_try)
2638  {
2639  /* only retry once */
2640  conn->wait_ssl_try = false;
2641  /* Must drop the old connection */
2642  pqDropConnection(conn, true);
2643  conn->status = CONNECTION_NEEDED;
2644  goto keep_going;
2645  }
2646 
2647  /*
2648  * if sslmode is "prefer" and we're in an SSL connection,
2649  * then do a non-SSL retry
2650  */
2651  if (conn->sslmode[0] == 'p' /* "prefer" */
2652  && conn->allow_ssl_try
2653  && !conn->wait_ssl_try) /* redundant? */
2654  {
2655  /* only retry once */
2656  conn->allow_ssl_try = false;
2657  /* Must drop the old connection */
2658  pqDropConnection(conn, true);
2659  conn->status = CONNECTION_NEEDED;
2660  goto keep_going;
2661  }
2662 #endif
2663 
2664  goto error_return;
2665  }
2666 
2667  /* It is an authentication request. */
2668  conn->auth_req_received = true;
2669 
2670  /* Get the type of request. */
2671  if (pqGetInt((int *) &areq, 4, conn))
2672  {
2673  /* We'll come back when there are more data */
2674  return PGRES_POLLING_READING;
2675  }
2676 
2677  /* Get the password salt if there is one. */
2678  if (areq == AUTH_REQ_MD5)
2679  {
2680  if (pqGetnchar(conn->md5Salt,
2681  sizeof(conn->md5Salt), conn))
2682  {
2683  /* We'll come back when there are more data */
2684  return PGRES_POLLING_READING;
2685  }
2686  }
2687 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
2688 
2689  /*
2690  * Continue GSSAPI/SSPI authentication
2691  */
2692  if (areq == AUTH_REQ_GSS_CONT)
2693  {
2694  int llen = msgLength - 4;
2695 
2696  /*
2697  * We can be called repeatedly for the same buffer. Avoid
2698  * re-allocating the buffer in this case - just re-use the
2699  * old buffer.
2700  */
2701  if (llen != conn->ginbuf.length)
2702  {
2703  if (conn->ginbuf.value)
2704  free(conn->ginbuf.value);
2705 
2706  conn->ginbuf.length = llen;
2707  conn->ginbuf.value = malloc(llen);
2708  if (!conn->ginbuf.value)
2709  {
2711  libpq_gettext("out of memory allocating GSSAPI buffer (%d)"),
2712  llen);
2713  goto error_return;
2714  }
2715  }
2716 
2717  if (pqGetnchar(conn->ginbuf.value, llen, conn))
2718  {
2719  /* We'll come back when there is more data. */
2720  return PGRES_POLLING_READING;
2721  }
2722  }
2723 #endif
2724 
2725  /*
2726  * OK, we successfully read the message; mark data consumed
2727  */
2728  conn->inStart = conn->inCursor;
2729 
2730  /* Respond to the request if necessary. */
2731 
2732  /*
2733  * Note that conn->pghost must be non-NULL if we are going to
2734  * avoid the Kerberos code doing a hostname look-up.
2735  */
2736 
2737  if (pg_fe_sendauth(areq, conn) != STATUS_OK)
2738  {
2739  conn->errorMessage.len = strlen(conn->errorMessage.data);
2740  goto error_return;
2741  }
2742  conn->errorMessage.len = strlen(conn->errorMessage.data);
2743 
2744  /*
2745  * Just make sure that any data sent by pg_fe_sendauth is
2746  * flushed out. Although this theoretically could block, it
2747  * really shouldn't since we don't send large auth responses.
2748  */
2749  if (pqFlush(conn))
2750  goto error_return;
2751 
2752  if (areq == AUTH_REQ_OK)
2753  {
2754  /* We are done with authentication exchange */
2755  conn->status = CONNECTION_AUTH_OK;
2756 
2757  /*
2758  * Set asyncStatus so that PQgetResult will think that
2759  * what comes back next is the result of a query. See
2760  * below.
2761  */
2762  conn->asyncStatus = PGASYNC_BUSY;
2763  }
2764 
2765  /* Look to see if we have more data yet. */
2766  goto keep_going;
2767  }
2768 
2769  case CONNECTION_AUTH_OK:
2770  {
2771  /*
2772  * Now we expect to hear from the backend. A ReadyForQuery
2773  * message indicates that startup is successful, but we might
2774  * also get an Error message indicating failure. (Notice
2775  * messages indicating nonfatal warnings are also allowed by
2776  * the protocol, as are ParameterStatus and BackendKeyData
2777  * messages.) Easiest way to handle this is to let
2778  * PQgetResult() read the messages. We just have to fake it
2779  * out about the state of the connection, by setting
2780  * asyncStatus = PGASYNC_BUSY (done above).
2781  */
2782 
2783  if (PQisBusy(conn))
2784  return PGRES_POLLING_READING;
2785 
2786  res = PQgetResult(conn);
2787 
2788  /*
2789  * NULL return indicating we have gone to IDLE state is
2790  * expected
2791  */
2792  if (res)
2793  {
2794  if (res->resultStatus != PGRES_FATAL_ERROR)
2796  libpq_gettext("unexpected message from server during startup\n"));
2797  else if (conn->send_appname &&
2798  (conn->appname || conn->fbappname))
2799  {
2800  /*
2801  * If we tried to send application_name, check to see
2802  * if the error is about that --- pre-9.0 servers will
2803  * reject it at this stage of the process. If so,
2804  * close the connection and retry without sending
2805  * application_name. We could possibly get a false
2806  * SQLSTATE match here and retry uselessly, but there
2807  * seems no great harm in that; we'll just get the
2808  * same error again if it's unrelated.
2809  */
2810  const char *sqlstate;
2811 
2812  sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
2813  if (sqlstate &&
2814  strcmp(sqlstate, ERRCODE_APPNAME_UNKNOWN) == 0)
2815  {
2816  PQclear(res);
2817  conn->send_appname = false;
2818  /* Must drop the old connection */
2819  pqDropConnection(conn, true);
2820  conn->status = CONNECTION_NEEDED;
2821  goto keep_going;
2822  }
2823  }
2824 
2825  /*
2826  * if the resultStatus is FATAL, then conn->errorMessage
2827  * already has a copy of the error; needn't copy it back.
2828  * But add a newline if it's not there already, since
2829  * postmaster error messages may not have one.
2830  */
2831  if (conn->errorMessage.len <= 0 ||
2832  conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
2833  appendPQExpBufferChar(&conn->errorMessage, '\n');
2834  PQclear(res);
2835  goto error_return;
2836  }
2837 
2838  /* Fire up post-connection housekeeping if needed */
2839  if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
2840  {
2841  conn->status = CONNECTION_SETENV;
2843  conn->next_eo = EnvironmentOptions;
2844  return PGRES_POLLING_WRITING;
2845  }
2846 
2847  /*
2848  * If a read-write connection is required, see if we have one.
2849  */
2850  if (conn->target_session_attrs != NULL &&
2851  strcmp(conn->target_session_attrs, "read-write") == 0)
2852  {
2853  /*
2854  * We are yet to make a connection. Save all existing error
2855  * messages until we make a successful connection state.
2856  * This is important because PQsendQuery is going to reset
2857  * conn->errorMessage and we will loose error messages
2858  * related to previous hosts we have tried to connect and
2859  * failed.
2860  */
2861  if (!saveErrorMessage(conn, &savedMessage))
2862  goto error_return;
2863 
2864  conn->status = CONNECTION_OK;
2865  if (!PQsendQuery(conn,
2866  "show transaction_read_only"))
2867  {
2868  restoreErrorMessage(conn, &savedMessage);
2869  goto error_return;
2870  }
2872  restoreErrorMessage(conn, &savedMessage);
2873  return PGRES_POLLING_READING;
2874  }
2875 
2876  /* We can release the address lists now. */
2877  release_all_addrinfo(conn);
2878 
2879  /* We are open for business! */
2880  conn->status = CONNECTION_OK;
2881  return PGRES_POLLING_OK;
2882  }
2883 
2884  case CONNECTION_SETENV:
2885 
2886  /*
2887  * Do post-connection housekeeping (only needed in protocol 2.0).
2888  *
2889  * We pretend that the connection is OK for the duration of these
2890  * queries.
2891  */
2892  conn->status = CONNECTION_OK;
2893 
2894  switch (pqSetenvPoll(conn))
2895  {
2896  case PGRES_POLLING_OK: /* Success */
2897  break;
2898 
2899  case PGRES_POLLING_READING: /* Still going */
2900  conn->status = CONNECTION_SETENV;
2901  return PGRES_POLLING_READING;
2902 
2903  case PGRES_POLLING_WRITING: /* Still going */
2904  conn->status = CONNECTION_SETENV;
2905  return PGRES_POLLING_WRITING;
2906 
2907  default:
2908  goto error_return;
2909  }
2910 
2911  /*
2912  * If a read-write connection is requested check for same.
2913  */
2914  if (conn->target_session_attrs != NULL &&
2915  strcmp(conn->target_session_attrs, "read-write") == 0)
2916  {
2917  if (!saveErrorMessage(conn, &savedMessage))
2918  goto error_return;
2919 
2920  conn->status = CONNECTION_OK;
2921  if (!PQsendQuery(conn,
2922  "show transaction_read_only"))
2923  {
2924  restoreErrorMessage(conn, &savedMessage);
2925  goto error_return;
2926  }
2928  restoreErrorMessage(conn, &savedMessage);
2929  return PGRES_POLLING_READING;
2930  }
2931 
2932  /* We can release the address lists now. */
2933  release_all_addrinfo(conn);
2934 
2935  /* We are open for business! */
2936  conn->status = CONNECTION_OK;
2937  return PGRES_POLLING_OK;
2938 
2939  case CONNECTION_CONSUME:
2940  {
2941  conn->status = CONNECTION_OK;
2942  if (!PQconsumeInput(conn))
2943  goto error_return;
2944 
2945  if (PQisBusy(conn))
2946  {
2947  conn->status = CONNECTION_CONSUME;
2948  restoreErrorMessage(conn, &savedMessage);
2949  return PGRES_POLLING_READING;
2950  }
2951 
2952  /*
2953  * Call PQgetResult() again to consume NULL result.
2954  */
2955  res = PQgetResult(conn);
2956  if (res != NULL)
2957  {
2958  PQclear(res);
2959  conn->status = CONNECTION_CONSUME;
2960  goto keep_going;
2961  }
2962 
2963  /* We are open for business! */
2964  conn->status = CONNECTION_OK;
2965  return PGRES_POLLING_OK;
2966  }
2968  {
2969  if (!saveErrorMessage(conn, &savedMessage))
2970  goto error_return;
2971 
2972  conn->status = CONNECTION_OK;
2973  if (!PQconsumeInput(conn))
2974  {
2975  restoreErrorMessage(conn, &savedMessage);
2976  goto error_return;
2977  }
2978 
2979  if (PQisBusy(conn))
2980  {
2982  restoreErrorMessage(conn, &savedMessage);
2983  return PGRES_POLLING_READING;
2984  }
2985 
2986  res = PQgetResult(conn);
2987  if (res && (PQresultStatus(res) == PGRES_TUPLES_OK) &&
2988  PQntuples(res) == 1)
2989  {
2990  char *val;
2991 
2992  val = PQgetvalue(res, 0, 0);
2993  if (strncmp(val, "on", 2) == 0)
2994  {
2995  PQclear(res);
2996  restoreErrorMessage(conn, &savedMessage);
2997 
2998  /* Not writable; close connection. */
3000  libpq_gettext("could not make a writable "
3001  "connection to server "
3002  "\"%s:%s\"\n"),
3003  conn->connhost[conn->whichhost].host,
3004  conn->connhost[conn->whichhost].port);
3005  conn->status = CONNECTION_OK;
3006  sendTerminateConn(conn);
3007  pqDropConnection(conn, true);
3008 
3009  /* Skip any remaining addresses for this host. */
3010  conn->addr_cur = NULL;
3011  if (conn->whichhost + 1 < conn->nconnhost)
3012  {
3013  conn->status = CONNECTION_NEEDED;
3014  goto keep_going;
3015  }
3016 
3017  /* No more addresses to try. So we fail. */
3018  goto error_return;
3019  }
3020  PQclear(res);
3021  termPQExpBuffer(&savedMessage);
3022 
3023  /* We can release the address lists now. */
3024  release_all_addrinfo(conn);
3025 
3026  /*
3027  * Finish reading any remaining messages before
3028  * being considered as ready.
3029  */
3030  conn->status = CONNECTION_CONSUME;
3031  goto keep_going;
3032  }
3033 
3034  /*
3035  * Something went wrong with "show transaction_read_only". We
3036  * should try next addresses.
3037  */
3038  if (res)
3039  PQclear(res);
3040  restoreErrorMessage(conn, &savedMessage);
3042  libpq_gettext("test \"show transaction_read_only\" failed "
3043  " on \"%s:%s\" \n"),
3044  conn->connhost[conn->whichhost].host,
3045  conn->connhost[conn->whichhost].port);
3046  conn->status = CONNECTION_OK;
3047  sendTerminateConn(conn);
3048  pqDropConnection(conn, true);
3049 
3050  if (conn->addr_cur->ai_next != NULL ||
3051  conn->whichhost + 1 < conn->nconnhost)
3052  {
3053  conn->addr_cur = conn->addr_cur->ai_next;
3054  conn->status = CONNECTION_NEEDED;
3055  goto keep_going;
3056  }
3057 
3058  /* No more addresses to try. So we fail. */
3059  goto error_return;
3060  }
3061 
3062  default:
3064  libpq_gettext("invalid connection state %d, "
3065  "probably indicative of memory corruption\n"),
3066  conn->status);
3067  goto error_return;
3068  }
3069 
3070  /* Unreachable */
3071 
3072 error_return:
3073 
3074  pgpassfileWarning(conn);
3075 
3076  /*
3077  * We used to close the socket at this point, but that makes it awkward
3078  * for those above us if they wish to remove this socket from their own
3079  * records (an fd_set for example). We'll just have this socket closed
3080  * when PQfinish is called (which is compulsory even after an error, since
3081  * the connection structure must be freed).
3082  */
3083  conn->status = CONNECTION_BAD;
3084  return PGRES_POLLING_FAILED;
3085 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:966
#define connect(s, name, namelen)
Definition: win32.h:383
#define EWOULDBLOCK
Definition: win32.h:301
bool sigpipe_flag
Definition: libpq-int.h:413
int inEnd
Definition: libpq-int.h:437
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int inStart
Definition: libpq-int.h:435
struct addrinfo * addr_cur
Definition: libpq-int.h:416
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
static int connectNoDelay(PGconn *conn)
Definition: fe-connect.c:1275
int gid_t
Definition: win32.h:261
int uid_t
Definition: win32.h:260
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
int getpeereid(int sock, uid_t *uid, gid_t *gid)
Definition: getpeereid.c:35
bool sigpipe_so
Definition: libpq-int.h:412
char * pqBuildStartupPacket2(PGconn *conn, int *packetlen, const PQEnvironmentOption *options)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define AUTH_REQ_OK
Definition: pqcomm.h:165
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:413
static void pgpassfileWarning(PGconn *conn)
Definition: fe-connect.c:6351
char * requirepeer
Definition: libpq-int.h:359
char * host
Definition: libpq-int.h:309
struct sockaddr_storage addr
Definition: pqcomm.h:64
char * pqStrerror(int errnum, char *strerrbuf, size_t buflen)
Definition: thread.c:61
static void release_all_addrinfo(PGconn *conn)
Definition: fe-connect.c:3373
static int setKeepalivesIdle(PGconn *conn)
Definition: fe-connect.c:1414
#define socket(af, type, protocol)
Definition: win32.h:379
#define EINPROGRESS
Definition: win32.h:307
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:272
static bool saveErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
Definition: fe-connect.c:1793
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:3401
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:410
int pqGetnchar(char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:200
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:104
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:53
uint32 AuthRequest
Definition: pqcomm.h:176
#define AUTH_REQ_MD5
Definition: pqcomm.h:170
int pg_fe_sendauth(AuthRequest areq, PGconn *conn)
Definition: fe-auth.c:558
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
PostgresPollingStatusType pqSetenvPoll(PGconn *conn)
Definition: fe-protocol2.c:50
#define malloc(a)
Definition: header.h:45
#define SOCK_STRERROR
Definition: libpq-int.h:703
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1132
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:381
char md5Salt[4]
Definition: libpq-int.h:424
PGSetenvStatusType setenv_state
Definition: libpq-int.h:417
static int useKeepalives(PGconn *conn)
Definition: fe-connect.c:1396
#define IS_AF_UNIX(fam)
Definition: ip.h:24
#define SOCK_ERRNO
Definition: libpq-int.h:702
int pqGetErrorNotice3(PGconn *conn, bool isError)
Definition: fe-protocol3.c:876
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
#define ERRCODE_APPNAME_UNKNOWN
Definition: fe-connect.c:95
pg_conn_host * connhost
Definition: libpq-int.h:399
int pqReadData(PGconn *conn)
Definition: fe-misc.c:634
const PQEnvironmentOption * next_eo
Definition: libpq-int.h:418
static void restoreErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
Definition: fe-connect.c:1813
char * appname
Definition: libpq-int.h:340
PostgresPollingStatusType pqsecure_open_client(PGconn *conn)
Definition: fe-secure.c:175
ACCEPT_TYPE_ARG3 salen
Definition: pqcomm.h:65
char * target_session_attrs
Definition: libpq-int.h:365
#define STATUS_OK
Definition: c.h:971
pgsocket sock
Definition: libpq-int.h:402
uint32 ProtocolVersion
Definition: pqcomm.h:113
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:99
static void connectFailureMessage(PGconn *conn, int errorno)
Definition: fe-connect.c:1303
SockAddr raddr
Definition: libpq-int.h:405
#define PGINVALID_SOCKET
Definition: port.h:24
#define EINTR
Definition: win32.h:295
int pqsecure_initialize(PGconn *conn)
Definition: fe-secure.c:160
int PQconsumeInput(PGconn *conn)
Definition: fe-exec.c:1631
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
char * sslmode
Definition: libpq-int.h:353
PQExpBufferData errorMessage
Definition: libpq-int.h:498
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define free(a)
Definition: header.h:60
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2658
#define NULL
Definition: c.h:226
struct addrinfo * addrlist
Definition: libpq-int.h:316
bool pg_set_noblock(pgsocket sock)
Definition: noblock.c:21
#define FD_CLOEXEC
Definition: fe-connect.c:79
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:1681
char * pqBuildStartupPacket3(PGconn *conn, int *packetlen, const PQEnvironmentOption *options)