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/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 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 104 of file fe-connect.c.

#define DefaultHost   "localhost"

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

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

#define DefaultOption   ""

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

#define DefaultSSLMode   "disable"

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

Referenced by connectOptions2().

#define DefaultTargetSessionAttrs   "any"

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

#define DefaultTty   ""

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

#define ERRCODE_APPNAME_UNKNOWN   "42704"

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

Referenced by PQconnectPoll().

#define ERRCODE_CANNOT_CONNECT_NOW   "57P03"

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

Referenced by internal_ping(), and ProcessStartupPacket().

#define ERRCODE_INVALID_PASSWORD   "28P01"

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

Referenced by auth_failed(), and pgpassfileWarning().

#define LINELEN   NAMEDATALEN*5

Referenced by passwordFromFile().

#define MAXBUFSIZE   256

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

Referenced by parseServiceFile().

#define PGPASSFILE   ".pgpass"

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

Referenced by connectOptions2().

Typedef Documentation

Function Documentation

static void closePGconn ( PGconn conn)
static

Definition at line 3494 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().

3495 {
3496  PGnotify *notify;
3497  pgParameterStatus *pstatus;
3498 
3499  sendTerminateConn(conn);
3500 
3501  /*
3502  * Must reset the blocking status so a possible reconnect will work.
3503  *
3504  * Don't call PQsetnonblocking() because it will fail if it's unable to
3505  * flush the connection.
3506  */
3507  conn->nonblocking = FALSE;
3508 
3509  /*
3510  * Close the connection, reset all transient state, flush I/O buffers.
3511  */
3512  pqDropConnection(conn, true);
3513  conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just absent */
3514  conn->asyncStatus = PGASYNC_IDLE;
3515  pqClearAsyncResult(conn); /* deallocate result */
3517  release_all_addrinfo(conn);
3518 
3519  notify = conn->notifyHead;
3520  while (notify != NULL)
3521  {
3522  PGnotify *prev = notify;
3523 
3524  notify = notify->next;
3525  free(prev);
3526  }
3527  conn->notifyHead = conn->notifyTail = NULL;
3528  pstatus = conn->pstatus;
3529  while (pstatus != NULL)
3530  {
3531  pgParameterStatus *prev = pstatus;
3532 
3533  pstatus = pstatus->next;
3534  free(prev);
3535  }
3536  conn->pstatus = NULL;
3537  if (conn->lobjfuncs)
3538  free(conn->lobjfuncs);
3539  conn->lobjfuncs = NULL;
3540 }
static void release_all_addrinfo(PGconn *conn)
Definition: fe-connect.c:3439
PGnotify * notifyHead
Definition: libpq-int.h:390
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:405
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:3467
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:379
#define FALSE
Definition: c.h:221
pgParameterStatus * pstatus
Definition: libpq-int.h:420
struct pgNotify * next
Definition: libpq-fe.h:167
PQExpBufferData errorMessage
Definition: libpq-int.h:490
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
struct pgParameterStatus * next
Definition: libpq-int.h:258
ConnStatusType status
Definition: libpq-int.h:378
PGnotify * notifyTail
Definition: libpq-int.h:391
bool nonblocking
Definition: libpq-int.h:385
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:705
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:425
static int connectDBComplete ( PGconn conn)
static

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

References pg_conn::addr_cur, pg_conn_host::addrlist, pg_conn::connect_timeout, CONNECTION_BAD, CONNECTION_NEEDED, pg_conn::connhost, pg_conn::errorMessage, flag(), pg_conn::nconnhost, NULL, PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PQconnectPoll(), pqDropConnection(), pqWaitTimed(), resetPQExpBuffer(), pg_conn::status, and pg_conn::whichhost.

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

1776 {
1778  time_t finish_time = ((time_t) -1);
1779  int timeout = 0;
1780 
1781  if (conn == NULL || conn->status == CONNECTION_BAD)
1782  return 0;
1783 
1784  /*
1785  * Set up a time limit, if connect_timeout isn't zero.
1786  */
1787  if (conn->connect_timeout != NULL)
1788  {
1789  timeout = atoi(conn->connect_timeout);
1790  if (timeout > 0)
1791  {
1792  /*
1793  * Rounding could cause connection to fail; need at least 2 secs
1794  */
1795  if (timeout < 2)
1796  timeout = 2;
1797  /* calculate the finish time based on start + timeout */
1798  finish_time = time(NULL) + timeout;
1799  }
1800  }
1801 
1802  for (;;)
1803  {
1804  int ret = 0;
1805 
1806  /*
1807  * Wait, if necessary. Note that the initial state (just after
1808  * PQconnectStart) is to wait for the socket to select for writing.
1809  */
1810  switch (flag)
1811  {
1812  case PGRES_POLLING_OK:
1813 
1814  /*
1815  * Reset stored error messages since we now have a working
1816  * connection
1817  */
1819  return 1; /* success! */
1820 
1821  case PGRES_POLLING_READING:
1822  ret = pqWaitTimed(1, 0, conn, finish_time);
1823  if (ret == -1)
1824  {
1825  conn->status = CONNECTION_BAD;
1826  return 0;
1827  }
1828  break;
1829 
1830  case PGRES_POLLING_WRITING:
1831  ret = pqWaitTimed(0, 1, conn, finish_time);
1832  if (ret == -1)
1833  {
1834  conn->status = CONNECTION_BAD;
1835  return 0;
1836  }
1837  break;
1838 
1839  default:
1840  /* Just in case we failed to set it in PQconnectPoll */
1841  conn->status = CONNECTION_BAD;
1842  return 0;
1843  }
1844 
1845  if (ret == 1) /* connect_timeout elapsed */
1846  {
1847  /*
1848  * If there are no more hosts, return (the error message is
1849  * already set)
1850  */
1851  if (++conn->whichhost >= conn->nconnhost)
1852  {
1853  conn->whichhost = 0;
1854  conn->status = CONNECTION_BAD;
1855  return 0;
1856  }
1857 
1858  /*
1859  * Attempt connection to the next host, starting the
1860  * connect_timeout timer
1861  */
1862  pqDropConnection(conn, true);
1863  conn->addr_cur = conn->connhost[conn->whichhost].addrlist;
1864  conn->status = CONNECTION_NEEDED;
1865  if (conn->connect_timeout != NULL)
1866  finish_time = time(NULL) + timeout;
1867  }
1868 
1869  /*
1870  * Now try to advance the state machine.
1871  */
1872  flag = PQconnectPoll(conn);
1873  }
1874 }
struct addrinfo * addr_cur
Definition: libpq-int.h:412
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:405
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
Definition: fe-misc.c:999
char * connect_timeout
Definition: libpq-int.h:335
pg_conn_host * connhost
Definition: libpq-int.h:396
char * flag(int b)
Definition: test-ctype.c:33
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:1937
PQExpBufferData errorMessage
Definition: libpq-int.h:490
#define NULL
Definition: c.h:229
struct addrinfo * addrlist
Definition: libpq-int.h:314
ConnStatusType status
Definition: libpq-int.h:378
PostgresPollingStatusType
Definition: libpq-fe.h:72
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
int nconnhost
Definition: libpq-int.h:394
int whichhost
Definition: libpq-int.h:395
static int connectDBStart ( PGconn conn)
static

Definition at line 1622 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().

1623 {
1624  char portstr[MAXPGPATH];
1625  int ret;
1626  int i;
1627 
1628  if (!conn)
1629  return 0;
1630 
1631  if (!conn->options_valid)
1632  goto connect_errReturn;
1633 
1634  /* Ensure our buffers are empty */
1635  conn->inStart = conn->inCursor = conn->inEnd = 0;
1636  conn->outCount = 0;
1637 
1638  /*
1639  * Look up socket addresses for each possible host using
1640  * pg_getaddrinfo_all.
1641  */
1642  for (i = 0; i < conn->nconnhost; ++i)
1643  {
1644  pg_conn_host *ch = &conn->connhost[i];
1645  struct addrinfo hint;
1646  int thisport;
1647 
1648  /* Initialize hint structure */
1649  MemSet(&hint, 0, sizeof(hint));
1650  hint.ai_socktype = SOCK_STREAM;
1651  hint.ai_family = AF_UNSPEC;
1652 
1653  /* Figure out the port number we're going to use. */
1654  if (ch->port == NULL)
1655  thisport = DEF_PGPORT;
1656  else
1657  {
1658  thisport = atoi(ch->port);
1659  if (thisport < 1 || thisport > 65535)
1660  {
1662  libpq_gettext("invalid port number: \"%s\"\n"),
1663  ch->port);
1664  conn->options_valid = false;
1665  goto connect_errReturn;
1666  }
1667  }
1668  snprintf(portstr, sizeof(portstr), "%d", thisport);
1669 
1670  /* Use pg_getaddrinfo_all() to resolve the address */
1671  ret = 1;
1672  switch (ch->type)
1673  {
1674  case CHT_HOST_NAME:
1675  ret = pg_getaddrinfo_all(ch->host, portstr, &hint, &ch->addrlist);
1676  if (ret || !ch->addrlist)
1678  libpq_gettext("could not translate host name \"%s\" to address: %s\n"),
1679  ch->host, gai_strerror(ret));
1680  break;
1681 
1682  case CHT_HOST_ADDRESS:
1683  hint.ai_flags = AI_NUMERICHOST;
1684  ret = pg_getaddrinfo_all(ch->host, portstr, &hint, &ch->addrlist);
1685  if (ret || !ch->addrlist)
1687  libpq_gettext("could not parse network address \"%s\": %s\n"),
1688  ch->host, gai_strerror(ret));
1689  break;
1690 
1691  case CHT_UNIX_SOCKET:
1692 #ifdef HAVE_UNIX_SOCKETS
1693  hint.ai_family = AF_UNIX;
1694  UNIXSOCK_PATH(portstr, thisport, ch->host);
1695  if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
1696  {
1698  libpq_gettext("Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n"),
1699  portstr,
1700  (int) (UNIXSOCK_PATH_BUFLEN - 1));
1701  conn->options_valid = false;
1702  goto connect_errReturn;
1703  }
1704 
1705  /*
1706  * NULL hostname tells pg_getaddrinfo_all to parse the service
1707  * name as a Unix-domain socket path.
1708  */
1709  ret = pg_getaddrinfo_all(NULL, portstr, &hint, &ch->addrlist);
1710  if (ret || !ch->addrlist)
1712  libpq_gettext("could not translate Unix-domain socket path \"%s\" to address: %s\n"),
1713  portstr, gai_strerror(ret));
1714  break;
1715 #else
1716  Assert(false);
1717  conn->options_valid = false;
1718  goto connect_errReturn;
1719 #endif
1720  }
1721  if (ret || !ch->addrlist)
1722  {
1723  if (ch->addrlist)
1724  {
1725  pg_freeaddrinfo_all(hint.ai_family, ch->addrlist);
1726  ch->addrlist = NULL;
1727  }
1728  conn->options_valid = false;
1729  goto connect_errReturn;
1730  }
1731  }
1732 
1733 #ifdef USE_SSL
1734  /* setup values based on SSL mode */
1735  if (conn->sslmode[0] == 'd') /* "disable" */
1736  conn->allow_ssl_try = false;
1737  else if (conn->sslmode[0] == 'a') /* "allow" */
1738  conn->wait_ssl_try = true;
1739 #endif
1740 
1741  /*
1742  * Set up to try to connect, with protocol 3.0 as the first attempt.
1743  */
1744  conn->whichhost = 0;
1745  conn->addr_cur = conn->connhost[0].addrlist;
1746  conn->pversion = PG_PROTOCOL(3, 0);
1747  conn->send_appname = true;
1748  conn->status = CONNECTION_NEEDED;
1749 
1750  /*
1751  * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
1752  * so that it can easily be re-executed if needed again during the
1753  * asynchronous startup process. However, we must run it once here,
1754  * because callers expect a success return from this routine to mean that
1755  * we are in PGRES_POLLING_WRITING connection state.
1756  */
1757  if (PQconnectPoll(conn) == PGRES_POLLING_WRITING)
1758  return 1;
1759 
1760 connect_errReturn:
1761  pqDropConnection(conn, true);
1762  conn->status = CONNECTION_BAD;
1763  return 0;
1764 }
int inEnd
Definition: libpq-int.h:432
void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
Definition: ip.c:88
#define UNIXSOCK_PATH(path, port, sockdir)
Definition: pqcomm.h:70
int inStart
Definition: libpq-int.h:430
struct addrinfo * addr_cur
Definition: libpq-int.h:412
#define UNIXSOCK_PATH_BUFLEN
Definition: pqcomm.h:86
int outCount
Definition: libpq-int.h:437
char * host
Definition: libpq-int.h:307
#define MemSet(start, val, len)
Definition: c.h:857
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:405
#define AI_NUMERICHOST
Definition: getaddrinfo.h:73
pg_conn_host_type type
Definition: libpq-int.h:308
#define gai_strerror
Definition: getaddrinfo.h:146
int pg_getaddrinfo_all(const char *hostname, const char *servname, const struct addrinfo *hintp, struct addrinfo **result)
Definition: ip.c:57
#define MAXPGPATH
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
pg_conn_host * connhost
Definition: libpq-int.h:396
char * sslmode
Definition: libpq-int.h:351
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:1937
PQExpBufferData errorMessage
Definition: libpq-int.h:490
bool options_valid
Definition: libpq-int.h:384
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
struct addrinfo * addrlist
Definition: libpq-int.h:314
ProtocolVersion pversion
Definition: libpq-int.h:403
ConnStatusType status
Definition: libpq-int.h:378
int i
int inCursor
Definition: libpq-int.h:431
char * port
Definition: libpq-int.h:309
int nconnhost
Definition: libpq-int.h:394
#define PG_PROTOCOL(m, n)
Definition: pqcomm.h:106
int whichhost
Definition: libpq-int.h:395
#define libpq_gettext(x)
Definition: libpq-int.h:681
bool send_appname
Definition: libpq-int.h:415
static void connectFailureMessage ( PGconn conn,
int  errorno 
)
static

