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 4361 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 3431 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, pg_fe_scram_free(), PGASYNC_IDLE, pqClearAsyncResult(), pqDropConnection(), pg_conn::pstatus, release_all_addrinfo(), resetPQExpBuffer(), pg_conn::sasl_state, sendTerminateConn(), and pg_conn::status.

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

3432 {
3433  PGnotify *notify;
3434  pgParameterStatus *pstatus;
3435 
3436  sendTerminateConn(conn);
3437 
3438  /*
3439  * Must reset the blocking status so a possible reconnect will work.
3440  *
3441  * Don't call PQsetnonblocking() because it will fail if it's unable to
3442  * flush the connection.
3443  */
3444  conn->nonblocking = FALSE;
3445 
3446  /*
3447  * Close the connection, reset all transient state, flush I/O buffers.
3448  */
3449  pqDropConnection(conn, true);
3450  conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just
3451  * absent */
3452  conn->asyncStatus = PGASYNC_IDLE;
3453  pqClearAsyncResult(conn); /* deallocate result */
3455  release_all_addrinfo(conn);
3456 
3457  notify = conn->notifyHead;
3458  while (notify != NULL)
3459  {
3460  PGnotify *prev = notify;
3461 
3462  notify = notify->next;
3463  free(prev);
3464  }
3465  conn->notifyHead = conn->notifyTail = NULL;
3466  pstatus = conn->pstatus;
3467  while (pstatus != NULL)
3468  {
3469  pgParameterStatus *prev = pstatus;
3470 
3471  pstatus = pstatus->next;
3472  free(prev);
3473  }
3474  conn->pstatus = NULL;
3475  if (conn->lobjfuncs)
3476  free(conn->lobjfuncs);
3477  conn->lobjfuncs = NULL;
3478 #ifdef ENABLE_GSS
3479  {
3480  OM_uint32 min_s;
3481 
3482  if (conn->gctx)
3483  gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
3484  if (conn->gtarg_nam)
3485  gss_release_name(&min_s, &conn->gtarg_nam);
3486  }
3487 #endif
3488 #ifdef ENABLE_SSPI
3489  if (conn->sspitarget)
3490  free(conn->sspitarget);
3491  conn->sspitarget = NULL;
3492  if (conn->sspicred)
3493  {
3494  FreeCredentialsHandle(conn->sspicred);
3495  free(conn->sspicred);
3496  conn->sspicred = NULL;
3497  }
3498  if (conn->sspictx)
3499  {
3500  DeleteSecurityContext(conn->sspictx);
3501  free(conn->sspictx);
3502  conn->sspictx = NULL;
3503  }
3504 #endif
3505  if (conn->sasl_state)
3506  {
3507  /*
3508  * XXX: if support for more authentication mechanisms is added, this
3509  * needs to call the right 'free' function.
3510  */
3512  conn->sasl_state = NULL;
3513  }
3514 }
void pg_fe_scram_free(void *opaq)
static void release_all_addrinfo(PGconn *conn)
Definition: fe-connect.c:3376
PGnotify * notifyHead
Definition: libpq-int.h:391
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:405
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:3404
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:379
#define FALSE
Definition: c.h:221
void * sasl_state
Definition: libpq-int.h:455
pgParameterStatus * pstatus
Definition: libpq-int.h:422
struct pgNotify * next
Definition: libpq-fe.h:167
PQExpBufferData errorMessage
Definition: libpq-int.h:492
#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:392
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:427
static int connectDBComplete ( PGconn conn)
static

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

