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 FD_CLOEXEC   1
 
#define PGPASSFILE   ".pgpass"
 
#define ERRCODE_APPNAME_UNKNOWN   "42704"
 
#define ERRCODE_INVALID_PASSWORD   "28P01"
 
#define ERRCODE_CANNOT_CONNECT_NOW   "57P03"
 
#define DefaultHost   "localhost"
 
#define DefaultTty   ""
 
#define DefaultOption   ""
 
#define DefaultAuthtype   ""
 
#define DefaultTargetSessionAttrs   "any"
 
#define DefaultSSLMode   "disable"
 
#define MAXBUFSIZE   256
 
#define LINELEN   NAMEDATALEN*5
 

Typedefs

typedef struct
_internalPQconninfoOption 
internalPQconninfoOption
 

Functions

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

Variables

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

Macro Definition Documentation

#define DefaultAuthtype   ""

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

#define DefaultHost   "localhost"

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

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

#define DefaultOption   ""

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

#define DefaultSSLMode   "disable"

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

Referenced by connectOptions2().

#define DefaultTargetSessionAttrs   "any"

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

#define DefaultTty   ""

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

#define ERRCODE_APPNAME_UNKNOWN   "42704"

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

Referenced by PQconnectPoll().

#define ERRCODE_CANNOT_CONNECT_NOW   "57P03"

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

Referenced by internal_ping(), and ProcessStartupPacket().

#define ERRCODE_INVALID_PASSWORD   "28P01"

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

Referenced by auth_failed(), and pgpassfileWarning().

#define FD_CLOEXEC   1

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

Referenced by PQconnectPoll().

#define LINELEN   NAMEDATALEN*5

Referenced by passwordFromFile().

#define MAXBUFSIZE   256

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

Referenced by parseServiceFile().

#define PGPASSFILE   ".pgpass"

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

Referenced by connectOptions2().

Typedef Documentation

Function Documentation

static void closePGconn ( PGconn conn)
static

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

3471 {
3472  PGnotify *notify;
3473  pgParameterStatus *pstatus;
3474 
3475  sendTerminateConn(conn);
3476 
3477  /*
3478  * Must reset the blocking status so a possible reconnect will work.
3479  *
3480  * Don't call PQsetnonblocking() because it will fail if it's unable to
3481  * flush the connection.
3482  */
3483  conn->nonblocking = FALSE;
3484 
3485  /*
3486  * Close the connection, reset all transient state, flush I/O buffers.
3487  */
3488  pqDropConnection(conn, true);
3489  conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just
3490  * absent */
3491  conn->asyncStatus = PGASYNC_IDLE;
3492  pqClearAsyncResult(conn); /* deallocate result */
3494  release_all_addrinfo(conn);
3495 
3496  notify = conn->notifyHead;
3497  while (notify != NULL)
3498  {
3499  PGnotify *prev = notify;
3500 
3501  notify = notify->next;
3502  free(prev);
3503  }
3504  conn->notifyHead = conn->notifyTail = NULL;
3505  pstatus = conn->pstatus;
3506  while (pstatus != NULL)
3507  {
3508  pgParameterStatus *prev = pstatus;
3509 
3510  pstatus = pstatus->next;
3511  free(prev);
3512  }
3513  conn->pstatus = NULL;
3514  if (conn->lobjfuncs)
3515  free(conn->lobjfuncs);
3516  conn->lobjfuncs = NULL;
3517 #ifdef ENABLE_GSS
3518  {
3519  OM_uint32 min_s;
3520 
3521  if (conn->gctx)
3522  gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
3523  if (conn->gtarg_nam)
3524  gss_release_name(&min_s, &conn->gtarg_nam);
3525  if (conn->ginbuf.length)
3526  gss_release_buffer(&min_s, &conn->ginbuf);
3527  if (conn->goutbuf.length)
3528  gss_release_buffer(&min_s, &conn->goutbuf);
3529  }
3530 #endif
3531 #ifdef ENABLE_SSPI
3532  if (conn->ginbuf.length)
3533  free(conn->ginbuf.value);
3534  conn->ginbuf.length = 0;
3535  conn->ginbuf.value = NULL;
3536  if (conn->sspitarget)
3537  free(conn->sspitarget);
3538  conn->sspitarget = NULL;
3539  if (conn->sspicred)
3540  {
3541  FreeCredentialsHandle(conn->sspicred);
3542  free(conn->sspicred);
3543  conn->sspicred = NULL;
3544  }
3545  if (conn->sspictx)
3546  {
3547  DeleteSecurityContext(conn->sspictx);
3548  free(conn->sspictx);
3549  conn->sspictx = NULL;
3550  }
3551 #endif
3552  if (conn->sasl_state)
3553  {
3554  /*
3555  * XXX: if support for more authentication mechanisms is added, this
3556  * needs to call the right 'free' function.
3557  */
3559  conn->sasl_state = NULL;
3560  }
3561 }
void pg_fe_scram_free(void *opaq)
static void release_all_addrinfo(PGconn *conn)
Definition: fe-connect.c:3415
PGnotify * notifyHead
Definition: libpq-int.h:391
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:409
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:3443
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:379
#define FALSE
Definition: c.h:221
void * sasl_state
Definition: libpq-int.h:460
pgParameterStatus * pstatus
Definition: libpq-int.h:423
struct pgNotify * next
Definition: libpq-fe.h:167
PQExpBufferData errorMessage
Definition: libpq-int.h:501
#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:428
static int connectDBComplete ( PGconn conn)
static

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

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

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

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

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

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

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