Definition at line 1351 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().

1352 {
1353  char sebuf[256];
1354 
1355 #ifdef HAVE_UNIX_SOCKETS
1356  if (IS_AF_UNIX(conn->raddr.addr.ss_family))
1357  {
1358  char service[NI_MAXHOST];
1359 
1360  pg_getnameinfo_all(&conn->raddr.addr, conn->raddr.salen,
1361  NULL, 0,
1362  service, sizeof(service),
1363  NI_NUMERICSERV);
1365  libpq_gettext("could not connect to server: %s\n"
1366  "\tIs the server running locally and accepting\n"
1367  "\tconnections on Unix domain socket \"%s\"?\n"),
1368  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1369  service);
1370  }
1371  else
1372 #endif /* HAVE_UNIX_SOCKETS */
1373  {
1374  char host_addr[NI_MAXHOST];
1375  const char *displayed_host;
1376  const char *displayed_port;
1377  struct sockaddr_storage *addr = &conn->raddr.addr;
1378 
1379  /*
1380  * Optionally display the network address with the hostname. This is
1381  * useful to distinguish between IPv4 and IPv6 connections.
1382  */
1383  if (conn->pghostaddr != NULL)
1384  strlcpy(host_addr, conn->pghostaddr, NI_MAXHOST);
1385  else if (addr->ss_family == AF_INET)
1386  {
1387  if (inet_net_ntop(AF_INET,
1388  &((struct sockaddr_in *) addr)->sin_addr.s_addr,
1389  32,
1390  host_addr, sizeof(host_addr)) == NULL)
1391  strcpy(host_addr, "???");
1392  }
1393 #ifdef HAVE_IPV6
1394  else if (addr->ss_family == AF_INET6)
1395  {
1396  if (inet_net_ntop(AF_INET6,
1397  &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
1398  128,
1399  host_addr, sizeof(host_addr)) == NULL)
1400  strcpy(host_addr, "???");
1401  }
1402 #endif
1403  else
1404  strcpy(host_addr, "???");
1405 
1406  /* To which host and port were we actually connecting? */
1407  displayed_host = conn->connhost[conn->whichhost].host;
1408  displayed_port = conn->connhost[conn->whichhost].port;
1409  if (displayed_port == NULL || displayed_port[0] == '\0')
1410  displayed_port = DEF_PGPORT_STR;
1411 
1412  /*
1413  * If the user did not supply an IP address using 'hostaddr', and
1414  * 'host' was missing or does not match our lookup, display the
1415  * looked-up IP address.
1416  */
1417  if ((conn->pghostaddr == NULL) &&
1418  (conn->pghost == NULL || strcmp(conn->pghost, host_addr) != 0))
1420  libpq_gettext("could not connect to server: %s\n"
1421  "\tIs the server running on host \"%s\" (%s) and accepting\n"
1422  "\tTCP/IP connections on port %s?\n"),
1423  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1424  displayed_host,
1425  host_addr,
1426  displayed_port);
1427  else
1429  libpq_gettext("could not connect to server: %s\n"
1430  "\tIs the server running on host \"%s\" and accepting\n"
1431  "\tTCP/IP connections on port %s?\n"),
1432  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1433  displayed_host,
1434  displayed_port);
1435  }
1436 }
char * host
Definition: libpq-int.h:307
struct sockaddr_storage addr
Definition: pqcomm.h:64
#define SOCK_STRERROR
Definition: libpq-int.h:695
#define NI_MAXHOST
Definition: getaddrinfo.h:88
#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:396
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:77
SockAddr raddr
Definition: libpq-int.h:402
PQExpBufferData errorMessage
Definition: libpq-int.h:490
#define NI_NUMERICSERV
Definition: getaddrinfo.h:81
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:229
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:122
char * pghostaddr
Definition: libpq-int.h:329
char * port
Definition: libpq-int.h:309
int whichhost
Definition: libpq-int.h:395
#define libpq_gettext(x)
Definition: libpq-int.h:681
char * pghost
Definition: libpq-int.h:324
static int connectNoDelay ( PGconn conn)
static

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

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

Referenced by PQconnectPoll().

1324 {
1325 #ifdef TCP_NODELAY
1326  int on = 1;
1327 
1328  if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
1329  (char *) &on,
1330  sizeof(on)) < 0)
1331  {
1332  char sebuf[256];
1333 
1335  libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
1336  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1337  return 0;
1338  }
1339 #endif
1340 
1341  return 1;
1342 }
#define SOCK_STRERROR
Definition: libpq-int.h:695
#define SOCK_ERRNO
Definition: libpq-int.h:694
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
pgsocket sock
Definition: libpq-int.h:399
PQExpBufferData errorMessage
Definition: libpq-int.h:490
#define libpq_gettext(x)
Definition: libpq-int.h:681
static bool connectOptions1 ( PGconn conn,
const char *  conninfo 
)
static

Definition at line 778 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().