1720 {
1722  time_t finish_time = ((time_t) -1);
1723  int timeout = 0;
1724 
1725  if (conn == NULL || conn->status == CONNECTION_BAD)
1726  return 0;
1727 
1728  /*
1729  * Set up a time limit, if connect_timeout isn't zero.
1730  */
1731  if (conn->connect_timeout != NULL)
1732  {
1733  timeout = atoi(conn->connect_timeout);
1734  if (timeout > 0)
1735  {
1736  /*
1737  * Rounding could cause connection to fail; need at least 2 secs
1738  */
1739  if (timeout < 2)
1740  timeout = 2;
1741  /* calculate the finish time based on start + timeout */
1742  finish_time = time(NULL) + timeout;
1743  }
1744  }
1745 
1746  for (;;)
1747  {
1748  int ret = 0;
1749 
1750  /*
1751  * Wait, if necessary. Note that the initial state (just after
1752  * PQconnectStart) is to wait for the socket to select for writing.
1753  */
1754  switch (flag)
1755  {
1756  case PGRES_POLLING_OK:
1757 
1758  /*
1759  * Reset stored error messages since we now have a working
1760  * connection
1761  */
1763  return 1; /* success! */
1764 
1765  case PGRES_POLLING_READING:
1766  ret = pqWaitTimed(1, 0, conn, finish_time);
1767  if (ret == -1)
1768  {
1769  conn->status = CONNECTION_BAD;
1770  return 0;
1771  }
1772  break;
1773 
1774  case PGRES_POLLING_WRITING:
1775  ret = pqWaitTimed(0, 1, conn, finish_time);
1776  if (ret == -1)
1777  {
1778  conn->status = CONNECTION_BAD;
1779  return 0;
1780  }
1781  break;
1782 
1783  default:
1784  /* Just in case we failed to set it in PQconnectPoll */
1785  conn->status = CONNECTION_BAD;
1786  return 0;
1787  }
1788 
1789  if (ret == 1) /* connect_timeout elapsed */
1790  {
1791  /* If there are no more hosts, return (the error message is already set) */
1792  if (++conn->whichhost >= conn->nconnhost)
1793  {
1794  conn->whichhost = 0;
1795  conn->status = CONNECTION_BAD;
1796  return 0;
1797  }
1798  /* Attempt connection to the next host, starting the connect_timeout timer */
1799  pqDropConnection(conn, true);
1800  conn->addr_cur = conn->connhost[conn->whichhost].addrlist;
1801  conn->status = CONNECTION_NEEDED;
1802  if (conn->connect_timeout != NULL)
1803  finish_time = time(NULL) + timeout;
1804  }
1805 
1806  /*
1807  * Now try to advance the state machine.
1808  */
1809  flag = PQconnectPoll(conn);
1810  }
1811 }
struct addrinfo * addr_cur
Definition: libpq-int.h:414
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:397
char * flag(int b)
Definition: test-ctype.c:33
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:1874
PQExpBufferData errorMessage
Definition: libpq-int.h:492
#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:395
int whichhost
Definition: libpq-int.h:396
static int connectDBStart ( PGconn conn)
static

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

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

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

1308 {
1309  char sebuf[256];
1310 
1311 #ifdef HAVE_UNIX_SOCKETS
1312  if (IS_AF_UNIX(conn->raddr.addr.ss_family))
1313  {
1314  char service[NI_MAXHOST];
1315 
1316  pg_getnameinfo_all(&conn->raddr.addr, conn->raddr.salen,
1317  NULL, 0,
1318  service, sizeof(service),
1319  NI_NUMERICSERV);
1321  libpq_gettext("could not connect to server: %s\n"
1322  "\tIs the server running locally and accepting\n"
1323  "\tconnections on Unix domain socket \"%s\"?\n"),
1324  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1325  service);
1326  }
1327  else
1328 #endif /* HAVE_UNIX_SOCKETS */
1329  {
1330  char host_addr[NI_MAXHOST];
1331  const char *displayed_host;
1332  const char *displayed_port;
1333  struct sockaddr_storage *addr = &conn->raddr.addr;
1334 
1335  /*
1336  * Optionally display the network address with the hostname. This is
1337  * useful to distinguish between IPv4 and IPv6 connections.
1338  */
1339  if (conn->pghostaddr != NULL)
1340  strlcpy(host_addr, conn->pghostaddr, NI_MAXHOST);
1341  else if (addr->ss_family == AF_INET)
1342  {
1343  if (inet_net_ntop(AF_INET,
1344  &((struct sockaddr_in *) addr)->sin_addr.s_addr,
1345  32,
1346  host_addr, sizeof(host_addr)) == NULL)
1347  strcpy(host_addr, "???");
1348  }
1349 #ifdef HAVE_IPV6
1350  else if (addr->ss_family == AF_INET6)
1351  {
1352  if (inet_net_ntop(AF_INET6,
1353  &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
1354  128,
1355  host_addr, sizeof(host_addr)) == NULL)
1356  strcpy(host_addr, "???");
1357  }
1358 #endif
1359  else
1360  strcpy(host_addr, "???");
1361 
1362  /* To which host and port were we actually connecting? */
1363  displayed_host = conn->connhost[conn->whichhost].host;
1364  displayed_port = conn->connhost[conn->whichhost].port;
1365  if (displayed_port == NULL || displayed_port[0] == '\0')
1366  displayed_port = DEF_PGPORT_STR;
1367 
1368  /*
1369  * If the user did not supply an IP address using 'hostaddr', and
1370  * 'host' was missing or does not match our lookup, display the
1371  * looked-up IP address.
1372  */
1373  if ((conn->pghostaddr == NULL) &&
1374  (conn->pghost == NULL || strcmp(conn->pghost, host_addr) != 0))
1376  libpq_gettext("could not connect to server: %s\n"
1377  "\tIs the server running on host \"%s\" (%s) and accepting\n"
1378  "\tTCP/IP connections on port %s?\n"),
1379  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1380  displayed_host,
1381  host_addr,
1382  displayed_port);
1383  else
1385  libpq_gettext("could not connect to server: %s\n"
1386  "\tIs the server running on host \"%s\" and accepting\n"
1387  "\tTCP/IP connections on port %s?\n"),
1388  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1389  displayed_host,
1390  displayed_port);
1391  }
1392 }
char * host
Definition: libpq-int.h:307
struct sockaddr_storage addr
Definition: pqcomm.h:64
#define SOCK_STRERROR
Definition: libpq-int.h:697
#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:397
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:403
PQExpBufferData errorMessage
Definition: libpq-int.h:492
#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:396
#define libpq_gettext(x)
Definition: libpq-int.h:683
char * pghost
Definition: libpq-int.h:324
static int connectNoDelay ( PGconn conn)
static

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

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

