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 4331 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 3401 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().

3402 {
3403  PGnotify *notify;
3404  pgParameterStatus *pstatus;
3405 
3406  sendTerminateConn(conn);
3407 
3408  /*
3409  * Must reset the blocking status so a possible reconnect will work.
3410  *
3411  * Don't call PQsetnonblocking() because it will fail if it's unable to
3412  * flush the connection.
3413  */
3414  conn->nonblocking = FALSE;
3415 
3416  /*
3417  * Close the connection, reset all transient state, flush I/O buffers.
3418  */
3419  pqDropConnection(conn, true);
3420  conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just
3421  * absent */
3422  conn->asyncStatus = PGASYNC_IDLE;
3423  pqClearAsyncResult(conn); /* deallocate result */
3425  release_all_addrinfo(conn);
3426 
3427  notify = conn->notifyHead;
3428  while (notify != NULL)
3429  {
3430  PGnotify *prev = notify;
3431 
3432  notify = notify->next;
3433  free(prev);
3434  }
3435  conn->notifyHead = conn->notifyTail = NULL;
3436  pstatus = conn->pstatus;
3437  while (pstatus != NULL)
3438  {
3439  pgParameterStatus *prev = pstatus;
3440 
3441  pstatus = pstatus->next;
3442  free(prev);
3443  }
3444  conn->pstatus = NULL;
3445  if (conn->lobjfuncs)
3446  free(conn->lobjfuncs);
3447  conn->lobjfuncs = NULL;
3448 #ifdef ENABLE_GSS
3449  {
3450  OM_uint32 min_s;
3451 
3452  if (conn->gctx)
3453  gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
3454  if (conn->gtarg_nam)
3455  gss_release_name(&min_s, &conn->gtarg_nam);
3456  }
3457 #endif
3458 #ifdef ENABLE_SSPI
3459  if (conn->sspitarget)
3460  free(conn->sspitarget);
3461  conn->sspitarget = NULL;
3462  if (conn->sspicred)
3463  {
3464  FreeCredentialsHandle(conn->sspicred);
3465  free(conn->sspicred);
3466  conn->sspicred = NULL;
3467  }
3468  if (conn->sspictx)
3469  {
3470  DeleteSecurityContext(conn->sspictx);
3471  free(conn->sspictx);
3472  conn->sspictx = NULL;
3473  }
3474 #endif
3475  if (conn->sasl_state)
3476  {
3477  /*
3478  * XXX: if support for more authentication mechanisms is added, this
3479  * needs to call the right 'free' function.
3480  */
3482  conn->sasl_state = NULL;
3483  }
3484 }
void pg_fe_scram_free(void *opaq)
static void release_all_addrinfo(PGconn *conn)
Definition: fe-connect.c:3346
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:3374
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 1710 of file fe-connect.c.

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

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

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

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

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

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

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

Referenced by PQconnectPoll().

1271 {
1272 #ifdef TCP_NODELAY
1273  int on = 1;
1274 
1275  if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
1276  (char *) &on,
1277  sizeof(on)) < 0)
1278  {
1279  char sebuf[256];
1280 
1282  libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
1283  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1284  return 0;
1285  }
1286 #endif
1287 
1288  return 1;
1289 }
#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:4640
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5784
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
802  * the 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.
895  * (If only one part number is specified, we reuse it for every
896  * host.)
897  */
898  if (*e != '\0')
899  {
900  s = e + 1;
901  ++nports;
902  }
903  }
904 
905  /*
906  * If multiple ports were specified, there must be exactly as many
907  * ports as there were hosts. Otherwise, we do not know how to match
908  * them up.
909  */
910  if (nports != 1 && nports != conn->nconnhost)
911  {
912  conn->status = CONNECTION_BAD;
914  libpq_gettext("could not match %d port numbers to %d hosts\n"),
915  nports, conn->nconnhost);
916  return false;
917  }
918  }
919 
920  /*
921  * If user name was not given, fetch it. (Most likely, the fetch will
922  * fail, since the only way we get here is if pg_fe_getauthname() failed
923  * during conninfo_add_defaults(). But now we want an error message.)
924  */
925  if (conn->pguser == NULL || conn->pguser[0] == '\0')
926  {
927  if (conn->pguser)
928  free(conn->pguser);
929  conn->pguser = pg_fe_getauthname(&conn->errorMessage);
930  if (!conn->pguser)
931  {
932  conn->status = CONNECTION_BAD;
933  return false;
934  }
935  }
936 
937  /*
938  * If database name was not given, default it to equal user name
939  */
940  if (conn->dbName == NULL || conn->dbName[0] == '\0')
941  {
942  if (conn->dbName)
943  free(conn->dbName);
944  conn->dbName = strdup(conn->pguser);
945  if (!conn->dbName)
946  goto oom_error;
947  }
948 
949  /*
950  * Supply default password if none given. Note that the password might
951  * be different for each host/port pair.
952  */
953  if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
954  {
955  int i;
956 
957  if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
958  {
959  /* Identify password file to use; fail if we can't */
960  char homedir[MAXPGPATH];
961 
962  if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
963  {
964  conn->status = CONNECTION_BAD;
966  libpq_gettext("could not get home directory to locate password file\n"));
967  return false;
968  }
969 
970  if (conn->pgpassfile)
971  free(conn->pgpassfile);
972  conn->pgpassfile = malloc(MAXPGPATH);
973  if (!conn->pgpassfile)
974  goto oom_error;
975 
976  snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s", homedir, PGPASSFILE);
977  }
978 
979  for (i = 0; i < conn->nconnhost; i++)
980  {
981  /* Try to get a password for this host from pgpassfile */
982  conn->connhost[i].password =
983  passwordFromFile(conn->connhost[i].host,
984  conn->connhost[i].port,
985  conn->dbName,
986  conn->pguser,
987  conn->pgpassfile);
988  /* If we got one, set pgpassfile_used */
989  if (conn->connhost[i].password != NULL)
990  conn->pgpassfile_used = true;
991  }
992  }
993 
994  /*
995  * validate sslmode option
996  */
997  if (conn->sslmode)
998  {
999  if (strcmp(conn->sslmode, "disable") != 0
1000  && strcmp(conn->sslmode, "allow") != 0
1001  && strcmp(conn->sslmode, "prefer") != 0
1002  && strcmp(conn->sslmode, "require") != 0
1003  && strcmp(conn->sslmode, "verify-ca") != 0
1004  && strcmp(conn->sslmode, "verify-full") != 0)
1005  {
1006  conn->status = CONNECTION_BAD;
1008  libpq_gettext("invalid sslmode value: \"%s\"\n"),
1009  conn->sslmode);
1010  return false;
1011  }
1012 
1013 #ifndef USE_SSL
1014  switch (conn->sslmode[0])
1015  {
1016  case 'a': /* "allow" */
1017  case 'p': /* "prefer" */
1018 
1019  /*
1020  * warn user that an SSL connection will never be negotiated
1021  * since SSL was not compiled in?
1022  */
1023  break;
1024 
1025  case 'r': /* "require" */
1026  case 'v': /* "verify-ca" or "verify-full" */
1027  conn->status = CONNECTION_BAD;
1029  libpq_gettext("sslmode value \"%s\" invalid when SSL support is not compiled in\n"),
1030  conn->sslmode);
1031  return false;
1032  }
1033 #endif
1034  }
1035  else
1036  {
1037  conn->sslmode = strdup(DefaultSSLMode);
1038  if (!conn->sslmode)
1039  goto oom_error;
1040  }
1041 
1042  /*
1043  * Resolve special "auto" client_encoding from the locale
1044  */
1045  if (conn->client_encoding_initial &&
1046  strcmp(conn->client_encoding_initial, "auto") == 0)
1047  {
1050  if (!conn->client_encoding_initial)
1051  goto oom_error;
1052  }
1053 
1054  /*
1055  * Validate target_session_attrs option.
1056  */
1057  if (conn->target_session_attrs)
1058  {
1059  if (strcmp(conn->target_session_attrs, "any") != 0
1060  && strcmp(conn->target_session_attrs, "read-write") != 0)
1061  {
1062  conn->status = CONNECTION_BAD;
1064  libpq_gettext("invalid target_session_attrs value: \"%s\"\n"),
1065  conn->target_session_attrs);
1066  return false;
1067  }
1068  }
1069 
1070  /*
1071  * Only if we get this far is it appropriate to try to connect. (We need a
1072  * state flag, rather than just the boolean result of this function, in
1073  * case someone tries to PQreset() the PGconn.)
1074  */
1075  conn->options_valid = true;
1076 
1077  return true;
1078 
1079 oom_error:
1080  conn->status = CONNECTION_BAD;
1082  libpq_gettext("out of memory\n"));
1083  return false;
1084 }
#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:363
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:6197
char * pghostaddr
Definition: libpq-int.h:329
e
Definition: preproc-init.c:82
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:6353
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 5036 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().

