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

Go to the source code of this file.

Data Structures

struct  _internalPQconninfoOption
 

Macros

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

Typedefs

typedef struct
_internalPQconninfoOption 
internalPQconninfoOption
 

Functions

static bool connectOptions1 (PGconn *conn, const char *conninfo)
 
static bool connectOptions2 (PGconn *conn)
 
static int connectDBStart (PGconn *conn)
 
static int connectDBComplete (PGconn *conn)
 
static PGPing internal_ping (PGconn *conn)
 
static PGconnmakeEmptyPGconn (void)
 
static bool fillPGconn (PGconn *conn, PQconninfoOption *connOptions)
 
static void freePGconn (PGconn *conn)
 
static void closePGconn (PGconn *conn)
 
static void release_all_addrinfo (PGconn *conn)
 
static void sendTerminateConn (PGconn *conn)
 
static PQconninfoOptionconninfo_init (PQExpBuffer errorMessage)
 
static PQconninfoOptionparse_connection_string (const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
 
static int uri_prefix_length (const char *connstr)
 
static bool recognized_connection_string (const char *connstr)
 
static PQconninfoOptionconninfo_parse (const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
 
static PQconninfoOptionconninfo_array_parse (const char *const *keywords, const char *const *values, PQExpBuffer errorMessage, bool use_defaults, int expand_dbname)
 
static bool conninfo_add_defaults (PQconninfoOption *options, PQExpBuffer errorMessage)
 
static PQconninfoOptionconninfo_uri_parse (const char *uri, PQExpBuffer errorMessage, bool use_defaults)
 
static bool conninfo_uri_parse_options (PQconninfoOption *options, const char *uri, PQExpBuffer errorMessage)
 
static bool conninfo_uri_parse_params (char *params, PQconninfoOption *connOptions, PQExpBuffer errorMessage)
 
static char * conninfo_uri_decode (const char *str, PQExpBuffer errorMessage)
 
static bool get_hexdigit (char digit, int *value)
 
static const char * conninfo_getval (PQconninfoOption *connOptions, const char *keyword)
 
static PQconninfoOptionconninfo_storeval (PQconninfoOption *connOptions, const char *keyword, const char *value, PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode)
 
static PQconninfoOptionconninfo_find (PQconninfoOption *connOptions, const char *keyword)
 
static void defaultNoticeReceiver (void *arg, const PGresult *res)
 
static void defaultNoticeProcessor (void *arg, const char *message)
 
static int parseServiceInfo (PQconninfoOption *options, PQExpBuffer errorMessage)
 
static int parseServiceFile (const char *serviceFile, const char *service, PQconninfoOption *options, PQExpBuffer errorMessage, bool *group_found)
 
static char * pwdfMatchesString (char *buf, char *token)
 
static char * passwordFromFile (char *hostname, char *port, char *dbname, char *username, char *pgpassfile)
 
static void pgpassfileWarning (PGconn *conn)
 
static void default_threadlock (int acquire)
 
void pqDropConnection (PGconn *conn, bool flushInput)
 
PGconnPQconnectdbParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PGPing PQpingParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PGconnPQconnectdb (const char *conninfo)
 
PGPing PQping (const char *conninfo)
 
PGconnPQconnectStartParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PGconnPQconnectStart (const char *conninfo)
 
static int count_comma_separated_elems (const char *input)
 
static char * parse_comma_separated_list (char **startptr, bool *more)
 
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 123 of file fe-connect.c.

#define DefaultHost   "localhost"

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

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

#define DefaultOption   ""

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

#define DefaultSSLMode   "disable"

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

Referenced by connectOptions2().

#define DefaultTargetSessionAttrs   "any"

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

#define DefaultTty   ""

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

#define ERRCODE_APPNAME_UNKNOWN   "42704"

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

Referenced by PQconnectPoll().

#define ERRCODE_CANNOT_CONNECT_NOW   "57P03"

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

Referenced by internal_ping(), and ProcessStartupPacket().

#define ERRCODE_INVALID_PASSWORD   "28P01"

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

Referenced by auth_failed(), pgpassfileWarning(), and recv_password_packet().

#define LINELEN   NAMEDATALEN*5

Referenced by passwordFromFile().

#define MAXBUFSIZE   256

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

Referenced by parseServiceFile().

#define PGPASSFILE   ".pgpass"

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

Referenced by connectOptions2().

Typedef Documentation

Function Documentation

static void closePGconn ( PGconn conn)
static

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

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

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

3578 {
3579  PGnotify *notify;
3580  pgParameterStatus *pstatus;
3581 
3582  sendTerminateConn(conn);
3583 
3584  /*
3585  * Must reset the blocking status so a possible reconnect will work.
3586  *
3587  * Don't call PQsetnonblocking() because it will fail if it's unable to
3588  * flush the connection.
3589  */
3590  conn->nonblocking = FALSE;
3591 
3592  /*
3593  * Close the connection, reset all transient state, flush I/O buffers.
3594  */
3595  pqDropConnection(conn, true);
3596  conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just absent */
3597  conn->asyncStatus = PGASYNC_IDLE;
3598  pqClearAsyncResult(conn); /* deallocate result */
3600  release_all_addrinfo(conn);
3601 
3602  notify = conn->notifyHead;
3603  while (notify != NULL)
3604  {
3605  PGnotify *prev = notify;
3606 
3607  notify = notify->next;
3608  free(prev);
3609  }
3610  conn->notifyHead = conn->notifyTail = NULL;
3611  pstatus = conn->pstatus;
3612  while (pstatus != NULL)
3613  {
3614  pgParameterStatus *prev = pstatus;
3615 
3616  pstatus = pstatus->next;
3617  free(prev);
3618  }
3619  conn->pstatus = NULL;
3620  if (conn->lobjfuncs)
3621  free(conn->lobjfuncs);
3622  conn->lobjfuncs = NULL;
3623 }
static void release_all_addrinfo(PGconn *conn)
Definition: fe-connect.c:3522
PGnotify * notifyHead
Definition: libpq-int.h:391
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:424
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:3550
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:380
#define FALSE
Definition: c.h:221
pgParameterStatus * pstatus
Definition: libpq-int.h:421
struct pgNotify * next
Definition: libpq-fe.h:167
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#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:379
PGnotify * notifyTail
Definition: libpq-int.h:392
bool nonblocking
Definition: libpq-int.h:386
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:705
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
static int connectDBComplete ( PGconn conn)
static

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

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

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

1836 {
1838  time_t finish_time = ((time_t) -1);
1839  int timeout = 0;
1840 
1841  if (conn == NULL || conn->status == CONNECTION_BAD)
1842  return 0;
1843 
1844  /*
1845  * Set up a time limit, if connect_timeout isn't zero.
1846  */
1847  if (conn->connect_timeout != NULL)
1848  {
1849  timeout = atoi(conn->connect_timeout);
1850  if (timeout > 0)
1851  {
1852  /*
1853  * Rounding could cause connection to fail; need at least 2 secs
1854  */
1855  if (timeout < 2)
1856  timeout = 2;
1857  /* calculate the finish time based on start + timeout */
1858  finish_time = time(NULL) + timeout;
1859  }
1860  }
1861 
1862  for (;;)
1863  {
1864  int ret = 0;
1865 
1866  /*
1867  * Wait, if necessary. Note that the initial state (just after
1868  * PQconnectStart) is to wait for the socket to select for writing.
1869  */
1870  switch (flag)
1871  {
1872  case PGRES_POLLING_OK:
1873 
1874  /*
1875  * Reset stored error messages since we now have a working
1876  * connection
1877  */
1879  return 1; /* success! */
1880 
1881  case PGRES_POLLING_READING:
1882  ret = pqWaitTimed(1, 0, conn, finish_time);
1883  if (ret == -1)
1884  {
1885  conn->status = CONNECTION_BAD;
1886  return 0;
1887  }
1888  break;
1889 
1890  case PGRES_POLLING_WRITING:
1891  ret = pqWaitTimed(0, 1, conn, finish_time);
1892  if (ret == -1)
1893  {
1894  conn->status = CONNECTION_BAD;
1895  return 0;
1896  }
1897  break;
1898 
1899  default:
1900  /* Just in case we failed to set it in PQconnectPoll */
1901  conn->status = CONNECTION_BAD;
1902  return 0;
1903  }
1904 
1905  if (ret == 1) /* connect_timeout elapsed */
1906  {
1907  /*
1908  * If there are no more hosts, return (the error message is
1909  * already set)
1910  */
1911  if (++conn->whichhost >= conn->nconnhost)
1912  {
1913  conn->whichhost = 0;
1914  conn->status = CONNECTION_BAD;
1915  return 0;
1916  }
1917 
1918  /*
1919  * Attempt connection to the next host, starting the
1920  * connect_timeout timer
1921  */
1922  pqDropConnection(conn, true);
1923  conn->addr_cur = conn->connhost[conn->whichhost].addrlist;
1924  conn->status = CONNECTION_NEEDED;
1925  if (conn->connect_timeout != NULL)
1926  finish_time = time(NULL) + timeout;
1927  }
1928 
1929  /*
1930  * Now try to advance the state machine.
1931  */
1932  flag = PQconnectPoll(conn);
1933  }
1934 }
struct addrinfo * addr_cur
Definition: libpq-int.h:413
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:424
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
Definition: fe-misc.c:999
char * connect_timeout
Definition: libpq-int.h:336
pg_conn_host * connhost
Definition: libpq-int.h:397
char * flag(int b)
Definition: test-ctype.c:33
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:1997
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define NULL
Definition: c.h:229
struct addrinfo * addrlist
Definition: libpq-int.h:315
ConnStatusType status
Definition: libpq-int.h:379
PostgresPollingStatusType
Definition: libpq-fe.h:72
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
int nconnhost
Definition: libpq-int.h:395
int whichhost
Definition: libpq-int.h:396
static int connectDBStart ( PGconn conn)
static

Definition at line 1682 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, pg_conn_host::hostaddr, 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().

1683 {
1684  char portstr[MAXPGPATH];
1685  int ret;
1686  int i;
1687 
1688  if (!conn)
1689  return 0;
1690 
1691  if (!conn->options_valid)
1692  goto connect_errReturn;
1693 
1694  /* Ensure our buffers are empty */
1695  conn->inStart = conn->inCursor = conn->inEnd = 0;
1696  conn->outCount = 0;
1697 
1698  /*
1699  * Look up socket addresses for each possible host using
1700  * pg_getaddrinfo_all.
1701  */
1702  for (i = 0; i < conn->nconnhost; ++i)
1703  {
1704  pg_conn_host *ch = &conn->connhost[i];
1705  struct addrinfo hint;
1706  int thisport;
1707 
1708  /* Initialize hint structure */
1709  MemSet(&hint, 0, sizeof(hint));
1710  hint.ai_socktype = SOCK_STREAM;
1711  hint.ai_family = AF_UNSPEC;
1712 
1713  /* Figure out the port number we're going to use. */
1714  if (ch->port == NULL || ch->port[0] == '\0')
1715  thisport = DEF_PGPORT;
1716  else
1717  {
1718  thisport = atoi(ch->port);
1719  if (thisport < 1 || thisport > 65535)
1720  {
1722  libpq_gettext("invalid port number: \"%s\"\n"),
1723  ch->port);
1724  conn->options_valid = false;
1725  goto connect_errReturn;
1726  }
1727  }
1728  snprintf(portstr, sizeof(portstr), "%d", thisport);
1729 
1730  /* Use pg_getaddrinfo_all() to resolve the address */
1731  ret = 1;
1732  switch (ch->type)
1733  {
1734  case CHT_HOST_NAME:
1735  ret = pg_getaddrinfo_all(ch->host, portstr, &hint, &ch->addrlist);
1736  if (ret || !ch->addrlist)
1738  libpq_gettext("could not translate host name \"%s\" to address: %s\n"),
1739  ch->host, gai_strerror(ret));
1740  break;
1741 
1742  case CHT_HOST_ADDRESS:
1743  hint.ai_flags = AI_NUMERICHOST;
1744  ret = pg_getaddrinfo_all(ch->hostaddr, portstr, &hint, &ch->addrlist);
1745  if (ret || !ch->addrlist)
1747  libpq_gettext("could not parse network address \"%s\": %s\n"),
1748  ch->host, gai_strerror(ret));
1749  break;
1750 
1751  case CHT_UNIX_SOCKET:
1752 #ifdef HAVE_UNIX_SOCKETS
1753  hint.ai_family = AF_UNIX;
1754  UNIXSOCK_PATH(portstr, thisport, ch->host);
1755  if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
1756  {
1758  libpq_gettext("Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n"),
1759  portstr,
1760  (int) (UNIXSOCK_PATH_BUFLEN - 1));
1761  conn->options_valid = false;
1762  goto connect_errReturn;
1763  }
1764 
1765  /*
1766  * NULL hostname tells pg_getaddrinfo_all to parse the service
1767  * name as a Unix-domain socket path.
1768  */
1769  ret = pg_getaddrinfo_all(NULL, portstr, &hint, &ch->addrlist);
1770  if (ret || !ch->addrlist)
1772  libpq_gettext("could not translate Unix-domain socket path \"%s\" to address: %s\n"),
1773  portstr, gai_strerror(ret));
1774  break;
1775 #else
1776  Assert(false);
1777  conn->options_valid = false;
1778  goto connect_errReturn;
1779 #endif
1780  }
1781  if (ret || !ch->addrlist)
1782  {
1783  if (ch->addrlist)
1784  {
1785  pg_freeaddrinfo_all(hint.ai_family, ch->addrlist);
1786  ch->addrlist = NULL;
1787  }
1788  conn->options_valid = false;
1789  goto connect_errReturn;
1790  }
1791  }
1792 
1793 #ifdef USE_SSL
1794  /* setup values based on SSL mode */
1795  if (conn->sslmode[0] == 'd') /* "disable" */
1796  conn->allow_ssl_try = false;
1797  else if (conn->sslmode[0] == 'a') /* "allow" */
1798  conn->wait_ssl_try = true;
1799 #endif
1800 
1801  /*
1802  * Set up to try to connect, with protocol 3.0 as the first attempt.
1803  */
1804  conn->whichhost = 0;
1805  conn->addr_cur = conn->connhost[0].addrlist;
1806  conn->pversion = PG_PROTOCOL(3, 0);
1807  conn->send_appname = true;
1808  conn->status = CONNECTION_NEEDED;
1809 
1810  /*
1811  * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
1812  * so that it can easily be re-executed if needed again during the
1813  * asynchronous startup process. However, we must run it once here,
1814  * because callers expect a success return from this routine to mean that
1815  * we are in PGRES_POLLING_WRITING connection state.
1816  */
1817  if (PQconnectPoll(conn) == PGRES_POLLING_WRITING)
1818  return 1;
1819 
1820 connect_errReturn:
1821  pqDropConnection(conn, true);
1822  conn->status = CONNECTION_BAD;
1823  return 0;
1824 }
int inEnd
Definition: libpq-int.h:433
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:431
struct addrinfo * addr_cur
Definition: libpq-int.h:413
#define UNIXSOCK_PATH_BUFLEN
Definition: pqcomm.h:86
int outCount
Definition: libpq-int.h:438
char * host
Definition: libpq-int.h:308
#define MemSet(start, val, len)
Definition: c.h:858
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:424
#define AI_NUMERICHOST
Definition: getaddrinfo.h:73
pg_conn_host_type type
Definition: libpq-int.h:307
#define gai_strerror
Definition: getaddrinfo.h:146
int pg_getaddrinfo_all(const char *hostname, const char *servname, const struct addrinfo *hintp, struct addrinfo **result)
Definition: ip.c:57
#define MAXPGPATH
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
char * hostaddr
Definition: libpq-int.h:309
pg_conn_host * connhost
Definition: libpq-int.h:397
char * sslmode
Definition: libpq-int.h:352
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:1997
PQExpBufferData errorMessage
Definition: libpq-int.h:491
bool options_valid
Definition: libpq-int.h:385
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:676
struct addrinfo * addrlist
Definition: libpq-int.h:315
ProtocolVersion pversion
Definition: libpq-int.h:404
ConnStatusType status
Definition: libpq-int.h:379
int i
int inCursor
Definition: libpq-int.h:432
char * port
Definition: libpq-int.h:310
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:682
bool send_appname
Definition: libpq-int.h:416
static void connectFailureMessage ( PGconn conn,
int  errorno 
)
static

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

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