Referenced by PQconnectPoll().

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

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

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

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

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

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

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

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

References _PQconninfoOption::keyword, and NULL.

Referenced by conninfo_getval(), and conninfo_storeval().

5780 {
5782 
5783  for (option = connOptions; option->keyword != NULL; option++)
5784  {
5785  if (strcmp(option->keyword, keyword) == 0)
5786  return option;
5787  }
5788 
5789  return NULL;
5790 }
#define NULL
Definition: c.h:229
static const char * conninfo_getval ( PQconninfoOption connOptions,
const char *  keyword 
)
static

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

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

Referenced by fillPGconn(), and parseServiceInfo().

5690 {
5692 
5693  option = conninfo_find(connOptions, keyword);
5694 
5695  return option ? option->val : NULL;
5696 }
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5779
#define NULL
Definition: c.h:229
static PQconninfoOption * conninfo_init ( PQExpBuffer  errorMessage)
static

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

4631 {
4633  PQconninfoOption *opt_dest;
4634  const internalPQconninfoOption *cur_opt;
4635 
4636  /*
4637  * Get enough memory for all options in PQconninfoOptions, even if some
4638  * end up being filtered out.
4639  */
4640  options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
4641  if (options == NULL)
4642  {
4643  printfPQExpBuffer(errorMessage,
4644  libpq_gettext("out of memory\n"));
4645  return NULL;
4646  }
4647  opt_dest = options;
4648 
4649  for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
4650  {
4651  /* Only copy the public part of the struct, not the full internal */
4652  memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
4653  opt_dest++;
4654  }
4655  MemSet(opt_dest, 0, sizeof(PQconninfoOption));
4656 
4657  return options;
4658 }
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:683
static PQconninfoOption * conninfo_parse ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

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

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