779 {
780  PQconninfoOption *connOptions;
781 
782  /*
783  * Parse the conninfo string
784  */
785  connOptions = parse_connection_string(conninfo, &conn->errorMessage, true);
786  if (connOptions == NULL)
787  {
788  conn->status = CONNECTION_BAD;
789  /* errorMessage is already set */
790  return false;
791  }
792 
793  /*
794  * Move option values into conn structure
795  */
796  if (!fillPGconn(conn, connOptions))
797  {
798  conn->status = CONNECTION_BAD;
799  PQconninfoFree(connOptions);
800  return false;
801  }
802 
803  /*
804  * Free the option info - all is in conn now
805  */
806  PQconninfoFree(connOptions);
807 
808  return true;
809 }
static PQconninfoOption * parse_connection_string(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4696
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5864
PQExpBufferData errorMessage
Definition: libpq-int.h:490
#define NULL
Definition: c.h:229
static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
Definition: fe-connect.c:736
ConnStatusType status
Definition: libpq-int.h:378
static bool connectOptions2 ( PGconn conn)
static

Definition at line 820 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().

821 {
822  /*
823  * Allocate memory for details about each host to which we might possibly
824  * try to connect. If pghostaddr is set, we're only going to try to
825  * connect to that one particular address. If it's not, we'll use pghost,
826  * which may contain multiple, comma-separated names.
827  */
828  conn->nconnhost = 1;
829  conn->whichhost = 0;
830  if ((conn->pghostaddr == NULL || conn->pghostaddr[0] == '\0')
831  && conn->pghost != NULL)
832  {
833  char *s;
834 
835  for (s = conn->pghost; *s != '\0'; ++s)
836  if (*s == ',')
837  conn->nconnhost++;
838  }
839  conn->connhost = (pg_conn_host *)
840  calloc(conn->nconnhost, sizeof(pg_conn_host));
841  if (conn->connhost == NULL)
842  goto oom_error;
843 
844  /*
845  * We now have one pg_conn_host structure per possible host. Fill in the
846  * host details for each one.
847  */
848  if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
849  {
850  conn->connhost[0].host = strdup(conn->pghostaddr);
851  if (conn->connhost[0].host == NULL)
852  goto oom_error;
853  conn->connhost[0].type = CHT_HOST_ADDRESS;
854  }
855  else if (conn->pghost != NULL && conn->pghost[0] != '\0')
856  {
857  int i = 0;
858  char *s = conn->pghost;
859 
860  while (1)
861  {
862  char *e = s;
863 
864  /*
865  * Search for the end of the current hostname; a comma or
866  * end-of-string acts as a terminator.
867  */
868  while (*e != '\0' && *e != ',')
869  ++e;
870 
871  /* Copy the hostname whose bounds we just identified. */
872  conn->connhost[i].host =
873  (char *) malloc(sizeof(char) * (e - s + 1));
874  if (conn->connhost[i].host == NULL)
875  goto oom_error;
876  memcpy(conn->connhost[i].host, s, e - s);
877  conn->connhost[i].host[e - s] = '\0';
878 
879  /* Identify the type of host. */
880  conn->connhost[i].type = CHT_HOST_NAME;
881 #ifdef HAVE_UNIX_SOCKETS
882  if (is_absolute_path(conn->connhost[i].host))
883  conn->connhost[i].type = CHT_UNIX_SOCKET;
884 #endif
885 
886  /* Prepare to find the next host (if any). */
887  if (*e == '\0')
888  break;
889  s = e + 1;
890  i++;
891  }
892  }
893  else
894  {
895 #ifdef HAVE_UNIX_SOCKETS
896  conn->connhost[0].host = strdup(DEFAULT_PGSOCKET_DIR);
897  conn->connhost[0].type = CHT_UNIX_SOCKET;
898 #else
899  conn->connhost[0].host = strdup(DefaultHost);
900  conn->connhost[0].type = CHT_HOST_NAME;
901 #endif
902  if (conn->connhost[0].host == NULL)
903  goto oom_error;
904  }
905 
906  /*
907  * Next, work out the port number corresponding to each host name.
908  */
909  if (conn->pgport != NULL && conn->pgport[0] != '\0')
910  {
911  int i = 0;
912  char *s = conn->pgport;
913  int nports = 1;
914 
915  for (i = 0; i < conn->nconnhost; ++i)
916  {
917  char *e = s;
918 
919  /* Search for the end of the current port number. */
920  while (*e != '\0' && *e != ',')
921  ++e;
922 
923  /*
924  * If we found a port number of non-zero length, copy it.
925  * Otherwise, insert the default port number.
926  */
927  if (e > s)
928  {
929  conn->connhost[i].port =
930  (char *) malloc(sizeof(char) * (e - s + 1));
931  if (conn->connhost[i].port == NULL)
932  goto oom_error;
933  memcpy(conn->connhost[i].port, s, e - s);
934  conn->connhost[i].port[e - s] = '\0';
935  }
936 
937  /*
938  * Move on to the next port number, unless there are no more. (If
939  * only one part number is specified, we reuse it for every host.)
940  */
941  if (*e != '\0')
942  {
943  s = e + 1;
944  ++nports;
945  }
946  }
947 
948  /*
949  * If multiple ports were specified, there must be exactly as many
950  * ports as there were hosts. Otherwise, we do not know how to match
951  * them up.
952  */
953  if (nports != 1 && nports != conn->nconnhost)
954  {
955  conn->status = CONNECTION_BAD;
957  libpq_gettext("could not match %d port numbers to %d hosts\n"),
958  nports, conn->nconnhost);
959  return false;
960  }
961  }
962 
963  /*
964  * If user name was not given, fetch it. (Most likely, the fetch will
965  * fail, since the only way we get here is if pg_fe_getauthname() failed
966  * during conninfo_add_defaults(). But now we want an error message.)
967  */
968  if (conn->pguser == NULL || conn->pguser[0] == '\0')
969  {
970  if (conn->pguser)
971  free(conn->pguser);
972  conn->pguser = pg_fe_getauthname(&conn->errorMessage);
973  if (!conn->pguser)
974  {
975  conn->status = CONNECTION_BAD;
976  return false;
977  }
978  }
979 
980  /*
981  * If database name was not given, default it to equal user name
982  */
983  if (conn->dbName == NULL || conn->dbName[0] == '\0')
984  {
985  if (conn->dbName)
986  free(conn->dbName);
987  conn->dbName = strdup(conn->pguser);
988  if (!conn->dbName)
989  goto oom_error;
990  }
991 
992  /*
993  * Supply default password if none given. Note that the password might be
994  * different for each host/port pair.
995  */
996  if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
997  {
998  int i;
999 
1000  if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
1001  {
1002  /* Identify password file to use; fail if we can't */
1003  char homedir[MAXPGPATH];
1004 
1005  if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
1006  {
1007  conn->status = CONNECTION_BAD;
1009  libpq_gettext("could not get home directory to locate password file\n"));
1010  return false;
1011  }
1012 
1013  if (conn->pgpassfile)
1014  free(conn->pgpassfile);
1015  conn->pgpassfile = malloc(MAXPGPATH);
1016  if (!conn->pgpassfile)
1017  goto oom_error;
1018 
1019  snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s", homedir, PGPASSFILE);
1020  }
1021 
1022  for (i = 0; i < conn->nconnhost; i++)
1023  {
1024  /*
1025  * Try to get a password for this host from pgpassfile. We use
1026  * host name rather than host address in the same manner to
1027  * PQhost().
1028  */
1029  char *pwhost = conn->connhost[i].host;
1030 
1031  if (conn->connhost[i].type == CHT_HOST_ADDRESS &&
1032  conn->pghost != NULL && conn->pghost[0] != '\0')
1033  pwhost = conn->pghost;
1034 
1035  conn->connhost[i].password =
1036  passwordFromFile(pwhost,
1037  conn->connhost[i].port,
1038  conn->dbName,
1039  conn->pguser,
1040  conn->pgpassfile);
1041  /* If we got one, set pgpassfile_used */
1042  if (conn->connhost[i].password != NULL)
1043  conn->pgpassfile_used = true;
1044  }
1045  }
1046 
1047  /*
1048  * validate sslmode option
1049  */
1050  if (conn->sslmode)
1051  {
1052  if (strcmp(conn->sslmode, "disable") != 0
1053  && strcmp(conn->sslmode, "allow") != 0
1054  && strcmp(conn->sslmode, "prefer") != 0
1055  && strcmp(conn->sslmode, "require") != 0
1056  && strcmp(conn->sslmode, "verify-ca") != 0
1057  && strcmp(conn->sslmode, "verify-full") != 0)
1058  {
1059  conn->status = CONNECTION_BAD;
1061  libpq_gettext("invalid sslmode value: \"%s\"\n"),
1062  conn->sslmode);
1063  return false;
1064  }
1065 
1066 #ifndef USE_SSL
1067  switch (conn->sslmode[0])
1068  {
1069  case 'a': /* "allow" */
1070  case 'p': /* "prefer" */
1071 
1072  /*
1073  * warn user that an SSL connection will never be negotiated
1074  * since SSL was not compiled in?
1075  */
1076  break;
1077 
1078  case 'r': /* "require" */
1079  case 'v': /* "verify-ca" or "verify-full" */
1080  conn->status = CONNECTION_BAD;
1082  libpq_gettext("sslmode value \"%s\" invalid when SSL support is not compiled in\n"),
1083  conn->sslmode);
1084  return false;
1085  }
1086 #endif
1087  }
1088  else
1089  {
1090  conn->sslmode = strdup(DefaultSSLMode);
1091  if (!conn->sslmode)
1092  goto oom_error;
1093  }
1094 
1095  /*
1096  * Resolve special "auto" client_encoding from the locale
1097  */
1098  if (conn->client_encoding_initial &&
1099  strcmp(conn->client_encoding_initial, "auto") == 0)
1100  {
1103  if (!conn->client_encoding_initial)
1104  goto oom_error;
1105  }
1106 
1107  /*
1108  * Validate target_session_attrs option.
1109  */
1110  if (conn->target_session_attrs)
1111  {
1112  if (strcmp(conn->target_session_attrs, "any") != 0
1113  && strcmp(conn->target_session_attrs, "read-write") != 0)
1114  {
1115  conn->status = CONNECTION_BAD;
1117  libpq_gettext("invalid target_session_attrs value: \"%s\"\n"),
1118  conn->target_session_attrs);
1119  return false;
1120  }
1121  }
1122 
1123  /*
1124  * Only if we get this far is it appropriate to try to connect. (We need a
1125  * state flag, rather than just the boolean result of this function, in
1126  * case someone tries to PQreset() the PGconn.)
1127  */
1128  conn->options_valid = true;
1129 
1130  return true;
1131 
1132 oom_error:
1133  conn->status = CONNECTION_BAD;
1135  libpq_gettext("out of memory\n"));
1136  return false;
1137 }
#define calloc(a, b)
Definition: header.h:55
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * pgpassfile
Definition: libpq-int.h:344
char * host
Definition: libpq-int.h:307
char * dbName
Definition: libpq-int.h:340
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
bool pgpassfile_used
Definition: libpq-int.h:407
#define DefaultSSLMode
Definition: fe-connect.c:109
pg_conn_host_type type
Definition: libpq-int.h:308
char * client_encoding_initial
Definition: libpq-int.h:336
#define malloc(a)
Definition: header.h:50
#define PGPASSFILE
Definition: fe-connect.c:79
#define MAXPGPATH
pg_conn_host * connhost
Definition: libpq-int.h:396
#define is_absolute_path(filename)
Definition: port.h:77
char * target_session_attrs
Definition: libpq-int.h:364
char * pguser
Definition: libpq-int.h:342
char * sslmode
Definition: libpq-int.h:351
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:1024
PQExpBufferData errorMessage
Definition: libpq-int.h:490
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:433
#define free(a)
Definition: header.h:65
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:607
bool options_valid
Definition: libpq-int.h:384
#define NULL
Definition: c.h:229
char * pgpass
Definition: libpq-int.h:343
ConnStatusType status
Definition: libpq-int.h:378
#define DefaultHost
Definition: fe-connect.c:101
static char * passwordFromFile(char *hostname, char *port, char *dbname, char *username, char *pgpassfile)
Definition: fe-connect.c:6277
char * pghostaddr
Definition: libpq-int.h:329
e
Definition: preproc-init.c:82
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:6433
int i
char * port
Definition: libpq-int.h:309
char * pgport
Definition: libpq-int.h:332
int nconnhost
Definition: libpq-int.h:394
int whichhost
Definition: libpq-int.h:395
#define libpq_gettext(x)
Definition: libpq-int.h:681
char * pghost
Definition: libpq-int.h:324
#define DEFAULT_PGSOCKET_DIR
char * password
Definition: libpq-int.h:311
static bool conninfo_add_defaults ( PQconninfoOption options,
PQExpBuffer  errorMessage 
)
static

Definition at line 5092 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().