Referenced by PQconnectPoll().

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

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

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

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

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

5114 {
5116  char *tmp;
5117 
5118  /*
5119  * If there's a service spec, use it to obtain any not-explicitly-given
5120  * parameters. Ignore error if no error message buffer is passed because
5121  * there is no way to pass back the failure message.
5122  */
5123  if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
5124  return false;
5125 
5126  /*
5127  * Get the fallback resources for parameters not specified in the conninfo
5128  * string nor the service.
5129  */
5130  for (option = options; option->keyword != NULL; option++)
5131  {
5132  if (option->val != NULL)
5133  continue; /* Value was in conninfo or service */
5134 
5135  /*
5136  * Try to get the environment variable fallback
5137  */
5138  if (option->envvar != NULL)
5139  {
5140  if ((tmp = getenv(option->envvar)) != NULL)
5141  {
5142  option->val = strdup(tmp);
5143  if (!option->val)
5144  {
5145  if (errorMessage)
5146  printfPQExpBuffer(errorMessage,
5147  libpq_gettext("out of memory\n"));
5148  return false;
5149  }
5150  continue;
5151  }
5152  }
5153 
5154  /*
5155  * No environment variable specified or the variable isn't set - try
5156  * compiled-in default
5157  */
5158  if (option->compiled != NULL)
5159  {
5160  option->val = strdup(option->compiled);
5161  if (!option->val)
5162  {
5163  if (errorMessage)
5164  printfPQExpBuffer(errorMessage,
5165  libpq_gettext("out of memory\n"));
5166  return false;
5167  }
5168  continue;
5169  }
5170 
5171  /*
5172  * Special handling for "user" option. Note that if pg_fe_getauthname
5173  * fails, we just leave the value as NULL; there's no need for this to
5174  * be an error condition if the caller provides a user name. The only
5175  * reason we do this now at all is so that callers of PQconndefaults
5176  * will see a correct default (barring error, of course).
5177  */
5178  if (strcmp(option->keyword, "user") == 0)
5179  {
5180  option->val = pg_fe_getauthname(NULL);
5181  continue;
5182  }
5183  }
5184 
5185  return true;
5186 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:846
#define NULL
Definition: c.h:229
static int parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:4411
#define libpq_gettext(x)
Definition: libpq-int.h:692
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 4949 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().

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

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

References _PQconninfoOption::keyword, and NULL.

Referenced by conninfo_getval(), and conninfo_storeval().

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

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

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

Referenced by fillPGconn(), and parseServiceInfo().

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

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

4678 {
4680  PQconninfoOption *opt_dest;
4681  const internalPQconninfoOption *cur_opt;
4682 
4683  /*
4684  * Get enough memory for all options in PQconninfoOptions, even if some
4685  * end up being filtered out.
4686  */
4687  options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
4688  if (options == NULL)
4689  {
4690  printfPQExpBuffer(errorMessage,
4691  libpq_gettext("out of memory\n"));
4692  return NULL;
4693  }
4694  opt_dest = options;
4695 
4696  for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
4697  {
4698  /* Only copy the public part of the struct, not the full internal */
4699  memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
4700  opt_dest++;
4701  }
4702  MemSet(opt_dest, 0, sizeof(PQconninfoOption));
4703 
4704  return options;
4705 }
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:166
static char ** options
#define NULL
Definition: c.h:229
#define libpq_gettext(x)
Definition: libpq-int.h:692
static PQconninfoOption * conninfo_parse ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

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

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

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

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

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

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

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

Referenced by parse_connection_string().

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

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

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

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

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

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

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

Referenced by PQregisterThreadLock().

6460 {
6461 #ifdef ENABLE_THREAD_SAFETY
6462 #ifndef WIN32
6463  static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
6464 #else
6465  static pthread_mutex_t singlethread_lock = NULL;
6466  static long mutex_initlock = 0;
6467 
6468  if (singlethread_lock == NULL)
6469  {
6470  while (InterlockedExchange(&mutex_initlock, 1) == 1)
6471  /* loop, another thread own the lock */ ;
6472  if (singlethread_lock == NULL)
6473  {
6474  if (pthread_mutex_init(&singlethread_lock, NULL))
6475  PGTHREAD_ERROR("failed to initialize mutex");
6476  }
6477  InterlockedExchange(&mutex_initlock, 0);
6478  }
6479 #endif
6480  if (acquire)
6481  {
6482  if (pthread_mutex_lock(&singlethread_lock))
6483  PGTHREAD_ERROR("failed to lock mutex");
6484  }
6485  else
6486  {
6487  if (pthread_mutex_unlock(&singlethread_lock))
6488  PGTHREAD_ERROR("failed to unlock mutex");
6489  }
6490 #endif
6491 }
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 6225 of file fe-connect.c.

Referenced by makeEmptyPGconn().

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

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

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

Referenced by makeEmptyPGconn().

6211 {
6212  (void) arg; /* not used */
6213  if (res->noticeHooks.noticeProc != NULL)
6215  PQresultErrorMessage(res));
6216 }
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 696 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().