5718 {
5720  char *value_copy;
5721 
5722  /*
5723  * For backwards compatibility, requiressl=1 gets translated to
5724  * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
5725  * (which is the default for sslmode).
5726  */
5727  if (strcmp(keyword, "requiressl") == 0)
5728  {
5729  keyword = "sslmode";
5730  if (value[0] == '1')
5731  value = "require";
5732  else
5733  value = "prefer";
5734  }
5735 
5736  option = conninfo_find(connOptions, keyword);
5737  if (option == NULL)
5738  {
5739  if (!ignoreMissing)
5740  printfPQExpBuffer(errorMessage,
5741  libpq_gettext("invalid connection option \"%s\"\n"),
5742  keyword);
5743  return NULL;
5744  }
5745 
5746  if (uri_decode)
5747  {
5748  value_copy = conninfo_uri_decode(value, errorMessage);
5749  if (value_copy == NULL)
5750  /* conninfo_uri_decode already set an error message */
5751  return NULL;
5752  }
5753  else
5754  {
5755  value_copy = strdup(value);
5756  if (value_copy == NULL)
5757  {
5758  printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5759  return NULL;
5760  }
5761  }
5762 
5763  if (option->val)
5764  free(option->val);
5765  option->val = value_copy;
5766 
5767  return option;
5768 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5779
static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
Definition: fe-connect.c:5599
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
static struct @121 value
#define libpq_gettext(x)
Definition: libpq-int.h:683
static char * conninfo_uri_decode ( const char *  str,
PQExpBuffer  errorMessage 
)
static

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

5600 {
5601  char *buf;
5602  char *p;
5603  const char *q = str;
5604 
5605  buf = malloc(strlen(str) + 1);
5606  if (buf == NULL)
5607  {
5608  printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5609  return NULL;
5610  }
5611  p = buf;
5612 
5613  for (;;)
5614  {
5615  if (*q != '%')
5616  {
5617  /* copy and check for NUL terminator */
5618  if (!(*(p++) = *(q++)))
5619  break;
5620  }
5621  else
5622  {
5623  int hi;
5624  int lo;
5625  int c;
5626 
5627  ++q; /* skip the percent sign itself */
5628 
5629  /*
5630  * Possible EOL will be caught by the first call to
5631  * get_hexdigit(), so we never dereference an invalid q pointer.
5632  */
5633  if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
5634  {
5635  printfPQExpBuffer(errorMessage,
5636  libpq_gettext("invalid percent-encoded token: \"%s\"\n"),
5637  str);
5638  free(buf);
5639  return NULL;
5640  }
5641 
5642  c = (hi << 4) | lo;
5643  if (c == 0)
5644  {
5645  printfPQExpBuffer(errorMessage,
5646  libpq_gettext("forbidden value %%00 in percent-encoded value: \"%s\"\n"),
5647  str);
5648  free(buf);
5649  return NULL;
5650  }
5651  *(p++) = c;
5652  }
5653  }
5654 
5655  return buf;
5656 }
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:5667
#define libpq_gettext(x)
Definition: libpq-int.h:683
static PQconninfoOption * conninfo_uri_parse ( const char *  uri,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

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

Referenced by parse_connection_string().

5173 {
5175 
5176  /* Make a working copy of PQconninfoOptions */
5177  options = conninfo_init(errorMessage);
5178  if (options == NULL)
5179  return NULL;
5180 
5181  if (!conninfo_uri_parse_options(options, uri, errorMessage))
5182  {
5183  PQconninfoFree(options);
5184  return NULL;
5185  }
5186 
5187  /*
5188  * Add in defaults if the caller wants that.
5189  */
5190  if (use_defaults)
5191  {
5192  if (!conninfo_add_defaults(options, errorMessage))
5193  {
5194  PQconninfoFree(options);
5195  return NULL;
5196  }
5197  }
5198 
5199  return options;
5200 }
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4630
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5838
static bool conninfo_uri_parse_options(PQconninfoOption *options, const char *uri, PQExpBuffer errorMessage)
Definition: fe-connect.c:5224
static char ** options
#define NULL
Definition: c.h:229
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5066
static bool conninfo_uri_parse_options ( PQconninfoOption options,
const char *  uri,
PQExpBuffer  errorMessage 
)
static

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

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

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

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

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

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

Referenced by PQregisterThreadLock().

6437 {
6438 #ifdef ENABLE_THREAD_SAFETY
6439 #ifndef WIN32
6440  static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
6441 #else
6442  static pthread_mutex_t singlethread_lock = NULL;
6443  static long mutex_initlock = 0;
6444 
6445  if (singlethread_lock == NULL)
6446  {
6447  while (InterlockedExchange(&mutex_initlock, 1) == 1)
6448  /* loop, another thread own the lock */ ;
6449  if (singlethread_lock == NULL)
6450  {
6451  if (pthread_mutex_init(&singlethread_lock, NULL))
6452  PGTHREAD_ERROR("failed to initialize mutex");
6453  }
6454  InterlockedExchange(&mutex_initlock, 0);
6455  }
6456 #endif
6457  if (acquire)
6458  {
6459  if (pthread_mutex_lock(&singlethread_lock))
6460  PGTHREAD_ERROR("failed to lock mutex");
6461  }
6462  else
6463  {
6464  if (pthread_mutex_unlock(&singlethread_lock))
6465  PGTHREAD_ERROR("failed to unlock mutex");
6466  }
6467 #endif
6468 }
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 6202 of file fe-connect.c.

Referenced by makeEmptyPGconn().

6203 {
6204  (void) arg; /* not used */
6205  /* Note: we expect the supplied string to end with a newline already. */
6206  fprintf(stderr, "%s", message);
6207 }
void * arg
static void defaultNoticeReceiver ( void *  arg,
const PGresult res 
)
static

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

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

Referenced by makeEmptyPGconn().

6188 {
6189  (void) arg; /* not used */
6190  if (res->noticeHooks.noticeProc != NULL)
6192  PQresultErrorMessage(res));
6193 }
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 692 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().

693 {
695 
696  for (option = PQconninfoOptions; option->keyword; option++)
697  {
698  if (option->connofs >= 0)
699  {
700  const char *tmp = conninfo_getval(connOptions, option->keyword);
701 
702  if (tmp)
703  {
704  char **connmember = (char **) ((char *) conn + option->connofs);
705 
706  if (*connmember)
707  free(*connmember);
708  *connmember = strdup(tmp);
709  if (*connmember == NULL)
710  {
712  libpq_gettext("out of memory\n"));
713  return false;
714  }
715  }
716  }
717  }
718 
719  return true;
720 }
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:492
#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:5688
#define libpq_gettext(x)
Definition: libpq-int.h:683
static void freePGconn ( PGconn conn)
static

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