Referenced by PQconnectPoll().

1420 {
1421  char sebuf[256];
1422 
1423 #ifdef HAVE_UNIX_SOCKETS
1424  if (IS_AF_UNIX(conn->raddr.addr.ss_family))
1425  {
1426  char service[NI_MAXHOST];
1427 
1428  pg_getnameinfo_all(&conn->raddr.addr, conn->raddr.salen,
1429  NULL, 0,
1430  service, sizeof(service),
1431  NI_NUMERICSERV);
1433  libpq_gettext("could not connect to server: %s\n"
1434  "\tIs the server running locally and accepting\n"
1435  "\tconnections on Unix domain socket \"%s\"?\n"),
1436  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1437  service);
1438  }
1439  else
1440 #endif /* HAVE_UNIX_SOCKETS */
1441  {
1442  char host_addr[NI_MAXHOST];
1443  const char *displayed_host;
1444  const char *displayed_port;
1445  struct sockaddr_storage *addr = &conn->raddr.addr;
1446 
1447  /*
1448  * Optionally display the network address with the hostname. This is
1449  * useful to distinguish between IPv4 and IPv6 connections.
1450  */
1451  if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
1452  strlcpy(host_addr, conn->connhost[conn->whichhost].hostaddr, NI_MAXHOST);
1453  else if (addr->ss_family == AF_INET)
1454  {
1455  if (inet_net_ntop(AF_INET,
1456  &((struct sockaddr_in *) addr)->sin_addr.s_addr,
1457  32,
1458  host_addr, sizeof(host_addr)) == NULL)
1459  strcpy(host_addr, "???");
1460  }
1461 #ifdef HAVE_IPV6
1462  else if (addr->ss_family == AF_INET6)
1463  {
1464  if (inet_net_ntop(AF_INET6,
1465  &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
1466  128,
1467  host_addr, sizeof(host_addr)) == NULL)
1468  strcpy(host_addr, "???");
1469  }
1470 #endif
1471  else
1472  strcpy(host_addr, "???");
1473 
1474  /* To which host and port were we actually connecting? */
1475  if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
1476  displayed_host = conn->connhost[conn->whichhost].hostaddr;
1477  else
1478  displayed_host = conn->connhost[conn->whichhost].host;
1479  displayed_port = conn->connhost[conn->whichhost].port;
1480  if (displayed_port == NULL || displayed_port[0] == '\0')
1481  displayed_port = DEF_PGPORT_STR;
1482 
1483  /*
1484  * If the user did not supply an IP address using 'hostaddr', and
1485  * 'host' was missing or does not match our lookup, display the
1486  * looked-up IP address.
1487  */
1488  if (conn->connhost[conn->whichhost].type != CHT_HOST_ADDRESS &&
1489  strcmp(displayed_host, host_addr) != 0)
1491  libpq_gettext("could not connect to server: %s\n"
1492  "\tIs the server running on host \"%s\" (%s) and accepting\n"
1493  "\tTCP/IP connections on port %s?\n"),
1494  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1495  displayed_host,
1496  host_addr,
1497  displayed_port);
1498  else
1500  libpq_gettext("could not connect to server: %s\n"
1501  "\tIs the server running on host \"%s\" and accepting\n"
1502  "\tTCP/IP connections on port %s?\n"),
1503  SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1504  displayed_host,
1505  displayed_port);
1506  }
1507 }
char * host
Definition: libpq-int.h:308
struct sockaddr_storage addr
Definition: pqcomm.h:64
pg_conn_host_type type
Definition: libpq-int.h:307
#define SOCK_STRERROR
Definition: libpq-int.h:696
#define NI_MAXHOST
Definition: getaddrinfo.h:88
#define IS_AF_UNIX(fam)
Definition: ip.h:24
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
char * hostaddr
Definition: libpq-int.h:309
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:491
#define NI_NUMERICSERV
Definition: getaddrinfo.h:81
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:229
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:122
char * port
Definition: libpq-int.h:310
int whichhost
Definition: libpq-int.h:396
#define libpq_gettext(x)
Definition: libpq-int.h:682
static int connectNoDelay ( PGconn conn)
static

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

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

Referenced by PQconnectPoll().

1392 {
1393 #ifdef TCP_NODELAY
1394  int on = 1;
1395 
1396  if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
1397  (char *) &on,
1398  sizeof(on)) < 0)
1399  {
1400  char sebuf[256];
1401 
1403  libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
1404  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1405  return 0;
1406  }
1407 #endif
1408 
1409  return 1;
1410 }
#define SOCK_STRERROR
Definition: libpq-int.h:696
#define SOCK_ERRNO
Definition: libpq-int.h:695
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
pgsocket sock
Definition: libpq-int.h:400
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define libpq_gettext(x)
Definition: libpq-int.h:682
static bool connectOptions1 ( PGconn conn,
const char *  conninfo 
)
static

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