697 {
699 
700  for (option = PQconninfoOptions; option->keyword; option++)
701  {
702  if (option->connofs >= 0)
703  {
704  const char *tmp = conninfo_getval(connOptions, option->keyword);
705 
706  if (tmp)
707  {
708  char **connmember = (char **) ((char *) conn + option->connofs);
709 
710  if (*connmember)
711  free(*connmember);
712  *connmember = strdup(tmp);
713  if (*connmember == NULL)
714  {
716  libpq_gettext("out of memory\n"));
717  return false;
718  }
719  }
720  }
721  }
722 
723  return true;
724 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:166
PQExpBufferData errorMessage
Definition: libpq-int.h:501
#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:5711
#define libpq_gettext(x)
Definition: libpq-int.h:692
static void freePGconn ( PGconn conn)
static

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

3299 {
3300  int i;
3301 
3302  /* let any event procs clean up their state data */
3303  for (i = 0; i < conn->nEvents; i++)
3304  {
3305  PGEventConnDestroy evt;
3306 
3307  evt.conn = conn;
3308  (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
3309  conn->events[i].passThrough);
3310  free(conn->events[i].name);
3311  }
3312 
3313  /* clean up pg_conn_host structures */
3314  if (conn->connhost != NULL)
3315  {
3316  for (i = 0; i < conn->nconnhost; ++i)
3317  {
3318  if (conn->connhost[i].host != NULL)
3319  free(conn->connhost[i].host);
3320  if (conn->connhost[i].port != NULL)
3321  free(conn->connhost[i].port);
3322  if (conn->connhost[i].password != NULL)
3323  free(conn->connhost[i].password);
3324  }
3325  free(conn->connhost);
3326  }
3327 
3328  if (conn->client_encoding_initial)
3330  if (conn->events)
3331  free(conn->events);
3332  if (conn->pghost)
3333  free(conn->pghost);
3334  if (conn->pghostaddr)
3335  free(conn->pghostaddr);
3336  if (conn->pgport)
3337  free(conn->pgport);
3338  if (conn->pgtty)
3339  free(conn->pgtty);
3340  if (conn->connect_timeout)
3341  free(conn->connect_timeout);
3342  if (conn->pgoptions)
3343  free(conn->pgoptions);
3344  if (conn->appname)
3345  free(conn->appname);
3346  if (conn->fbappname)
3347  free(conn->fbappname);
3348  if (conn->dbName)
3349  free(conn->dbName);
3350  if (conn->replication)
3351  free(conn->replication);
3352  if (conn->pguser)
3353  free(conn->pguser);
3354  if (conn->pgpass)
3355  free(conn->pgpass);
3356  if (conn->pgpassfile)
3357  free(conn->pgpassfile);
3358  if (conn->keepalives)
3359  free(conn->keepalives);
3360  if (conn->keepalives_idle)
3361  free(conn->keepalives_idle);
3362  if (conn->keepalives_interval)
3363  free(conn->keepalives_interval);
3364  if (conn->keepalives_count)
3365  free(conn->keepalives_count);
3366  if (conn->sslmode)
3367  free(conn->sslmode);
3368  if (conn->sslcert)
3369  free(conn->sslcert);
3370  if (conn->sslkey)
3371  free(conn->sslkey);
3372  if (conn->sslrootcert)
3373  free(conn->sslrootcert);
3374  if (conn->sslcrl)
3375  free(conn->sslcrl);
3376  if (conn->sslcompression)
3377  free(conn->sslcompression);
3378  if (conn->requirepeer)
3379  free(conn->requirepeer);
3380 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
3381  if (conn->krbsrvname)
3382  free(conn->krbsrvname);
3383 #endif
3384 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
3385  if (conn->gsslib)
3386  free(conn->gsslib);
3387 #endif
3388  /* Note that conn->Pfdebug is not ours to close or free */
3389  if (conn->last_query)
3390  free(conn->last_query);
3391  if (conn->inBuffer)
3392  free(conn->inBuffer);
3393  if (conn->outBuffer)
3394  free(conn->outBuffer);
3395  if (conn->rowBuf)
3396  free(conn->rowBuf);
3397  if (conn->target_session_attrs)
3398  free(conn->target_session_attrs);
3399  termPQExpBuffer(&conn->errorMessage);
3400  termPQExpBuffer(&conn->workBuffer);
3401 
3402  free(conn);
3403 
3404 #ifdef WIN32
3405  WSACleanup();
3406 #endif
3407 }
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:504
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:448
char * pguser
Definition: libpq-int.h:342
char * inBuffer
Definition: libpq-int.h:431
char * sslmode
Definition: libpq-int.h:351
PQExpBufferData errorMessage
Definition: libpq-int.h:501
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:438
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 5690 of file fe-connect.c.