3260 {
3261  int i;
3262 
3263  /* let any event procs clean up their state data */
3264  for (i = 0; i < conn->nEvents; i++)
3265  {
3266  PGEventConnDestroy evt;
3267 
3268  evt.conn = conn;
3269  (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
3270  conn->events[i].passThrough);
3271  free(conn->events[i].name);
3272  }
3273 
3274  /* clean up pg_conn_host structures */
3275  if (conn->connhost != NULL)
3276  {
3277  for (i = 0; i < conn->nconnhost; ++i)
3278  {
3279  if (conn->connhost[i].host != NULL)
3280  free(conn->connhost[i].host);
3281  if (conn->connhost[i].port != NULL)
3282  free(conn->connhost[i].port);
3283  if (conn->connhost[i].password != NULL)
3284  free(conn->connhost[i].password);
3285  }
3286  free(conn->connhost);
3287  }
3288 
3289  if (conn->client_encoding_initial)
3291  if (conn->events)
3292  free(conn->events);
3293  if (conn->pghost)
3294  free(conn->pghost);
3295  if (conn->pghostaddr)
3296  free(conn->pghostaddr);
3297  if (conn->pgport)
3298  free(conn->pgport);
3299  if (conn->pgtty)
3300  free(conn->pgtty);
3301  if (conn->connect_timeout)
3302  free(conn->connect_timeout);
3303  if (conn->pgoptions)
3304  free(conn->pgoptions);
3305  if (conn->appname)
3306  free(conn->appname);
3307  if (conn->fbappname)
3308  free(conn->fbappname);
3309  if (conn->dbName)
3310  free(conn->dbName);
3311  if (conn->replication)
3312  free(conn->replication);
3313  if (conn->pguser)
3314  free(conn->pguser);
3315  if (conn->pgpass)
3316  free(conn->pgpass);
3317  if (conn->pgpassfile)
3318  free(conn->pgpassfile);
3319  if (conn->keepalives)
3320  free(conn->keepalives);
3321  if (conn->keepalives_idle)
3322  free(conn->keepalives_idle);
3323  if (conn->keepalives_interval)
3324  free(conn->keepalives_interval);
3325  if (conn->keepalives_count)
3326  free(conn->keepalives_count);
3327  if (conn->sslmode)
3328  free(conn->sslmode);
3329  if (conn->sslcert)
3330  free(conn->sslcert);
3331  if (conn->sslkey)
3332  free(conn->sslkey);
3333  if (conn->sslrootcert)
3334  free(conn->sslrootcert);
3335  if (conn->sslcrl)
3336  free(conn->sslcrl);
3337  if (conn->sslcompression)
3338  free(conn->sslcompression);
3339  if (conn->requirepeer)
3340  free(conn->requirepeer);
3341 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
3342  if (conn->krbsrvname)
3343  free(conn->krbsrvname);
3344 #endif
3345 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
3346  if (conn->gsslib)
3347  free(conn->gsslib);
3348 #endif
3349  /* Note that conn->Pfdebug is not ours to close or free */
3350  if (conn->last_query)
3351  free(conn->last_query);
3352  if (conn->inBuffer)
3353  free(conn->inBuffer);
3354  if (conn->outBuffer)
3355  free(conn->outBuffer);
3356  if (conn->rowBuf)
3357  free(conn->rowBuf);
3358  if (conn->target_session_attrs)
3359  free(conn->target_session_attrs);
3360  termPQExpBuffer(&conn->errorMessage);
3361  termPQExpBuffer(&conn->workBuffer);
3362 
3363  free(conn);
3364 
3365 #ifdef WIN32
3366  WSACleanup();
3367 #endif
3368 }
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:495
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:397
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:447
char * pguser
Definition: libpq-int.h:342
char * inBuffer
Definition: libpq-int.h:430
char * sslmode
Definition: libpq-int.h:351
PQExpBufferData errorMessage
Definition: libpq-int.h:492
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:437
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:395
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 5667 of file fe-connect.c.

Referenced by conninfo_uri_decode().

5668 {
5669  if ('0' <= digit && digit <= '9')
5670  *value = digit - '0';
5671  else if ('A' <= digit && digit <= 'F')
5672  *value = digit - 'A' + 10;
5673  else if ('a' <= digit && digit <= 'f')
5674  *value = digit - 'a' + 10;
5675  else
5676  return false;
5677 
5678  return true;
5679 }
static struct @121 value
static int internal_cancel ( SockAddr raddr,
int  be_pid,
int  be_key,
char *  errbuf,
int  errbufsize 
)
static

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

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

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

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