5037 {
5039  char *tmp;
5040 
5041  /*
5042  * If there's a service spec, use it to obtain any not-explicitly-given
5043  * parameters. Ignore error if no error message buffer is passed because
5044  * there is no way to pass back the failure message.
5045  */
5046  if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
5047  return false;
5048 
5049  /*
5050  * Get the fallback resources for parameters not specified in the conninfo
5051  * string nor the service.
5052  */
5053  for (option = options; option->keyword != NULL; option++)
5054  {
5055  if (option->val != NULL)
5056  continue; /* Value was in conninfo or service */
5057 
5058  /*
5059  * Try to get the environment variable fallback
5060  */
5061  if (option->envvar != NULL)
5062  {
5063  if ((tmp = getenv(option->envvar)) != NULL)
5064  {
5065  option->val = strdup(tmp);
5066  if (!option->val)
5067  {
5068  if (errorMessage)
5069  printfPQExpBuffer(errorMessage,
5070  libpq_gettext("out of memory\n"));
5071  return false;
5072  }
5073  continue;
5074  }
5075  }
5076 
5077  /*
5078  * No environment variable specified or the variable isn't set - try
5079  * compiled-in default
5080  */
5081  if (option->compiled != NULL)
5082  {
5083  option->val = strdup(option->compiled);
5084  if (!option->val)
5085  {
5086  if (errorMessage)
5087  printfPQExpBuffer(errorMessage,
5088  libpq_gettext("out of memory\n"));
5089  return false;
5090  }
5091  continue;
5092  }
5093 
5094  /*
5095  * Special handling for "user" option. Note that if pg_fe_getauthname
5096  * fails, we just leave the value as NULL; there's no need for this to
5097  * be an error condition if the caller provides a user name. The only
5098  * reason we do this now at all is so that callers of PQconndefaults
5099  * will see a correct default (barring error, of course).
5100  */
5101  if (strcmp(option->keyword, "user") == 0)
5102  {
5103  option->val = pg_fe_getauthname(NULL);
5104  continue;
5105  }
5106  }
5107 
5108  return true;
5109 }
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:4334
#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 4872 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().