Referenced by conninfo_uri_decode().

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

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

3742 {
3743  int save_errno = SOCK_ERRNO;
3744  pgsocket tmpsock = PGINVALID_SOCKET;
3745  char sebuf[256];
3746  int maxlen;
3747  struct
3748  {
3749  uint32 packetlen;
3751  } crp;
3752 
3753  /*
3754  * We need to open a temporary connection to the postmaster. Do this with
3755  * only kernel calls.
3756  */
3757  if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
3758  {
3759  strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
3760  goto cancel_errReturn;
3761  }
3762 retry3:
3763  if (connect(tmpsock, (struct sockaddr *) & raddr->addr,
3764  raddr->salen) < 0)
3765  {
3766  if (SOCK_ERRNO == EINTR)
3767  /* Interrupted system call - we'll just try again */
3768  goto retry3;
3769  strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
3770  goto cancel_errReturn;
3771  }
3772 
3773  /*
3774  * We needn't set nonblocking I/O or NODELAY options here.
3775  */
3776 
3777  /* Create and send the cancel request packet. */
3778 
3779  crp.packetlen = htonl((uint32) sizeof(crp));
3780  crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE);
3781  crp.cp.backendPID = htonl(be_pid);
3782  crp.cp.cancelAuthCode = htonl(be_key);
3783 
3784 retry4:
3785  if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
3786  {
3787  if (SOCK_ERRNO == EINTR)
3788  /* Interrupted system call - we'll just try again */
3789  goto retry4;
3790  strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
3791  goto cancel_errReturn;
3792  }
3793 
3794  /*
3795  * Wait for the postmaster to close the connection, which indicates that
3796  * it's processed the request. Without this delay, we might issue another
3797  * command only to find that our cancel zaps that command instead of the
3798  * one we thought we were canceling. Note we don't actually expect this
3799  * read to obtain any data, we are just waiting for EOF to be signaled.
3800  */
3801 retry5:
3802  if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
3803  {
3804  if (SOCK_ERRNO == EINTR)
3805  /* Interrupted system call - we'll just try again */
3806  goto retry5;
3807  /* we ignore other error conditions */
3808  }
3809 
3810  /* All done */
3811  closesocket(tmpsock);
3812  SOCK_ERRNO_SET(save_errno);
3813  return TRUE;
3814 
3815 cancel_errReturn:
3816 
3817  /*
3818  * Make sure we don't overflow the error buffer. Leave space for the \n at
3819  * the end, and for the terminating zero.
3820  */
3821  maxlen = errbufsize - strlen(errbuf) - 2;
3822  if (maxlen >= 0)
3823  {
3824  strncat(errbuf, SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)),
3825  maxlen);
3826  strcat(errbuf, "\n");
3827  }
3828  if (tmpsock != PGINVALID_SOCKET)
3829  closesocket(tmpsock);
3830  SOCK_ERRNO_SET(save_errno);
3831  return FALSE;
3832 }
#define send(s, buf, len, flags)
Definition: win32.h:386
#define connect(s, name, namelen)
Definition: win32.h:383
#define closesocket
Definition: port.h:328
struct sockaddr_storage addr
Definition: pqcomm.h:64
#define socket(af, type, protocol)
Definition: win32.h:379
#define recv(s, buf, len, flags)
Definition: win32.h:385
#define SOCK_STRERROR
Definition: libpq-int.h:706
#define FALSE
Definition: c.h:221
#define SOCK_ERRNO
Definition: libpq-int.h:705
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:707
#define PGINVALID_SOCKET
Definition: port.h:24
#define EINTR
Definition: win32.h:295
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:189
ProtocolVersion MsgType
Definition: pqcomm.h:115
#define TRUE
Definition: c.h:217
static PGPing internal_ping ( PGconn conn)
static

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