3164 {
3165  PGconn *conn;
3166 
3167 #ifdef WIN32
3168 
3169  /*
3170  * Make sure socket support is up and running.
3171  */
3172  WSADATA wsaData;
3173 
3174  if (WSAStartup(MAKEWORD(1, 1), &wsaData))
3175  return NULL;
3176  WSASetLastError(0);
3177 #endif
3178 
3179  conn = (PGconn *) malloc(sizeof(PGconn));
3180  if (conn == NULL)
3181  {
3182 #ifdef WIN32
3183  WSACleanup();
3184 #endif
3185  return conn;
3186  }
3187 
3188  /* Zero all pointers and booleans */
3189  MemSet(conn, 0, sizeof(PGconn));
3190 
3191  /* install default notice hooks */
3194 
3195  conn->status = CONNECTION_BAD;
3196  conn->asyncStatus = PGASYNC_IDLE;
3197  conn->xactStatus = PQTRANS_IDLE;
3198  conn->options_valid = false;
3199  conn->nonblocking = false;
3201  conn->client_encoding = PG_SQL_ASCII;
3202  conn->std_strings = false; /* unless server says differently */
3203  conn->verbosity = PQERRORS_DEFAULT;
3205  conn->sock = PGINVALID_SOCKET;
3206  conn->auth_req_received = false;
3207  conn->password_needed = false;
3208  conn->pgpassfile_used = false;
3209 #ifdef USE_SSL
3210  conn->allow_ssl_try = true;
3211  conn->wait_ssl_try = false;
3212  conn->ssl_in_use = false;
3213 #endif
3214 
3215  /*
3216  * We try to send at least 8K at a time, which is the usual size of pipe
3217  * buffers on Unix systems. That way, when we are sending a large amount
3218  * of data, we avoid incurring extra kernel context swaps for partial
3219  * bufferloads. The output buffer is initially made 16K in size, and we
3220  * try to dump it after accumulating 8K.
3221  *
3222  * With the same goal of minimizing context swaps, the input buffer will
3223  * be enlarged anytime it has less than 8K free, so we initially allocate
3224  * twice that.
3225  */
3226  conn->inBufSize = 16 * 1024;
3227  conn->inBuffer = (char *) malloc(conn->inBufSize);
3228  conn->outBufSize = 16 * 1024;
3229  conn->outBuffer = (char *) malloc(conn->outBufSize);
3230  conn->rowBufLen = 32;
3231  conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
3232  initPQExpBuffer(&conn->errorMessage);
3233  initPQExpBuffer(&conn->workBuffer);
3234 
3235  if (conn->inBuffer == NULL ||
3236  conn->outBuffer == NULL ||
3237  conn->rowBuf == NULL ||
3238  PQExpBufferBroken(&conn->errorMessage) ||
3239  PQExpBufferBroken(&conn->workBuffer))
3240  {
3241  /* out of memory already :-( */
3242  freePGconn(conn);
3243  conn = NULL;
3244  }
3245 
3246  return conn;
3247 }
PGContextVisibility show_context
Definition: libpq-int.h:426
int rowBufLen
Definition: libpq-int.h:448
bool password_needed
Definition: libpq-int.h:408
PQExpBufferData workBuffer
Definition: libpq-int.h:495
#define MemSet(start, val, len)
Definition: c.h:857
bool pgpassfile_used
Definition: libpq-int.h:409
#define malloc(a)
Definition: header.h:50
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:379
PGSetenvStatusType setenv_state
Definition: libpq-int.h:415
PGconn * conn
Definition: streamutil.c:42
int inBufSize
Definition: libpq-int.h:431
PGNoticeHooks noticeHooks
Definition: libpq-int.h:370
PGVerbosity verbosity
Definition: libpq-int.h:425
PQnoticeReceiver noticeRec
Definition: libpq-int.h:152
PGdataValue * rowBuf
Definition: libpq-int.h:447
pgsocket sock
Definition: libpq-int.h:400
#define PGINVALID_SOCKET
Definition: port.h:24
char * inBuffer
Definition: libpq-int.h:430
PQnoticeProcessor noticeProc
Definition: libpq-int.h:154
static void freePGconn(PGconn *conn)
Definition: fe-connect.c:3259
PQExpBufferData errorMessage
Definition: libpq-int.h:492
bool std_strings
Definition: libpq-int.h:424
bool options_valid
Definition: libpq-int.h:384
int outBufSize
Definition: libpq-int.h:438
#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:406
char * outBuffer
Definition: libpq-int.h:437
bool nonblocking
Definition: libpq-int.h:385
static void defaultNoticeProcessor(void *arg, const char *message)
Definition: fe-connect.c:6202
int client_encoding
Definition: libpq-int.h:423
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
static void defaultNoticeReceiver(void *arg, const PGresult *res)
Definition: fe-connect.c:6187
PGTransactionStatusType xactStatus
Definition: libpq-int.h:380
static PQconninfoOption * parse_connection_string ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

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

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