5093 {
5095  char *tmp;
5096 
5097  /*
5098  * If there's a service spec, use it to obtain any not-explicitly-given
5099  * parameters. Ignore error if no error message buffer is passed because
5100  * there is no way to pass back the failure message.
5101  */
5102  if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
5103  return false;
5104 
5105  /*
5106  * Get the fallback resources for parameters not specified in the conninfo
5107  * string nor the service.
5108  */
5109  for (option = options; option->keyword != NULL; option++)
5110  {
5111  if (option->val != NULL)
5112  continue; /* Value was in conninfo or service */
5113 
5114  /*
5115  * Try to get the environment variable fallback
5116  */
5117  if (option->envvar != NULL)
5118  {
5119  if ((tmp = getenv(option->envvar)) != NULL)
5120  {
5121  option->val = strdup(tmp);
5122  if (!option->val)
5123  {
5124  if (errorMessage)
5125  printfPQExpBuffer(errorMessage,
5126  libpq_gettext("out of memory\n"));
5127  return false;
5128  }
5129  continue;
5130  }
5131  }
5132 
5133  /*
5134  * Interpret the deprecated PGREQUIRESSL environment variable. Per
5135  * tradition, translate values starting with "1" to sslmode=require,
5136  * and ignore other values. Given both PGREQUIRESSL=1 and PGSSLMODE,
5137  * PGSSLMODE takes precedence; the opposite was true before v9.3.
5138  */
5139  if (strcmp(option->keyword, "sslmode") == 0)
5140  {
5141  const char *requiresslenv = getenv("PGREQUIRESSL");
5142 
5143  if (requiresslenv != NULL && requiresslenv[0] == '1')
5144  {
5145  option->val = strdup("require");
5146  if (!option->val)
5147  {
5148  if (errorMessage)
5149  printfPQExpBuffer(errorMessage,
5150  libpq_gettext("out of memory\n"));
5151  return false;
5152  }
5153  continue;
5154  }
5155  }
5156 
5157  /*
5158  * No environment variable specified or the variable isn't set - try
5159  * compiled-in default
5160  */
5161  if (option->compiled != NULL)
5162  {
5163  option->val = strdup(option->compiled);
5164  if (!option->val)
5165  {
5166  if (errorMessage)
5167  printfPQExpBuffer(errorMessage,
5168  libpq_gettext("out of memory\n"));
5169  return false;
5170  }
5171  continue;
5172  }
5173 
5174  /*
5175  * Special handling for "user" option. Note that if pg_fe_getauthname
5176  * fails, we just leave the value as NULL; there's no need for this to
5177  * be an error condition if the caller provides a user name. The only
5178  * reason we do this now at all is so that callers of PQconndefaults
5179  * will see a correct default (barring error, of course).
5180  */
5181  if (strcmp(option->keyword, "user") == 0)
5182  {
5183  option->val = pg_fe_getauthname(NULL);
5184  continue;
5185  }
5186  }
5187 
5188  return true;
5189 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:1024
#define NULL
Definition: c.h:229
static int parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:4390
#define libpq_gettext(x)
Definition: libpq-int.h:681
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 4928 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().

4931 {
4933  PQconninfoOption *dbname_options = NULL;
4935  int i = 0;
4936 
4937  /*
4938  * If expand_dbname is non-zero, check keyword "dbname" to see if val is
4939  * actually a recognized connection string.
4940  */
4941  while (expand_dbname && keywords[i])
4942  {
4943  const char *pname = keywords[i];
4944  const char *pvalue = values[i];
4945 
4946  /* first find "dbname" if any */
4947  if (strcmp(pname, "dbname") == 0 && pvalue)
4948  {
4949  /*
4950  * If value is a connection string, parse it, but do not use
4951  * defaults here -- those get picked up later. We only want to
4952  * override for those parameters actually passed.
4953  */
4954  if (recognized_connection_string(pvalue))
4955  {
4956  dbname_options = parse_connection_string(pvalue, errorMessage, false);
4957  if (dbname_options == NULL)
4958  return NULL;
4959  }
4960  break;
4961  }
4962  ++i;
4963  }
4964 
4965  /* Make a working copy of PQconninfoOptions */
4966  options = conninfo_init(errorMessage);
4967  if (options == NULL)
4968  {
4969  PQconninfoFree(dbname_options);
4970  return NULL;
4971  }
4972 
4973  /* Parse the keywords/values arrays */
4974  i = 0;
4975  while (keywords[i])
4976  {
4977  const char *pname = keywords[i];
4978  const char *pvalue = values[i];
4979 
4980  if (pvalue != NULL && pvalue[0] != '\0')
4981  {
4982  /* Search for the param record */
4983  for (option = options; option->keyword != NULL; option++)
4984  {
4985  if (strcmp(option->keyword, pname) == 0)
4986  break;
4987  }
4988 
4989  /* Check for invalid connection option */
4990  if (option->keyword == NULL)
4991  {
4992  printfPQExpBuffer(errorMessage,
4993  libpq_gettext("invalid connection option \"%s\"\n"),
4994  pname);
4995  PQconninfoFree(options);
4996  PQconninfoFree(dbname_options);
4997  return NULL;
4998  }
4999 
5000  /*
5001  * If we are on the first dbname parameter, and we have a parsed
5002  * connection string, copy those parameters across, overriding any
5003  * existing previous settings.
5004  */
5005  if (strcmp(pname, "dbname") == 0 && dbname_options)
5006  {
5007  PQconninfoOption *str_option;
5008 
5009  for (str_option = dbname_options; str_option->keyword != NULL; str_option++)
5010  {
5011  if (str_option->val != NULL)
5012  {
5013  int k;
5014 
5015  for (k = 0; options[k].keyword; k++)
5016  {
5017  if (strcmp(options[k].keyword, str_option->keyword) == 0)
5018  {
5019  if (options[k].val)
5020  free(options[k].val);
5021  options[k].val = strdup(str_option->val);
5022  if (!options[k].val)
5023  {
5024  printfPQExpBuffer(errorMessage,
5025  libpq_gettext("out of memory\n"));
5026  PQconninfoFree(options);
5027  PQconninfoFree(dbname_options);
5028  return NULL;
5029  }
5030  break;
5031  }
5032  }
5033  }
5034  }
5035 
5036  /*
5037  * Forget the parsed connection string, so that any subsequent
5038  * dbname parameters will not be expanded.
5039  */
5040  PQconninfoFree(dbname_options);
5041  dbname_options = NULL;
5042  }
5043  else
5044  {
5045  /*
5046  * Store the value, overriding previous settings
5047  */
5048  if (option->val)
5049  free(option->val);
5050  option->val = strdup(pvalue);
5051  if (!option->val)
5052  {
5053  printfPQExpBuffer(errorMessage,
5054  libpq_gettext("out of memory\n"));
5055  PQconninfoFree(options);
5056  PQconninfoFree(dbname_options);
5057  return NULL;
5058  }
5059  }
5060  }
5061  ++i;
5062  }
5063  PQconninfoFree(dbname_options);
5064 
5065  /*
5066  * Add in defaults if the caller wants that.
5067  */
5068  if (use_defaults)
5069  {
5070  if (!conninfo_add_defaults(options, errorMessage))
5071  {
5072  PQconninfoFree(options);
5073  return NULL;
5074  }
5075  }
5076 
5077  return options;
5078 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4656
static PQconninfoOption * parse_connection_string(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4696
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5864
static char ** options
static bool recognized_connection_string(const char *connstr)
Definition: fe-connect.c:4739
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5092
static Datum values[MAXATTR]
Definition: bootstrap.c:163
int i
long val
Definition: informix.c:689
#define libpq_gettext(x)
Definition: libpq-int.h:681
static PQconninfoOption * conninfo_find ( PQconninfoOption connOptions,
const char *  keyword 
)
static

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

References _PQconninfoOption::keyword, and NULL.

Referenced by conninfo_getval(), and conninfo_storeval().

5806 {
5808 
5809  for (option = connOptions; option->keyword != NULL; option++)
5810  {
5811  if (strcmp(option->keyword, keyword) == 0)
5812  return option;
5813  }
5814 
5815  return NULL;
5816 }
#define NULL
Definition: c.h:229
static const char * conninfo_getval ( PQconninfoOption connOptions,
const char *  keyword 
)
static

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

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

Referenced by fillPGconn(), and parseServiceInfo().

5716 {
5718 
5719  option = conninfo_find(connOptions, keyword);
5720 
5721  return option ? option->val : NULL;
5722 }
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5805
#define NULL
Definition: c.h:229
static PQconninfoOption * conninfo_init ( PQExpBuffer  errorMessage)
static

Definition at line 4656 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().

4657 {
4659  PQconninfoOption *opt_dest;
4660  const internalPQconninfoOption *cur_opt;
4661 
4662  /*
4663  * Get enough memory for all options in PQconninfoOptions, even if some
4664  * end up being filtered out.
4665  */
4666  options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
4667  if (options == NULL)
4668  {
4669  printfPQExpBuffer(errorMessage,
4670  libpq_gettext("out of memory\n"));
4671  return NULL;
4672  }
4673  opt_dest = options;
4674 
4675  for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
4676  {
4677  /* Only copy the public part of the struct, not the full internal */
4678  memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
4679  opt_dest++;
4680  }
4681  MemSet(opt_dest, 0, sizeof(PQconninfoOption));
4682 
4683  return options;
4684 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define MemSet(start, val, len)
Definition: c.h:857
#define malloc(a)
Definition: header.h:50
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:162
static char ** options
#define NULL
Definition: c.h:229
#define libpq_gettext(x)
Definition: libpq-int.h:681
static PQconninfoOption * conninfo_parse ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

Definition at line 4750 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().

4752 {
4753  char *pname;
4754  char *pval;
4755  char *buf;
4756  char *cp;
4757  char *cp2;
4759 
4760  /* Make a working copy of PQconninfoOptions */
4761  options = conninfo_init(errorMessage);
4762  if (options == NULL)
4763  return NULL;
4764 
4765  /* Need a modifiable copy of the input string */
4766  if ((buf = strdup(conninfo)) == NULL)
4767  {
4768  printfPQExpBuffer(errorMessage,
4769  libpq_gettext("out of memory\n"));
4770  PQconninfoFree(options);
4771  return NULL;
4772  }
4773  cp = buf;
4774 
4775  while (*cp)
4776  {
4777  /* Skip blanks before the parameter name */
4778  if (isspace((unsigned char) *cp))
4779  {
4780  cp++;
4781  continue;
4782  }
4783 
4784  /* Get the parameter name */
4785  pname = cp;
4786  while (*cp)
4787  {
4788  if (*cp == '=')
4789  break;
4790  if (isspace((unsigned char) *cp))
4791  {
4792  *cp++ = '\0';
4793  while (*cp)
4794  {
4795  if (!isspace((unsigned char) *cp))
4796  break;
4797  cp++;
4798  }
4799  break;
4800  }
4801  cp++;
4802  }
4803 
4804  /* Check that there is a following '=' */
4805  if (*cp != '=')
4806  {
4807  printfPQExpBuffer(errorMessage,
4808  libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
4809  pname);
4810  PQconninfoFree(options);
4811  free(buf);
4812  return NULL;
4813  }
4814  *cp++ = '\0';
4815 
4816  /* Skip blanks after the '=' */
4817  while (*cp)
4818  {
4819  if (!isspace((unsigned char) *cp))
4820  break;
4821  cp++;
4822  }
4823 
4824  /* Get the parameter value */
4825  pval = cp;
4826 
4827  if (*cp != '\'')
4828  {
4829  cp2 = pval;
4830  while (*cp)
4831  {
4832  if (isspace((unsigned char) *cp))
4833  {
4834  *cp++ = '\0';
4835  break;
4836  }
4837  if (*cp == '\\')
4838  {
4839  cp++;
4840  if (*cp != '\0')
4841  *cp2++ = *cp++;
4842  }
4843  else
4844  *cp2++ = *cp++;
4845  }
4846  *cp2 = '\0';
4847  }
4848  else
4849  {
4850  cp2 = pval;
4851  cp++;
4852  for (;;)
4853  {
4854  if (*cp == '\0')
4855  {
4856  printfPQExpBuffer(errorMessage,
4857  libpq_gettext("unterminated quoted string in connection info string\n"));
4858  PQconninfoFree(options);
4859  free(buf);
4860  return NULL;
4861  }
4862  if (*cp == '\\')
4863  {
4864  cp++;
4865  if (*cp != '\0')
4866  *cp2++ = *cp++;
4867  continue;
4868  }
4869  if (*cp == '\'')
4870  {
4871  *cp2 = '\0';
4872  cp++;
4873  break;
4874  }
4875  *cp2++ = *cp++;
4876  }
4877  }
4878 
4879  /*
4880  * Now that we have the name and the value, store the record.
4881  */
4882  if (!conninfo_storeval(options, pname, pval, errorMessage, false, false))
4883  {
4884  PQconninfoFree(options);
4885  free(buf);
4886  return NULL;
4887  }
4888  }
4889 
4890  /* Done with the modifiable input string */
4891  free(buf);
4892 
4893  /*
4894  * Add in defaults if the caller wants that.
4895  */
4896  if (use_defaults)
4897  {
4898  if (!conninfo_add_defaults(options, errorMessage))
4899  {
4900  PQconninfoFree(options);
4901  return NULL;
4902  }
4903  }
4904 
4905  return options;
4906 }
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:5740
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4656
static char * buf
Definition: pg_test_fsync.c:66
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5864
static char ** options
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5092
#define libpq_gettext(x)
Definition: libpq-int.h:681
static PQconninfoOption * conninfo_storeval ( PQconninfoOption connOptions,
const char *  keyword,
const char *  value,
PQExpBuffer  errorMessage,
bool  ignoreMissing,
bool  uri_decode 
)
static

Definition at line 5740 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().

5744 {
5746  char *value_copy;
5747 
5748  /*
5749  * For backwards compatibility, requiressl=1 gets translated to
5750  * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
5751  * (which is the default for sslmode).
5752  */
5753  if (strcmp(keyword, "requiressl") == 0)
5754  {
5755  keyword = "sslmode";
5756  if (value[0] == '1')
5757  value = "require";
5758  else
5759  value = "prefer";
5760  }
5761 
5762  option = conninfo_find(connOptions, keyword);
5763  if (option == NULL)
5764  {
5765  if (!ignoreMissing)
5766  printfPQExpBuffer(errorMessage,
5767  libpq_gettext("invalid connection option \"%s\"\n"),
5768  keyword);
5769  return NULL;
5770  }
5771 
5772  if (uri_decode)
5773  {
5774  value_copy = conninfo_uri_decode(value, errorMessage);
5775  if (value_copy == NULL)
5776  /* conninfo_uri_decode already set an error message */
5777  return NULL;
5778  }
5779  else
5780  {
5781  value_copy = strdup(value);
5782  if (value_copy == NULL)
5783  {
5784  printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5785  return NULL;
5786  }
5787  }
5788 
5789  if (option->val)
5790  free(option->val);
5791  option->val = value_copy;
5792 
5793  return option;
5794 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5805
static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
Definition: fe-connect.c:5625
static struct @121 value
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
#define libpq_gettext(x)
Definition: libpq-int.h:681
static char * conninfo_uri_decode ( const char *  str,
PQExpBuffer  errorMessage 
)
static

Definition at line 5625 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().

5626 {
5627  char *buf;
5628  char *p;
5629  const char *q = str;
5630 
5631  buf = malloc(strlen(str) + 1);
5632  if (buf == NULL)
5633  {
5634  printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5635  return NULL;
5636  }
5637  p = buf;
5638 
5639  for (;;)
5640  {
5641  if (*q != '%')
5642  {
5643  /* copy and check for NUL terminator */
5644  if (!(*(p++) = *(q++)))
5645  break;
5646  }
5647  else
5648  {
5649  int hi;
5650  int lo;
5651  int c;
5652 
5653  ++q; /* skip the percent sign itself */
5654 
5655  /*
5656  * Possible EOL will be caught by the first call to
5657  * get_hexdigit(), so we never dereference an invalid q pointer.
5658  */
5659  if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
5660  {
5661  printfPQExpBuffer(errorMessage,
5662  libpq_gettext("invalid percent-encoded token: \"%s\"\n"),
5663  str);
5664  free(buf);
5665  return NULL;
5666  }
5667 
5668  c = (hi << 4) | lo;
5669  if (c == 0)
5670  {
5671  printfPQExpBuffer(errorMessage,
5672  libpq_gettext("forbidden value %%00 in percent-encoded value: \"%s\"\n"),
5673  str);
5674  free(buf);
5675  return NULL;
5676  }
5677  *(p++) = c;
5678  }
5679  }
5680 
5681  return buf;
5682 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define malloc(a)
Definition: header.h:50
char * c
static char * buf
Definition: pg_test_fsync.c:66
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
static bool get_hexdigit(char digit, int *value)
Definition: fe-connect.c:5693
#define libpq_gettext(x)
Definition: libpq-int.h:681
static PQconninfoOption * conninfo_uri_parse ( const char *  uri,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

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

Referenced by parse_connection_string().

5199 {
5201 
5202  /* Make a working copy of PQconninfoOptions */
5203  options = conninfo_init(errorMessage);
5204  if (options == NULL)
5205  return NULL;
5206 
5207  if (!conninfo_uri_parse_options(options, uri, errorMessage))
5208  {
5209  PQconninfoFree(options);
5210  return NULL;
5211  }
5212 
5213  /*
5214  * Add in defaults if the caller wants that.
5215  */
5216  if (use_defaults)
5217  {
5218  if (!conninfo_add_defaults(options, errorMessage))
5219  {
5220  PQconninfoFree(options);
5221  return NULL;
5222  }
5223  }
5224 
5225  return options;
5226 }
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4656
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5864
static bool conninfo_uri_parse_options(PQconninfoOption *options, const char *uri, PQExpBuffer errorMessage)
Definition: fe-connect.c:5250
static char ** options
#define NULL
Definition: c.h:229
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5092
static bool conninfo_uri_parse_options ( PQconninfoOption options,
const char *  uri,
PQExpBuffer  errorMessage 
)
static

Definition at line 5250 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().

5252 {
5253  int prefix_len;
5254  char *p;
5255  char *buf = NULL;
5256  char *start;
5257  char prevchar = '\0';
5258  char *user = NULL;
5259  char *host = NULL;
5260  bool retval = false;
5261  PQExpBufferData hostbuf;
5262  PQExpBufferData portbuf;
5263 
5264  initPQExpBuffer(&hostbuf);
5265  initPQExpBuffer(&portbuf);
5266  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
5267  {
5268  printfPQExpBuffer(errorMessage,
5269  libpq_gettext("out of memory\n"));
5270  goto cleanup;
5271  }
5272 
5273  /* need a modifiable copy of the input URI */
5274  buf = strdup(uri);
5275  if (buf == NULL)
5276  {
5277  printfPQExpBuffer(errorMessage,
5278  libpq_gettext("out of memory\n"));
5279  goto cleanup;
5280  }
5281  start = buf;
5282 
5283  /* Skip the URI prefix */
5284  prefix_len = uri_prefix_length(uri);
5285  if (prefix_len == 0)
5286  {
5287  /* Should never happen */
5288  printfPQExpBuffer(errorMessage,
5289  libpq_gettext("invalid URI propagated to internal parser routine: \"%s\"\n"),
5290  uri);
5291  goto cleanup;
5292  }
5293  start += prefix_len;
5294  p = start;
5295 
5296  /* Look ahead for possible user credentials designator */
5297  while (*p && *p != '@' && *p != '/')
5298  ++p;
5299  if (*p == '@')
5300  {
5301  /*
5302  * Found username/password designator, so URI should be of the form
5303  * "scheme://user[:password]@[netloc]".
5304  */
5305  user = start;
5306 
5307  p = user;
5308  while (*p != ':' && *p != '@')
5309  ++p;
5310 
5311  /* Save last char and cut off at end of user name */
5312  prevchar = *p;
5313  *p = '\0';
5314 
5315  if (*user &&
5316  !conninfo_storeval(options, "user", user,
5317  errorMessage, false, true))
5318  goto cleanup;
5319 
5320  if (prevchar == ':')
5321  {
5322  const char *password = p + 1;
5323 
5324  while (*p != '@')
5325  ++p;
5326  *p = '\0';
5327 
5328  if (*password &&
5329  !conninfo_storeval(options, "password", password,
5330  errorMessage, false, true))
5331  goto cleanup;
5332  }
5333 
5334  /* Advance past end of parsed user name or password token */
5335  ++p;
5336  }
5337  else
5338  {
5339  /*
5340  * No username/password designator found. Reset to start of URI.
5341  */
5342  p = start;
5343  }
5344 
5345  /*
5346  * There may be multiple netloc[:port] pairs, each separated from the next
5347  * by a comma. When we initially enter this loop, "p" has been
5348  * incremented past optional URI credential information at this point and
5349  * now points at the "netloc" part of the URI. On subsequent loop
5350  * iterations, "p" has been incremented past the comma separator and now
5351  * points at the start of the next "netloc".
5352  */
5353  for (;;)
5354  {
5355  /*
5356  * Look for IPv6 address.
5357  */
5358  if (*p == '[')
5359  {
5360  host = ++p;
5361  while (*p && *p != ']')
5362  ++p;
5363  if (!*p)
5364  {
5365  printfPQExpBuffer(errorMessage,
5366  libpq_gettext("end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n"),
5367  uri);
5368  goto cleanup;
5369  }
5370  if (p == host)
5371  {
5372  printfPQExpBuffer(errorMessage,
5373  libpq_gettext("IPv6 host address may not be empty in URI: \"%s\"\n"),
5374  uri);
5375  goto cleanup;
5376  }
5377 
5378  /* Cut off the bracket and advance */
5379  *(p++) = '\0';
5380 
5381  /*
5382  * The address may be followed by a port specifier or a slash or a
5383  * query or a separator comma.
5384  */
5385  if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
5386  {
5387  printfPQExpBuffer(errorMessage,
5388  libpq_gettext("unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n"),
5389  *p, (int) (p - buf + 1), uri);
5390  goto cleanup;
5391  }
5392  }
5393  else
5394  {
5395  /* not an IPv6 address: DNS-named or IPv4 netloc */
5396  host = p;
5397 
5398  /*
5399  * Look for port specifier (colon) or end of host specifier
5400  * (slash) or query (question mark) or host separator (comma).
5401  */
5402  while (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
5403  ++p;
5404  }
5405 
5406  /* Save the hostname terminator before we null it */
5407  prevchar = *p;
5408  *p = '\0';
5409 
5410  appendPQExpBufferStr(&hostbuf, host);
5411 
5412  if (prevchar == ':')
5413  {
5414  const char *port = ++p; /* advance past host terminator */
5415 
5416  while (*p && *p != '/' && *p != '?' && *p != ',')
5417  ++p;
5418 
5419  prevchar = *p;
5420  *p = '\0';
5421 
5422  appendPQExpBufferStr(&portbuf, port);
5423  }
5424 
5425  if (prevchar != ',')
5426  break;
5427  ++p; /* advance past comma separator */
5428  appendPQExpBufferStr(&hostbuf, ",");
5429  appendPQExpBufferStr(&portbuf, ",");
5430  }
5431 
5432  /* Save final values for host and port. */
5433  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
5434  goto cleanup;
5435  if (hostbuf.data[0] &&
5436  !conninfo_storeval(options, "host", hostbuf.data,
5437  errorMessage, false, true))
5438  goto cleanup;
5439  if (portbuf.data[0] &&
5440  !conninfo_storeval(options, "port", portbuf.data,
5441  errorMessage, false, true))
5442  goto cleanup;
5443 
5444  if (prevchar && prevchar != '?')
5445  {
5446  const char *dbname = ++p; /* advance past host terminator */
5447 
5448  /* Look for query parameters */
5449  while (*p && *p != '?')
5450  ++p;
5451 
5452  prevchar = *p;
5453  *p = '\0';
5454 
5455  /*
5456  * Avoid setting dbname to an empty string, as it forces the default
5457  * value (username) and ignores $PGDATABASE, as opposed to not setting
5458  * it at all.
5459  */
5460  if (*dbname &&
5461  !conninfo_storeval(options, "dbname", dbname,
5462  errorMessage, false, true))
5463  goto cleanup;
5464  }
5465 
5466  if (prevchar)
5467  {
5468  ++p; /* advance past terminator */
5469 
5470  if (!conninfo_uri_parse_params(p, options, errorMessage))
5471  goto cleanup;
5472  }
5473 
5474  /* everything parsed okay */
5475  retval = true;
5476 
5477 cleanup:
5478  termPQExpBuffer(&hostbuf);
5479  termPQExpBuffer(&portbuf);
5480  if (buf)
5481  free(buf);
5482  return retval;
5483 }
static char password[100]
Definition: streamutil.c:41
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:5740
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:66
static int port
Definition: pg_regress.c:89
static void cleanup(void)
Definition: bootstrap.c:860
static bool conninfo_uri_parse_params(char *params, PQconninfoOption *connOptions, PQExpBuffer errorMessage)
Definition: fe-connect.c:5494
#define free(a)
Definition: header.h:65
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
#define NULL
Definition: c.h:229
char * dbname
Definition: streamutil.c:38
static char * user
Definition: pg_regress.c:92
static int uri_prefix_length(const char *connstr)
Definition: fe-connect.c:4716
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
#define libpq_gettext(x)
Definition: libpq-int.h:681
static bool conninfo_uri_parse_params ( char *  params,
PQconninfoOption connOptions,
PQExpBuffer  errorMessage 
)
static

Definition at line 5494 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().

5497 {
5498  while (*params)
5499  {
5500  char *keyword = params;
5501  char *value = NULL;
5502  char *p = params;
5503  bool malloced = false;
5504 
5505  /*
5506  * Scan the params string for '=' and '&', marking the end of keyword
5507  * and value respectively.
5508  */
5509  for (;;)
5510  {
5511  if (*p == '=')
5512  {
5513  /* Was there '=' already? */
5514  if (value != NULL)
5515  {
5516  printfPQExpBuffer(errorMessage,
5517  libpq_gettext("extra key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5518  keyword);
5519  return false;
5520  }
5521  /* Cut off keyword, advance to value */
5522  *p++ = '\0';
5523  value = p;
5524  }
5525  else if (*p == '&' || *p == '\0')
5526  {
5527  /*
5528  * If not at the end, cut off value and advance; leave p
5529  * pointing to start of the next parameter, if any.
5530  */
5531  if (*p != '\0')
5532  *p++ = '\0';
5533  /* Was there '=' at all? */
5534  if (value == NULL)
5535  {
5536  printfPQExpBuffer(errorMessage,
5537  libpq_gettext("missing key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5538  keyword);
5539  return false;
5540  }
5541  /* Got keyword and value, go process them. */
5542  break;
5543  }
5544  else
5545  ++p; /* Advance over all other bytes. */
5546  }
5547 
5548  keyword = conninfo_uri_decode(keyword, errorMessage);
5549  if (keyword == NULL)
5550  {
5551  /* conninfo_uri_decode already set an error message */
5552  return false;
5553  }
5554  value = conninfo_uri_decode(value, errorMessage);
5555  if (value == NULL)
5556  {
5557  /* conninfo_uri_decode already set an error message */
5558  free(keyword);
5559  return false;
5560  }
5561  malloced = true;
5562 
5563  /*
5564  * Special keyword handling for improved JDBC compatibility.
5565  */
5566  if (strcmp(keyword, "ssl") == 0 &&
5567  strcmp(value, "true") == 0)
5568  {
5569  free(keyword);
5570  free(value);
5571  malloced = false;
5572 
5573  keyword = "sslmode";
5574  value = "require";
5575  }
5576 
5577  /*
5578  * Store the value if the corresponding option exists; ignore
5579  * otherwise. At this point both keyword and value are not
5580  * URI-encoded.
5581  */
5582  if (!conninfo_storeval(connOptions, keyword, value,
5583  errorMessage, true, false))
5584  {
5585  /* Insert generic message if conninfo_storeval didn't give one. */
5586  if (errorMessage->len == 0)
5587  printfPQExpBuffer(errorMessage,
5588  libpq_gettext("invalid URI query parameter: \"%s\"\n"),
5589  keyword);
5590  /* And fail. */
5591  if (malloced)
5592  {
5593  free(keyword);
5594  free(value);
5595  }
5596  return false;
5597  }
5598 
5599  if (malloced)
5600  {
5601  free(keyword);
5602  free(value);
5603  }
5604 
5605  /* Proceed to next key=value pair, if any */
5606  params = p;
5607  }
5608 
5609  return true;
5610 }
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:5740
static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
Definition: fe-connect.c:5625
static struct @121 value
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
#define libpq_gettext(x)
Definition: libpq-int.h:681
static void default_threadlock ( int  acquire)
static

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

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

Referenced by PQregisterThreadLock().

6463 {
6464 #ifdef ENABLE_THREAD_SAFETY
6465 #ifndef WIN32
6466  static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
6467 #else
6468  static pthread_mutex_t singlethread_lock = NULL;
6469  static long mutex_initlock = 0;
6470 
6471  if (singlethread_lock == NULL)
6472  {
6473  while (InterlockedExchange(&mutex_initlock, 1) == 1)
6474  /* loop, another thread own the lock */ ;
6475  if (singlethread_lock == NULL)
6476  {
6477  if (pthread_mutex_init(&singlethread_lock, NULL))
6478  PGTHREAD_ERROR("failed to initialize mutex");
6479  }
6480  InterlockedExchange(&mutex_initlock, 0);
6481  }
6482 #endif
6483  if (acquire)
6484  {
6485  if (pthread_mutex_lock(&singlethread_lock))
6486  PGTHREAD_ERROR("failed to lock mutex");
6487  }
6488  else
6489  {
6490  if (pthread_mutex_unlock(&singlethread_lock))
6491  PGTHREAD_ERROR("failed to unlock mutex");
6492  }
6493 #endif
6494 }
CRITICAL_SECTION * pthread_mutex_t
Definition: pthread-win32.h:8
int pthread_mutex_init(pthread_mutex_t *mp, void *attr)
Definition: pthread-win32.c:35
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:45
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:54
#define NULL
Definition: c.h:229
static void defaultNoticeProcessor ( void *  arg,
const char *  message 
)
static

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

Referenced by makeEmptyPGconn().

6229 {
6230  (void) arg; /* not used */
6231  /* Note: we expect the supplied string to end with a newline already. */
6232  fprintf(stderr, "%s", message);
6233 }
void * arg
static void defaultNoticeReceiver ( void *  arg,
const PGresult res 
)
static

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

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

Referenced by makeEmptyPGconn().

6214 {
6215  (void) arg; /* not used */
6216  if (res->noticeHooks.noticeProc != NULL)
6218  PQresultErrorMessage(res));
6219 }
PGNoticeHooks noticeHooks
Definition: libpq-int.h:186
void * noticeProcArg
Definition: libpq-int.h:155
PQnoticeProcessor noticeProc
Definition: libpq-int.h:154
#define NULL
Definition: c.h:229
char * PQresultErrorMessage(const PGresult *res)
Definition: fe-exec.c:2612
void * arg
static bool fillPGconn ( PGconn conn,
PQconninfoOption connOptions 
)
static

Definition at line 736 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().

737 {
739 
740  for (option = PQconninfoOptions; option->keyword; option++)
741  {
742  if (option->connofs >= 0)
743  {
744  const char *tmp = conninfo_getval(connOptions, option->keyword);
745 
746  if (tmp)
747  {
748  char **connmember = (char **) ((char *) conn + option->connofs);
749 
750  if (*connmember)
751  free(*connmember);
752  *connmember = strdup(tmp);
753  if (*connmember == NULL)
754  {
756  libpq_gettext("out of memory\n"));
757  return false;
758  }
759  }
760  }
761  }
762 
763  return true;
764 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:162
PQExpBufferData errorMessage
Definition: libpq-int.h:490
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
static const char * conninfo_getval(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5714
#define libpq_gettext(x)
Definition: libpq-int.h:681
static void freePGconn ( PGconn conn)
static

Definition at line 3322 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().

3323 {
3324  int i;
3325 
3326  /* let any event procs clean up their state data */
3327  for (i = 0; i < conn->nEvents; i++)
3328  {
3329  PGEventConnDestroy evt;
3330 
3331  evt.conn = conn;
3332  (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
3333  conn->events[i].passThrough);
3334  free(conn->events[i].name);
3335  }
3336 
3337  /* clean up pg_conn_host structures */
3338  if (conn->connhost != NULL)
3339  {
3340  for (i = 0; i < conn->nconnhost; ++i)
3341  {
3342  if (conn->connhost[i].host != NULL)
3343  free(conn->connhost[i].host);
3344  if (conn->connhost[i].port != NULL)
3345  free(conn->connhost[i].port);
3346  if (conn->connhost[i].password != NULL)
3347  free(conn->connhost[i].password);
3348  }
3349  free(conn->connhost);
3350  }
3351 
3352  if (conn->client_encoding_initial)
3354  if (conn->events)
3355  free(conn->events);
3356  if (conn->pghost)
3357  free(conn->pghost);
3358  if (conn->pghostaddr)
3359  free(conn->pghostaddr);
3360  if (conn->pgport)
3361  free(conn->pgport);
3362  if (conn->pgtty)
3363  free(conn->pgtty);
3364  if (conn->connect_timeout)
3365  free(conn->connect_timeout);
3366  if (conn->pgoptions)
3367  free(conn->pgoptions);
3368  if (conn->appname)
3369  free(conn->appname);
3370  if (conn->fbappname)
3371  free(conn->fbappname);
3372  if (conn->dbName)
3373  free(conn->dbName);
3374  if (conn->replication)
3375  free(conn->replication);
3376  if (conn->pguser)
3377  free(conn->pguser);
3378  if (conn->pgpass)
3379  free(conn->pgpass);
3380  if (conn->pgpassfile)
3381  free(conn->pgpassfile);
3382  if (conn->keepalives)
3383  free(conn->keepalives);
3384  if (conn->keepalives_idle)
3385  free(conn->keepalives_idle);
3386  if (conn->keepalives_interval)
3387  free(conn->keepalives_interval);
3388  if (conn->keepalives_count)
3389  free(conn->keepalives_count);
3390  if (conn->sslmode)
3391  free(conn->sslmode);
3392  if (conn->sslcert)
3393  free(conn->sslcert);
3394  if (conn->sslkey)
3395  free(conn->sslkey);
3396  if (conn->sslrootcert)
3397  free(conn->sslrootcert);
3398  if (conn->sslcrl)
3399  free(conn->sslcrl);
3400  if (conn->sslcompression)
3401  free(conn->sslcompression);
3402  if (conn->requirepeer)
3403  free(conn->requirepeer);
3404 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
3405  if (conn->krbsrvname)
3406  free(conn->krbsrvname);
3407 #endif
3408 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
3409  if (conn->gsslib)
3410  free(conn->gsslib);
3411 #endif
3412  /* Note that conn->Pfdebug is not ours to close or free */
3413  if (conn->last_query)
3414  free(conn->last_query);
3415  if (conn->inBuffer)
3416  free(conn->inBuffer);
3417  if (conn->outBuffer)
3418  free(conn->outBuffer);
3419  if (conn->rowBuf)
3420  free(conn->rowBuf);
3421  if (conn->target_session_attrs)
3422  free(conn->target_session_attrs);
3423  termPQExpBuffer(&conn->errorMessage);
3424  termPQExpBuffer(&conn->workBuffer);
3425 
3426  free(conn);
3427 
3428 #ifdef WIN32
3429  WSACleanup();
3430 #endif
3431 }
PGEvent * events
Definition: libpq-int.h:373
char * replication
Definition: libpq-int.h:341
char * pgpassfile
Definition: libpq-int.h:344
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
PQExpBufferData workBuffer
Definition: libpq-int.h:493
char * requirepeer
Definition: libpq-int.h:357
char * host
Definition: libpq-int.h:307
char * dbName
Definition: libpq-int.h:340
char * keepalives
Definition: libpq-int.h:345
char * keepalives_idle
Definition: libpq-int.h:346
char * client_encoding_initial
Definition: libpq-int.h:336
char * sslkey
Definition: libpq-int.h:353
char * sslcompression
Definition: libpq-int.h:352
PGconn * conn
Definition: streamutil.c:42
char * connect_timeout
Definition: libpq-int.h:335
pg_conn_host * connhost
Definition: libpq-int.h:396
char * keepalives_interval
Definition: libpq-int.h:347
char * appname
Definition: libpq-int.h:338
char * target_session_attrs
Definition: libpq-int.h:364
char * last_query
Definition: libpq-int.h:382
PGdataValue * rowBuf
Definition: libpq-int.h:445
char * pguser
Definition: libpq-int.h:342
char * inBuffer
Definition: libpq-int.h:428
char * sslmode
Definition: libpq-int.h:351
PQExpBufferData errorMessage
Definition: libpq-int.h:490
char * sslcert
Definition: libpq-int.h:354
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
char * pgoptions
Definition: libpq-int.h:337
char * pgpass
Definition: libpq-int.h:343
char * sslrootcert
Definition: libpq-int.h:355
PGEventProc proc
Definition: libpq-int.h:160
char * outBuffer
Definition: libpq-int.h:435
char * pghostaddr
Definition: libpq-int.h:329
int nEvents
Definition: libpq-int.h:374
int i
void * passThrough
Definition: libpq-int.h:162
char * fbappname
Definition: libpq-int.h:339
char * port
Definition: libpq-int.h:309
char * pgport
Definition: libpq-int.h:332
int nconnhost
Definition: libpq-int.h:394
char * name
Definition: libpq-int.h:161
char * sslcrl
Definition: libpq-int.h:356
char * keepalives_count
Definition: libpq-int.h:349
char * pghost
Definition: libpq-int.h:324
char * pgtty
Definition: libpq-int.h:333
char * password
Definition: libpq-int.h:311
static bool get_hexdigit ( char  digit,
int *  value 
)
static

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

Referenced by conninfo_uri_decode().

5694 {
5695  if ('0' <= digit && digit <= '9')
5696  *value = digit - '0';
5697  else if ('A' <= digit && digit <= 'F')
5698  *value = digit - 'A' + 10;
5699  else if ('a' <= digit && digit <= 'f')
5700  *value = digit - 'a' + 10;
5701  else
5702  return false;
5703 
5704  return true;
5705 }
static struct @121 value
static int internal_cancel ( SockAddr raddr,
int  be_pid,
int  be_key,
char *  errbuf,
int  errbufsize 
)
static

Definition at line 3719 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().

3721 {
3722  int save_errno = SOCK_ERRNO;
3723  pgsocket tmpsock = PGINVALID_SOCKET;
3724  char sebuf[256];
3725  int maxlen;
3726  struct
3727  {
3728  uint32 packetlen;
3730  } crp;
3731 
3732  /*
3733  * We need to open a temporary connection to the postmaster. Do this with
3734  * only kernel calls.
3735  */
3736  if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
3737  {
3738  strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
3739  goto cancel_errReturn;
3740  }
3741 retry3:
3742  if (connect(tmpsock, (struct sockaddr *) &raddr->addr,
3743  raddr->salen) < 0)
3744  {
3745  if (SOCK_ERRNO == EINTR)
3746  /* Interrupted system call - we'll just try again */
3747  goto retry3;
3748  strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
3749  goto cancel_errReturn;
3750  }
3751 
3752  /*
3753  * We needn't set nonblocking I/O or NODELAY options here.
3754  */
3755 
3756  /* Create and send the cancel request packet. */
3757 
3758  crp.packetlen = htonl((uint32) sizeof(crp));
3759  crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE);
3760  crp.cp.backendPID = htonl(be_pid);
3761  crp.cp.cancelAuthCode = htonl(be_key);
3762 
3763 retry4:
3764  if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
3765  {
3766  if (SOCK_ERRNO == EINTR)
3767  /* Interrupted system call - we'll just try again */
3768  goto retry4;
3769  strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
3770  goto cancel_errReturn;
3771  }
3772 
3773  /*
3774  * Wait for the postmaster to close the connection, which indicates that
3775  * it's processed the request. Without this delay, we might issue another
3776  * command only to find that our cancel zaps that command instead of the
3777  * one we thought we were canceling. Note we don't actually expect this
3778  * read to obtain any data, we are just waiting for EOF to be signaled.
3779  */
3780 retry5:
3781  if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
3782  {
3783  if (SOCK_ERRNO == EINTR)
3784  /* Interrupted system call - we'll just try again */
3785  goto retry5;
3786  /* we ignore other error conditions */
3787  }
3788 
3789  /* All done */
3790  closesocket(tmpsock);
3791  SOCK_ERRNO_SET(save_errno);
3792  return TRUE;
3793 
3794 cancel_errReturn:
3795 
3796  /*
3797  * Make sure we don't overflow the error buffer. Leave space for the \n at
3798  * the end, and for the terminating zero.
3799  */
3800  maxlen = errbufsize - strlen(errbuf) - 2;
3801  if (maxlen >= 0)
3802  {
3803  strncat(errbuf, SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)),
3804  maxlen);
3805  strcat(errbuf, "\n");
3806  }
3807  if (tmpsock != PGINVALID_SOCKET)
3808  closesocket(tmpsock);
3809  SOCK_ERRNO_SET(save_errno);
3810  return FALSE;
3811 }
#define send(s, buf, len, flags)
Definition: win32.h:376
#define connect(s, name, namelen)
Definition: win32.h:373
#define closesocket
Definition: port.h:328
struct sockaddr_storage addr
Definition: pqcomm.h:64
#define socket(af, type, protocol)
Definition: win32.h:369
#define recv(s, buf, len, flags)
Definition: win32.h:375
#define SOCK_STRERROR
Definition: libpq-int.h:695
#define FALSE
Definition: c.h:221
#define SOCK_ERRNO
Definition: libpq-int.h:694
unsigned int uint32
Definition: c.h:268
int pgsocket
Definition: port.h:22
ACCEPT_TYPE_ARG3 salen
Definition: pqcomm.h:65
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:696
#define PGINVALID_SOCKET
Definition: port.h:24
#define EINTR
Definition: win32.h:285
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:190
ProtocolVersion MsgType
Definition: pqcomm.h:115
#define TRUE
Definition: c.h:217
static PGPing internal_ping ( PGconn conn)
static

Definition at line 3161 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().

3162 {
3163  /* Say "no attempt" if we never got to PQconnectPoll */
3164  if (!conn || !conn->options_valid)
3165  return PQPING_NO_ATTEMPT;
3166 
3167  /* Attempt to complete the connection */
3168  if (conn->status != CONNECTION_BAD)
3169  (void) connectDBComplete(conn);
3170 
3171  /* Definitely OK if we succeeded */
3172  if (conn->status != CONNECTION_BAD)
3173  return PQPING_OK;
3174 
3175  /*
3176  * Here begins the interesting part of "ping": determine the cause of the
3177  * failure in sufficient detail to decide what to return. We do not want
3178  * to report that the server is not up just because we didn't have a valid
3179  * password, for example. In fact, any sort of authentication request
3180  * implies the server is up. (We need this check since the libpq side of
3181  * things might have pulled the plug on the connection before getting an
3182  * error as such from the postmaster.)
3183  */
3184  if (conn->auth_req_received)
3185  return PQPING_OK;
3186 
3187  /*
3188  * If we failed to get any ERROR response from the postmaster, report
3189  * PQPING_NO_RESPONSE. This result could be somewhat misleading for a
3190  * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
3191  * out of support. Another corner case where the server could return a
3192  * failure without a SQLSTATE is fork failure, but NO_RESPONSE isn't
3193  * totally unreasonable for that anyway. We expect that every other
3194  * failure case in a modern server will produce a report with a SQLSTATE.
3195  *
3196  * NOTE: whenever we get around to making libpq generate SQLSTATEs for
3197  * client-side errors, we should either not store those into
3198  * last_sqlstate, or add an extra flag so we can tell client-side errors
3199  * apart from server-side ones.
3200  */
3201  if (strlen(conn->last_sqlstate) != 5)
3202  return PQPING_NO_RESPONSE;
3203 
3204  /*
3205  * Report PQPING_REJECT if server says it's not accepting connections. (We
3206  * distinguish this case mainly for the convenience of pg_ctl.)
3207  */
3208  if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
3209  return PQPING_REJECT;
3210 
3211  /*
3212  * Any other SQLSTATE can be taken to indicate that the server is up.
3213  * Presumably it didn't like our username, password, or database name; or
3214  * perhaps it had some transient failure, but that should not be taken as
3215  * meaning "it's down".
3216  */
3217  return PQPING_OK;
3218 }
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1775
bool options_valid
Definition: libpq-int.h:384
#define ERRCODE_CANNOT_CONNECT_NOW
Definition: fe-connect.c:95
ConnStatusType status
Definition: libpq-int.h:378
bool auth_req_received
Definition: libpq-int.h:405
char last_sqlstate[6]
Definition: libpq-int.h:383
static PGconn * makeEmptyPGconn ( void  )
static

Definition at line 3226 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().

3227 {
3228  PGconn *conn;
3229 
3230 #ifdef WIN32
3231 
3232  /*
3233  * Make sure socket support is up and running.
3234  */
3235  WSADATA wsaData;
3236 
3237  if (WSAStartup(MAKEWORD(1, 1), &wsaData))
3238  return NULL;
3239  WSASetLastError(0);
3240 #endif
3241 
3242  conn = (PGconn *) malloc(sizeof(PGconn));
3243  if (conn == NULL)
3244  {
3245 #ifdef WIN32
3246  WSACleanup();
3247 #endif
3248  return conn;
3249  }
3250 
3251  /* Zero all pointers and booleans */
3252  MemSet(conn, 0, sizeof(PGconn));
3253 
3254  /* install default notice hooks */
3257 
3258  conn->status = CONNECTION_BAD;
3259  conn->asyncStatus = PGASYNC_IDLE;
3260  conn->xactStatus = PQTRANS_IDLE;
3261  conn->options_valid = false;
3262  conn->nonblocking = false;
3264  conn->client_encoding = PG_SQL_ASCII;
3265  conn->std_strings = false; /* unless server says differently */
3266  conn->verbosity = PQERRORS_DEFAULT;
3268  conn->sock = PGINVALID_SOCKET;
3269  conn->auth_req_received = false;
3270  conn->password_needed = false;
3271  conn->pgpassfile_used = false;
3272 #ifdef USE_SSL
3273  conn->allow_ssl_try = true;
3274  conn->wait_ssl_try = false;
3275  conn->ssl_in_use = false;
3276 #endif
3277 
3278  /*
3279  * We try to send at least 8K at a time, which is the usual size of pipe
3280  * buffers on Unix systems. That way, when we are sending a large amount
3281  * of data, we avoid incurring extra kernel context swaps for partial
3282  * bufferloads. The output buffer is initially made 16K in size, and we
3283  * try to dump it after accumulating 8K.
3284  *
3285  * With the same goal of minimizing context swaps, the input buffer will
3286  * be enlarged anytime it has less than 8K free, so we initially allocate
3287  * twice that.
3288  */
3289  conn->inBufSize = 16 * 1024;
3290  conn->inBuffer = (char *) malloc(conn->inBufSize);
3291  conn->outBufSize = 16 * 1024;
3292  conn->outBuffer = (char *) malloc(conn->outBufSize);
3293  conn->rowBufLen = 32;
3294  conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
3295  initPQExpBuffer(&conn->errorMessage);
3296  initPQExpBuffer(&conn->workBuffer);
3297 
3298  if (conn->inBuffer == NULL ||
3299  conn->outBuffer == NULL ||
3300  conn->rowBuf == NULL ||
3301  PQExpBufferBroken(&conn->errorMessage) ||
3302  PQExpBufferBroken(&conn->workBuffer))
3303  {
3304  /* out of memory already :-( */
3305  freePGconn(conn);
3306  conn = NULL;
3307  }
3308 
3309  return conn;
3310 }
PGContextVisibility show_context
Definition: libpq-int.h:424
int rowBufLen
Definition: libpq-int.h:446
bool password_needed
Definition: libpq-int.h:406
PQExpBufferData workBuffer
Definition: libpq-int.h:493
#define MemSet(start, val, len)
Definition: c.h:857
bool pgpassfile_used
Definition: libpq-int.h:407
#define malloc(a)
Definition: header.h:50
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:379
PGSetenvStatusType setenv_state
Definition: libpq-int.h:413
PGconn * conn
Definition: streamutil.c:42
int inBufSize
Definition: libpq-int.h:429
PGNoticeHooks noticeHooks
Definition: libpq-int.h:370
PGVerbosity verbosity
Definition: libpq-int.h:423
PQnoticeReceiver noticeRec
Definition: libpq-int.h:152
PGdataValue * rowBuf
Definition: libpq-int.h:445
pgsocket sock
Definition: libpq-int.h:399
#define PGINVALID_SOCKET
Definition: port.h:24
char * inBuffer
Definition: libpq-int.h:428
PQnoticeProcessor noticeProc
Definition: libpq-int.h:154
static void freePGconn(PGconn *conn)
Definition: fe-connect.c:3322
PQExpBufferData errorMessage
Definition: libpq-int.h:490
bool std_strings
Definition: libpq-int.h:422
bool options_valid
Definition: libpq-int.h:384
int outBufSize
Definition: libpq-int.h:436
#define NULL
Definition: c.h:229
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
ConnStatusType status
Definition: libpq-int.h:378
bool auth_req_received
Definition: libpq-int.h:405
char * outBuffer
Definition: libpq-int.h:435
bool nonblocking
Definition: libpq-int.h:385
static void defaultNoticeProcessor(void *arg, const char *message)
Definition: fe-connect.c:6228
int client_encoding
Definition: libpq-int.h:421
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
static void defaultNoticeReceiver(void *arg, const PGresult *res)
Definition: fe-connect.c:6213
PGTransactionStatusType xactStatus
Definition: libpq-int.h:380
static PQconninfoOption * parse_connection_string ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

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

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

4698 {
4699  /* Parse as URI if connection string matches URI prefix */
4700  if (uri_prefix_length(connstr) != 0)
4701  return conninfo_uri_parse(connstr, errorMessage, use_defaults);
4702 
4703  /* Parse as default otherwise */
4704  return conninfo_parse(connstr, errorMessage, use_defaults);
4705 }
static PQconninfoOption * conninfo_parse(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4750
static int uri_prefix_length(const char *connstr)
Definition: fe-connect.c:4716
static PQconninfoOption * conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:5197
static char * connstr
Definition: pg_dumpall.c:64
static int parseServiceFile ( const char *  serviceFile,
const char *  service,
PQconninfoOption options,
PQExpBuffer  errorMessage,
bool group_found 
)
static

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

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

Referenced by parseServiceInfo().

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

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

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

Referenced by conninfo_add_defaults().

4391 {
4392  const char *service = conninfo_getval(options, "service");
4393  char serviceFile[MAXPGPATH];
4394  char *env;
4395  bool group_found = false;
4396  int status;
4397  struct stat stat_buf;
4398 
4399  /*
4400  * We have to special-case the environment variable PGSERVICE here, since
4401  * this is and should be called before inserting environment defaults for
4402  * other connection options.
4403  */
4404  if (service == NULL)
4405  service = getenv("PGSERVICE");
4406 
4407  if (service == NULL)
4408  return 0;
4409 
4410  if ((env = getenv("PGSERVICEFILE")) != NULL)
4411  strlcpy(serviceFile, env, sizeof(serviceFile));
4412  else
4413  {
4414  char homedir[MAXPGPATH];
4415 
4416  if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
4417  {
4418  printfPQExpBuffer(errorMessage, libpq_gettext("could not get home directory to locate service definition file"));
4419  return 1;
4420  }
4421  snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
4422  errno = 0;
4423  if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4424  goto next_file;
4425  }
4426 
4427  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4428  if (group_found || status != 0)
4429  return status;
4430 
4431 next_file:
4432 
4433  /*
4434  * This could be used by any application so we can't use the binary
4435  * location to find our config files.
4436  */
4437  snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
4438  getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
4439  errno = 0;
4440  if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4441  goto last_file;
4442 
4443  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4444  if (status != 0)
4445  return status;
4446 
4447 last_file:
4448  if (!group_found)
4449  {
4450  printfPQExpBuffer(errorMessage,
4451  libpq_gettext("definition of service \"%s\" not found\n"), service);
4452  return 3;
4453  }
4454 
4455  return 0;
4456 }
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:229
static int parseServiceFile(const char *serviceFile, const char *service, PQconninfoOption *options, PQExpBuffer errorMessage, bool *group_found)
Definition: fe-connect.c:4459
static const char * conninfo_getval(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5714
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:6433
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
#define libpq_gettext(x)
Definition: libpq-int.h:681
static char * passwordFromFile ( char *  hostname,
char *  port,
char *  dbname,
char *  username,
char *  pgpassfile 
)
static

Definition at line 6277 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().

6279 {
6280  FILE *fp;
6281  struct stat stat_buf;
6282 
6283 #define LINELEN NAMEDATALEN*5
6284  char buf[LINELEN];
6285 
6286  if (dbname == NULL || strlen(dbname) == 0)
6287  return NULL;
6288 
6289  if (username == NULL || strlen(username) == 0)
6290  return NULL;
6291 
6292  /* 'localhost' matches pghost of '' or the default socket directory */
6293  if (hostname == NULL)
6295  else if (is_absolute_path(hostname))
6296 
6297  /*
6298  * We should probably use canonicalize_path(), but then we have to
6299  * bring path.c into libpq, and it doesn't seem worth it.
6300  */
6301  if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
6303 
6304  if (port == NULL)
6305  port = DEF_PGPORT_STR;
6306 
6307  /* If password file cannot be opened, ignore it. */
6308  if (stat(pgpassfile, &stat_buf) != 0)
6309  return NULL;
6310 
6311 #ifndef WIN32
6312  if (!S_ISREG(stat_buf.st_mode))
6313  {
6314  fprintf(stderr,
6315  libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
6316  pgpassfile);
6317  return NULL;
6318  }
6319 
6320  /* If password file is insecure, alert the user and ignore it. */
6321  if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
6322  {
6323  fprintf(stderr,
6324  libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
6325  pgpassfile);
6326  return NULL;
6327  }
6328 #else
6329 
6330  /*
6331  * On Win32, the directory is protected, so we don't have to check the
6332  * file.
6333  */
6334 #endif
6335 
6336  fp = fopen(pgpassfile, "r");
6337  if (fp == NULL)
6338  return NULL;
6339 
6340  while (!feof(fp) && !ferror(fp))
6341  {
6342  char *t = buf,
6343  *ret,
6344  *p1,
6345  *p2;
6346  int len;
6347 
6348  if (fgets(buf, sizeof(buf), fp) == NULL)
6349  break;
6350 
6351  len = strlen(buf);
6352 
6353  /* Remove trailing newline */
6354  if (len > 0 && buf[len - 1] == '\n')
6355  {
6356  buf[--len] = '\0';
6357  /* Handle DOS-style line endings, too, even when not on Windows */
6358  if (len > 0 && buf[len - 1] == '\r')
6359  buf[--len] = '\0';
6360  }
6361 
6362  if (len == 0)
6363  continue;
6364 
6365  if ((t = pwdfMatchesString(t, hostname)) == NULL ||
6366  (t = pwdfMatchesString(t, port)) == NULL ||
6367  (t = pwdfMatchesString(t, dbname)) == NULL ||
6368  (t = pwdfMatchesString(t, username)) == NULL)
6369  continue;
6370 
6371  /* Found a match. */
6372  ret = strdup(t);
6373  fclose(fp);
6374 
6375  if (!ret)
6376  {
6377  /* Out of memory. XXX: an error message would be nice. */
6378  return NULL;
6379  }
6380 
6381  /* De-escape password. */
6382  for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
6383  {
6384  if (*p1 == '\\' && p1[1] != '\0')
6385  ++p1;
6386  *p2 = *p1;
6387  }
6388  *p2 = '\0';
6389 
6390  return ret;
6391  }
6392 
6393  fclose(fp);
6394  return NULL;
6395 
6396 #undef LINELEN
6397 }
#define LINELEN
struct stat stat_buf
Definition: pg_standby.c:101
static char * buf
Definition: pg_test_fsync.c:66
#define is_absolute_path(filename)
Definition: port.h:77
static int port
Definition: pg_regress.c:89
#define S_IRWXO
Definition: win32.h:455
static char * username
Definition: initdb.c:131
#define NULL
Definition: c.h:229
char * dbname
Definition: streamutil.c:38
#define DefaultHost
Definition: fe-connect.c:101
#define S_IRWXG
Definition: win32.h:451
static char * hostname
Definition: pg_regress.c:88
static char * pwdfMatchesString(char *buf, char *token)
Definition: fe-connect.c:6240
#define libpq_gettext(x)
Definition: libpq-int.h:681
#define DEFAULT_PGSOCKET_DIR
static void pgpassfileWarning ( PGconn conn)
static

Definition at line 6405 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().

6406 {
6407  /* If it was 'invalid authorization', add pgpassfile mention */
6408  /* only works with >= 9.0 servers */
6409  if (conn->pgpassfile_used && conn->password_needed && conn->result)
6410  {
6411  const char *sqlstate = PQresultErrorField(conn->result,
6413 
6414  if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
6416  libpq_gettext("password retrieved from file \"%s\"\n"),
6417  conn->pgpassfile);
6418  }
6419 }
char * pgpassfile
Definition: libpq-int.h:344
bool password_needed
Definition: libpq-int.h:406
bool pgpassfile_used
Definition: libpq-int.h:407
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
PGresult * result
Definition: libpq-int.h:449
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
PQExpBufferData errorMessage
Definition: libpq-int.h:490
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2658
#define ERRCODE_INVALID_PASSWORD
Definition: fe-connect.c:93
#define libpq_gettext(x)
Definition: libpq-int.h:681
int PQbackendPID ( const PGconn conn)

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

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

Referenced by get_prompt(), and LogStreamerMain().

6041 {
6042  if (!conn || conn->status != CONNECTION_OK)
6043  return 0;
6044  return conn->be_pid;
6045 }
ConnStatusType status
Definition: libpq-int.h:378
int be_pid
Definition: libpq-int.h:418
int PQcancel ( PGcancel cancel,
char *  errbuf,
int  errbufsize 
)

Definition at line 3823 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_cancel_query(), ShutdownWorkersHard(), sigTermHandler(), and try_complete_step().

3824 {
3825  if (!cancel)
3826  {
3827  strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
3828  return FALSE;
3829  }
3830 
3831  return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
3832  errbuf, errbufsize);
3833 }
static int internal_cancel(SockAddr *raddr, int be_pid, int be_key, char *errbuf, int errbufsize)
Definition: fe-connect.c:3719
int be_pid
Definition: libpq-int.h:503
#define FALSE
Definition: c.h:221
int be_key
Definition: libpq-int.h:504
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
SockAddr raddr
Definition: libpq-int.h:502
int PQclientEncoding ( const PGconn conn)

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

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

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

6075 {
6076  if (!conn || conn->status != CONNECTION_OK)
6077  return -1;
6078  return conn->client_encoding;
6079 }
ConnStatusType status
Definition: libpq-int.h:378
int client_encoding
Definition: libpq-int.h:421
PQconninfoOption* PQconndefaults ( void  )

Definition at line 1156 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().

1157 {
1158  PQExpBufferData errorBuf;
1159  PQconninfoOption *connOptions;
1160 
1161  /* We don't actually report any errors here, but callees want a buffer */
1162  initPQExpBuffer(&errorBuf);
1163  if (PQExpBufferDataBroken(errorBuf))
1164  return NULL; /* out of memory already :-( */
1165 
1166  connOptions = conninfo_init(&errorBuf);
1167  if (connOptions != NULL)
1168  {
1169  /* pass NULL errorBuf to ignore errors */
1170  if (!conninfo_add_defaults(connOptions, NULL))
1171  {
1172  PQconninfoFree(connOptions);
1173  connOptions = NULL;
1174  }
1175  }
1176 
1177  termPQExpBuffer(&errorBuf);
1178  return connOptions;
1179 }
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4656
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5864
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
#define NULL
Definition: c.h:229
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5092
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGconn* PQconnectdb ( const char *  conninfo)

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

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

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

567 {
568  PGconn *conn = PQconnectStart(conninfo);
569 
570  if (conn && conn->status != CONNECTION_BAD)
571  (void) connectDBComplete(conn);
572 
573  return conn;
574 }
PGconn * conn
Definition: streamutil.c:42
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1775
PGconn * PQconnectStart(const char *conninfo)
Definition: fe-connect.c:692
ConnStatusType status
Definition: libpq-int.h:378
PGconn* PQconnectdbParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)

Definition at line 510 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(), main(), sql_conn(), and vacuumlo().

513 {
514  PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
515 
516  if (conn && conn->status != CONNECTION_BAD)
517  (void) connectDBComplete(conn);
518 
519  return conn;
520 
521 }
PGconn * conn
Definition: streamutil.c:42
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1775
ConnStatusType status
Definition: libpq-int.h:378
static Datum values[MAXATTR]
Definition: bootstrap.c:163
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:613
int PQconnectionNeedsPassword ( const PGconn conn)

Definition at line 6048 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().

6049 {
6050  char *password;
6051 
6052  if (!conn)
6053  return false;
6054  password = PQpass(conn);
6055  if (conn->password_needed &&
6056  (password == NULL || password[0] == '\0'))
6057  return true;
6058  else
6059  return false;
6060 }
static char password[100]
Definition: streamutil.c:41
bool password_needed
Definition: libpq-int.h:406
char * PQpass(const PGconn *conn)
Definition: fe-connect.c:5898
#define NULL
Definition: c.h:229
int PQconnectionUsedPassword ( const PGconn conn)

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

References pg_conn::password_needed.

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

6064 {
6065  if (!conn)
6066  return false;
6067  if (conn->password_needed)
6068  return true;
6069  else
6070  return false;
6071 }
bool password_needed
Definition: libpq-int.h:406
PostgresPollingStatusType PQconnectPoll ( PGconn conn)

Definition at line 1937 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_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, 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, 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(), 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(), libpqrcv_connect(), and PQresetPoll().

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