798 {
799  PQconninfoOption *connOptions;
800 
801  /*
802  * Parse the conninfo string
803  */
804  connOptions = parse_connection_string(conninfo, &conn->errorMessage, true);
805  if (connOptions == NULL)
806  {
807  conn->status = CONNECTION_BAD;
808  /* errorMessage is already set */
809  return false;
810  }
811 
812  /*
813  * Move option values into conn structure
814  */
815  if (!fillPGconn(conn, connOptions))
816  {
817  conn->status = CONNECTION_BAD;
818  PQconninfoFree(connOptions);
819  return false;
820  }
821 
822  /*
823  * Free the option info - all is in conn now
824  */
825  PQconninfoFree(connOptions);
826 
827  return true;
828 }
static PQconninfoOption * parse_connection_string(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4779
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5947
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#define NULL
Definition: c.h:229
static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
Definition: fe-connect.c:755
ConnStatusType status
Definition: libpq-int.h:379
static bool connectOptions2 ( PGconn conn)
static

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

References Assert, calloc, CHT_HOST_ADDRESS, CHT_HOST_NAME, CHT_UNIX_SOCKET, pg_conn::client_encoding_initial, CONNECTION_BAD, pg_conn::connhost, count_comma_separated_elems(), pg_conn::dbName, DEFAULT_PGSOCKET_DIR, DefaultHost, DefaultSSLMode, pg_conn::errorMessage, free, pg_conn_host::host, pg_conn_host::hostaddr, i, is_absolute_path, libpq_gettext, malloc, MAXPGPATH, pg_conn::nconnhost, NULL, pg_conn::options_valid, parse_comma_separated_list(), 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().

896 {
897  /*
898  * Allocate memory for details about each host to which we might possibly
899  * try to connect. For that, count the number of elements in the hostaddr
900  * or host options. If neither is given, assume one host.
901  */
902  conn->whichhost = 0;
903  if (conn->pghostaddr && conn->pghostaddr[0] != '\0')
905  else if (conn->pghost && conn->pghost[0] != '\0')
907  else
908  conn->nconnhost = 1;
909  conn->connhost = (pg_conn_host *)
910  calloc(conn->nconnhost, sizeof(pg_conn_host));
911  if (conn->connhost == NULL)
912  goto oom_error;
913 
914  /*
915  * We now have one pg_conn_host structure per possible host. Fill in the
916  * host details for each one.
917  */
918  if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
919  {
920  int i;
921  char *s = conn->pghostaddr;
922  bool more = true;
923 
924  for (i = 0; i < conn->nconnhost && more; i++)
925  {
926  conn->connhost[i].hostaddr = parse_comma_separated_list(&s, &more);
927  if (conn->connhost[i].hostaddr == NULL)
928  goto oom_error;
929 
930  conn->connhost[i].type = CHT_HOST_ADDRESS;
931  }
932 
933  /*
934  * If hostaddr was given, the array was allocated according to the
935  * number of elements in the hostaddr list, so it really should be the
936  * right size.
937  */
938  Assert(!more);
939  Assert(i == conn->nconnhost);
940  }
941 
942  if (conn->pghost != NULL && conn->pghost[0] != '\0')
943  {
944  int i;
945  char *s = conn->pghost;
946  bool more = true;
947 
948  for (i = 0; i < conn->nconnhost && more; i++)
949  {
950  conn->connhost[i].host = parse_comma_separated_list(&s, &more);
951  if (conn->connhost[i].host == NULL)
952  goto oom_error;
953 
954  /* Identify the type of host. */
955  if (conn->pghostaddr == NULL || conn->pghostaddr[0] == '\0')
956  {
957  conn->connhost[i].type = CHT_HOST_NAME;
958 #ifdef HAVE_UNIX_SOCKETS
959  if (is_absolute_path(conn->connhost[i].host))
960  conn->connhost[i].type = CHT_UNIX_SOCKET;
961 #endif
962  }
963  }
964  if (more || i != conn->nconnhost)
965  {
966  conn->status = CONNECTION_BAD;
968  libpq_gettext("could not match %d host names to %d hostaddrs\n"),
970  return false;
971  }
972  }
973 
974  /*
975  * If neither host or hostaddr options was given, connect to default host.
976  */
977  if ((conn->pghostaddr == NULL || conn->pghostaddr[0] == '\0') &&
978  (conn->pghost == NULL || conn->pghost[0] == '\0'))
979  {
980  Assert(conn->nconnhost == 1);
981 #ifdef HAVE_UNIX_SOCKETS
982  conn->connhost[0].host = strdup(DEFAULT_PGSOCKET_DIR);
983  conn->connhost[0].type = CHT_UNIX_SOCKET;
984 #else
985  conn->connhost[0].host = strdup(DefaultHost);
986  conn->connhost[0].type = CHT_HOST_NAME;
987 #endif
988  if (conn->connhost[0].host == NULL)
989  goto oom_error;
990  }
991 
992  /*
993  * Next, work out the port number corresponding to each host name.
994  */
995  if (conn->pgport != NULL && conn->pgport[0] != '\0')
996  {
997  int i;
998  char *s = conn->pgport;
999  bool more = true;
1000 
1001  for (i = 0; i < conn->nconnhost && more; i++)
1002  {
1003  conn->connhost[i].port = parse_comma_separated_list(&s, &more);
1004  if (conn->connhost[i].port == NULL)
1005  goto oom_error;
1006  }
1007 
1008  /*
1009  * If exactly one port was given, use it for every host. Otherwise,
1010  * there must be exactly as many ports as there were hosts.
1011  */
1012  if (i == 1 && !more)
1013  {
1014  for (i = 1; i < conn->nconnhost; i++)
1015  {
1016  conn->connhost[i].port = strdup(conn->connhost[0].port);
1017  if (conn->connhost[i].port == NULL)
1018  goto oom_error;
1019  }
1020  }
1021  else if (more || i != conn->nconnhost)
1022  {
1023  conn->status = CONNECTION_BAD;
1025  libpq_gettext("could not match %d port numbers to %d hosts\n"),
1027  return false;
1028  }
1029  }
1030 
1031  /*
1032  * If user name was not given, fetch it. (Most likely, the fetch will
1033  * fail, since the only way we get here is if pg_fe_getauthname() failed
1034  * during conninfo_add_defaults(). But now we want an error message.)
1035  */
1036  if (conn->pguser == NULL || conn->pguser[0] == '\0')
1037  {
1038  if (conn->pguser)
1039  free(conn->pguser);
1040  conn->pguser = pg_fe_getauthname(&conn->errorMessage);
1041  if (!conn->pguser)
1042  {
1043  conn->status = CONNECTION_BAD;
1044  return false;
1045  }
1046  }
1047 
1048  /*
1049  * If database name was not given, default it to equal user name
1050  */
1051  if (conn->dbName == NULL || conn->dbName[0] == '\0')
1052  {
1053  if (conn->dbName)
1054  free(conn->dbName);
1055  conn->dbName = strdup(conn->pguser);
1056  if (!conn->dbName)
1057  goto oom_error;
1058  }
1059 
1060  /*
1061  * Supply default password if none given. Note that the password might be
1062  * different for each host/port pair.
1063  */
1064  if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
1065  {
1066  int i;
1067 
1068  if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
1069  {
1070  /* Identify password file to use; fail if we can't */
1071  char homedir[MAXPGPATH];
1072 
1073  if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
1074  {
1075  conn->status = CONNECTION_BAD;
1077  libpq_gettext("could not get home directory to locate password file\n"));
1078  return false;
1079  }
1080 
1081  if (conn->pgpassfile)
1082  free(conn->pgpassfile);
1083  conn->pgpassfile = malloc(MAXPGPATH);
1084  if (!conn->pgpassfile)
1085  goto oom_error;
1086 
1087  snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s", homedir, PGPASSFILE);
1088  }
1089 
1090  for (i = 0; i < conn->nconnhost; i++)
1091  {
1092  /*
1093  * Try to get a password for this host from pgpassfile. We use
1094  * host name rather than host address in the same manner to
1095  * PQhost().
1096  */
1097  char *pwhost = conn->connhost[i].host;
1098 
1099  if (conn->connhost[i].type == CHT_HOST_ADDRESS &&
1100  conn->connhost[i].host != NULL && conn->connhost[i].host[0] != '\0')
1101  pwhost = conn->connhost[i].hostaddr;
1102 
1103  conn->connhost[i].password =
1104  passwordFromFile(pwhost,
1105  conn->connhost[i].port,
1106  conn->dbName,
1107  conn->pguser,
1108  conn->pgpassfile);
1109  /* If we got one, set pgpassfile_used */
1110  if (conn->connhost[i].password != NULL)
1111  conn->pgpassfile_used = true;
1112  }
1113  }
1114 
1115  /*
1116  * validate sslmode option
1117  */
1118  if (conn->sslmode)
1119  {
1120  if (strcmp(conn->sslmode, "disable") != 0
1121  && strcmp(conn->sslmode, "allow") != 0
1122  && strcmp(conn->sslmode, "prefer") != 0
1123  && strcmp(conn->sslmode, "require") != 0
1124  && strcmp(conn->sslmode, "verify-ca") != 0
1125  && strcmp(conn->sslmode, "verify-full") != 0)
1126  {
1127  conn->status = CONNECTION_BAD;
1129  libpq_gettext("invalid sslmode value: \"%s\"\n"),
1130  conn->sslmode);
1131  return false;
1132  }
1133 
1134 #ifndef USE_SSL
1135  switch (conn->sslmode[0])
1136  {
1137  case 'a': /* "allow" */
1138  case 'p': /* "prefer" */
1139 
1140  /*
1141  * warn user that an SSL connection will never be negotiated
1142  * since SSL was not compiled in?
1143  */
1144  break;
1145 
1146  case 'r': /* "require" */
1147  case 'v': /* "verify-ca" or "verify-full" */
1148  conn->status = CONNECTION_BAD;
1150  libpq_gettext("sslmode value \"%s\" invalid when SSL support is not compiled in\n"),
1151  conn->sslmode);
1152  return false;
1153  }
1154 #endif
1155  }
1156  else
1157  {
1158  conn->sslmode = strdup(DefaultSSLMode);
1159  if (!conn->sslmode)
1160  goto oom_error;
1161  }
1162 
1163  /*
1164  * Resolve special "auto" client_encoding from the locale
1165  */
1166  if (conn->client_encoding_initial &&
1167  strcmp(conn->client_encoding_initial, "auto") == 0)
1168  {
1171  if (!conn->client_encoding_initial)
1172  goto oom_error;
1173  }
1174 
1175  /*
1176  * Validate target_session_attrs option.
1177  */
1178  if (conn->target_session_attrs)
1179  {
1180  if (strcmp(conn->target_session_attrs, "any") != 0
1181  && strcmp(conn->target_session_attrs, "read-write") != 0)
1182  {
1183  conn->status = CONNECTION_BAD;
1185  libpq_gettext("invalid target_session_attrs value: \"%s\"\n"),
1186  conn->target_session_attrs);
1187  return false;
1188  }
1189  }
1190 
1191  /*
1192  * Only if we get this far is it appropriate to try to connect. (We need a
1193  * state flag, rather than just the boolean result of this function, in
1194  * case someone tries to PQreset() the PGconn.)
1195  */
1196  conn->options_valid = true;
1197 
1198  return true;
1199 
1200 oom_error:
1201  conn->status = CONNECTION_BAD;
1203  libpq_gettext("out of memory\n"));
1204  return false;
1205 }
#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:345
char * host
Definition: libpq-int.h:308
char * dbName
Definition: libpq-int.h:341
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
bool pgpassfile_used
Definition: libpq-int.h:408
#define DefaultSSLMode
Definition: fe-connect.c:128
pg_conn_host_type type
Definition: libpq-int.h:307
char * client_encoding_initial
Definition: libpq-int.h:337
#define malloc(a)
Definition: header.h:50
#define PGPASSFILE
Definition: fe-connect.c:79
#define MAXPGPATH
char * hostaddr
Definition: libpq-int.h:309
pg_conn_host * connhost
Definition: libpq-int.h:397
#define is_absolute_path(filename)
Definition: port.h:77
static int count_comma_separated_elems(const char *input)
Definition: fe-connect.c:834
char * target_session_attrs
Definition: libpq-int.h:365
char * pguser
Definition: libpq-int.h:343
char * sslmode
Definition: libpq-int.h:352
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:1024
PQExpBufferData errorMessage
Definition: libpq-int.h:491
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:433
#define free(a)
Definition: header.h:65
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:607
bool options_valid
Definition: libpq-int.h:385
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:676
char * pgpass
Definition: libpq-int.h:344
ConnStatusType status
Definition: libpq-int.h:379
static char * parse_comma_separated_list(char **startptr, bool *more)
Definition: fe-connect.c:858
#define DefaultHost
Definition: fe-connect.c:120
static char * passwordFromFile(char *hostname, char *port, char *dbname, char *username, char *pgpassfile)
Definition: fe-connect.c:6360
char * pghostaddr
Definition: libpq-int.h:330
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:6516
int i
char * port
Definition: libpq-int.h:310
char * pgport
Definition: libpq-int.h:333
int nconnhost
Definition: libpq-int.h:395
int whichhost
Definition: libpq-int.h:396
#define libpq_gettext(x)
Definition: libpq-int.h:682
char * pghost
Definition: libpq-int.h:325
#define DEFAULT_PGSOCKET_DIR
char * password
Definition: libpq-int.h:312
static bool conninfo_add_defaults ( PQconninfoOption options,
PQExpBuffer  errorMessage 
)
static

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