3138 {
3139  /* Say "no attempt" if we never got to PQconnectPoll */
3140  if (!conn || !conn->options_valid)
3141  return PQPING_NO_ATTEMPT;
3142 
3143  /* Attempt to complete the connection */
3144  if (conn->status != CONNECTION_BAD)
3145  (void) connectDBComplete(conn);
3146 
3147  /* Definitely OK if we succeeded */
3148  if (conn->status != CONNECTION_BAD)
3149  return PQPING_OK;
3150 
3151  /*
3152  * Here begins the interesting part of "ping": determine the cause of the
3153  * failure in sufficient detail to decide what to return. We do not want
3154  * to report that the server is not up just because we didn't have a valid
3155  * password, for example. In fact, any sort of authentication request
3156  * implies the server is up. (We need this check since the libpq side of
3157  * things might have pulled the plug on the connection before getting an
3158  * error as such from the postmaster.)
3159  */
3160  if (conn->auth_req_received)
3161  return PQPING_OK;
3162 
3163  /*
3164  * If we failed to get any ERROR response from the postmaster, report
3165  * PQPING_NO_RESPONSE. This result could be somewhat misleading for a
3166  * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
3167  * out of support. Another corner case where the server could return a
3168  * failure without a SQLSTATE is fork failure, but NO_RESPONSE isn't
3169  * totally unreasonable for that anyway. We expect that every other
3170  * failure case in a modern server will produce a report with a SQLSTATE.
3171  *
3172  * NOTE: whenever we get around to making libpq generate SQLSTATEs for
3173  * client-side errors, we should either not store those into
3174  * last_sqlstate, or add an extra flag so we can tell client-side errors
3175  * apart from server-side ones.
3176  */
3177  if (strlen(conn->last_sqlstate) != 5)
3178  return PQPING_NO_RESPONSE;
3179 
3180  /*
3181  * Report PQPING_REJECT if server says it's not accepting connections. (We
3182  * distinguish this case mainly for the convenience of pg_ctl.)
3183  */
3184  if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
3185  return PQPING_REJECT;
3186 
3187  /*
3188  * Any other SQLSTATE can be taken to indicate that the server is up.
3189  * Presumably it didn't like our username, password, or database name; or
3190  * perhaps it had some transient failure, but that should not be taken as
3191  * meaning "it's down".
3192  */
3193  return PQPING_OK;
3194 }
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1714
bool options_valid
Definition: libpq-int.h:384
#define ERRCODE_CANNOT_CONNECT_NOW
Definition: fe-connect.c:99
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 3202 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().