4672 {
4673  /* Parse as URI if connection string matches URI prefix */
4674  if (uri_prefix_length(connstr) != 0)
4675  return conninfo_uri_parse(connstr, errorMessage, use_defaults);
4676 
4677  /* Parse as default otherwise */
4678  return conninfo_parse(connstr, errorMessage, use_defaults);
4679 }
static PQconninfoOption * conninfo_parse(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4724
static int uri_prefix_length(const char *connstr)
Definition: fe-connect.c:4690
static PQconninfoOption * conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:5171
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 4433 of file fe-connect.c.

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

Referenced by parseServiceInfo().

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

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

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

Referenced by conninfo_add_defaults().

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

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

6253 {
6254  FILE *fp;
6255  struct stat stat_buf;
6256 
6257 #define LINELEN NAMEDATALEN*5
6258  char buf[LINELEN];
6259 
6260  if (dbname == NULL || strlen(dbname) == 0)
6261  return NULL;
6262 
6263  if (username == NULL || strlen(username) == 0)
6264  return NULL;
6265 
6266  /* 'localhost' matches pghost of '' or the default socket directory */
6267  if (hostname == NULL)
6269  else if (is_absolute_path(hostname))
6270 
6271  /*
6272  * We should probably use canonicalize_path(), but then we have to
6273  * bring path.c into libpq, and it doesn't seem worth it.
6274  */
6275  if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
6277 
6278  if (port == NULL)
6279  port = DEF_PGPORT_STR;
6280 
6281  /* If password file cannot be opened, ignore it. */
6282  if (stat(pgpassfile, &stat_buf) != 0)
6283  return NULL;
6284 
6285 #ifndef WIN32
6286  if (!S_ISREG(stat_buf.st_mode))
6287  {
6288  fprintf(stderr,
6289  libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
6290  pgpassfile);
6291  return NULL;
6292  }
6293 
6294  /* If password file is insecure, alert the user and ignore it. */
6295  if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
6296  {
6297  fprintf(stderr,
6298  libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
6299  pgpassfile);
6300  return NULL;
6301  }
6302 #else
6303 
6304  /*
6305  * On Win32, the directory is protected, so we don't have to check the
6306  * file.
6307  */
6308 #endif
6309 
6310  fp = fopen(pgpassfile, "r");
6311  if (fp == NULL)
6312  return NULL;
6313 
6314  while (!feof(fp) && !ferror(fp))
6315  {
6316  char *t = buf,
6317  *ret,
6318  *p1,
6319  *p2;
6320  int len;
6321 
6322  if (fgets(buf, sizeof(buf), fp) == NULL)
6323  break;
6324 
6325  len = strlen(buf);
6326 
6327  /* Remove trailing newline */
6328  if (len > 0 && buf[len - 1] == '\n')
6329  {
6330  buf[--len] = '\0';
6331  /* Handle DOS-style line endings, too, even when not on Windows */
6332  if (len > 0 && buf[len - 1] == '\r')
6333  buf[--len] = '\0';
6334  }
6335 
6336  if (len == 0)
6337  continue;
6338 
6339  if ((t = pwdfMatchesString(t, hostname)) == NULL ||
6340  (t = pwdfMatchesString(t, port)) == NULL ||
6341  (t = pwdfMatchesString(t, dbname)) == NULL ||
6342  (t = pwdfMatchesString(t, username)) == NULL)
6343  continue;
6344 
6345  /* Found a match. */
6346  ret = strdup(t);
6347  fclose(fp);
6348 
6349  if (!ret)
6350  {
6351  /* Out of memory. XXX: an error message would be nice. */
6352  return NULL;
6353  }
6354 
6355  /* De-escape password. */
6356  for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
6357  {
6358  if (*p1 == '\\' && p1[1] != '\0')
6359  ++p1;
6360  *p2 = *p1;
6361  }
6362  *p2 = '\0';
6363 
6364  return ret;
6365  }
6366 
6367  fclose(fp);
6368  return NULL;
6369 
6370 #undef LINELEN
6371 }
#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:6214
#define libpq_gettext(x)
Definition: libpq-int.h:683
#define DEFAULT_PGSOCKET_DIR
static void pgpassfileWarning ( PGconn conn)
static

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

6380 {
6381  /* If it was 'invalid authorization', add pgpassfile mention */
6382  /* only works with >= 9.0 servers */
6383  if (conn->pgpassfile_used && conn->password_needed && conn->result)
6384  {
6385  const char *sqlstate = PQresultErrorField(conn->result,
6387 
6388  if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
6390  libpq_gettext("password retrieved from file \"%s\"\n"),
6391  conn->pgpassfile);
6392  }
6393 }
char * pgpassfile
Definition: libpq-int.h:344
bool password_needed
Definition: libpq-int.h:408
bool pgpassfile_used
Definition: libpq-int.h:409
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
PGresult * result
Definition: libpq-int.h:451
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
PQExpBufferData errorMessage
Definition: libpq-int.h:492
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:683
int PQbackendPID ( const PGconn conn)

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

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

Referenced by get_prompt().

6015 {
6016  if (!conn || conn->status != CONNECTION_OK)
6017  return 0;
6018  return conn->be_pid;
6019 }
ConnStatusType status
Definition: libpq-int.h:378
int be_pid
Definition: libpq-int.h:420
int PQcancel ( PGcancel cancel,
char *  errbuf,
int  errbufsize 
)

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

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

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

3798 {
3799  if (!cancel)
3800  {
3801  strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
3802  return FALSE;
3803  }
3804 
3805  return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
3806  errbuf, errbufsize);
3807 }
static int internal_cancel(SockAddr *raddr, int be_pid, int be_key, char *errbuf, int errbufsize)
Definition: fe-connect.c:3693
int be_pid
Definition: libpq-int.h:505
#define FALSE
Definition: c.h:221
int be_key
Definition: libpq-int.h:506
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
SockAddr raddr
Definition: libpq-int.h:504
int PQclientEncoding ( const PGconn conn)

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