4875 {
4877  PQconninfoOption *dbname_options = NULL;
4879  int i = 0;
4880 
4881  /*
4882  * If expand_dbname is non-zero, check keyword "dbname" to see if val is
4883  * actually a recognized connection string.
4884  */
4885  while (expand_dbname && keywords[i])
4886  {
4887  const char *pname = keywords[i];
4888  const char *pvalue = values[i];
4889 
4890  /* first find "dbname" if any */
4891  if (strcmp(pname, "dbname") == 0 && pvalue)
4892  {
4893  /*
4894  * If value is a connection string, parse it, but do not use
4895  * defaults here -- those get picked up later. We only want to
4896  * override for those parameters actually passed.
4897  */
4898  if (recognized_connection_string(pvalue))
4899  {
4900  dbname_options = parse_connection_string(pvalue, errorMessage, false);
4901  if (dbname_options == NULL)
4902  return NULL;
4903  }
4904  break;
4905  }
4906  ++i;
4907  }
4908 
4909  /* Make a working copy of PQconninfoOptions */
4910  options = conninfo_init(errorMessage);
4911  if (options == NULL)
4912  {
4913  PQconninfoFree(dbname_options);
4914  return NULL;
4915  }
4916 
4917  /* Parse the keywords/values arrays */
4918  i = 0;
4919  while (keywords[i])
4920  {
4921  const char *pname = keywords[i];
4922  const char *pvalue = values[i];
4923 
4924  if (pvalue != NULL && pvalue[0] != '\0')
4925  {
4926  /* Search for the param record */
4927  for (option = options; option->keyword != NULL; option++)
4928  {
4929  if (strcmp(option->keyword, pname) == 0)
4930  break;
4931  }
4932 
4933  /* Check for invalid connection option */
4934  if (option->keyword == NULL)
4935  {
4936  printfPQExpBuffer(errorMessage,
4937  libpq_gettext("invalid connection option \"%s\"\n"),
4938  pname);
4939  PQconninfoFree(options);
4940  PQconninfoFree(dbname_options);
4941  return NULL;
4942  }
4943 
4944  /*
4945  * If we are on the first dbname parameter, and we have a parsed
4946  * connection string, copy those parameters across, overriding any
4947  * existing previous settings.
4948  */
4949  if (strcmp(pname, "dbname") == 0 && dbname_options)
4950  {
4951  PQconninfoOption *str_option;
4952 
4953  for (str_option = dbname_options; str_option->keyword != NULL; str_option++)
4954  {
4955  if (str_option->val != NULL)
4956  {
4957  int k;
4958 
4959  for (k = 0; options[k].keyword; k++)
4960  {
4961  if (strcmp(options[k].keyword, str_option->keyword) == 0)
4962  {
4963  if (options[k].val)
4964  free(options[k].val);
4965  options[k].val = strdup(str_option->val);
4966  if (!options[k].val)
4967  {
4968  printfPQExpBuffer(errorMessage,
4969  libpq_gettext("out of memory\n"));
4970  PQconninfoFree(options);
4971  PQconninfoFree(dbname_options);
4972  return NULL;
4973  }
4974  break;
4975  }
4976  }
4977  }
4978  }
4979 
4980  /*
4981  * Forget the parsed connection string, so that any subsequent
4982  * dbname parameters will not be expanded.
4983  */
4984  PQconninfoFree(dbname_options);
4985  dbname_options = NULL;
4986  }
4987  else
4988  {
4989  /*
4990  * Store the value, overriding previous settings
4991  */
4992  if (option->val)
4993  free(option->val);
4994  option->val = strdup(pvalue);
4995  if (!option->val)
4996  {
4997  printfPQExpBuffer(errorMessage,
4998  libpq_gettext("out of memory\n"));
4999  PQconninfoFree(options);
5000  PQconninfoFree(dbname_options);
5001  return NULL;
5002  }
5003  }
5004  }
5005  ++i;
5006  }
5007  PQconninfoFree(dbname_options);
5008 
5009  /*
5010  * Add in defaults if the caller wants that.
5011  */
5012  if (use_defaults)
5013  {
5014  if (!conninfo_add_defaults(options, errorMessage))
5015  {
5016  PQconninfoFree(options);
5017  return NULL;
5018  }
5019  }
5020 
5021  return options;
5022 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4600
static PQconninfoOption * parse_connection_string(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4640
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5784
static char ** options
static bool recognized_connection_string(const char *connstr)
Definition: fe-connect.c:4683
#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:5036
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 5725 of file fe-connect.c.

References _PQconninfoOption::keyword, and NULL.

Referenced by conninfo_getval(), and conninfo_storeval().

5726 {
5728 
5729  for (option = connOptions; option->keyword != NULL; option++)
5730  {
5731  if (strcmp(option->keyword, keyword) == 0)
5732  return option;
5733  }
5734 
5735  return NULL;
5736 }
#define NULL
Definition: c.h:229
static const char * conninfo_getval ( PQconninfoOption connOptions,
const char *  keyword 
)
static

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

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

Referenced by fillPGconn(), and parseServiceInfo().

5636 {
5638 
5639  option = conninfo_find(connOptions, keyword);
5640 
5641  return option ? option->val : NULL;
5642 }
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5725
#define NULL
Definition: c.h:229
static PQconninfoOption * conninfo_init ( PQExpBuffer  errorMessage)
static

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

4601 {
4603  PQconninfoOption *opt_dest;
4604  const internalPQconninfoOption *cur_opt;
4605 
4606  /*
4607  * Get enough memory for all options in PQconninfoOptions, even if some
4608  * end up being filtered out.
4609  */
4610  options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
4611  if (options == NULL)
4612  {
4613  printfPQExpBuffer(errorMessage,
4614  libpq_gettext("out of memory\n"));
4615  return NULL;
4616  }
4617  opt_dest = options;
4618 
4619  for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
4620  {
4621  /* Only copy the public part of the struct, not the full internal */
4622  memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
4623  opt_dest++;
4624  }
4625  MemSet(opt_dest, 0, sizeof(PQconninfoOption));
4626 
4627  return options;
4628 }
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 4694 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().

4696 {
4697  char *pname;
4698  char *pval;
4699  char *buf;
4700  char *cp;
4701  char *cp2;
4703 
4704  /* Make a working copy of PQconninfoOptions */
4705  options = conninfo_init(errorMessage);
4706  if (options == NULL)
4707  return NULL;
4708 
4709  /* Need a modifiable copy of the input string */
4710  if ((buf = strdup(conninfo)) == NULL)
4711  {
4712  printfPQExpBuffer(errorMessage,
4713  libpq_gettext("out of memory\n"));
4714  PQconninfoFree(options);
4715  return NULL;
4716  }
4717  cp = buf;
4718 
4719  while (*cp)
4720  {
4721  /* Skip blanks before the parameter name */
4722  if (isspace((unsigned char) *cp))
4723  {
4724  cp++;
4725  continue;
4726  }
4727 
4728  /* Get the parameter name */
4729  pname = cp;
4730  while (*cp)
4731  {
4732  if (*cp == '=')
4733  break;
4734  if (isspace((unsigned char) *cp))
4735  {
4736  *cp++ = '\0';
4737  while (*cp)
4738  {
4739  if (!isspace((unsigned char) *cp))
4740  break;
4741  cp++;
4742  }
4743  break;
4744  }
4745  cp++;
4746  }
4747 
4748  /* Check that there is a following '=' */
4749  if (*cp != '=')
4750  {
4751  printfPQExpBuffer(errorMessage,
4752  libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
4753  pname);
4754  PQconninfoFree(options);
4755  free(buf);
4756  return NULL;
4757  }
4758  *cp++ = '\0';
4759 
4760  /* Skip blanks after the '=' */
4761  while (*cp)
4762  {
4763  if (!isspace((unsigned char) *cp))
4764  break;
4765  cp++;
4766  }
4767 
4768  /* Get the parameter value */
4769  pval = cp;
4770 
4771  if (*cp != '\'')
4772  {
4773  cp2 = pval;
4774  while (*cp)
4775  {
4776  if (isspace((unsigned char) *cp))
4777  {
4778  *cp++ = '\0';
4779  break;
4780  }
4781  if (*cp == '\\')
4782  {
4783  cp++;
4784  if (*cp != '\0')
4785  *cp2++ = *cp++;
4786  }
4787  else
4788  *cp2++ = *cp++;
4789  }
4790  *cp2 = '\0';
4791  }
4792  else
4793  {
4794  cp2 = pval;
4795  cp++;
4796  for (;;)
4797  {
4798  if (*cp == '\0')
4799  {
4800  printfPQExpBuffer(errorMessage,
4801  libpq_gettext("unterminated quoted string in connection info string\n"));
4802  PQconninfoFree(options);
4803  free(buf);
4804  return NULL;
4805  }
4806  if (*cp == '\\')
4807  {
4808  cp++;
4809  if (*cp != '\0')
4810  *cp2++ = *cp++;
4811  continue;
4812  }
4813  if (*cp == '\'')
4814  {
4815  *cp2 = '\0';
4816  cp++;
4817  break;
4818  }
4819  *cp2++ = *cp++;
4820  }
4821  }
4822 
4823  /*
4824  * Now that we have the name and the value, store the record.
4825  */
4826  if (!conninfo_storeval(options, pname, pval, errorMessage, false, false))
4827  {
4828  PQconninfoFree(options);
4829  free(buf);
4830  return NULL;
4831  }
4832  }
4833 
4834  /* Done with the modifiable input string */
4835  free(buf);
4836 
4837  /*
4838  * Add in defaults if the caller wants that.
4839  */
4840  if (use_defaults)
4841  {
4842  if (!conninfo_add_defaults(options, errorMessage))
4843  {
4844  PQconninfoFree(options);
4845  return NULL;
4846  }
4847  }
4848 
4849  return options;
4850 }
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:5660
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4600
static char * buf
Definition: pg_test_fsync.c:66
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5784
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:5036
#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 5660 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().

5664 {
5666  char *value_copy;
5667 
5668  /*
5669  * For backwards compatibility, requiressl=1 gets translated to
5670  * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
5671  * (which is the default for sslmode).
5672  */
5673  if (strcmp(keyword, "requiressl") == 0)
5674  {
5675  keyword = "sslmode";
5676  if (value[0] == '1')
5677  value = "require";
5678  else
5679  value = "prefer";
5680  }
5681 
5682  option = conninfo_find(connOptions, keyword);
5683  if (option == NULL)
5684  {
5685  if (!ignoreMissing)
5686  printfPQExpBuffer(errorMessage,
5687  libpq_gettext("invalid connection option \"%s\"\n"),
5688  keyword);
5689  return NULL;
5690  }
5691 
5692  if (uri_decode)
5693  {
5694  value_copy = conninfo_uri_decode(value, errorMessage);
5695  if (value_copy == NULL)
5696  /* conninfo_uri_decode already set an error message */
5697  return NULL;
5698  }
5699  else
5700  {
5701  value_copy = strdup(value);
5702  if (value_copy == NULL)
5703  {
5704  printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5705  return NULL;
5706  }
5707  }
5708 
5709  if (option->val)
5710  free(option->val);
5711  option->val = value_copy;
5712 
5713  return option;
5714 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5725
static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
Definition: fe-connect.c:5545
#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 5545 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().

5546 {
5547  char *buf;
5548  char *p;
5549  const char *q = str;
5550 
5551  buf = malloc(strlen(str) + 1);
5552  if (buf == NULL)
5553  {
5554  printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5555  return NULL;
5556  }
5557  p = buf;
5558 
5559  for (;;)
5560  {
5561  if (*q != '%')
5562  {
5563  /* copy and check for NUL terminator */
5564  if (!(*(p++) = *(q++)))
5565  break;
5566  }
5567  else
5568  {
5569  int hi;
5570  int lo;
5571  int c;
5572 
5573  ++q; /* skip the percent sign itself */
5574 
5575  /*
5576  * Possible EOL will be caught by the first call to
5577  * get_hexdigit(), so we never dereference an invalid q pointer.
5578  */
5579  if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
5580  {
5581  printfPQExpBuffer(errorMessage,
5582  libpq_gettext("invalid percent-encoded token: \"%s\"\n"),
5583  str);
5584  free(buf);
5585  return NULL;
5586  }
5587 
5588  c = (hi << 4) | lo;
5589  if (c == 0)
5590  {
5591  printfPQExpBuffer(errorMessage,
5592  libpq_gettext("forbidden value %%00 in percent-encoded value: \"%s\"\n"),
5593  str);
5594  free(buf);
5595  return NULL;
5596  }
5597  *(p++) = c;
5598  }
5599  }
5600 
5601  return buf;
5602 }
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:5613
#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 5117 of file fe-connect.c.

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

Referenced by parse_connection_string().

5119 {
5121 
5122  /* Make a working copy of PQconninfoOptions */
5123  options = conninfo_init(errorMessage);
5124  if (options == NULL)
5125  return NULL;
5126 
5127  if (!conninfo_uri_parse_options(options, uri, errorMessage))
5128  {
5129  PQconninfoFree(options);
5130  return NULL;
5131  }
5132 
5133  /*
5134  * Add in defaults if the caller wants that.
5135  */
5136  if (use_defaults)
5137  {
5138  if (!conninfo_add_defaults(options, errorMessage))
5139  {
5140  PQconninfoFree(options);
5141  return NULL;
5142  }
5143  }
5144 
5145  return options;
5146 }
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4600
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5784
static bool conninfo_uri_parse_options(PQconninfoOption *options, const char *uri, PQExpBuffer errorMessage)
Definition: fe-connect.c:5170
static char ** options
#define NULL
Definition: c.h:229
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5036
static bool conninfo_uri_parse_options ( PQconninfoOption options,
const char *  uri,
PQExpBuffer  errorMessage 
)
static

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

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

5417 {
5418  while (*params)
5419  {
5420  char *keyword = params;
5421  char *value = NULL;
5422  char *p = params;
5423  bool malloced = false;
5424 
5425  /*
5426  * Scan the params string for '=' and '&', marking the end of keyword
5427  * and value respectively.
5428  */
5429  for (;;)
5430  {
5431  if (*p == '=')
5432  {
5433  /* Was there '=' already? */
5434  if (value != NULL)
5435  {
5436  printfPQExpBuffer(errorMessage,
5437  libpq_gettext("extra key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5438  keyword);
5439  return false;
5440  }
5441  /* Cut off keyword, advance to value */
5442  *p++ = '\0';
5443  value = p;
5444  }
5445  else if (*p == '&' || *p == '\0')
5446  {
5447  /*
5448  * If not at the end, cut off value and advance; leave p
5449  * pointing to start of the next parameter, if any.
5450  */
5451  if (*p != '\0')
5452  *p++ = '\0';
5453  /* Was there '=' at all? */
5454  if (value == NULL)
5455  {
5456  printfPQExpBuffer(errorMessage,
5457  libpq_gettext("missing key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5458  keyword);
5459  return false;
5460  }
5461  /* Got keyword and value, go process them. */
5462  break;
5463  }
5464  else
5465  ++p; /* Advance over all other bytes. */
5466  }
5467 
5468  keyword = conninfo_uri_decode(keyword, errorMessage);
5469  if (keyword == NULL)
5470  {
5471  /* conninfo_uri_decode already set an error message */
5472  return false;
5473  }
5474  value = conninfo_uri_decode(value, errorMessage);
5475  if (value == NULL)
5476  {
5477  /* conninfo_uri_decode already set an error message */
5478  free(keyword);
5479  return false;
5480  }
5481  malloced = true;
5482 
5483  /*
5484  * Special keyword handling for improved JDBC compatibility.
5485  */
5486  if (strcmp(keyword, "ssl") == 0 &&
5487  strcmp(value, "true") == 0)
5488  {
5489  free(keyword);
5490  free(value);
5491  malloced = false;
5492 
5493  keyword = "sslmode";
5494  value = "require";
5495  }
5496 
5497  /*
5498  * Store the value if the corresponding option exists; ignore
5499  * otherwise. At this point both keyword and value are not
5500  * URI-encoded.
5501  */
5502  if (!conninfo_storeval(connOptions, keyword, value,
5503  errorMessage, true, false))
5504  {
5505  /* Insert generic message if conninfo_storeval didn't give one. */
5506  if (errorMessage->len == 0)
5507  printfPQExpBuffer(errorMessage,
5508  libpq_gettext("invalid URI query parameter: \"%s\"\n"),
5509  keyword);
5510  /* And fail. */
5511  if (malloced)
5512  {
5513  free(keyword);
5514  free(value);
5515  }
5516  return false;
5517  }
5518 
5519  if (malloced)
5520  {
5521  free(keyword);
5522  free(value);
5523  }
5524 
5525  /* Proceed to next key=value pair, if any */
5526  params = p;
5527  }
5528 
5529  return true;
5530 }
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:5660
static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
Definition: fe-connect.c:5545
#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 6382 of file fe-connect.c.

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

Referenced by PQregisterThreadLock().

6383 {
6384 #ifdef ENABLE_THREAD_SAFETY
6385 #ifndef WIN32
6386  static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
6387 #else
6388  static pthread_mutex_t singlethread_lock = NULL;
6389  static long mutex_initlock = 0;
6390 
6391  if (singlethread_lock == NULL)
6392  {
6393  while (InterlockedExchange(&mutex_initlock, 1) == 1)
6394  /* loop, another thread own the lock */ ;
6395  if (singlethread_lock == NULL)
6396  {
6397  if (pthread_mutex_init(&singlethread_lock, NULL))
6398  PGTHREAD_ERROR("failed to initialize mutex");
6399  }
6400  InterlockedExchange(&mutex_initlock, 0);
6401  }
6402 #endif
6403  if (acquire)
6404  {
6405  if (pthread_mutex_lock(&singlethread_lock))
6406  PGTHREAD_ERROR("failed to lock mutex");
6407  }
6408  else
6409  {
6410  if (pthread_mutex_unlock(&singlethread_lock))
6411  PGTHREAD_ERROR("failed to unlock mutex");
6412  }
6413 #endif
6414 }
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 6148 of file fe-connect.c.

Referenced by makeEmptyPGconn().

6149 {
6150  (void) arg; /* not used */
6151  /* Note: we expect the supplied string to end with a newline already. */
6152  fprintf(stderr, "%s", message);
6153 }
void * arg
static void defaultNoticeReceiver ( void *  arg,
const PGresult res 
)
static

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

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

Referenced by makeEmptyPGconn().

6134 {
6135  (void) arg; /* not used */
6136  if (res->noticeHooks.noticeProc != NULL)
6138  PQresultErrorMessage(res));
6139 }
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:5634
#define libpq_gettext(x)
Definition: libpq-int.h:683
static void freePGconn ( PGconn conn)
static

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

3230 {
3231  int i;
3232 
3233  /* let any event procs clean up their state data */
3234  for (i = 0; i < conn->nEvents; i++)
3235  {
3236  PGEventConnDestroy evt;
3237 
3238  evt.conn = conn;
3239  (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
3240  conn->events[i].passThrough);
3241  free(conn->events[i].name);
3242  }
3243 
3244  /* clean up pg_conn_host structures */
3245  if (conn->connhost != NULL)
3246  {
3247  for (i = 0; i < conn->nconnhost; ++i)
3248  {
3249  if (conn->connhost[i].host != NULL)
3250  free(conn->connhost[i].host);
3251  if (conn->connhost[i].port != NULL)
3252  free(conn->connhost[i].port);
3253  if (conn->connhost[i].password != NULL)
3254  free(conn->connhost[i].password);
3255  }
3256  free(conn->connhost);
3257  }
3258 
3259  if (conn->client_encoding_initial)
3261  if (conn->events)
3262  free(conn->events);
3263  if (conn->pghost)
3264  free(conn->pghost);
3265  if (conn->pghostaddr)
3266  free(conn->pghostaddr);
3267  if (conn->pgport)
3268  free(conn->pgport);
3269  if (conn->pgtty)
3270  free(conn->pgtty);
3271  if (conn->connect_timeout)
3272  free(conn->connect_timeout);
3273  if (conn->pgoptions)
3274  free(conn->pgoptions);
3275  if (conn->appname)
3276  free(conn->appname);
3277  if (conn->fbappname)
3278  free(conn->fbappname);
3279  if (conn->dbName)
3280  free(conn->dbName);
3281  if (conn->replication)
3282  free(conn->replication);
3283  if (conn->pguser)
3284  free(conn->pguser);
3285  if (conn->pgpass)
3286  free(conn->pgpass);
3287  if (conn->pgpassfile)
3288  free(conn->pgpassfile);
3289  if (conn->keepalives)
3290  free(conn->keepalives);
3291  if (conn->keepalives_idle)
3292  free(conn->keepalives_idle);
3293  if (conn->keepalives_interval)
3294  free(conn->keepalives_interval);
3295  if (conn->keepalives_count)
3296  free(conn->keepalives_count);
3297  if (conn->sslmode)
3298  free(conn->sslmode);
3299  if (conn->sslcert)
3300  free(conn->sslcert);
3301  if (conn->sslkey)
3302  free(conn->sslkey);
3303  if (conn->sslrootcert)
3304  free(conn->sslrootcert);
3305  if (conn->sslcrl)
3306  free(conn->sslcrl);
3307  if (conn->sslcompression)
3308  free(conn->sslcompression);
3309  if (conn->requirepeer)
3310  free(conn->requirepeer);
3311 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
3312  if (conn->krbsrvname)
3313  free(conn->krbsrvname);
3314 #endif
3315 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
3316  if (conn->gsslib)
3317  free(conn->gsslib);
3318 #endif
3319  /* Note that conn->Pfdebug is not ours to close or free */
3320  if (conn->last_query)
3321  free(conn->last_query);
3322  if (conn->inBuffer)
3323  free(conn->inBuffer);
3324  if (conn->outBuffer)
3325  free(conn->outBuffer);
3326  if (conn->rowBuf)
3327  free(conn->rowBuf);
3328  if (conn->target_session_attrs)
3329  free(conn->target_session_attrs);
3330  termPQExpBuffer(&conn->errorMessage);
3331  termPQExpBuffer(&conn->workBuffer);
3332 
3333  free(conn);
3334 
3335 #ifdef WIN32
3336  WSACleanup();
3337 #endif
3338 }
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:363
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 5613 of file fe-connect.c.

Referenced by conninfo_uri_decode().

5614 {
5615  if ('0' <= digit && digit <= '9')
5616  *value = digit - '0';
5617  else if ('A' <= digit && digit <= 'F')
5618  *value = digit - 'A' + 10;
5619  else if ('a' <= digit && digit <= 'f')
5620  *value = digit - 'a' + 10;
5621  else
5622  return false;
5623 
5624  return true;
5625 }
static struct @121 value
static int internal_cancel ( SockAddr raddr,
int  be_pid,
int  be_key,
char *  errbuf,
int  errbufsize 
)
static

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

3665 {
3666  int save_errno = SOCK_ERRNO;
3667  pgsocket tmpsock = PGINVALID_SOCKET;
3668  char sebuf[256];
3669  int maxlen;
3670  struct
3671  {
3672  uint32 packetlen;
3674  } crp;
3675 
3676  /*
3677  * We need to open a temporary connection to the postmaster. Do this with
3678  * only kernel calls.
3679  */
3680  if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
3681  {
3682  strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
3683  goto cancel_errReturn;
3684  }
3685 retry3:
3686  if (connect(tmpsock, (struct sockaddr *) & raddr->addr,
3687  raddr->salen) < 0)
3688  {
3689  if (SOCK_ERRNO == EINTR)
3690  /* Interrupted system call - we'll just try again */
3691  goto retry3;
3692  strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
3693  goto cancel_errReturn;
3694  }
3695 
3696  /*
3697  * We needn't set nonblocking I/O or NODELAY options here.
3698  */
3699 
3700  /* Create and send the cancel request packet. */
3701 
3702  crp.packetlen = htonl((uint32) sizeof(crp));
3703  crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE);
3704  crp.cp.backendPID = htonl(be_pid);
3705  crp.cp.cancelAuthCode = htonl(be_key);
3706 
3707 retry4:
3708  if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
3709  {
3710  if (SOCK_ERRNO == EINTR)
3711  /* Interrupted system call - we'll just try again */
3712  goto retry4;
3713  strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
3714  goto cancel_errReturn;
3715  }
3716 
3717  /*
3718  * Wait for the postmaster to close the connection, which indicates that
3719  * it's processed the request. Without this delay, we might issue another
3720  * command only to find that our cancel zaps that command instead of the
3721  * one we thought we were canceling. Note we don't actually expect this
3722  * read to obtain any data, we are just waiting for EOF to be signaled.
3723  */
3724 retry5:
3725  if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
3726  {
3727  if (SOCK_ERRNO == EINTR)
3728  /* Interrupted system call - we'll just try again */
3729  goto retry5;
3730  /* we ignore other error conditions */
3731  }
3732 
3733  /* All done */
3734  closesocket(tmpsock);
3735  SOCK_ERRNO_SET(save_errno);
3736  return TRUE;
3737 
3738 cancel_errReturn:
3739 
3740  /*
3741  * Make sure we don't overflow the error buffer. Leave space for the \n at
3742  * the end, and for the terminating zero.
3743  */
3744  maxlen = errbufsize - strlen(errbuf) - 2;
3745  if (maxlen >= 0)
3746  {
3747  strncat(errbuf, SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)),
3748  maxlen);
3749  strcat(errbuf, "\n");
3750  }
3751  if (tmpsock != PGINVALID_SOCKET)
3752  closesocket(tmpsock);
3753  SOCK_ERRNO_SET(save_errno);
3754  return FALSE;
3755 }
#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 3068 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().

3069 {
3070  /* Say "no attempt" if we never got to PQconnectPoll */
3071  if (!conn || !conn->options_valid)
3072  return PQPING_NO_ATTEMPT;
3073 
3074  /* Attempt to complete the connection */
3075  if (conn->status != CONNECTION_BAD)
3076  (void) connectDBComplete(conn);
3077 
3078  /* Definitely OK if we succeeded */
3079  if (conn->status != CONNECTION_BAD)
3080  return PQPING_OK;
3081 
3082  /*
3083  * Here begins the interesting part of "ping": determine the cause of the
3084  * failure in sufficient detail to decide what to return. We do not want
3085  * to report that the server is not up just because we didn't have a valid
3086  * password, for example. In fact, any sort of authentication request
3087  * implies the server is up. (We need this check since the libpq side of
3088  * things might have pulled the plug on the connection before getting an
3089  * error as such from the postmaster.)
3090  */
3091  if (conn->auth_req_received)
3092  return PQPING_OK;
3093 
3094  /*
3095  * If we failed to get any ERROR response from the postmaster, report
3096  * PQPING_NO_RESPONSE. This result could be somewhat misleading for a
3097  * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
3098  * out of support. Another corner case where the server could return a
3099  * failure without a SQLSTATE is fork failure, but NO_RESPONSE isn't
3100  * totally unreasonable for that anyway. We expect that every other
3101  * failure case in a modern server will produce a report with a SQLSTATE.
3102  *
3103  * NOTE: whenever we get around to making libpq generate SQLSTATEs for
3104  * client-side errors, we should either not store those into
3105  * last_sqlstate, or add an extra flag so we can tell client-side errors
3106  * apart from server-side ones.
3107  */
3108  if (strlen(conn->last_sqlstate) != 5)
3109  return PQPING_NO_RESPONSE;
3110 
3111  /*
3112  * Report PQPING_REJECT if server says it's not accepting connections. (We
3113  * distinguish this case mainly for the convenience of pg_ctl.)
3114  */
3115  if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
3116  return PQPING_REJECT;
3117 
3118  /*
3119  * Any other SQLSTATE can be taken to indicate that the server is up.
3120  * Presumably it didn't like our username, password, or database name; or
3121  * perhaps it had some transient failure, but that should not be taken as
3122  * meaning "it's down".
3123  */
3124  return PQPING_OK;
3125 }
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1710
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 3133 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().

3134 {
3135  PGconn *conn;
3136 
3137 #ifdef WIN32
3138 
3139  /*
3140  * Make sure socket support is up and running.
3141  */
3142  WSADATA wsaData;
3143 
3144  if (WSAStartup(MAKEWORD(1, 1), &wsaData))
3145  return NULL;
3146  WSASetLastError(0);
3147 #endif
3148 
3149  conn = (PGconn *) malloc(sizeof(PGconn));
3150  if (conn == NULL)
3151  {
3152 #ifdef WIN32
3153  WSACleanup();
3154 #endif
3155  return conn;
3156  }
3157 
3158  /* Zero all pointers and booleans */
3159  MemSet(conn, 0, sizeof(PGconn));
3160 
3161  /* install default notice hooks */
3164 
3165  conn->status = CONNECTION_BAD;
3166  conn->asyncStatus = PGASYNC_IDLE;
3167  conn->xactStatus = PQTRANS_IDLE;
3168  conn->options_valid = false;
3169  conn->nonblocking = false;
3171  conn->client_encoding = PG_SQL_ASCII;
3172  conn->std_strings = false; /* unless server says differently */
3173  conn->verbosity = PQERRORS_DEFAULT;
3175  conn->sock = PGINVALID_SOCKET;
3176  conn->auth_req_received = false;
3177  conn->password_needed = false;
3178  conn->pgpassfile_used = false;
3179 #ifdef USE_SSL
3180  conn->allow_ssl_try = true;
3181  conn->wait_ssl_try = false;
3182  conn->ssl_in_use = false;
3183 #endif
3184 
3185  /*
3186  * We try to send at least 8K at a time, which is the usual size of pipe
3187  * buffers on Unix systems. That way, when we are sending a large amount
3188  * of data, we avoid incurring extra kernel context swaps for partial
3189  * bufferloads. The output buffer is initially made 16K in size, and we
3190  * try to dump it after accumulating 8K.
3191  *
3192  * With the same goal of minimizing context swaps, the input buffer will
3193  * be enlarged anytime it has less than 8K free, so we initially allocate
3194  * twice that.
3195  */
3196  conn->inBufSize = 16 * 1024;
3197  conn->inBuffer = (char *) malloc(conn->inBufSize);
3198  conn->outBufSize = 16 * 1024;
3199  conn->outBuffer = (char *) malloc(conn->outBufSize);
3200  conn->rowBufLen = 32;
3201  conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
3202  initPQExpBuffer(&conn->errorMessage);
3203  initPQExpBuffer(&conn->workBuffer);
3204 
3205  if (conn->inBuffer == NULL ||
3206  conn->outBuffer == NULL ||
3207  conn->rowBuf == NULL ||
3208  PQExpBufferBroken(&conn->errorMessage) ||
3209  PQExpBufferBroken(&conn->workBuffer))
3210  {
3211  /* out of memory already :-( */
3212  freePGconn(conn);
3213  conn = NULL;
3214  }
3215 
3216  return conn;
3217 }
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:3229
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:6148
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:6133
PGTransactionStatusType xactStatus
Definition: libpq-int.h:380
static PQconninfoOption * parse_connection_string ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

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

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

4642 {
4643  /* Parse as URI if connection string matches URI prefix */
4644  if (uri_prefix_length(connstr) != 0)
4645  return conninfo_uri_parse(connstr, errorMessage, use_defaults);
4646 
4647  /* Parse as default otherwise */
4648  return conninfo_parse(connstr, errorMessage, use_defaults);
4649 }
static PQconninfoOption * conninfo_parse(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4694
static int uri_prefix_length(const char *connstr)
Definition: fe-connect.c:4660
static PQconninfoOption * conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:5117
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 4403 of file fe-connect.c.

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

Referenced by parseServiceInfo().

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

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

Referenced by conninfo_add_defaults().

4335 {
4336  const char *service = conninfo_getval(options, "service");
4337  char serviceFile[MAXPGPATH];
4338  char *env;
4339  bool group_found = false;
4340  int status;
4341  struct stat stat_buf;
4342 
4343  /*
4344  * We have to special-case the environment variable PGSERVICE here, since
4345  * this is and should be called before inserting environment defaults for
4346  * other connection options.
4347  */
4348  if (service == NULL)
4349  service = getenv("PGSERVICE");
4350 
4351  if (service == NULL)
4352  return 0;
4353 
4354  if ((env = getenv("PGSERVICEFILE")) != NULL)
4355  strlcpy(serviceFile, env, sizeof(serviceFile));
4356  else
4357  {
4358  char homedir[MAXPGPATH];
4359 
4360  if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
4361  {
4362  printfPQExpBuffer(errorMessage, libpq_gettext("could not get home directory to locate service definition file"));
4363  return 1;
4364  }
4365  snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
4366  errno = 0;
4367  if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4368  goto next_file;
4369  }
4370 
4371  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4372  if (group_found || status != 0)
4373  return status;
4374 
4375 next_file:
4376 
4377  /*
4378  * This could be used by any application so we can't use the binary
4379  * location to find our config files.
4380  */
4381  snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
4382  getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
4383  errno = 0;
4384  if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4385  goto last_file;
4386 
4387  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4388  if (status != 0)
4389  return status;
4390 
4391 last_file:
4392  if (!group_found)
4393  {
4394  printfPQExpBuffer(errorMessage,
4395  libpq_gettext("definition of service \"%s\" not found\n"), service);
4396  return 3;
4397  }
4398 
4399  return 0;
4400 }
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:4403
static const char * conninfo_getval(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5634
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:6353
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 6197 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().

6199 {
6200  FILE *fp;
6201  struct stat stat_buf;
6202 
6203 #define LINELEN NAMEDATALEN*5
6204  char buf[LINELEN];
6205 
6206  if (dbname == NULL || strlen(dbname) == 0)
6207  return NULL;
6208 
6209  if (username == NULL || strlen(username) == 0)
6210  return NULL;
6211 
6212  /* 'localhost' matches pghost of '' or the default socket directory */
6213  if (hostname == NULL)
6215  else if (is_absolute_path(hostname))
6216 
6217  /*
6218  * We should probably use canonicalize_path(), but then we have to
6219  * bring path.c into libpq, and it doesn't seem worth it.
6220  */
6221  if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
6223 
6224  if (port == NULL)
6225  port = DEF_PGPORT_STR;
6226 
6227  /* If password file cannot be opened, ignore it. */
6228  if (stat(pgpassfile, &stat_buf) != 0)
6229  return NULL;
6230 
6231 #ifndef WIN32
6232  if (!S_ISREG(stat_buf.st_mode))
6233  {
6234  fprintf(stderr,
6235  libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
6236  pgpassfile);
6237  return NULL;
6238  }
6239 
6240  /* If password file is insecure, alert the user and ignore it. */
6241  if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
6242  {
6243  fprintf(stderr,
6244  libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
6245  pgpassfile);
6246  return NULL;
6247  }
6248 #else
6249 
6250  /*
6251  * On Win32, the directory is protected, so we don't have to check the
6252  * file.
6253  */
6254 #endif
6255 
6256  fp = fopen(pgpassfile, "r");
6257  if (fp == NULL)
6258  return NULL;
6259 
6260  while (!feof(fp) && !ferror(fp))
6261  {
6262  char *t = buf,
6263  *ret,
6264  *p1,
6265  *p2;
6266  int len;
6267 
6268  if (fgets(buf, sizeof(buf), fp) == NULL)
6269  break;
6270 
6271  len = strlen(buf);
6272 
6273  /* Remove trailing newline */
6274  if (len > 0 && buf[len - 1] == '\n')
6275  {
6276  buf[--len] = '\0';
6277  /* Handle DOS-style line endings, too, even when not on Windows */
6278  if (len > 0 && buf[len - 1] == '\r')
6279  buf[--len] = '\0';
6280  }
6281 
6282  if (len == 0)
6283  continue;
6284 
6285  if ((t = pwdfMatchesString(t, hostname)) == NULL ||
6286  (t = pwdfMatchesString(t, port)) == NULL ||
6287  (t = pwdfMatchesString(t, dbname)) == NULL ||
6288  (t = pwdfMatchesString(t, username)) == NULL)
6289  continue;
6290 
6291  /* Found a match. */
6292  ret = strdup(t);
6293  fclose(fp);
6294 
6295  if (!ret)
6296  {
6297  /* Out of memory. XXX: an error message would be nice. */
6298  return NULL;
6299  }
6300 
6301  /* De-escape password. */
6302  for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
6303  {
6304  if (*p1 == '\\' && p1[1] != '\0')
6305  ++p1;
6306  *p2 = *p1;
6307  }
6308  *p2 = '\0';
6309 
6310  return ret;
6311  }
6312 
6313  fclose(fp);
6314  return NULL;
6315 
6316 #undef LINELEN
6317 }
#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:6160
#define libpq_gettext(x)
Definition: libpq-int.h:683
#define DEFAULT_PGSOCKET_DIR
static void pgpassfileWarning ( PGconn conn)
static

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

6326 {
6327  /* If it was 'invalid authorization', add pgpassfile mention */
6328  /* only works with >= 9.0 servers */
6329  if (conn->pgpassfile_used && conn->password_needed && conn->result)
6330  {
6331  const char *sqlstate = PQresultErrorField(conn->result,
6333 
6334  if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
6336  libpq_gettext("password retrieved from file \"%s\"\n"),
6337  conn->pgpassfile);
6338  }
6339 }
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 5960 of file fe-connect.c.

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

Referenced by get_prompt().

5961 {
5962  if (!conn || conn->status != CONNECTION_OK)
5963  return 0;
5964  return conn->be_pid;
5965 }
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 3767 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().

3768 {
3769  if (!cancel)
3770  {
3771  strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
3772  return FALSE;
3773  }
3774 
3775  return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
3776  errbuf, errbufsize);
3777 }
static int internal_cancel(SockAddr *raddr, int be_pid, int be_key, char *errbuf, int errbufsize)
Definition: fe-connect.c:3663
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 5994 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().

5995 {
5996  if (!conn || conn->status != CONNECTION_OK)
5997  return -1;
5998  return conn->client_encoding;
5999 }
ConnStatusType status
Definition: libpq-int.h:378
int client_encoding
Definition: libpq-int.h:423
PQconninfoOption* PQconndefaults ( void  )

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

1104 {
1105  PQExpBufferData errorBuf;
1106  PQconninfoOption *connOptions;
1107 
1108  /* We don't actually report any errors here, but callees want a buffer */
1109  initPQExpBuffer(&errorBuf);
1110  if (PQExpBufferDataBroken(errorBuf))
1111  return NULL; /* out of memory already :-( */
1112 
1113  connOptions = conninfo_init(&errorBuf);
1114  if (connOptions != NULL)
1115  {
1116  /* pass NULL errorBuf to ignore errors */
1117  if (!conninfo_add_defaults(connOptions, NULL))
1118  {
1119  PQconninfoFree(connOptions);
1120  connOptions = NULL;
1121  }
1122  }
1123 
1124  termPQExpBuffer(&errorBuf);
1125  return connOptions;
1126 }
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4600
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5784
#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:5036
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:1710
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:1710
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 5968 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().

5969 {
5970  char *password;
5971 
5972  if (!conn)
5973  return false;
5974  password = PQpass(conn);
5975  if (conn->password_needed &&
5976  (password == NULL || password[0] == '\0'))
5977  return true;
5978  else
5979  return false;
5980 }
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:5818
#define NULL
Definition: c.h:229
int PQconnectionUsedPassword ( const PGconn conn)

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

References pg_conn::password_needed.

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

5984 {
5985  if (!conn)
5986  return false;
5987  if (conn->password_needed)
5988  return true;
5989  else
5990  return false;
5991 }
bool password_needed
Definition: libpq-int.h:408
PostgresPollingStatusType PQconnectPoll ( PGconn conn)

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

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