3203 {
3204  PGconn *conn;
3205 
3206 #ifdef WIN32
3207 
3208  /*
3209  * Make sure socket support is up and running.
3210  */
3211  WSADATA wsaData;
3212 
3213  if (WSAStartup(MAKEWORD(1, 1), &wsaData))
3214  return NULL;
3215  WSASetLastError(0);
3216 #endif
3217 
3218  conn = (PGconn *) malloc(sizeof(PGconn));
3219  if (conn == NULL)
3220  {
3221 #ifdef WIN32
3222  WSACleanup();
3223 #endif
3224  return conn;
3225  }
3226 
3227  /* Zero all pointers and booleans */
3228  MemSet(conn, 0, sizeof(PGconn));
3229 
3230  /* install default notice hooks */
3233 
3234  conn->status = CONNECTION_BAD;
3235  conn->asyncStatus = PGASYNC_IDLE;
3236  conn->xactStatus = PQTRANS_IDLE;
3237  conn->options_valid = false;
3238  conn->nonblocking = false;
3240  conn->client_encoding = PG_SQL_ASCII;
3241  conn->std_strings = false; /* unless server says differently */
3242  conn->verbosity = PQERRORS_DEFAULT;
3244  conn->sock = PGINVALID_SOCKET;
3245  conn->auth_req_received = false;
3246  conn->password_needed = false;
3247  conn->pgpassfile_used = false;
3248 #ifdef USE_SSL
3249  conn->allow_ssl_try = true;
3250  conn->wait_ssl_try = false;
3251  conn->ssl_in_use = false;
3252 #endif
3253 
3254  /*
3255  * We try to send at least 8K at a time, which is the usual size of pipe
3256  * buffers on Unix systems. That way, when we are sending a large amount
3257  * of data, we avoid incurring extra kernel context swaps for partial
3258  * bufferloads. The output buffer is initially made 16K in size, and we
3259  * try to dump it after accumulating 8K.
3260  *
3261  * With the same goal of minimizing context swaps, the input buffer will
3262  * be enlarged anytime it has less than 8K free, so we initially allocate
3263  * twice that.
3264  */
3265  conn->inBufSize = 16 * 1024;
3266  conn->inBuffer = (char *) malloc(conn->inBufSize);
3267  conn->outBufSize = 16 * 1024;
3268  conn->outBuffer = (char *) malloc(conn->outBufSize);
3269  conn->rowBufLen = 32;
3270  conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
3271  initPQExpBuffer(&conn->errorMessage);
3272  initPQExpBuffer(&conn->workBuffer);
3273 
3274  if (conn->inBuffer == NULL ||
3275  conn->outBuffer == NULL ||
3276  conn->rowBuf == NULL ||
3277  PQExpBufferBroken(&conn->errorMessage) ||
3278  PQExpBufferBroken(&conn->workBuffer))
3279  {
3280  /* out of memory already :-( */
3281  freePGconn(conn);
3282  conn = NULL;
3283  }
3284 
3285  return conn;
3286 }
PGContextVisibility show_context
Definition: libpq-int.h:427
int rowBufLen
Definition: libpq-int.h:449
bool password_needed
Definition: libpq-int.h:408
PQExpBufferData workBuffer
Definition: libpq-int.h:504
#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:432
PGNoticeHooks noticeHooks
Definition: libpq-int.h:370
PGVerbosity verbosity
Definition: libpq-int.h:426
PQnoticeReceiver noticeRec
Definition: libpq-int.h:152
PGdataValue * rowBuf
Definition: libpq-int.h:448
pgsocket sock
Definition: libpq-int.h:400
#define PGINVALID_SOCKET
Definition: port.h:24
char * inBuffer
Definition: libpq-int.h:431
PQnoticeProcessor noticeProc
Definition: libpq-int.h:154
static void freePGconn(PGconn *conn)
Definition: fe-connect.c:3298
PQExpBufferData errorMessage
Definition: libpq-int.h:501
bool std_strings
Definition: libpq-int.h:425
bool options_valid
Definition: libpq-int.h:384
int outBufSize
Definition: libpq-int.h:439
#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:438
bool nonblocking
Definition: libpq-int.h:385
static void defaultNoticeProcessor(void *arg, const char *message)
Definition: fe-connect.c:6225
int client_encoding
Definition: libpq-int.h:424
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
static void defaultNoticeReceiver(void *arg, const PGresult *res)
Definition: fe-connect.c:6210
PGTransactionStatusType xactStatus
Definition: libpq-int.h:380
static PQconninfoOption * parse_connection_string ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

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

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