6049 {
6050  if (!conn || conn->status != CONNECTION_OK)
6051  return -1;
6052  return conn->client_encoding;
6053 }
ConnStatusType status
Definition: libpq-int.h:378
int client_encoding
Definition: libpq-int.h:423
PQconninfoOption* PQconndefaults ( void  )

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

1113 {
1114  PQExpBufferData errorBuf;
1115  PQconninfoOption *connOptions;
1116 
1117  /* We don't actually report any errors here, but callees want a buffer */
1118  initPQExpBuffer(&errorBuf);
1119  if (PQExpBufferDataBroken(errorBuf))
1120  return NULL; /* out of memory already :-( */
1121 
1122  connOptions = conninfo_init(&errorBuf);
1123  if (connOptions != NULL)
1124  {
1125  /* pass NULL errorBuf to ignore errors */
1126  if (!conninfo_add_defaults(connOptions, NULL))
1127  {
1128  PQconninfoFree(connOptions);
1129  connOptions = NULL;
1130  }
1131  }
1132 
1133  termPQExpBuffer(&errorBuf);
1134  return connOptions;
1135 }
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4630
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5838
#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:5066
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGconn* PQconnectdb ( const char *  conninfo)

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

523 {
524  PGconn *conn = PQconnectStart(conninfo);
525 
526  if (conn && conn->status != CONNECTION_BAD)
527  (void) connectDBComplete(conn);
528 
529  return conn;
530 }
PGconn * conn
Definition: streamutil.c:42
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1719
PGconn * PQconnectStart(const char *conninfo)
Definition: fe-connect.c:648
ConnStatusType status
Definition: libpq-int.h:378
PGconn* PQconnectdbParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)

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

469 {
470  PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
471 
472  if (conn && conn->status != CONNECTION_BAD)
473  (void) connectDBComplete(conn);
474 
475  return conn;
476 
477 }
PGconn * conn
Definition: streamutil.c:42
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1719
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:569
int PQconnectionNeedsPassword ( const PGconn conn)

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

6023 {
6024  char *password;
6025 
6026  if (!conn)
6027  return false;
6028  password = PQpass(conn);
6029  if (conn->password_needed &&
6030  (password == NULL || password[0] == '\0'))
6031  return true;
6032  else
6033  return false;
6034 }
static char password[100]
Definition: streamutil.c:41
bool password_needed
Definition: libpq-int.h:408
char * PQpass(const PGconn *conn)
Definition: fe-connect.c:5872
#define NULL
Definition: c.h:229
int PQconnectionUsedPassword ( const PGconn conn)

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

References pg_conn::password_needed.

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

6038 {
6039  if (!conn)
6040  return false;
6041  if (conn->password_needed)
6042  return true;
6043  else
6044  return false;
6045 }
bool password_needed
Definition: libpq-int.h:408
PostgresPollingStatusType PQconnectPoll ( PGconn conn)

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

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