5176 {
5178  char *tmp;
5179 
5180  /*
5181  * If there's a service spec, use it to obtain any not-explicitly-given
5182  * parameters. Ignore error if no error message buffer is passed because
5183  * there is no way to pass back the failure message.
5184  */
5185  if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
5186  return false;
5187 
5188  /*
5189  * Get the fallback resources for parameters not specified in the conninfo
5190  * string nor the service.
5191  */
5192  for (option = options; option->keyword != NULL; option++)
5193  {
5194  if (option->val != NULL)
5195  continue; /* Value was in conninfo or service */
5196 
5197  /*
5198  * Try to get the environment variable fallback
5199  */
5200  if (option->envvar != NULL)
5201  {
5202  if ((tmp = getenv(option->envvar)) != NULL)
5203  {
5204  option->val = strdup(tmp);
5205  if (!option->val)
5206  {
5207  if (errorMessage)
5208  printfPQExpBuffer(errorMessage,
5209  libpq_gettext("out of memory\n"));
5210  return false;
5211  }
5212  continue;
5213  }
5214  }
5215 
5216  /*
5217  * Interpret the deprecated PGREQUIRESSL environment variable. Per
5218  * tradition, translate values starting with "1" to sslmode=require,
5219  * and ignore other values. Given both PGREQUIRESSL=1 and PGSSLMODE,
5220  * PGSSLMODE takes precedence; the opposite was true before v9.3.
5221  */
5222  if (strcmp(option->keyword, "sslmode") == 0)
5223  {
5224  const char *requiresslenv = getenv("PGREQUIRESSL");
5225 
5226  if (requiresslenv != NULL && requiresslenv[0] == '1')
5227  {
5228  option->val = strdup("require");
5229  if (!option->val)
5230  {
5231  if (errorMessage)
5232  printfPQExpBuffer(errorMessage,
5233  libpq_gettext("out of memory\n"));
5234  return false;
5235  }
5236  continue;
5237  }
5238  }
5239 
5240  /*
5241  * No environment variable specified or the variable isn't set - try
5242  * compiled-in default
5243  */
5244  if (option->compiled != NULL)
5245  {
5246  option->val = strdup(option->compiled);
5247  if (!option->val)
5248  {
5249  if (errorMessage)
5250  printfPQExpBuffer(errorMessage,
5251  libpq_gettext("out of memory\n"));
5252  return false;
5253  }
5254  continue;
5255  }
5256 
5257  /*
5258  * Special handling for "user" option. Note that if pg_fe_getauthname
5259  * fails, we just leave the value as NULL; there's no need for this to
5260  * be an error condition if the caller provides a user name. The only
5261  * reason we do this now at all is so that callers of PQconndefaults
5262  * will see a correct default (barring error, of course).
5263  */
5264  if (strcmp(option->keyword, "user") == 0)
5265  {
5266  option->val = pg_fe_getauthname(NULL);
5267  continue;
5268  }
5269  }
5270 
5271  return true;
5272 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:1024
#define NULL
Definition: c.h:229
static int parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:4473
#define libpq_gettext(x)
Definition: libpq-int.h:682
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 5011 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().

5014 {
5016  PQconninfoOption *dbname_options = NULL;
5018  int i = 0;
5019 
5020  /*
5021  * If expand_dbname is non-zero, check keyword "dbname" to see if val is
5022  * actually a recognized connection string.
5023  */
5024  while (expand_dbname && keywords[i])
5025  {
5026  const char *pname = keywords[i];
5027  const char *pvalue = values[i];
5028 
5029  /* first find "dbname" if any */
5030  if (strcmp(pname, "dbname") == 0 && pvalue)
5031  {
5032  /*
5033  * If value is a connection string, parse it, but do not use
5034  * defaults here -- those get picked up later. We only want to
5035  * override for those parameters actually passed.
5036  */
5037  if (recognized_connection_string(pvalue))
5038  {
5039  dbname_options = parse_connection_string(pvalue, errorMessage, false);
5040  if (dbname_options == NULL)
5041  return NULL;
5042  }
5043  break;
5044  }
5045  ++i;
5046  }
5047 
5048  /* Make a working copy of PQconninfoOptions */
5049  options = conninfo_init(errorMessage);
5050  if (options == NULL)
5051  {
5052  PQconninfoFree(dbname_options);
5053  return NULL;
5054  }
5055 
5056  /* Parse the keywords/values arrays */
5057  i = 0;
5058  while (keywords[i])
5059  {
5060  const char *pname = keywords[i];
5061  const char *pvalue = values[i];
5062 
5063  if (pvalue != NULL && pvalue[0] != '\0')
5064  {
5065  /* Search for the param record */
5066  for (option = options; option->keyword != NULL; option++)
5067  {
5068  if (strcmp(option->keyword, pname) == 0)
5069  break;
5070  }
5071 
5072  /* Check for invalid connection option */
5073  if (option->keyword == NULL)
5074  {
5075  printfPQExpBuffer(errorMessage,
5076  libpq_gettext("invalid connection option \"%s\"\n"),
5077  pname);
5078  PQconninfoFree(options);
5079  PQconninfoFree(dbname_options);
5080  return NULL;
5081  }
5082 
5083  /*
5084  * If we are on the first dbname parameter, and we have a parsed
5085  * connection string, copy those parameters across, overriding any
5086  * existing previous settings.
5087  */
5088  if (strcmp(pname, "dbname") == 0 && dbname_options)
5089  {
5090  PQconninfoOption *str_option;
5091 
5092  for (str_option = dbname_options; str_option->keyword != NULL; str_option++)
5093  {
5094  if (str_option->val != NULL)
5095  {
5096  int k;
5097 
5098  for (k = 0; options[k].keyword; k++)
5099  {
5100  if (strcmp(options[k].keyword, str_option->keyword) == 0)
5101  {
5102  if (options[k].val)
5103  free(options[k].val);
5104  options[k].val = strdup(str_option->val);
5105  if (!options[k].val)
5106  {
5107  printfPQExpBuffer(errorMessage,
5108  libpq_gettext("out of memory\n"));
5109  PQconninfoFree(options);
5110  PQconninfoFree(dbname_options);
5111  return NULL;
5112  }
5113  break;
5114  }
5115  }
5116  }
5117  }
5118 
5119  /*
5120  * Forget the parsed connection string, so that any subsequent
5121  * dbname parameters will not be expanded.
5122  */
5123  PQconninfoFree(dbname_options);
5124  dbname_options = NULL;
5125  }
5126  else
5127  {
5128  /*
5129  * Store the value, overriding previous settings
5130  */
5131  if (option->val)
5132  free(option->val);
5133  option->val = strdup(pvalue);
5134  if (!option->val)
5135  {
5136  printfPQExpBuffer(errorMessage,
5137  libpq_gettext("out of memory\n"));
5138  PQconninfoFree(options);
5139  PQconninfoFree(dbname_options);
5140  return NULL;
5141  }
5142  }
5143  }
5144  ++i;
5145  }
5146  PQconninfoFree(dbname_options);
5147 
5148  /*
5149  * Add in defaults if the caller wants that.
5150  */
5151  if (use_defaults)
5152  {
5153  if (!conninfo_add_defaults(options, errorMessage))
5154  {
5155  PQconninfoFree(options);
5156  return NULL;
5157  }
5158  }
5159 
5160  return options;
5161 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4739
static PQconninfoOption * parse_connection_string(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4779
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5947
static char ** options
static bool recognized_connection_string(const char *connstr)
Definition: fe-connect.c:4822
#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:5175
static Datum values[MAXATTR]
Definition: bootstrap.c:163
int i
long val
Definition: informix.c:689
#define libpq_gettext(x)
Definition: libpq-int.h:682
static PQconninfoOption * conninfo_find ( PQconninfoOption connOptions,
const char *  keyword 
)
static

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

References _PQconninfoOption::keyword, and NULL.

Referenced by conninfo_getval(), and conninfo_storeval().

5889 {
5891 
5892  for (option = connOptions; option->keyword != NULL; option++)
5893  {
5894  if (strcmp(option->keyword, keyword) == 0)
5895  return option;
5896  }
5897 
5898  return NULL;
5899 }
#define NULL
Definition: c.h:229
static const char * conninfo_getval ( PQconninfoOption connOptions,
const char *  keyword 
)
static

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

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

Referenced by fillPGconn(), and parseServiceInfo().

5799 {
5801 
5802  option = conninfo_find(connOptions, keyword);
5803 
5804  return option ? option->val : NULL;
5805 }
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5888
#define NULL
Definition: c.h:229
static PQconninfoOption * conninfo_init ( PQExpBuffer  errorMessage)
static

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

4740 {
4742  PQconninfoOption *opt_dest;
4743  const internalPQconninfoOption *cur_opt;
4744 
4745  /*
4746  * Get enough memory for all options in PQconninfoOptions, even if some
4747  * end up being filtered out.
4748  */
4749  options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
4750  if (options == NULL)
4751  {
4752  printfPQExpBuffer(errorMessage,
4753  libpq_gettext("out of memory\n"));
4754  return NULL;
4755  }
4756  opt_dest = options;
4757 
4758  for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
4759  {
4760  /* Only copy the public part of the struct, not the full internal */
4761  memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
4762  opt_dest++;
4763  }
4764  MemSet(opt_dest, 0, sizeof(PQconninfoOption));
4765 
4766  return options;
4767 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define MemSet(start, val, len)
Definition: c.h:858
#define malloc(a)
Definition: header.h:50
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:181
static char ** options
#define NULL
Definition: c.h:229
#define libpq_gettext(x)
Definition: libpq-int.h:682
static PQconninfoOption * conninfo_parse ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

4835 {
4836  char *pname;
4837  char *pval;
4838  char *buf;
4839  char *cp;
4840  char *cp2;
4842 
4843  /* Make a working copy of PQconninfoOptions */
4844  options = conninfo_init(errorMessage);
4845  if (options == NULL)
4846  return NULL;
4847 
4848  /* Need a modifiable copy of the input string */
4849  if ((buf = strdup(conninfo)) == NULL)
4850  {
4851  printfPQExpBuffer(errorMessage,
4852  libpq_gettext("out of memory\n"));
4853  PQconninfoFree(options);
4854  return NULL;
4855  }
4856  cp = buf;
4857 
4858  while (*cp)
4859  {
4860  /* Skip blanks before the parameter name */
4861  if (isspace((unsigned char) *cp))
4862  {
4863  cp++;
4864  continue;
4865  }
4866 
4867  /* Get the parameter name */
4868  pname = cp;
4869  while (*cp)
4870  {
4871  if (*cp == '=')
4872  break;
4873  if (isspace((unsigned char) *cp))
4874  {
4875  *cp++ = '\0';
4876  while (*cp)
4877  {
4878  if (!isspace((unsigned char) *cp))
4879  break;
4880  cp++;
4881  }
4882  break;
4883  }
4884  cp++;
4885  }
4886 
4887  /* Check that there is a following '=' */
4888  if (*cp != '=')
4889  {
4890  printfPQExpBuffer(errorMessage,
4891  libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
4892  pname);
4893  PQconninfoFree(options);
4894  free(buf);
4895  return NULL;
4896  }
4897  *cp++ = '\0';
4898 
4899  /* Skip blanks after the '=' */
4900  while (*cp)
4901  {
4902  if (!isspace((unsigned char) *cp))
4903  break;
4904  cp++;
4905  }
4906 
4907  /* Get the parameter value */
4908  pval = cp;
4909 
4910  if (*cp != '\'')
4911  {
4912  cp2 = pval;
4913  while (*cp)
4914  {
4915  if (isspace((unsigned char) *cp))
4916  {
4917  *cp++ = '\0';
4918  break;
4919  }
4920  if (*cp == '\\')
4921  {
4922  cp++;
4923  if (*cp != '\0')
4924  *cp2++ = *cp++;
4925  }
4926  else
4927  *cp2++ = *cp++;
4928  }
4929  *cp2 = '\0';
4930  }
4931  else
4932  {
4933  cp2 = pval;
4934  cp++;
4935  for (;;)
4936  {
4937  if (*cp == '\0')
4938  {
4939  printfPQExpBuffer(errorMessage,
4940  libpq_gettext("unterminated quoted string in connection info string\n"));
4941  PQconninfoFree(options);
4942  free(buf);
4943  return NULL;
4944  }
4945  if (*cp == '\\')
4946  {
4947  cp++;
4948  if (*cp != '\0')
4949  *cp2++ = *cp++;
4950  continue;
4951  }
4952  if (*cp == '\'')
4953  {
4954  *cp2 = '\0';
4955  cp++;
4956  break;
4957  }
4958  *cp2++ = *cp++;
4959  }
4960  }
4961 
4962  /*
4963  * Now that we have the name and the value, store the record.
4964  */
4965  if (!conninfo_storeval(options, pname, pval, errorMessage, false, false))
4966  {
4967  PQconninfoFree(options);
4968  free(buf);
4969  return NULL;
4970  }
4971  }
4972 
4973  /* Done with the modifiable input string */
4974  free(buf);
4975 
4976  /*
4977  * Add in defaults if the caller wants that.
4978  */
4979  if (use_defaults)
4980  {
4981  if (!conninfo_add_defaults(options, errorMessage))
4982  {
4983  PQconninfoFree(options);
4984  return NULL;
4985  }
4986  }
4987 
4988  return options;
4989 }
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:5823
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4739
static char * buf
Definition: pg_test_fsync.c:66
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5947
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:5175
#define libpq_gettext(x)
Definition: libpq-int.h:682
static PQconninfoOption * conninfo_storeval ( PQconninfoOption connOptions,
const char *  keyword,
const char *  value,
PQExpBuffer  errorMessage,
bool  ignoreMissing,
bool  uri_decode 
)
static

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

5827 {
5829  char *value_copy;
5830 
5831  /*
5832  * For backwards compatibility, requiressl=1 gets translated to
5833  * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
5834  * (which is the default for sslmode).
5835  */
5836  if (strcmp(keyword, "requiressl") == 0)
5837  {
5838  keyword = "sslmode";
5839  if (value[0] == '1')
5840  value = "require";
5841  else
5842  value = "prefer";
5843  }
5844 
5845  option = conninfo_find(connOptions, keyword);
5846  if (option == NULL)
5847  {
5848  if (!ignoreMissing)
5849  printfPQExpBuffer(errorMessage,
5850  libpq_gettext("invalid connection option \"%s\"\n"),
5851  keyword);
5852  return NULL;
5853  }
5854 
5855  if (uri_decode)
5856  {
5857  value_copy = conninfo_uri_decode(value, errorMessage);
5858  if (value_copy == NULL)
5859  /* conninfo_uri_decode already set an error message */
5860  return NULL;
5861  }
5862  else
5863  {
5864  value_copy = strdup(value);
5865  if (value_copy == NULL)
5866  {
5867  printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5868  return NULL;
5869  }
5870  }
5871 
5872  if (option->val)
5873  free(option->val);
5874  option->val = value_copy;
5875 
5876  return option;
5877 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static PQconninfoOption * conninfo_find(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5888
static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
Definition: fe-connect.c:5708
static struct @121 value
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
#define libpq_gettext(x)
Definition: libpq-int.h:682
static char * conninfo_uri_decode ( const char *  str,
PQExpBuffer  errorMessage 
)
static

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

5709 {
5710  char *buf;
5711  char *p;
5712  const char *q = str;
5713 
5714  buf = malloc(strlen(str) + 1);
5715  if (buf == NULL)
5716  {
5717  printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5718  return NULL;
5719  }
5720  p = buf;
5721 
5722  for (;;)
5723  {
5724  if (*q != '%')
5725  {
5726  /* copy and check for NUL terminator */
5727  if (!(*(p++) = *(q++)))
5728  break;
5729  }
5730  else
5731  {
5732  int hi;
5733  int lo;
5734  int c;
5735 
5736  ++q; /* skip the percent sign itself */
5737 
5738  /*
5739  * Possible EOL will be caught by the first call to
5740  * get_hexdigit(), so we never dereference an invalid q pointer.
5741  */
5742  if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
5743  {
5744  printfPQExpBuffer(errorMessage,
5745  libpq_gettext("invalid percent-encoded token: \"%s\"\n"),
5746  str);
5747  free(buf);
5748  return NULL;
5749  }
5750 
5751  c = (hi << 4) | lo;
5752  if (c == 0)
5753  {
5754  printfPQExpBuffer(errorMessage,
5755  libpq_gettext("forbidden value %%00 in percent-encoded value: \"%s\"\n"),
5756  str);
5757  free(buf);
5758  return NULL;
5759  }
5760  *(p++) = c;
5761  }
5762  }
5763 
5764  return buf;
5765 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define malloc(a)
Definition: header.h:50
char * c
static char * buf
Definition: pg_test_fsync.c:66
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
static bool get_hexdigit(char digit, int *value)
Definition: fe-connect.c:5776
#define libpq_gettext(x)
Definition: libpq-int.h:682
static PQconninfoOption * conninfo_uri_parse ( const char *  uri,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

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

Referenced by parse_connection_string().

5282 {
5284 
5285  /* Make a working copy of PQconninfoOptions */
5286  options = conninfo_init(errorMessage);
5287  if (options == NULL)
5288  return NULL;
5289 
5290  if (!conninfo_uri_parse_options(options, uri, errorMessage))
5291  {
5292  PQconninfoFree(options);
5293  return NULL;
5294  }
5295 
5296  /*
5297  * Add in defaults if the caller wants that.
5298  */
5299  if (use_defaults)
5300  {
5301  if (!conninfo_add_defaults(options, errorMessage))
5302  {
5303  PQconninfoFree(options);
5304  return NULL;
5305  }
5306  }
5307 
5308  return options;
5309 }
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4739
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5947
static bool conninfo_uri_parse_options(PQconninfoOption *options, const char *uri, PQExpBuffer errorMessage)
Definition: fe-connect.c:5333
static char ** options
#define NULL
Definition: c.h:229
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5175
static bool conninfo_uri_parse_options ( PQconninfoOption options,
const char *  uri,
PQExpBuffer  errorMessage 
)
static

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

References appendPQExpBufferChar(), 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().

5335 {
5336  int prefix_len;
5337  char *p;
5338  char *buf = NULL;
5339  char *start;
5340  char prevchar = '\0';
5341  char *user = NULL;
5342  char *host = NULL;
5343  bool retval = false;
5344  PQExpBufferData hostbuf;
5345  PQExpBufferData portbuf;
5346 
5347  initPQExpBuffer(&hostbuf);
5348  initPQExpBuffer(&portbuf);
5349  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
5350  {
5351  printfPQExpBuffer(errorMessage,
5352  libpq_gettext("out of memory\n"));
5353  goto cleanup;
5354  }
5355 
5356  /* need a modifiable copy of the input URI */
5357  buf = strdup(uri);
5358  if (buf == NULL)
5359  {
5360  printfPQExpBuffer(errorMessage,
5361  libpq_gettext("out of memory\n"));
5362  goto cleanup;
5363  }
5364  start = buf;
5365 
5366  /* Skip the URI prefix */
5367  prefix_len = uri_prefix_length(uri);
5368  if (prefix_len == 0)
5369  {
5370  /* Should never happen */
5371  printfPQExpBuffer(errorMessage,
5372  libpq_gettext("invalid URI propagated to internal parser routine: \"%s\"\n"),
5373  uri);
5374  goto cleanup;
5375  }
5376  start += prefix_len;
5377  p = start;
5378 
5379  /* Look ahead for possible user credentials designator */
5380  while (*p && *p != '@' && *p != '/')
5381  ++p;
5382  if (*p == '@')
5383  {
5384  /*
5385  * Found username/password designator, so URI should be of the form
5386  * "scheme://user[:password]@[netloc]".
5387  */
5388  user = start;
5389 
5390  p = user;
5391  while (*p != ':' && *p != '@')
5392  ++p;
5393 
5394  /* Save last char and cut off at end of user name */
5395  prevchar = *p;
5396  *p = '\0';
5397 
5398  if (*user &&
5399  !conninfo_storeval(options, "user", user,
5400  errorMessage, false, true))
5401  goto cleanup;
5402 
5403  if (prevchar == ':')
5404  {
5405  const char *password = p + 1;
5406 
5407  while (*p != '@')
5408  ++p;
5409  *p = '\0';
5410 
5411  if (*password &&
5412  !conninfo_storeval(options, "password", password,
5413  errorMessage, false, true))
5414  goto cleanup;
5415  }
5416 
5417  /* Advance past end of parsed user name or password token */
5418  ++p;
5419  }
5420  else
5421  {
5422  /*
5423  * No username/password designator found. Reset to start of URI.
5424  */
5425  p = start;
5426  }
5427 
5428  /*
5429  * There may be multiple netloc[:port] pairs, each separated from the next
5430  * by a comma. When we initially enter this loop, "p" has been
5431  * incremented past optional URI credential information at this point and
5432  * now points at the "netloc" part of the URI. On subsequent loop
5433  * iterations, "p" has been incremented past the comma separator and now
5434  * points at the start of the next "netloc".
5435  */
5436  for (;;)
5437  {
5438  /*
5439  * Look for IPv6 address.
5440  */
5441  if (*p == '[')
5442  {
5443  host = ++p;
5444  while (*p && *p != ']')
5445  ++p;
5446  if (!*p)
5447  {
5448  printfPQExpBuffer(errorMessage,
5449  libpq_gettext("end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n"),
5450  uri);
5451  goto cleanup;
5452  }
5453  if (p == host)
5454  {
5455  printfPQExpBuffer(errorMessage,
5456  libpq_gettext("IPv6 host address may not be empty in URI: \"%s\"\n"),
5457  uri);
5458  goto cleanup;
5459  }
5460 
5461  /* Cut off the bracket and advance */
5462  *(p++) = '\0';
5463 
5464  /*
5465  * The address may be followed by a port specifier or a slash or a
5466  * query or a separator comma.
5467  */
5468  if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
5469  {
5470  printfPQExpBuffer(errorMessage,
5471  libpq_gettext("unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n"),
5472  *p, (int) (p - buf + 1), uri);
5473  goto cleanup;
5474  }
5475  }
5476  else
5477  {
5478  /* not an IPv6 address: DNS-named or IPv4 netloc */
5479  host = p;
5480 
5481  /*
5482  * Look for port specifier (colon) or end of host specifier
5483  * (slash) or query (question mark) or host separator (comma).
5484  */
5485  while (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
5486  ++p;
5487  }
5488 
5489  /* Save the hostname terminator before we null it */
5490  prevchar = *p;
5491  *p = '\0';
5492 
5493  appendPQExpBufferStr(&hostbuf, host);
5494 
5495  if (prevchar == ':')
5496  {
5497  const char *port = ++p; /* advance past host terminator */
5498 
5499  while (*p && *p != '/' && *p != '?' && *p != ',')
5500  ++p;
5501 
5502  prevchar = *p;
5503  *p = '\0';
5504 
5505  appendPQExpBufferStr(&portbuf, port);
5506  }
5507 
5508  if (prevchar != ',')
5509  break;
5510  ++p; /* advance past comma separator */
5511  appendPQExpBufferChar(&hostbuf, ',');
5512  appendPQExpBufferChar(&portbuf, ',');
5513  }
5514 
5515  /* Save final values for host and port. */
5516  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
5517  goto cleanup;
5518  if (hostbuf.data[0] &&
5519  !conninfo_storeval(options, "host", hostbuf.data,
5520  errorMessage, false, true))
5521  goto cleanup;
5522  if (portbuf.data[0] &&
5523  !conninfo_storeval(options, "port", portbuf.data,
5524  errorMessage, false, true))
5525  goto cleanup;
5526 
5527  if (prevchar && prevchar != '?')
5528  {
5529  const char *dbname = ++p; /* advance past host terminator */
5530 
5531  /* Look for query parameters */
5532  while (*p && *p != '?')
5533  ++p;
5534 
5535  prevchar = *p;
5536  *p = '\0';
5537 
5538  /*
5539  * Avoid setting dbname to an empty string, as it forces the default
5540  * value (username) and ignores $PGDATABASE, as opposed to not setting
5541  * it at all.
5542  */
5543  if (*dbname &&
5544  !conninfo_storeval(options, "dbname", dbname,
5545  errorMessage, false, true))
5546  goto cleanup;
5547  }
5548 
5549  if (prevchar)
5550  {
5551  ++p; /* advance past terminator */
5552 
5553  if (!conninfo_uri_parse_params(p, options, errorMessage))
5554  goto cleanup;
5555  }
5556 
5557  /* everything parsed okay */
5558  retval = true;
5559 
5560 cleanup:
5561  termPQExpBuffer(&hostbuf);
5562  termPQExpBuffer(&portbuf);
5563  if (buf)
5564  free(buf);
5565  return retval;
5566 }
static char password[100]
Definition: streamutil.c:42
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:5823
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
static char * buf
Definition: pg_test_fsync.c:66
static int port
Definition: pg_regress.c:89
static void cleanup(void)
Definition: bootstrap.c:860
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
static bool conninfo_uri_parse_params(char *params, PQconninfoOption *connOptions, PQExpBuffer errorMessage)
Definition: fe-connect.c:5577
#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:39
static char * user
Definition: pg_regress.c:92
static int uri_prefix_length(const char *connstr)
Definition: fe-connect.c:4799
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
#define libpq_gettext(x)
Definition: libpq-int.h:682
static bool conninfo_uri_parse_params ( char *  params,
PQconninfoOption connOptions,
PQExpBuffer  errorMessage 
)
static

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

5580 {
5581  while (*params)
5582  {
5583  char *keyword = params;
5584  char *value = NULL;
5585  char *p = params;
5586  bool malloced = false;
5587 
5588  /*
5589  * Scan the params string for '=' and '&', marking the end of keyword
5590  * and value respectively.
5591  */
5592  for (;;)
5593  {
5594  if (*p == '=')
5595  {
5596  /* Was there '=' already? */
5597  if (value != NULL)
5598  {
5599  printfPQExpBuffer(errorMessage,
5600  libpq_gettext("extra key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5601  keyword);
5602  return false;
5603  }
5604  /* Cut off keyword, advance to value */
5605  *p++ = '\0';
5606  value = p;
5607  }
5608  else if (*p == '&' || *p == '\0')
5609  {
5610  /*
5611  * If not at the end, cut off value and advance; leave p
5612  * pointing to start of the next parameter, if any.
5613  */
5614  if (*p != '\0')
5615  *p++ = '\0';
5616  /* Was there '=' at all? */
5617  if (value == NULL)
5618  {
5619  printfPQExpBuffer(errorMessage,
5620  libpq_gettext("missing key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5621  keyword);
5622  return false;
5623  }
5624  /* Got keyword and value, go process them. */
5625  break;
5626  }
5627  else
5628  ++p; /* Advance over all other bytes. */
5629  }
5630 
5631  keyword = conninfo_uri_decode(keyword, errorMessage);
5632  if (keyword == NULL)
5633  {
5634  /* conninfo_uri_decode already set an error message */
5635  return false;
5636  }
5637  value = conninfo_uri_decode(value, errorMessage);
5638  if (value == NULL)
5639  {
5640  /* conninfo_uri_decode already set an error message */
5641  free(keyword);
5642  return false;
5643  }
5644  malloced = true;
5645 
5646  /*
5647  * Special keyword handling for improved JDBC compatibility.
5648  */
5649  if (strcmp(keyword, "ssl") == 0 &&
5650  strcmp(value, "true") == 0)
5651  {
5652  free(keyword);
5653  free(value);
5654  malloced = false;
5655 
5656  keyword = "sslmode";
5657  value = "require";
5658  }
5659 
5660  /*
5661  * Store the value if the corresponding option exists; ignore
5662  * otherwise. At this point both keyword and value are not
5663  * URI-encoded.
5664  */
5665  if (!conninfo_storeval(connOptions, keyword, value,
5666  errorMessage, true, false))
5667  {
5668  /* Insert generic message if conninfo_storeval didn't give one. */
5669  if (errorMessage->len == 0)
5670  printfPQExpBuffer(errorMessage,
5671  libpq_gettext("invalid URI query parameter: \"%s\"\n"),
5672  keyword);
5673  /* And fail. */
5674  if (malloced)
5675  {
5676  free(keyword);
5677  free(value);
5678  }
5679  return false;
5680  }
5681 
5682  if (malloced)
5683  {
5684  free(keyword);
5685  free(value);
5686  }
5687 
5688  /* Proceed to next key=value pair, if any */
5689  params = p;
5690  }
5691 
5692  return true;
5693 }
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:5823
static char * conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
Definition: fe-connect.c:5708
static struct @121 value
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
#define libpq_gettext(x)
Definition: libpq-int.h:682
static int count_comma_separated_elems ( const char *  input)
static

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

Referenced by connectOptions2().

835 {
836  int n;
837 
838  n = 1;
839  for (; *input != '\0'; input++)
840  {
841  if (*input == ',')
842  n++;
843  }
844 
845  return n;
846 }
static void default_threadlock ( int  acquire)
static

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

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

Referenced by PQregisterThreadLock().

6546 {
6547 #ifdef ENABLE_THREAD_SAFETY
6548 #ifndef WIN32
6549  static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
6550 #else
6551  static pthread_mutex_t singlethread_lock = NULL;
6552  static long mutex_initlock = 0;
6553 
6554  if (singlethread_lock == NULL)
6555  {
6556  while (InterlockedExchange(&mutex_initlock, 1) == 1)
6557  /* loop, another thread own the lock */ ;
6558  if (singlethread_lock == NULL)
6559  {
6560  if (pthread_mutex_init(&singlethread_lock, NULL))
6561  PGTHREAD_ERROR("failed to initialize mutex");
6562  }
6563  InterlockedExchange(&mutex_initlock, 0);
6564  }
6565 #endif
6566  if (acquire)
6567  {
6568  if (pthread_mutex_lock(&singlethread_lock))
6569  PGTHREAD_ERROR("failed to lock mutex");
6570  }
6571  else
6572  {
6573  if (pthread_mutex_unlock(&singlethread_lock))
6574  PGTHREAD_ERROR("failed to unlock mutex");
6575  }
6576 #endif
6577 }
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 6311 of file fe-connect.c.

Referenced by makeEmptyPGconn().

6312 {
6313  (void) arg; /* not used */
6314  /* Note: we expect the supplied string to end with a newline already. */
6315  fprintf(stderr, "%s", message);
6316 }
void * arg
static void defaultNoticeReceiver ( void *  arg,
const PGresult res 
)
static

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

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

Referenced by makeEmptyPGconn().

6297 {
6298  (void) arg; /* not used */
6299  if (res->noticeHooks.noticeProc != NULL)
6301  PQresultErrorMessage(res));
6302 }
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 755 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().

756 {
758 
759  for (option = PQconninfoOptions; option->keyword; option++)
760  {
761  if (option->connofs >= 0)
762  {
763  const char *tmp = conninfo_getval(connOptions, option->keyword);
764 
765  if (tmp)
766  {
767  char **connmember = (char **) ((char *) conn + option->connofs);
768 
769  if (*connmember)
770  free(*connmember);
771  *connmember = strdup(tmp);
772  if (*connmember == NULL)
773  {
775  libpq_gettext("out of memory\n"));
776  return false;
777  }
778  }
779  }
780  }
781 
782  return true;
783 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:181
PQExpBufferData errorMessage
Definition: libpq-int.h:491
#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:5797
#define libpq_gettext(x)
Definition: libpq-int.h:682
static void freePGconn ( PGconn conn)
static

Definition at line 3403 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, pg_conn_host::hostaddr, 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().

3404 {
3405  int i;
3406 
3407  /* let any event procs clean up their state data */
3408  for (i = 0; i < conn->nEvents; i++)
3409  {
3410  PGEventConnDestroy evt;
3411 
3412  evt.conn = conn;
3413  (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
3414  conn->events[i].passThrough);
3415  free(conn->events[i].name);
3416  }
3417 
3418  /* clean up pg_conn_host structures */
3419  if (conn->connhost != NULL)
3420  {
3421  for (i = 0; i < conn->nconnhost; ++i)
3422  {
3423  if (conn->connhost[i].host != NULL)
3424  free(conn->connhost[i].host);
3425  if (conn->connhost[i].hostaddr != NULL)
3426  free(conn->connhost[i].hostaddr);
3427  if (conn->connhost[i].port != NULL)
3428  free(conn->connhost[i].port);
3429  if (conn->connhost[i].password != NULL)
3430  free(conn->connhost[i].password);
3431  }
3432  free(conn->connhost);
3433  }
3434 
3435  if (conn->client_encoding_initial)
3437  if (conn->events)
3438  free(conn->events);
3439  if (conn->pghost)
3440  free(conn->pghost);
3441  if (conn->pghostaddr)
3442  free(conn->pghostaddr);
3443  if (conn->pgport)
3444  free(conn->pgport);
3445  if (conn->pgtty)
3446  free(conn->pgtty);
3447  if (conn->connect_timeout)
3448  free(conn->connect_timeout);
3449  if (conn->pgoptions)
3450  free(conn->pgoptions);
3451  if (conn->appname)
3452  free(conn->appname);
3453  if (conn->fbappname)
3454  free(conn->fbappname);
3455  if (conn->dbName)
3456  free(conn->dbName);
3457  if (conn->replication)
3458  free(conn->replication);
3459  if (conn->pguser)
3460  free(conn->pguser);
3461  if (conn->pgpass)
3462  free(conn->pgpass);
3463  if (conn->pgpassfile)
3464  free(conn->pgpassfile);
3465  if (conn->keepalives)
3466  free(conn->keepalives);
3467  if (conn->keepalives_idle)
3468  free(conn->keepalives_idle);
3469  if (conn->keepalives_interval)
3470  free(conn->keepalives_interval);
3471  if (conn->keepalives_count)
3472  free(conn->keepalives_count);
3473  if (conn->sslmode)
3474  free(conn->sslmode);
3475  if (conn->sslcert)
3476  free(conn->sslcert);
3477  if (conn->sslkey)
3478  free(conn->sslkey);
3479  if (conn->sslrootcert)
3480  free(conn->sslrootcert);
3481  if (conn->sslcrl)
3482  free(conn->sslcrl);
3483  if (conn->sslcompression)
3484  free(conn->sslcompression);
3485  if (conn->requirepeer)
3486  free(conn->requirepeer);
3487 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
3488  if (conn->krbsrvname)
3489  free(conn->krbsrvname);
3490 #endif
3491 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
3492  if (conn->gsslib)
3493  free(conn->gsslib);
3494 #endif
3495  /* Note that conn->Pfdebug is not ours to close or free */
3496  if (conn->last_query)
3497  free(conn->last_query);
3498  if (conn->inBuffer)
3499  free(conn->inBuffer);
3500  if (conn->outBuffer)
3501  free(conn->outBuffer);
3502  if (conn->rowBuf)
3503  free(conn->rowBuf);
3504  if (conn->target_session_attrs)
3505  free(conn->target_session_attrs);
3506  termPQExpBuffer(&conn->errorMessage);
3507  termPQExpBuffer(&conn->workBuffer);
3508 
3509  free(conn);
3510 
3511 #ifdef WIN32
3512  WSACleanup();
3513 #endif
3514 }
PGEvent * events
Definition: libpq-int.h:374
char * replication
Definition: libpq-int.h:342
char * pgpassfile
Definition: libpq-int.h:345
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
PQExpBufferData workBuffer
Definition: libpq-int.h:494
char * requirepeer
Definition: libpq-int.h:358
char * host
Definition: libpq-int.h:308
char * dbName
Definition: libpq-int.h:341
char * keepalives
Definition: libpq-int.h:346
char * keepalives_idle
Definition: libpq-int.h:347
char * client_encoding_initial
Definition: libpq-int.h:337
char * sslkey
Definition: libpq-int.h:354
char * sslcompression
Definition: libpq-int.h:353
PGconn * conn
Definition: streamutil.c:43
char * hostaddr
Definition: libpq-int.h:309
char * connect_timeout
Definition: libpq-int.h:336
pg_conn_host * connhost
Definition: libpq-int.h:397
char * keepalives_interval
Definition: libpq-int.h:348
char * appname
Definition: libpq-int.h:339
char * target_session_attrs
Definition: libpq-int.h:365
char * last_query
Definition: libpq-int.h:383
PGdataValue * rowBuf
Definition: libpq-int.h:446
char * pguser
Definition: libpq-int.h:343
char * inBuffer
Definition: libpq-int.h:429
char * sslmode
Definition: libpq-int.h:352
PQExpBufferData errorMessage
Definition: libpq-int.h:491
char * sslcert
Definition: libpq-int.h:355
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
char * pgoptions
Definition: libpq-int.h:338
char * pgpass
Definition: libpq-int.h:344
char * sslrootcert
Definition: libpq-int.h:356
PGEventProc proc
Definition: libpq-int.h:160
char * outBuffer
Definition: libpq-int.h:436
char * pghostaddr
Definition: libpq-int.h:330
int nEvents
Definition: libpq-int.h:375
int i
void * passThrough
Definition: libpq-int.h:162
char * fbappname
Definition: libpq-int.h:340
char * port
Definition: libpq-int.h:310
char * pgport
Definition: libpq-int.h:333
int nconnhost
Definition: libpq-int.h:395
char * name
Definition: libpq-int.h:161
char * sslcrl
Definition: libpq-int.h:357
char * keepalives_count
Definition: libpq-int.h:350
char * pghost
Definition: libpq-int.h:325
char * pgtty
Definition: libpq-int.h:334
char * password
Definition: libpq-int.h:312
static bool get_hexdigit ( char  digit,
int *  value 
)
static

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

Referenced by conninfo_uri_decode().

5777 {
5778  if ('0' <= digit && digit <= '9')
5779  *value = digit - '0';
5780  else if ('A' <= digit && digit <= 'F')
5781  *value = digit - 'A' + 10;
5782  else if ('a' <= digit && digit <= 'f')
5783  *value = digit - 'a' + 10;
5784  else
5785  return false;
5786 
5787  return true;
5788 }
static struct @121 value
static int internal_cancel ( SockAddr raddr,
int  be_pid,
int  be_key,
char *  errbuf,
int  errbufsize 
)
static

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

3804 {
3805  int save_errno = SOCK_ERRNO;
3806  pgsocket tmpsock = PGINVALID_SOCKET;
3807  char sebuf[256];
3808  int maxlen;
3809  struct
3810  {
3811  uint32 packetlen;
3813  } crp;
3814 
3815  /*
3816  * We need to open a temporary connection to the postmaster. Do this with
3817  * only kernel calls.
3818  */
3819  if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
3820  {
3821  strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
3822  goto cancel_errReturn;
3823  }
3824 retry3:
3825  if (connect(tmpsock, (struct sockaddr *) &raddr->addr,
3826  raddr->salen) < 0)
3827  {
3828  if (SOCK_ERRNO == EINTR)
3829  /* Interrupted system call - we'll just try again */
3830  goto retry3;
3831  strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
3832  goto cancel_errReturn;
3833  }
3834 
3835  /*
3836  * We needn't set nonblocking I/O or NODELAY options here.
3837  */
3838 
3839  /* Create and send the cancel request packet. */
3840 
3841  crp.packetlen = htonl((uint32) sizeof(crp));
3842  crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE);
3843  crp.cp.backendPID = htonl(be_pid);
3844  crp.cp.cancelAuthCode = htonl(be_key);
3845 
3846 retry4:
3847  if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
3848  {
3849  if (SOCK_ERRNO == EINTR)
3850  /* Interrupted system call - we'll just try again */
3851  goto retry4;
3852  strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
3853  goto cancel_errReturn;
3854  }
3855 
3856  /*
3857  * Wait for the postmaster to close the connection, which indicates that
3858  * it's processed the request. Without this delay, we might issue another
3859  * command only to find that our cancel zaps that command instead of the
3860  * one we thought we were canceling. Note we don't actually expect this
3861  * read to obtain any data, we are just waiting for EOF to be signaled.
3862  */
3863 retry5:
3864  if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
3865  {
3866  if (SOCK_ERRNO == EINTR)
3867  /* Interrupted system call - we'll just try again */
3868  goto retry5;
3869  /* we ignore other error conditions */
3870  }
3871 
3872  /* All done */
3873  closesocket(tmpsock);
3874  SOCK_ERRNO_SET(save_errno);
3875  return TRUE;
3876 
3877 cancel_errReturn:
3878 
3879  /*
3880  * Make sure we don't overflow the error buffer. Leave space for the \n at
3881  * the end, and for the terminating zero.
3882  */
3883  maxlen = errbufsize - strlen(errbuf) - 2;
3884  if (maxlen >= 0)
3885  {
3886  strncat(errbuf, SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)),
3887  maxlen);
3888  strcat(errbuf, "\n");
3889  }
3890  if (tmpsock != PGINVALID_SOCKET)
3891  closesocket(tmpsock);
3892  SOCK_ERRNO_SET(save_errno);
3893  return FALSE;
3894 }
#define send(s, buf, len, flags)
Definition: win32.h:376
#define connect(s, name, namelen)
Definition: win32.h:373
#define closesocket
Definition: port.h:331
struct sockaddr_storage addr
Definition: pqcomm.h:64
#define socket(af, type, protocol)
Definition: win32.h:369
#define recv(s, buf, len, flags)
Definition: win32.h:375
#define SOCK_STRERROR
Definition: libpq-int.h:696
#define FALSE
Definition: c.h:221
#define SOCK_ERRNO
Definition: libpq-int.h:695
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:697
#define PGINVALID_SOCKET
Definition: port.h:24
#define EINTR
Definition: win32.h:285
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:190
ProtocolVersion MsgType
Definition: pqcomm.h:115
#define TRUE
Definition: c.h:217
static PGPing internal_ping ( PGconn conn)
static

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

3243 {
3244  /* Say "no attempt" if we never got to PQconnectPoll */
3245  if (!conn || !conn->options_valid)
3246  return PQPING_NO_ATTEMPT;
3247 
3248  /* Attempt to complete the connection */
3249  if (conn->status != CONNECTION_BAD)
3250  (void) connectDBComplete(conn);
3251 
3252  /* Definitely OK if we succeeded */
3253  if (conn->status != CONNECTION_BAD)
3254  return PQPING_OK;
3255 
3256  /*
3257  * Here begins the interesting part of "ping": determine the cause of the
3258  * failure in sufficient detail to decide what to return. We do not want
3259  * to report that the server is not up just because we didn't have a valid
3260  * password, for example. In fact, any sort of authentication request
3261  * implies the server is up. (We need this check since the libpq side of
3262  * things might have pulled the plug on the connection before getting an
3263  * error as such from the postmaster.)
3264  */
3265  if (conn->auth_req_received)
3266  return PQPING_OK;
3267 
3268  /*
3269  * If we failed to get any ERROR response from the postmaster, report
3270  * PQPING_NO_RESPONSE. This result could be somewhat misleading for a
3271  * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
3272  * out of support. Another corner case where the server could return a
3273  * failure without a SQLSTATE is fork failure, but NO_RESPONSE isn't
3274  * totally unreasonable for that anyway. We expect that every other
3275  * failure case in a modern server will produce a report with a SQLSTATE.
3276  *
3277  * NOTE: whenever we get around to making libpq generate SQLSTATEs for
3278  * client-side errors, we should either not store those into
3279  * last_sqlstate, or add an extra flag so we can tell client-side errors
3280  * apart from server-side ones.
3281  */
3282  if (strlen(conn->last_sqlstate) != 5)
3283  return PQPING_NO_RESPONSE;
3284 
3285  /*
3286  * Report PQPING_REJECT if server says it's not accepting connections. (We
3287  * distinguish this case mainly for the convenience of pg_ctl.)
3288  */
3289  if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
3290  return PQPING_REJECT;
3291 
3292  /*
3293  * Any other SQLSTATE can be taken to indicate that the server is up.
3294  * Presumably it didn't like our username, password, or database name; or
3295  * perhaps it had some transient failure, but that should not be taken as
3296  * meaning "it's down".
3297  */
3298  return PQPING_OK;
3299 }
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1835
bool options_valid
Definition: libpq-int.h:385
#define ERRCODE_CANNOT_CONNECT_NOW
Definition: fe-connect.c:95
ConnStatusType status
Definition: libpq-int.h:379
bool auth_req_received
Definition: libpq-int.h:406
char last_sqlstate[6]
Definition: libpq-int.h:384
static PGconn * makeEmptyPGconn ( void  )
static

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

3308 {
3309  PGconn *conn;
3310 
3311 #ifdef WIN32
3312 
3313  /*
3314  * Make sure socket support is up and running.
3315  */
3316  WSADATA wsaData;
3317 
3318  if (WSAStartup(MAKEWORD(1, 1), &wsaData))
3319  return NULL;
3320  WSASetLastError(0);
3321 #endif
3322 
3323  conn = (PGconn *) malloc(sizeof(PGconn));
3324  if (conn == NULL)
3325  {
3326 #ifdef WIN32
3327  WSACleanup();
3328 #endif
3329  return conn;
3330  }
3331 
3332  /* Zero all pointers and booleans */
3333  MemSet(conn, 0, sizeof(PGconn));
3334 
3335  /* install default notice hooks */
3338 
3339  conn->status = CONNECTION_BAD;
3340  conn->asyncStatus = PGASYNC_IDLE;
3341  conn->xactStatus = PQTRANS_IDLE;
3342  conn->options_valid = false;
3343  conn->nonblocking = false;
3345  conn->client_encoding = PG_SQL_ASCII;
3346  conn->std_strings = false; /* unless server says differently */
3347  conn->verbosity = PQERRORS_DEFAULT;
3349  conn->sock = PGINVALID_SOCKET;
3350  conn->auth_req_received = false;
3351  conn->password_needed = false;
3352  conn->pgpassfile_used = false;
3353 #ifdef USE_SSL
3354  conn->allow_ssl_try = true;
3355  conn->wait_ssl_try = false;
3356  conn->ssl_in_use = false;
3357 #endif
3358 
3359  /*
3360  * We try to send at least 8K at a time, which is the usual size of pipe
3361  * buffers on Unix systems. That way, when we are sending a large amount
3362  * of data, we avoid incurring extra kernel context swaps for partial
3363  * bufferloads. The output buffer is initially made 16K in size, and we
3364  * try to dump it after accumulating 8K.
3365  *
3366  * With the same goal of minimizing context swaps, the input buffer will
3367  * be enlarged anytime it has less than 8K free, so we initially allocate
3368  * twice that.
3369  */
3370  conn->inBufSize = 16 * 1024;
3371  conn->inBuffer = (char *) malloc(conn->inBufSize);
3372  conn->outBufSize = 16 * 1024;
3373  conn->outBuffer = (char *) malloc(conn->outBufSize);
3374  conn->rowBufLen = 32;
3375  conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
3376  initPQExpBuffer(&conn->errorMessage);
3377  initPQExpBuffer(&conn->workBuffer);
3378 
3379  if (conn->inBuffer == NULL ||
3380  conn->outBuffer == NULL ||
3381  conn->rowBuf == NULL ||
3382  PQExpBufferBroken(&conn->errorMessage) ||
3383  PQExpBufferBroken(&conn->workBuffer))
3384  {
3385  /* out of memory already :-( */
3386  freePGconn(conn);
3387  conn = NULL;
3388  }
3389 
3390  return conn;
3391 }
PGContextVisibility show_context
Definition: libpq-int.h:425
int rowBufLen
Definition: libpq-int.h:447
bool password_needed
Definition: libpq-int.h:407
PQExpBufferData workBuffer
Definition: libpq-int.h:494
#define MemSet(start, val, len)
Definition: c.h:858
bool pgpassfile_used
Definition: libpq-int.h:408
#define malloc(a)
Definition: header.h:50
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:380
PGSetenvStatusType setenv_state
Definition: libpq-int.h:414
PGconn * conn
Definition: streamutil.c:43
int inBufSize
Definition: libpq-int.h:430
PGNoticeHooks noticeHooks
Definition: libpq-int.h:371
PGVerbosity verbosity
Definition: libpq-int.h:424
PQnoticeReceiver noticeRec
Definition: libpq-int.h:152
PGdataValue * rowBuf
Definition: libpq-int.h:446
pgsocket sock
Definition: libpq-int.h:400
#define PGINVALID_SOCKET
Definition: port.h:24
char * inBuffer
Definition: libpq-int.h:429
PQnoticeProcessor noticeProc
Definition: libpq-int.h:154
static void freePGconn(PGconn *conn)
Definition: fe-connect.c:3403
PQExpBufferData errorMessage
Definition: libpq-int.h:491
bool std_strings
Definition: libpq-int.h:423
bool options_valid
Definition: libpq-int.h:385
int outBufSize
Definition: libpq-int.h:437
#define NULL
Definition: c.h:229
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
ConnStatusType status
Definition: libpq-int.h:379
bool auth_req_received
Definition: libpq-int.h:406
char * outBuffer
Definition: libpq-int.h:436
bool nonblocking
Definition: libpq-int.h:386
static void defaultNoticeProcessor(void *arg, const char *message)
Definition: fe-connect.c:6311
int client_encoding
Definition: libpq-int.h:422
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
static void defaultNoticeReceiver(void *arg, const PGresult *res)
Definition: fe-connect.c:6296
PGTransactionStatusType xactStatus
Definition: libpq-int.h:381
static char* parse_comma_separated_list ( char **  startptr,
bool more 
)
static

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

References malloc.

Referenced by connectOptions2().

859 {
860  char *p;
861  char *s = *startptr;
862  char *e;
863  int len;
864 
865  /*
866  * Search for the end of the current element; a comma or end-of-string
867  * acts as a terminator.
868  */
869  e = s;
870  while (*e != '\0' && *e != ',')
871  ++e;
872  *more = (*e == ',');
873 
874  len = e - s;
875  p = (char *) malloc(sizeof(char) * (len + 1));
876  if (p)
877  {
878  memcpy(p, s, len);
879  p[len] = '\0';
880  }
881  *startptr = e + 1;
882 
883  return p;
884 }
#define malloc(a)
Definition: header.h:50
e
Definition: preproc-init.c:82
static PQconninfoOption * parse_connection_string ( const char *  conninfo,
PQExpBuffer  errorMessage,
bool  use_defaults 
)
static

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

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

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

4781 {
4782  /* Parse as URI if connection string matches URI prefix */
4783  if (uri_prefix_length(connstr) != 0)
4784  return conninfo_uri_parse(connstr, errorMessage, use_defaults);
4785 
4786  /* Parse as default otherwise */
4787  return conninfo_parse(connstr, errorMessage, use_defaults);
4788 }
static PQconninfoOption * conninfo_parse(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:4833
static int uri_prefix_length(const char *connstr)
Definition: fe-connect.c:4799
static PQconninfoOption * conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:5280
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 4542 of file fe-connect.c.

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

Referenced by parseServiceInfo().

4547 {
4548  int linenr = 0,
4549  i;
4550  FILE *f;
4551  char buf[MAXBUFSIZE],
4552  *line;
4553 
4554  f = fopen(serviceFile, "r");
4555  if (f == NULL)
4556  {
4557  printfPQExpBuffer(errorMessage, libpq_gettext("service file \"%s\" not found\n"),
4558  serviceFile);
4559  return 1;
4560  }
4561 
4562  while ((line = fgets(buf, sizeof(buf), f)) != NULL)
4563  {
4564  linenr++;
4565 
4566  if (strlen(line) >= sizeof(buf) - 1)
4567  {
4568  fclose(f);
4569  printfPQExpBuffer(errorMessage,
4570  libpq_gettext("line %d too long in service file \"%s\"\n"),
4571  linenr,
4572  serviceFile);
4573  return 2;
4574  }
4575 
4576  /* ignore EOL at end of line */
4577  if (strlen(line) && line[strlen(line) - 1] == '\n')
4578  line[strlen(line) - 1] = 0;
4579 
4580  /* ignore leading blanks */
4581  while (*line && isspace((unsigned char) line[0]))
4582  line++;
4583 
4584  /* ignore comments and empty lines */
4585  if (strlen(line) == 0 || line[0] == '#')
4586  continue;
4587 
4588  /* Check for right groupname */
4589  if (line[0] == '[')
4590  {
4591  if (*group_found)
4592  {
4593  /* group info already read */
4594  fclose(f);
4595  return 0;
4596  }
4597 
4598  if (strncmp(line + 1, service, strlen(service)) == 0 &&
4599  line[strlen(service) + 1] == ']')
4600  *group_found = true;
4601  else
4602  *group_found = false;
4603  }
4604  else
4605  {
4606  if (*group_found)
4607  {
4608  /*
4609  * Finally, we are in the right group and can parse the line
4610  */
4611  char *key,
4612  *val;
4613  bool found_keyword;
4614 
4615 #ifdef USE_LDAP
4616  if (strncmp(line, "ldap", 4) == 0)
4617  {
4618  int rc = ldapServiceLookup(line, options, errorMessage);
4619 
4620  /* if rc = 2, go on reading for fallback */
4621  switch (rc)
4622  {
4623  case 0:
4624  fclose(f);
4625  return 0;
4626  case 1:
4627  case 3:
4628  fclose(f);
4629  return 3;
4630  case 2:
4631  continue;
4632  }
4633  }
4634 #endif
4635 
4636  key = line;
4637  val = strchr(line, '=');
4638  if (val == NULL)
4639  {
4640  printfPQExpBuffer(errorMessage,
4641  libpq_gettext("syntax error in service file \"%s\", line %d\n"),
4642  serviceFile,
4643  linenr);
4644  fclose(f);
4645  return 3;
4646  }
4647  *val++ = '\0';
4648 
4649  if (strcmp(key, "service") == 0)
4650  {
4651  printfPQExpBuffer(errorMessage,
4652  libpq_gettext("nested service specifications not supported in service file \"%s\", line %d\n"),
4653  serviceFile,
4654  linenr);
4655  fclose(f);
4656  return 3;
4657  }
4658 
4659  /*
4660  * Set the parameter --- but don't override any previous
4661  * explicit setting.
4662  */
4663  found_keyword = false;
4664  for (i = 0; options[i].keyword; i++)
4665  {
4666  if (strcmp(options[i].keyword, key) == 0)
4667  {
4668  if (options[i].val == NULL)
4669  options[i].val = strdup(val);
4670  if (!options[i].val)
4671  {
4672  printfPQExpBuffer(errorMessage,
4673  libpq_gettext("out of memory\n"));
4674  fclose(f);
4675  return 3;
4676  }
4677  found_keyword = true;
4678  break;
4679  }
4680  }
4681 
4682  if (!found_keyword)
4683  {
4684  printfPQExpBuffer(errorMessage,
4685  libpq_gettext("syntax error in service file \"%s\", line %d\n"),
4686  serviceFile,
4687  linenr);
4688  fclose(f);
4689  return 3;
4690  }
4691  }
4692  }
4693  }
4694 
4695  fclose(f);
4696 
4697  return 0;
4698 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define MAXBUFSIZE
Definition: fe-connect.c:4470
static char * buf
Definition: pg_test_fsync.c:66
#define NULL
Definition: c.h:229
int i
long val
Definition: informix.c:689
#define libpq_gettext(x)
Definition: libpq-int.h:682
static int parseServiceInfo ( PQconninfoOption options,
PQExpBuffer  errorMessage 
)
static

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

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

Referenced by conninfo_add_defaults().

4474 {
4475  const char *service = conninfo_getval(options, "service");
4476  char serviceFile[MAXPGPATH];
4477  char *env;
4478  bool group_found = false;
4479  int status;
4480  struct stat stat_buf;
4481 
4482  /*
4483  * We have to special-case the environment variable PGSERVICE here, since
4484  * this is and should be called before inserting environment defaults for
4485  * other connection options.
4486  */
4487  if (service == NULL)
4488  service = getenv("PGSERVICE");
4489 
4490  if (service == NULL)
4491  return 0;
4492 
4493  if ((env = getenv("PGSERVICEFILE")) != NULL)
4494  strlcpy(serviceFile, env, sizeof(serviceFile));
4495  else
4496  {
4497  char homedir[MAXPGPATH];
4498 
4499  if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
4500  {
4501  printfPQExpBuffer(errorMessage, libpq_gettext("could not get home directory to locate service definition file"));
4502  return 1;
4503  }
4504  snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
4505  errno = 0;
4506  if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4507  goto next_file;
4508  }
4509 
4510  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4511  if (group_found || status != 0)
4512  return status;
4513 
4514 next_file:
4515 
4516  /*
4517  * This could be used by any application so we can't use the binary
4518  * location to find our config files.
4519  */
4520  snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
4521  getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
4522  errno = 0;
4523  if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4524  goto last_file;
4525 
4526  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4527  if (status != 0)
4528  return status;
4529 
4530 last_file:
4531  if (!group_found)
4532  {
4533  printfPQExpBuffer(errorMessage,
4534  libpq_gettext("definition of service \"%s\" not found\n"), service);
4535  return 3;
4536  }
4537 
4538  return 0;
4539 }
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:4542
static const char * conninfo_getval(PQconninfoOption *connOptions, const char *keyword)
Definition: fe-connect.c:5797
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:6516
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:682
static char * passwordFromFile ( char *  hostname,
char *  port,
char *  dbname,
char *  username,
char *  pgpassfile 
)
static

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

6362 {
6363  FILE *fp;
6364  struct stat stat_buf;
6365 
6366 #define LINELEN NAMEDATALEN*5
6367  char buf[LINELEN];
6368 
6369  if (dbname == NULL || strlen(dbname) == 0)
6370  return NULL;
6371 
6372  if (username == NULL || strlen(username) == 0)
6373  return NULL;
6374 
6375  /* 'localhost' matches pghost of '' or the default socket directory */
6376  if (hostname == NULL)
6378  else if (is_absolute_path(hostname))
6379 
6380  /*
6381  * We should probably use canonicalize_path(), but then we have to
6382  * bring path.c into libpq, and it doesn't seem worth it.
6383  */
6384  if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
6386 
6387  if (port == NULL)
6388  port = DEF_PGPORT_STR;
6389 
6390  /* If password file cannot be opened, ignore it. */
6391  if (stat(pgpassfile, &stat_buf) != 0)
6392  return NULL;
6393 
6394 #ifndef WIN32
6395  if (!S_ISREG(stat_buf.st_mode))
6396  {
6397  fprintf(stderr,
6398  libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
6399  pgpassfile);
6400  return NULL;
6401  }
6402 
6403  /* If password file is insecure, alert the user and ignore it. */
6404  if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
6405  {
6406  fprintf(stderr,
6407  libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
6408  pgpassfile);
6409  return NULL;
6410  }
6411 #else
6412 
6413  /*
6414  * On Win32, the directory is protected, so we don't have to check the
6415  * file.
6416  */
6417 #endif
6418 
6419  fp = fopen(pgpassfile, "r");
6420  if (fp == NULL)
6421  return NULL;
6422 
6423  while (!feof(fp) && !ferror(fp))
6424  {
6425  char *t = buf,
6426  *ret,
6427  *p1,
6428  *p2;
6429  int len;
6430 
6431  if (fgets(buf, sizeof(buf), fp) == NULL)
6432  break;
6433 
6434  len = strlen(buf);
6435 
6436  /* Remove trailing newline */
6437  if (len > 0 && buf[len - 1] == '\n')
6438  {
6439  buf[--len] = '\0';
6440  /* Handle DOS-style line endings, too, even when not on Windows */
6441  if (len > 0 && buf[len - 1] == '\r')
6442  buf[--len] = '\0';
6443  }
6444 
6445  if (len == 0)
6446  continue;
6447 
6448  if ((t = pwdfMatchesString(t, hostname)) == NULL ||
6449  (t = pwdfMatchesString(t, port)) == NULL ||
6450  (t = pwdfMatchesString(t, dbname)) == NULL ||
6451  (t = pwdfMatchesString(t, username)) == NULL)
6452  continue;
6453 
6454  /* Found a match. */
6455  ret = strdup(t);
6456  fclose(fp);
6457 
6458  if (!ret)
6459  {
6460  /* Out of memory. XXX: an error message would be nice. */
6461  return NULL;
6462  }
6463 
6464  /* De-escape password. */
6465  for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
6466  {
6467  if (*p1 == '\\' && p1[1] != '\0')
6468  ++p1;
6469  *p2 = *p1;
6470  }
6471  *p2 = '\0';
6472 
6473  return ret;
6474  }
6475 
6476  fclose(fp);
6477  return NULL;
6478 
6479 #undef LINELEN
6480 }
#define LINELEN
struct stat stat_buf
Definition: pg_standby.c:101
static char * buf
Definition: pg_test_fsync.c:66
#define is_absolute_path(filename)
Definition: port.h:77
static int port
Definition: pg_regress.c:89
#define S_IRWXO
Definition: win32.h:455
static char * username
Definition: initdb.c:131
#define NULL
Definition: c.h:229
char * dbname
Definition: streamutil.c:39
#define DefaultHost
Definition: fe-connect.c:120
#define S_IRWXG
Definition: win32.h:451
static char * hostname
Definition: pg_regress.c:88
static char * pwdfMatchesString(char *buf, char *token)
Definition: fe-connect.c:6323
#define libpq_gettext(x)
Definition: libpq-int.h:682
#define DEFAULT_PGSOCKET_DIR
static void pgpassfileWarning ( PGconn conn)
static

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

6489 {
6490  /* If it was 'invalid authorization', add pgpassfile mention */
6491  /* only works with >= 9.0 servers */
6492  if (conn->pgpassfile_used && conn->password_needed && conn->result)
6493  {
6494  const char *sqlstate = PQresultErrorField(conn->result,
6496 
6497  if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
6499  libpq_gettext("password retrieved from file \"%s\"\n"),
6500  conn->pgpassfile);
6501  }
6502 }
char * pgpassfile
Definition: libpq-int.h:345
bool password_needed
Definition: libpq-int.h:407
bool pgpassfile_used
Definition: libpq-int.h:408
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
PGresult * result
Definition: libpq-int.h:450
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
PQExpBufferData errorMessage
Definition: libpq-int.h:491
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2658
#define ERRCODE_INVALID_PASSWORD
Definition: fe-connect.c:93
#define libpq_gettext(x)
Definition: libpq-int.h:682
int PQbackendPID ( const PGconn conn)

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

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

Referenced by get_prompt(), and LogStreamerMain().

6124 {
6125  if (!conn || conn->status != CONNECTION_OK)
6126  return 0;
6127  return conn->be_pid;
6128 }
ConnStatusType status
Definition: libpq-int.h:379
int be_pid
Definition: libpq-int.h:419
int PQcancel ( PGcancel cancel,
char *  errbuf,
int  errbufsize 
)

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

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

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

3907 {
3908  if (!cancel)
3909  {
3910  strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
3911  return FALSE;
3912  }
3913 
3914  return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
3915  errbuf, errbufsize);
3916 }
static int internal_cancel(SockAddr *raddr, int be_pid, int be_key, char *errbuf, int errbufsize)
Definition: fe-connect.c:3802
int be_pid
Definition: libpq-int.h:504
#define FALSE
Definition: c.h:221
int be_key
Definition: libpq-int.h:505
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
SockAddr raddr
Definition: libpq-int.h:503
int PQclientEncoding ( const PGconn conn)

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

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

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

6158 {
6159  if (!conn || conn->status != CONNECTION_OK)
6160  return -1;
6161  return conn->client_encoding;
6162 }
ConnStatusType status
Definition: libpq-int.h:379
int client_encoding
Definition: libpq-int.h:422
PQconninfoOption* PQconndefaults ( void  )

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

1225 {
1226  PQExpBufferData errorBuf;
1227  PQconninfoOption *connOptions;
1228 
1229  /* We don't actually report any errors here, but callees want a buffer */
1230  initPQExpBuffer(&errorBuf);
1231  if (PQExpBufferDataBroken(errorBuf))
1232  return NULL; /* out of memory already :-( */
1233 
1234  connOptions = conninfo_init(&errorBuf);
1235  if (connOptions != NULL)
1236  {
1237  /* pass NULL errorBuf to ignore errors */
1238  if (!conninfo_add_defaults(connOptions, NULL))
1239  {
1240  PQconninfoFree(connOptions);
1241  connOptions = NULL;
1242  }
1243  }
1244 
1245  termPQExpBuffer(&errorBuf);
1246  return connOptions;
1247 }
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:4739
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5947
#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:5175
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGconn* PQconnectdb ( const char *  conninfo)

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

586 {
587  PGconn *conn = PQconnectStart(conninfo);
588 
589  if (conn && conn->status != CONNECTION_BAD)
590  (void) connectDBComplete(conn);
591 
592  return conn;
593 }
PGconn * conn
Definition: streamutil.c:43
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1835
PGconn * PQconnectStart(const char *conninfo)
Definition: fe-connect.c:711
ConnStatusType status
Definition: libpq-int.h:379
PGconn* PQconnectdbParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)

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

532 {
533  PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
534 
535  if (conn && conn->status != CONNECTION_BAD)
536  (void) connectDBComplete(conn);
537 
538  return conn;
539 
540 }
PGconn * conn
Definition: streamutil.c:43
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:1835
ConnStatusType status
Definition: libpq-int.h:379
static Datum values[MAXATTR]
Definition: bootstrap.c:163
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:632
int PQconnectionNeedsPassword ( const PGconn conn)

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

6132 {
6133  char *password;
6134 
6135  if (!conn)
6136  return false;
6137  password = PQpass(conn);
6138  if (conn->password_needed &&
6139  (password == NULL || password[0] == '\0'))
6140  return true;
6141  else
6142  return false;
6143 }
static char password[100]
Definition: streamutil.c:42
bool password_needed
Definition: libpq-int.h:407
char * PQpass(const PGconn *conn)
Definition: fe-connect.c:5981
#define NULL
Definition: c.h:229
int PQconnectionUsedPassword ( const PGconn conn)

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

References pg_conn::password_needed.

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

6147 {
6148  if (!conn)
6149  return false;
6150  if (conn->password_needed)
6151  return true;
6152  else
6153  return false;
6154 }
bool password_needed
Definition: libpq-int.h:407
PostgresPollingStatusType PQconnectPoll ( PGconn conn)

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

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

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

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