4719 {
4720  /* Parse as URI if connection string matches URI prefix */
4721  if (uri_prefix_length(connstr) != 0)
4722  return conninfo_uri_parse(connstr, errorMessage, use_defaults);
4723 
4724  /* Parse as default otherwise */
4725  return conninfo_parse(connstr, errorMessage, use_defaults);
4726 }
static PQconninfoOption * conninfo_parse(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4771
static int uri_prefix_length(const char *connstr)
Definition: fe-connect.c:4737
static PQconninfoOption * conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:5194
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 4480 of file fe-connect.c.

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

Referenced by parseServiceInfo().

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

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

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

Referenced by conninfo_add_defaults().

4412 {
4413  const char *service = conninfo_getval(options, "service");
4414  char serviceFile[MAXPGPATH];
4415  char *env;
4416  bool group_found = false;
4417  int status;
4418  struct stat stat_buf;
4419 
4420  /*
4421  * We have to special-case the environment variable PGSERVICE here, since
4422  * this is and should be called before inserting environment defaults for
4423  * other connection options.
4424  */
4425  if (service == NULL)
4426  service = getenv("PGSERVICE");
4427 
4428  if (service == NULL)
4429  return 0;
4430 
4431  if ((env = getenv("PGSERVICEFILE")) != NULL)
4432  strlcpy(serviceFile, env, sizeof(serviceFile));
4433  else
4434  {
4435  char homedir[MAXPGPATH];
4436 
4437  if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
4438  {
4439  printfPQExpBuffer(errorMessage, libpq_gettext("could not get home directory to locate service definition file"));
4440  return 1;
4441  }
4442  snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
4443  errno = 0;
4444  if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4445  goto next_file;
4446  }
4447 
4448  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4449  if (group_found || status != 0)
4450  return status;
4451 
4452 next_file:
4453 
4454  /*
4455  * This could be used by any application so we can't use the binary
4456  * location to find our config files.
4457  */
4458  snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
4459  getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
4460  errno = 0;
4461  if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4462  goto last_file;
4463 
4464  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4465  if (status != 0)
4466  return status;
4467 
4468 last_file:
4469  if (!group_found)
4470  {
4471  printfPQExpBuffer(errorMessage,
4472  libpq_gettext("definition of service \"%s\" not found\n"), service);
4473  return 3;
4474  }
4475 
4476  return 0;
4477 }
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:4480
static const char * conninfo_getval(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5711
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:6430
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:692
static char * passwordFromFile ( char *  hostname,
char *  port,
char *  dbname,
char *  username,
char *  pgpassfile 
)
static

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

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

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

6403 {
6404  /* If it was 'invalid authorization', add pgpassfile mention */
6405  /* only works with >= 9.0 servers */
6406  if (conn->pgpassfile_used && conn->password_needed && conn->result)
6407  {
6408  const char *sqlstate = PQresultErrorField(conn->result,
6410 
6411  if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
6413  libpq_gettext("password retrieved from file \"%s\"\n"),
6414  conn->pgpassfile);
6415  }
6416 }
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:452
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
PQExpBufferData errorMessage
Definition: libpq-int.h:501
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2658
#define ERRCODE_INVALID_PASSWORD
Definition: fe-connect.c:97
#define libpq_gettext(x)
Definition: libpq-int.h:692
int PQbackendPID ( const PGconn conn)

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

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

Referenced by get_prompt().

6038 {
6039  if (!conn || conn->status != CONNECTION_OK)
6040  return 0;
6041  return conn->be_pid;
6042 }
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 3844 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().

3845 {
3846  if (!cancel)
3847  {
3848  strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
3849  return FALSE;
3850  }
3851 
3852  return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
3853  errbuf, errbufsize);
3854 }
static int internal_cancel(SockAddr *raddr, int be_pid, int be_key, char *errbuf, int errbufsize)
Definition: fe-connect.c:3740
int be_pid
Definition: libpq-int.h:514
#define FALSE
Definition: c.h:221
int be_key
Definition: libpq-int.h:515
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
SockAddr raddr
Definition: libpq-int.h:513
int PQclientEncoding ( const PGconn conn)

Definition at line 6071 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(), main(), processSQLNamePattern(), SendQuery(), setup_connection(), and SyncVariables().

6072 {
6073  if (!conn || conn->status != CONNECTION_OK)
6074  return -1;
6075  return conn->client_encoding;
6076 }
ConnStatusType status
Definition: libpq-int.h:378
int client_encoding
Definition: libpq-int.h:424
PQconninfoOption* PQconndefaults ( void  )

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

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

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

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

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

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

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

6046 {
6047  char *password;
6048 
6049  if (!conn)
6050  return false;
6051  password = PQpass(conn);
6052  if (conn->password_needed &&
6053  (password == NULL || password[0] == '\0'))
6054  return true;
6055  else
6056  return false;
6057 }
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:5895
#define NULL
Definition: c.h:229
int PQconnectionUsedPassword ( const PGconn conn)

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

References pg_conn::password_needed.

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

6061 {
6062  if (!conn)
6063  return false;
6064  if (conn->password_needed)
6065  return true;
6066  else
6067  return false;
6068 }
bool password_needed
Definition: libpq-int.h:408
PostgresPollingStatusType PQconnectPoll ( PGconn conn)

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

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

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

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