LCOV - code coverage report
Current view: top level - src/interfaces/libpq - fe-connect.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 1241 2518 49.3 %
Date: 2020-06-01 00:06:26 Functions: 83 102 81.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * fe-connect.c
       4             :  *    functions related to setting up a connection to the backend
       5             :  *
       6             :  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/interfaces/libpq/fe-connect.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : 
      16             : #include "postgres_fe.h"
      17             : 
      18             : #include <sys/stat.h>
      19             : #include <fcntl.h>
      20             : #include <ctype.h>
      21             : #include <time.h>
      22             : #include <unistd.h>
      23             : 
      24             : #include "common/ip.h"
      25             : #include "common/link-canary.h"
      26             : #include "common/scram-common.h"
      27             : #include "common/string.h"
      28             : #include "fe-auth.h"
      29             : #include "libpq-fe.h"
      30             : #include "libpq-int.h"
      31             : #include "mb/pg_wchar.h"
      32             : #include "pg_config_paths.h"
      33             : #include "port/pg_bswap.h"
      34             : 
      35             : #ifdef WIN32
      36             : #include "win32.h"
      37             : #ifdef _WIN32_IE
      38             : #undef _WIN32_IE
      39             : #endif
      40             : #define _WIN32_IE 0x0500
      41             : #ifdef near
      42             : #undef near
      43             : #endif
      44             : #define near
      45             : #include <shlobj.h>
      46             : #ifdef _MSC_VER                 /* mstcpip.h is missing on mingw */
      47             : #include <mstcpip.h>
      48             : #endif
      49             : #else
      50             : #include <sys/socket.h>
      51             : #include <netdb.h>
      52             : #include <netinet/in.h>
      53             : #ifdef HAVE_NETINET_TCP_H
      54             : #include <netinet/tcp.h>
      55             : #endif
      56             : #endif
      57             : 
      58             : #ifdef ENABLE_THREAD_SAFETY
      59             : #ifdef WIN32
      60             : #include "pthread-win32.h"
      61             : #else
      62             : #include <pthread.h>
      63             : #endif
      64             : #endif
      65             : 
      66             : #ifdef USE_LDAP
      67             : #ifdef WIN32
      68             : #include <winldap.h>
      69             : #else
      70             : /* OpenLDAP deprecates RFC 1823, but we want standard conformance */
      71             : #define LDAP_DEPRECATED 1
      72             : #include <ldap.h>
      73             : typedef struct timeval LDAP_TIMEVAL;
      74             : #endif
      75             : static int  ldapServiceLookup(const char *purl, PQconninfoOption *options,
      76             :                               PQExpBuffer errorMessage);
      77             : #endif
      78             : 
      79             : #ifndef WIN32
      80             : #define PGPASSFILE ".pgpass"
      81             : #else
      82             : #define PGPASSFILE "pgpass.conf"
      83             : #endif
      84             : 
      85             : /*
      86             :  * Pre-9.0 servers will return this SQLSTATE if asked to set
      87             :  * application_name in a startup packet.  We hard-wire the value rather
      88             :  * than looking into errcodes.h since it reflects historical behavior
      89             :  * rather than that of the current code.
      90             :  */
      91             : #define ERRCODE_APPNAME_UNKNOWN "42704"
      92             : 
      93             : /* This is part of the protocol so just define it */
      94             : #define ERRCODE_INVALID_PASSWORD "28P01"
      95             : /* This too */
      96             : #define ERRCODE_CANNOT_CONNECT_NOW "57P03"
      97             : 
      98             : /*
      99             :  * Cope with the various platform-specific ways to spell TCP keepalive socket
     100             :  * options.  This doesn't cover Windows, which as usual does its own thing.
     101             :  */
     102             : #if defined(TCP_KEEPIDLE)
     103             : /* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
     104             : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPIDLE
     105             : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPIDLE"
     106             : #elif defined(TCP_KEEPALIVE_THRESHOLD)
     107             : /* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris >= 11 */
     108             : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE_THRESHOLD
     109             : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE_THRESHOLD"
     110             : #elif defined(TCP_KEEPALIVE) && defined(__darwin__)
     111             : /* TCP_KEEPALIVE is the name of this option on macOS */
     112             : /* Caution: Solaris has this symbol but it means something different */
     113             : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE
     114             : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE"
     115             : #endif
     116             : 
     117             : /*
     118             :  * fall back options if they are not specified by arguments or defined
     119             :  * by environment variables
     120             :  */
     121             : #define DefaultHost     "localhost"
     122             : #define DefaultTty      ""
     123             : #define DefaultOption   ""
     124             : #define DefaultAuthtype       ""
     125             : #ifdef USE_SSL
     126             : #define DefaultChannelBinding   "prefer"
     127             : #else
     128             : #define DefaultChannelBinding   "disable"
     129             : #endif
     130             : #define DefaultTargetSessionAttrs   "any"
     131             : #ifdef USE_SSL
     132             : #define DefaultSSLMode "prefer"
     133             : #else
     134             : #define DefaultSSLMode  "disable"
     135             : #endif
     136             : #ifdef ENABLE_GSS
     137             : #include "fe-gssapi-common.h"
     138             : #define DefaultGSSMode "prefer"
     139             : #else
     140             : #define DefaultGSSMode "disable"
     141             : #endif
     142             : 
     143             : /* ----------
     144             :  * Definition of the conninfo parameters and their fallback resources.
     145             :  *
     146             :  * If Environment-Var and Compiled-in are specified as NULL, no
     147             :  * fallback is available. If after all no value can be determined
     148             :  * for an option, an error is returned.
     149             :  *
     150             :  * The value for the username is treated specially in conninfo_add_defaults.
     151             :  * If the value is not obtained any other way, the username is determined
     152             :  * by pg_fe_getauthname().
     153             :  *
     154             :  * The Label and Disp-Char entries are provided for applications that
     155             :  * want to use PQconndefaults() to create a generic database connection
     156             :  * dialog. Disp-Char is defined as follows:
     157             :  *      ""        Normal input field
     158             :  *      "*"       Password field - hide value
     159             :  *      "D"       Debug option - don't show by default
     160             :  *
     161             :  * PQconninfoOptions[] is a constant static array that we use to initialize
     162             :  * a dynamically allocated working copy.  All the "val" fields in
     163             :  * PQconninfoOptions[] *must* be NULL.  In a working copy, non-null "val"
     164             :  * fields point to malloc'd strings that should be freed when the working
     165             :  * array is freed (see PQconninfoFree).
     166             :  *
     167             :  * The first part of each struct is identical to the one in libpq-fe.h,
     168             :  * which is required since we memcpy() data between the two!
     169             :  * ----------
     170             :  */
     171             : typedef struct _internalPQconninfoOption
     172             : {
     173             :     char       *keyword;        /* The keyword of the option            */
     174             :     char       *envvar;         /* Fallback environment variable name   */
     175             :     char       *compiled;       /* Fallback compiled in default value   */
     176             :     char       *val;            /* Option's current value, or NULL      */
     177             :     char       *label;          /* Label for field in connect dialog    */
     178             :     char       *dispchar;       /* Indicates how to display this field in a
     179             :                                  * connect dialog. Values are: "" Display
     180             :                                  * entered value as is "*" Password field -
     181             :                                  * hide value "D"  Debug option - don't show
     182             :                                  * by default */
     183             :     int         dispsize;       /* Field size in characters for dialog  */
     184             :     /* ---
     185             :      * Anything above this comment must be synchronized with
     186             :      * PQconninfoOption in libpq-fe.h, since we memcpy() data
     187             :      * between them!
     188             :      * ---
     189             :      */
     190             :     off_t       connofs;        /* Offset into PGconn struct, -1 if not there */
     191             : } internalPQconninfoOption;
     192             : 
     193             : static const internalPQconninfoOption PQconninfoOptions[] = {
     194             :     /*
     195             :      * "authtype" is no longer used, so mark it "don't show".  We keep it in
     196             :      * the array so as not to reject conninfo strings from old apps that might
     197             :      * still try to set it.
     198             :      */
     199             :     {"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
     200             :     "Database-Authtype", "D", 20, -1},
     201             : 
     202             :     {"service", "PGSERVICE", NULL, NULL,
     203             :     "Database-Service", "", 20, -1},
     204             : 
     205             :     {"user", "PGUSER", NULL, NULL,
     206             :         "Database-User", "", 20,
     207             :     offsetof(struct pg_conn, pguser)},
     208             : 
     209             :     {"password", "PGPASSWORD", NULL, NULL,
     210             :         "Database-Password", "*", 20,
     211             :     offsetof(struct pg_conn, pgpass)},
     212             : 
     213             :     {"passfile", "PGPASSFILE", NULL, NULL,
     214             :         "Database-Password-File", "", 64,
     215             :     offsetof(struct pg_conn, pgpassfile)},
     216             : 
     217             :     {"channel_binding", "PGCHANNELBINDING", NULL, NULL,
     218             :         "Channel-Binding", "", 8,   /* sizeof("require") == 8 */
     219             :     offsetof(struct pg_conn, channel_binding)},
     220             : 
     221             :     {"connect_timeout", "PGCONNECT_TIMEOUT", NULL, NULL,
     222             :         "Connect-timeout", "", 10,  /* strlen(INT32_MAX) == 10 */
     223             :     offsetof(struct pg_conn, connect_timeout)},
     224             : 
     225             :     {"dbname", "PGDATABASE", NULL, NULL,
     226             :         "Database-Name", "", 20,
     227             :     offsetof(struct pg_conn, dbName)},
     228             : 
     229             :     {"host", "PGHOST", NULL, NULL,
     230             :         "Database-Host", "", 40,
     231             :     offsetof(struct pg_conn, pghost)},
     232             : 
     233             :     {"hostaddr", "PGHOSTADDR", NULL, NULL,
     234             :         "Database-Host-IP-Address", "", 45,
     235             :     offsetof(struct pg_conn, pghostaddr)},
     236             : 
     237             :     {"port", "PGPORT", DEF_PGPORT_STR, NULL,
     238             :         "Database-Port", "", 6,
     239             :     offsetof(struct pg_conn, pgport)},
     240             : 
     241             :     {"client_encoding", "PGCLIENTENCODING", NULL, NULL,
     242             :         "Client-Encoding", "", 10,
     243             :     offsetof(struct pg_conn, client_encoding_initial)},
     244             : 
     245             :     /*
     246             :      * "tty" is no longer used either, but keep it present for backwards
     247             :      * compatibility.
     248             :      */
     249             :     {"tty", "PGTTY", DefaultTty, NULL,
     250             :         "Backend-Debug-TTY", "D", 40,
     251             :     offsetof(struct pg_conn, pgtty)},
     252             : 
     253             :     {"options", "PGOPTIONS", DefaultOption, NULL,
     254             :         "Backend-Options", "", 40,
     255             :     offsetof(struct pg_conn, pgoptions)},
     256             : 
     257             :     {"application_name", "PGAPPNAME", NULL, NULL,
     258             :         "Application-Name", "", 64,
     259             :     offsetof(struct pg_conn, appname)},
     260             : 
     261             :     {"fallback_application_name", NULL, NULL, NULL,
     262             :         "Fallback-Application-Name", "", 64,
     263             :     offsetof(struct pg_conn, fbappname)},
     264             : 
     265             :     {"keepalives", NULL, NULL, NULL,
     266             :         "TCP-Keepalives", "", 1,    /* should be just '0' or '1' */
     267             :     offsetof(struct pg_conn, keepalives)},
     268             : 
     269             :     {"keepalives_idle", NULL, NULL, NULL,
     270             :         "TCP-Keepalives-Idle", "", 10,  /* strlen(INT32_MAX) == 10 */
     271             :     offsetof(struct pg_conn, keepalives_idle)},
     272             : 
     273             :     {"keepalives_interval", NULL, NULL, NULL,
     274             :         "TCP-Keepalives-Interval", "", 10,  /* strlen(INT32_MAX) == 10 */
     275             :     offsetof(struct pg_conn, keepalives_interval)},
     276             : 
     277             :     {"keepalives_count", NULL, NULL, NULL,
     278             :         "TCP-Keepalives-Count", "", 10, /* strlen(INT32_MAX) == 10 */
     279             :     offsetof(struct pg_conn, keepalives_count)},
     280             : 
     281             :     {"tcp_user_timeout", NULL, NULL, NULL,
     282             :         "TCP-User-Timeout", "", 10, /* strlen(INT32_MAX) == 10 */
     283             :     offsetof(struct pg_conn, pgtcp_user_timeout)},
     284             : 
     285             :     /*
     286             :      * ssl options are allowed even without client SSL support because the
     287             :      * client can still handle SSL modes "disable" and "allow". Other
     288             :      * parameters have no effect on non-SSL connections, so there is no reason
     289             :      * to exclude them since none of them are mandatory.
     290             :      */
     291             :     {"sslmode", "PGSSLMODE", DefaultSSLMode, NULL,
     292             :         "SSL-Mode", "", 12,     /* sizeof("verify-full") == 12 */
     293             :     offsetof(struct pg_conn, sslmode)},
     294             : 
     295             :     {"sslcompression", "PGSSLCOMPRESSION", "0", NULL,
     296             :         "SSL-Compression", "", 1,
     297             :     offsetof(struct pg_conn, sslcompression)},
     298             : 
     299             :     {"sslcert", "PGSSLCERT", NULL, NULL,
     300             :         "SSL-Client-Cert", "", 64,
     301             :     offsetof(struct pg_conn, sslcert)},
     302             : 
     303             :     {"sslkey", "PGSSLKEY", NULL, NULL,
     304             :         "SSL-Client-Key", "", 64,
     305             :     offsetof(struct pg_conn, sslkey)},
     306             : 
     307             :     {"sslpassword", NULL, NULL, NULL,
     308             :         "SSL-Client-Key-Password", "*", 20,
     309             :     offsetof(struct pg_conn, sslpassword)},
     310             : 
     311             :     {"sslrootcert", "PGSSLROOTCERT", NULL, NULL,
     312             :         "SSL-Root-Certificate", "", 64,
     313             :     offsetof(struct pg_conn, sslrootcert)},
     314             : 
     315             :     {"sslcrl", "PGSSLCRL", NULL, NULL,
     316             :         "SSL-Revocation-List", "", 64,
     317             :     offsetof(struct pg_conn, sslcrl)},
     318             : 
     319             :     {"requirepeer", "PGREQUIREPEER", NULL, NULL,
     320             :         "Require-Peer", "", 10,
     321             :     offsetof(struct pg_conn, requirepeer)},
     322             : 
     323             :     {"ssl_min_protocol_version", "PGSSLMINPROTOCOLVERSION", NULL, NULL,
     324             :         "SSL-Minimum-Protocol-Version", "", 8,  /* sizeof("TLSv1.x") == 8 */
     325             :     offsetof(struct pg_conn, ssl_min_protocol_version)},
     326             : 
     327             :     {"ssl_max_protocol_version", "PGSSLMAXPROTOCOLVERSION", NULL, NULL,
     328             :         "SSL-Maximum-Protocol-Version", "", 8,  /* sizeof("TLSv1.x") == 8 */
     329             :     offsetof(struct pg_conn, ssl_max_protocol_version)},
     330             : 
     331             :     /*
     332             :      * As with SSL, all GSS options are exposed even in builds that don't have
     333             :      * support.
     334             :      */
     335             :     {"gssencmode", "PGGSSENCMODE", DefaultGSSMode, NULL,
     336             :         "GSSENC-Mode", "", 8,   /* sizeof("disable") == 8 */
     337             :     offsetof(struct pg_conn, gssencmode)},
     338             : 
     339             :     /* Kerberos and GSSAPI authentication support specifying the service name */
     340             :     {"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
     341             :         "Kerberos-service-name", "", 20,
     342             :     offsetof(struct pg_conn, krbsrvname)},
     343             : 
     344             :     {"gsslib", "PGGSSLIB", NULL, NULL,
     345             :         "GSS-library", "", 7,   /* sizeof("gssapi") == 7 */
     346             :     offsetof(struct pg_conn, gsslib)},
     347             : 
     348             :     {"replication", NULL, NULL, NULL,
     349             :         "Replication", "D", 5,
     350             :     offsetof(struct pg_conn, replication)},
     351             : 
     352             :     {"target_session_attrs", "PGTARGETSESSIONATTRS",
     353             :         DefaultTargetSessionAttrs, NULL,
     354             :         "Target-Session-Attrs", "", 11, /* sizeof("read-write") = 11 */
     355             :     offsetof(struct pg_conn, target_session_attrs)},
     356             : 
     357             :     /* Terminating entry --- MUST BE LAST */
     358             :     {NULL, NULL, NULL, NULL,
     359             :     NULL, NULL, 0}
     360             : };
     361             : 
     362             : static const PQEnvironmentOption EnvironmentOptions[] =
     363             : {
     364             :     /* common user-interface settings */
     365             :     {
     366             :         "PGDATESTYLE", "datestyle"
     367             :     },
     368             :     {
     369             :         "PGTZ", "timezone"
     370             :     },
     371             :     /* internal performance-related settings */
     372             :     {
     373             :         "PGGEQO", "geqo"
     374             :     },
     375             :     {
     376             :         NULL, NULL
     377             :     }
     378             : };
     379             : 
     380             : /* The connection URI must start with either of the following designators: */
     381             : static const char uri_designator[] = "postgresql://";
     382             : static const char short_uri_designator[] = "postgres://";
     383             : 
     384             : static bool connectOptions1(PGconn *conn, const char *conninfo);
     385             : static bool connectOptions2(PGconn *conn);
     386             : static int  connectDBStart(PGconn *conn);
     387             : static int  connectDBComplete(PGconn *conn);
     388             : static PGPing internal_ping(PGconn *conn);
     389             : static PGconn *makeEmptyPGconn(void);
     390             : static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions);
     391             : static void freePGconn(PGconn *conn);
     392             : static void closePGconn(PGconn *conn);
     393             : static void release_conn_addrinfo(PGconn *conn);
     394             : static void sendTerminateConn(PGconn *conn);
     395             : static PQconninfoOption *conninfo_init(PQExpBuffer errorMessage);
     396             : static PQconninfoOption *parse_connection_string(const char *conninfo,
     397             :                                                  PQExpBuffer errorMessage, bool use_defaults);
     398             : static int  uri_prefix_length(const char *connstr);
     399             : static bool recognized_connection_string(const char *connstr);
     400             : static PQconninfoOption *conninfo_parse(const char *conninfo,
     401             :                                         PQExpBuffer errorMessage, bool use_defaults);
     402             : static PQconninfoOption *conninfo_array_parse(const char *const *keywords,
     403             :                                               const char *const *values, PQExpBuffer errorMessage,
     404             :                                               bool use_defaults, int expand_dbname);
     405             : static bool conninfo_add_defaults(PQconninfoOption *options,
     406             :                                   PQExpBuffer errorMessage);
     407             : static PQconninfoOption *conninfo_uri_parse(const char *uri,
     408             :                                             PQExpBuffer errorMessage, bool use_defaults);
     409             : static bool conninfo_uri_parse_options(PQconninfoOption *options,
     410             :                                        const char *uri, PQExpBuffer errorMessage);
     411             : static bool conninfo_uri_parse_params(char *params,
     412             :                                       PQconninfoOption *connOptions,
     413             :                                       PQExpBuffer errorMessage);
     414             : static char *conninfo_uri_decode(const char *str, PQExpBuffer errorMessage);
     415             : static bool get_hexdigit(char digit, int *value);
     416             : static const char *conninfo_getval(PQconninfoOption *connOptions,
     417             :                                    const char *keyword);
     418             : static PQconninfoOption *conninfo_storeval(PQconninfoOption *connOptions,
     419             :                                            const char *keyword, const char *value,
     420             :                                            PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode);
     421             : static PQconninfoOption *conninfo_find(PQconninfoOption *connOptions,
     422             :                                        const char *keyword);
     423             : static void defaultNoticeReceiver(void *arg, const PGresult *res);
     424             : static void defaultNoticeProcessor(void *arg, const char *message);
     425             : static int  parseServiceInfo(PQconninfoOption *options,
     426             :                              PQExpBuffer errorMessage);
     427             : static int  parseServiceFile(const char *serviceFile,
     428             :                              const char *service,
     429             :                              PQconninfoOption *options,
     430             :                              PQExpBuffer errorMessage,
     431             :                              bool *group_found);
     432             : static char *pwdfMatchesString(char *buf, const char *token);
     433             : static char *passwordFromFile(const char *hostname, const char *port, const char *dbname,
     434             :                               const char *username, const char *pgpassfile);
     435             : static void pgpassfileWarning(PGconn *conn);
     436             : static void default_threadlock(int acquire);
     437             : static bool sslVerifyProtocolVersion(const char *version);
     438             : static bool sslVerifyProtocolRange(const char *min, const char *max);
     439             : 
     440             : 
     441             : /* global variable because fe-auth.c needs to access it */
     442             : pgthreadlock_t pg_g_threadlock = default_threadlock;
     443             : 
     444             : 
     445             : /*
     446             :  *      pqDropConnection
     447             :  *
     448             :  * Close any physical connection to the server, and reset associated
     449             :  * state inside the connection object.  We don't release state that
     450             :  * would be needed to reconnect, though, nor local state that might still
     451             :  * be useful later.
     452             :  *
     453             :  * We can always flush the output buffer, since there's no longer any hope
     454             :  * of sending that data.  However, unprocessed input data might still be
     455             :  * valuable, so the caller must tell us whether to flush that or not.
     456             :  */
     457             : void
     458       17464 : pqDropConnection(PGconn *conn, bool flushInput)
     459             : {
     460             :     /* Drop any SSL state */
     461       17464 :     pqsecure_close(conn);
     462             : 
     463             :     /* Close the socket itself */
     464       17464 :     if (conn->sock != PGINVALID_SOCKET)
     465        8456 :         closesocket(conn->sock);
     466       17464 :     conn->sock = PGINVALID_SOCKET;
     467             : 
     468             :     /* Optionally discard any unread data */
     469       17464 :     if (flushInput)
     470       17358 :         conn->inStart = conn->inCursor = conn->inEnd = 0;
     471             : 
     472             :     /* Always discard any unsent data */
     473       17464 :     conn->outCount = 0;
     474             : 
     475             :     /* Free authentication/encryption state */
     476             : #ifdef ENABLE_GSS
     477             :     {
     478             :         OM_uint32   min_s;
     479             : 
     480             :         if (conn->gctx)
     481             :             gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
     482             :         if (conn->gtarg_nam)
     483             :             gss_release_name(&min_s, &conn->gtarg_nam);
     484             :         if (conn->gss_SendBuffer)
     485             :         {
     486             :             free(conn->gss_SendBuffer);
     487             :             conn->gss_SendBuffer = NULL;
     488             :         }
     489             :         if (conn->gss_RecvBuffer)
     490             :         {
     491             :             free(conn->gss_RecvBuffer);
     492             :             conn->gss_RecvBuffer = NULL;
     493             :         }
     494             :         if (conn->gss_ResultBuffer)
     495             :         {
     496             :             free(conn->gss_ResultBuffer);
     497             :             conn->gss_ResultBuffer = NULL;
     498             :         }
     499             :     }
     500             : #endif
     501             : #ifdef ENABLE_SSPI
     502             :     if (conn->sspitarget)
     503             :     {
     504             :         free(conn->sspitarget);
     505             :         conn->sspitarget = NULL;
     506             :     }
     507             :     if (conn->sspicred)
     508             :     {
     509             :         FreeCredentialsHandle(conn->sspicred);
     510             :         free(conn->sspicred);
     511             :         conn->sspicred = NULL;
     512             :     }
     513             :     if (conn->sspictx)
     514             :     {
     515             :         DeleteSecurityContext(conn->sspictx);
     516             :         free(conn->sspictx);
     517             :         conn->sspictx = NULL;
     518             :     }
     519             :     conn->usesspi = 0;
     520             : #endif
     521       17464 :     if (conn->sasl_state)
     522             :     {
     523             :         /*
     524             :          * XXX: if support for more authentication mechanisms is added, this
     525             :          * needs to call the right 'free' function.
     526             :          */
     527          36 :         pg_fe_scram_free(conn->sasl_state);
     528          36 :         conn->sasl_state = NULL;
     529             :     }
     530       17464 : }
     531             : 
     532             : 
     533             : /*
     534             :  *      pqDropServerData
     535             :  *
     536             :  * Clear all connection state data that was received from (or deduced about)
     537             :  * the server.  This is essential to do between connection attempts to
     538             :  * different servers, else we may incorrectly hold over some data from the
     539             :  * old server.
     540             :  *
     541             :  * It would be better to merge this into pqDropConnection, perhaps, but
     542             :  * right now we cannot because that function is called immediately on
     543             :  * detection of connection loss (cf. pqReadData, for instance).  This data
     544             :  * should be kept until we are actually starting a new connection.
     545             :  */
     546             : static void
     547       17032 : pqDropServerData(PGconn *conn)
     548             : {
     549             :     PGnotify   *notify;
     550             :     pgParameterStatus *pstatus;
     551             : 
     552             :     /* Forget pending notifies */
     553       17032 :     notify = conn->notifyHead;
     554       17032 :     while (notify != NULL)
     555             :     {
     556           0 :         PGnotify   *prev = notify;
     557             : 
     558           0 :         notify = notify->next;
     559           0 :         free(prev);
     560             :     }
     561       17032 :     conn->notifyHead = conn->notifyTail = NULL;
     562             : 
     563             :     /* Reset ParameterStatus data, as well as variables deduced from it */
     564       17032 :     pstatus = conn->pstatus;
     565      104724 :     while (pstatus != NULL)
     566             :     {
     567       87692 :         pgParameterStatus *prev = pstatus;
     568             : 
     569       87692 :         pstatus = pstatus->next;
     570       87692 :         free(prev);
     571             :     }
     572       17032 :     conn->pstatus = NULL;
     573       17032 :     conn->client_encoding = PG_SQL_ASCII;
     574       17032 :     conn->std_strings = false;
     575       17032 :     conn->sversion = 0;
     576             : 
     577             :     /* Drop large-object lookup data */
     578       17032 :     if (conn->lobjfuncs)
     579          48 :         free(conn->lobjfuncs);
     580       17032 :     conn->lobjfuncs = NULL;
     581             : 
     582             :     /* Reset assorted other per-connection state */
     583       17032 :     conn->last_sqlstate[0] = '\0';
     584       17032 :     conn->auth_req_received = false;
     585       17032 :     conn->password_needed = false;
     586       17032 :     conn->write_failed = false;
     587       17032 :     if (conn->write_err_msg)
     588           2 :         free(conn->write_err_msg);
     589       17032 :     conn->write_err_msg = NULL;
     590       17032 :     conn->be_pid = 0;
     591       17032 :     conn->be_key = 0;
     592       17032 : }
     593             : 
     594             : 
     595             : /*
     596             :  *      Connecting to a Database
     597             :  *
     598             :  * There are now six different ways a user of this API can connect to the
     599             :  * database.  Two are not recommended for use in new code, because of their
     600             :  * lack of extensibility with respect to the passing of options to the
     601             :  * backend.  These are PQsetdb and PQsetdbLogin (the former now being a macro
     602             :  * to the latter).
     603             :  *
     604             :  * If it is desired to connect in a synchronous (blocking) manner, use the
     605             :  * function PQconnectdb or PQconnectdbParams. The former accepts a string of
     606             :  * option = value pairs (or a URI) which must be parsed; the latter takes two
     607             :  * NULL terminated arrays instead.
     608             :  *
     609             :  * To connect in an asynchronous (non-blocking) manner, use the functions
     610             :  * PQconnectStart or PQconnectStartParams (which differ in the same way as
     611             :  * PQconnectdb and PQconnectdbParams) and PQconnectPoll.
     612             :  *
     613             :  * Internally, the static functions connectDBStart, connectDBComplete
     614             :  * are part of the connection procedure.
     615             :  */
     616             : 
     617             : /*
     618             :  *      PQconnectdbParams
     619             :  *
     620             :  * establishes a connection to a postgres backend through the postmaster
     621             :  * using connection information in two arrays.
     622             :  *
     623             :  * The keywords array is defined as
     624             :  *
     625             :  *     const char *params[] = {"option1", "option2", NULL}
     626             :  *
     627             :  * The values array is defined as
     628             :  *
     629             :  *     const char *values[] = {"value1", "value2", NULL}
     630             :  *
     631             :  * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL
     632             :  * if a memory allocation failed.
     633             :  * If the status field of the connection returned is CONNECTION_BAD,
     634             :  * then some fields may be null'ed out instead of having valid values.
     635             :  *
     636             :  * You should call PQfinish (if conn is not NULL) regardless of whether this
     637             :  * call succeeded.
     638             :  */
     639             : PGconn *
     640        7408 : PQconnectdbParams(const char *const *keywords,
     641             :                   const char *const *values,
     642             :                   int expand_dbname)
     643             : {
     644        7408 :     PGconn     *conn = PQconnectStartParams(keywords, values, expand_dbname);
     645             : 
     646        7408 :     if (conn && conn->status != CONNECTION_BAD)
     647        7154 :         (void) connectDBComplete(conn);
     648             : 
     649        7408 :     return conn;
     650             : 
     651             : }
     652             : 
     653             : /*
     654             :  *      PQpingParams
     655             :  *
     656             :  * check server status, accepting parameters identical to PQconnectdbParams
     657             :  */
     658             : PGPing
     659           4 : PQpingParams(const char *const *keywords,
     660             :              const char *const *values,
     661             :              int expand_dbname)
     662             : {
     663           4 :     PGconn     *conn = PQconnectStartParams(keywords, values, expand_dbname);
     664             :     PGPing      ret;
     665             : 
     666           4 :     ret = internal_ping(conn);
     667           4 :     PQfinish(conn);
     668             : 
     669           4 :     return ret;
     670             : }
     671             : 
     672             : /*
     673             :  *      PQconnectdb
     674             :  *
     675             :  * establishes a connection to a postgres backend through the postmaster
     676             :  * using connection information in a string.
     677             :  *
     678             :  * The conninfo string is either a whitespace-separated list of
     679             :  *
     680             :  *     option = value
     681             :  *
     682             :  * definitions or a URI (refer to the documentation for details.) Value
     683             :  * might be a single value containing no whitespaces or a single quoted
     684             :  * string. If a single quote should appear anywhere in the value, it must be
     685             :  * escaped with a backslash like \'
     686             :  *
     687             :  * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL
     688             :  * if a memory allocation failed.
     689             :  * If the status field of the connection returned is CONNECTION_BAD,
     690             :  * then some fields may be null'ed out instead of having valid values.
     691             :  *
     692             :  * You should call PQfinish (if conn is not NULL) regardless of whether this
     693             :  * call succeeded.
     694             :  */
     695             : PGconn *
     696         822 : PQconnectdb(const char *conninfo)
     697             : {
     698         822 :     PGconn     *conn = PQconnectStart(conninfo);
     699             : 
     700         822 :     if (conn && conn->status != CONNECTION_BAD)
     701         818 :         (void) connectDBComplete(conn);
     702             : 
     703         822 :     return conn;
     704             : }
     705             : 
     706             : /*
     707             :  *      PQping
     708             :  *
     709             :  * check server status, accepting parameters identical to PQconnectdb
     710             :  */
     711             : PGPing
     712           0 : PQping(const char *conninfo)
     713             : {
     714           0 :     PGconn     *conn = PQconnectStart(conninfo);
     715             :     PGPing      ret;
     716             : 
     717           0 :     ret = internal_ping(conn);
     718           0 :     PQfinish(conn);
     719             : 
     720           0 :     return ret;
     721             : }
     722             : 
     723             : /*
     724             :  *      PQconnectStartParams
     725             :  *
     726             :  * Begins the establishment of a connection to a postgres backend through the
     727             :  * postmaster using connection information in a struct.
     728             :  *
     729             :  * See comment for PQconnectdbParams for the definition of the string format.
     730             :  *
     731             :  * Returns a PGconn*.  If NULL is returned, a malloc error has occurred, and
     732             :  * you should not attempt to proceed with this connection.  If the status
     733             :  * field of the connection returned is CONNECTION_BAD, an error has
     734             :  * occurred. In this case you should call PQfinish on the result, (perhaps
     735             :  * inspecting the error message first).  Other fields of the structure may not
     736             :  * be valid if that occurs.  If the status field is not CONNECTION_BAD, then
     737             :  * this stage has succeeded - call PQconnectPoll, using select(2) to see when
     738             :  * this is necessary.
     739             :  *
     740             :  * See PQconnectPoll for more info.
     741             :  */
     742             : PGconn *
     743        7850 : PQconnectStartParams(const char *const *keywords,
     744             :                      const char *const *values,
     745             :                      int expand_dbname)
     746             : {
     747             :     PGconn     *conn;
     748             :     PQconninfoOption *connOptions;
     749             : 
     750             :     /*
     751             :      * Allocate memory for the conn structure
     752             :      */
     753        7850 :     conn = makeEmptyPGconn();
     754        7850 :     if (conn == NULL)
     755           0 :         return NULL;
     756             : 
     757             :     /*
     758             :      * Parse the conninfo arrays
     759             :      */
     760        7850 :     connOptions = conninfo_array_parse(keywords, values,
     761             :                                        &conn->errorMessage,
     762             :                                        true, expand_dbname);
     763        7850 :     if (connOptions == NULL)
     764             :     {
     765           0 :         conn->status = CONNECTION_BAD;
     766             :         /* errorMessage is already set */
     767           0 :         return conn;
     768             :     }
     769             : 
     770             :     /*
     771             :      * Move option values into conn structure
     772             :      */
     773        7850 :     if (!fillPGconn(conn, connOptions))
     774             :     {
     775           0 :         PQconninfoFree(connOptions);
     776           0 :         return conn;
     777             :     }
     778             : 
     779             :     /*
     780             :      * Free the option info - all is in conn now
     781             :      */
     782        7850 :     PQconninfoFree(connOptions);
     783             : 
     784             :     /*
     785             :      * Compute derived options
     786             :      */
     787        7850 :     if (!connectOptions2(conn))
     788           8 :         return conn;
     789             : 
     790             :     /*
     791             :      * Connect to the database
     792             :      */
     793        7842 :     if (!connectDBStart(conn))
     794             :     {
     795             :         /* Just in case we failed to set it in connectDBStart */
     796         326 :         conn->status = CONNECTION_BAD;
     797             :     }
     798             : 
     799        7842 :     return conn;
     800             : }
     801             : 
     802             : /*
     803             :  *      PQconnectStart
     804             :  *
     805             :  * Begins the establishment of a connection to a postgres backend through the
     806             :  * postmaster using connection information in a string.
     807             :  *
     808             :  * See comment for PQconnectdb for the definition of the string format.
     809             :  *
     810             :  * Returns a PGconn*.  If NULL is returned, a malloc error has occurred, and
     811             :  * you should not attempt to proceed with this connection.  If the status
     812             :  * field of the connection returned is CONNECTION_BAD, an error has
     813             :  * occurred. In this case you should call PQfinish on the result, (perhaps
     814             :  * inspecting the error message first).  Other fields of the structure may not
     815             :  * be valid if that occurs.  If the status field is not CONNECTION_BAD, then
     816             :  * this stage has succeeded - call PQconnectPoll, using select(2) to see when
     817             :  * this is necessary.
     818             :  *
     819             :  * See PQconnectPoll for more info.
     820             :  */
     821             : PGconn *
     822         822 : PQconnectStart(const char *conninfo)
     823             : {
     824             :     PGconn     *conn;
     825             : 
     826             :     /*
     827             :      * Allocate memory for the conn structure
     828             :      */
     829         822 :     conn = makeEmptyPGconn();
     830         822 :     if (conn == NULL)
     831           0 :         return NULL;
     832             : 
     833             :     /*
     834             :      * Parse the conninfo string
     835             :      */
     836         822 :     if (!connectOptions1(conn, conninfo))
     837           4 :         return conn;
     838             : 
     839             :     /*
     840             :      * Compute derived options
     841             :      */
     842         818 :     if (!connectOptions2(conn))
     843           0 :         return conn;
     844             : 
     845             :     /*
     846             :      * Connect to the database
     847             :      */
     848         818 :     if (!connectDBStart(conn))
     849             :     {
     850             :         /* Just in case we failed to set it in connectDBStart */
     851           0 :         conn->status = CONNECTION_BAD;
     852             :     }
     853             : 
     854         818 :     return conn;
     855             : }
     856             : 
     857             : /*
     858             :  * Move option values into conn structure
     859             :  *
     860             :  * Don't put anything cute here --- intelligence should be in
     861             :  * connectOptions2 ...
     862             :  *
     863             :  * Returns true on success. On failure, returns false and sets error message.
     864             :  */
     865             : static bool
     866        8668 : fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
     867             : {
     868             :     const internalPQconninfoOption *option;
     869             : 
     870      320716 :     for (option = PQconninfoOptions; option->keyword; option++)
     871             :     {
     872      312048 :         if (option->connofs >= 0)
     873             :         {
     874      294712 :             const char *tmp = conninfo_getval(connOptions, option->keyword);
     875             : 
     876      294712 :             if (tmp)
     877             :             {
     878      113308 :                 char      **connmember = (char **) ((char *) conn + option->connofs);
     879             : 
     880      113308 :                 if (*connmember)
     881           0 :                     free(*connmember);
     882      113308 :                 *connmember = strdup(tmp);
     883      113308 :                 if (*connmember == NULL)
     884             :                 {
     885           0 :                     printfPQExpBuffer(&conn->errorMessage,
     886           0 :                                       libpq_gettext("out of memory\n"));
     887           0 :                     return false;
     888             :                 }
     889             :             }
     890             :         }
     891             :     }
     892             : 
     893        8668 :     return true;
     894             : }
     895             : 
     896             : /*
     897             :  *      connectOptions1
     898             :  *
     899             :  * Internal subroutine to set up connection parameters given an already-
     900             :  * created PGconn and a conninfo string.  Derived settings should be
     901             :  * processed by calling connectOptions2 next.  (We split them because
     902             :  * PQsetdbLogin overrides defaults in between.)
     903             :  *
     904             :  * Returns true if OK, false if trouble (in which case errorMessage is set
     905             :  * and so is conn->status).
     906             :  */
     907             : static bool
     908         822 : connectOptions1(PGconn *conn, const char *conninfo)
     909             : {
     910             :     PQconninfoOption *connOptions;
     911             : 
     912             :     /*
     913             :      * Parse the conninfo string
     914             :      */
     915         822 :     connOptions = parse_connection_string(conninfo, &conn->errorMessage, true);
     916         822 :     if (connOptions == NULL)
     917             :     {
     918           4 :         conn->status = CONNECTION_BAD;
     919             :         /* errorMessage is already set */
     920           4 :         return false;
     921             :     }
     922             : 
     923             :     /*
     924             :      * Move option values into conn structure
     925             :      */
     926         818 :     if (!fillPGconn(conn, connOptions))
     927             :     {
     928           0 :         conn->status = CONNECTION_BAD;
     929           0 :         PQconninfoFree(connOptions);
     930           0 :         return false;
     931             :     }
     932             : 
     933             :     /*
     934             :      * Free the option info - all is in conn now
     935             :      */
     936         818 :     PQconninfoFree(connOptions);
     937             : 
     938         818 :     return true;
     939             : }
     940             : 
     941             : /*
     942             :  * Count the number of elements in a simple comma-separated list.
     943             :  */
     944             : static int
     945        8668 : count_comma_separated_elems(const char *input)
     946             : {
     947             :     int         n;
     948             : 
     949        8668 :     n = 1;
     950      166470 :     for (; *input != '\0'; input++)
     951             :     {
     952      157802 :         if (*input == ',')
     953           8 :             n++;
     954             :     }
     955             : 
     956        8668 :     return n;
     957             : }
     958             : 
     959             : /*
     960             :  * Parse a simple comma-separated list.
     961             :  *
     962             :  * On each call, returns a malloc'd copy of the next element, and sets *more
     963             :  * to indicate whether there are any more elements in the list after this,
     964             :  * and updates *startptr to point to the next element, if any.
     965             :  *
     966             :  * On out of memory, returns NULL.
     967             :  */
     968             : static char *
     969       17472 : parse_comma_separated_list(char **startptr, bool *more)
     970             : {
     971             :     char       *p;
     972       17472 :     char       *s = *startptr;
     973             :     char       *e;
     974             :     int         len;
     975             : 
     976             :     /*
     977             :      * Search for the end of the current element; a comma or end-of-string
     978             :      * acts as a terminator.
     979             :      */
     980       17472 :     e = s;
     981      221398 :     while (*e != '\0' && *e != ',')
     982      203926 :         ++e;
     983       17472 :     *more = (*e == ',');
     984             : 
     985       17472 :     len = e - s;
     986       17472 :     p = (char *) malloc(sizeof(char) * (len + 1));
     987       17472 :     if (p)
     988             :     {
     989       17472 :         memcpy(p, s, len);
     990       17472 :         p[len] = '\0';
     991             :     }
     992       17472 :     *startptr = e + 1;
     993             : 
     994       17472 :     return p;
     995             : }
     996             : 
     997             : /*
     998             :  *      connectOptions2
     999             :  *
    1000             :  * Compute derived connection options after absorbing all user-supplied info.
    1001             :  *
    1002             :  * Returns true if OK, false if trouble (in which case errorMessage is set
    1003             :  * and so is conn->status).
    1004             :  */
    1005             : static bool
    1006        8668 : connectOptions2(PGconn *conn)
    1007             : {
    1008             :     int         i;
    1009             : 
    1010             :     /*
    1011             :      * Allocate memory for details about each host to which we might possibly
    1012             :      * try to connect.  For that, count the number of elements in the hostaddr
    1013             :      * or host options.  If neither is given, assume one host.
    1014             :      */
    1015        8668 :     conn->whichhost = 0;
    1016        8668 :     if (conn->pghostaddr && conn->pghostaddr[0] != '\0')
    1017         120 :         conn->nconnhost = count_comma_separated_elems(conn->pghostaddr);
    1018        8548 :     else if (conn->pghost && conn->pghost[0] != '\0')
    1019        8548 :         conn->nconnhost = count_comma_separated_elems(conn->pghost);
    1020             :     else
    1021           0 :         conn->nconnhost = 1;
    1022        8668 :     conn->connhost = (pg_conn_host *)
    1023        8668 :         calloc(conn->nconnhost, sizeof(pg_conn_host));
    1024        8668 :     if (conn->connhost == NULL)
    1025           0 :         goto oom_error;
    1026             : 
    1027             :     /*
    1028             :      * We now have one pg_conn_host structure per possible host.  Fill in the
    1029             :      * host and hostaddr fields for each, by splitting the parameter strings.
    1030             :      */
    1031        8668 :     if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
    1032             :     {
    1033         120 :         char       *s = conn->pghostaddr;
    1034         120 :         bool        more = true;
    1035             : 
    1036         240 :         for (i = 0; i < conn->nconnhost && more; i++)
    1037             :         {
    1038         120 :             conn->connhost[i].hostaddr = parse_comma_separated_list(&s, &more);
    1039         120 :             if (conn->connhost[i].hostaddr == NULL)
    1040           0 :                 goto oom_error;
    1041             :         }
    1042             : 
    1043             :         /*
    1044             :          * If hostaddr was given, the array was allocated according to the
    1045             :          * number of elements in the hostaddr list, so it really should be the
    1046             :          * right size.
    1047             :          */
    1048             :         Assert(!more);
    1049             :         Assert(i == conn->nconnhost);
    1050             :     }
    1051             : 
    1052        8668 :     if (conn->pghost != NULL && conn->pghost[0] != '\0')
    1053             :     {
    1054        8668 :         char       *s = conn->pghost;
    1055        8668 :         bool        more = true;
    1056             : 
    1057       17344 :         for (i = 0; i < conn->nconnhost && more; i++)
    1058             :         {
    1059        8676 :             conn->connhost[i].host = parse_comma_separated_list(&s, &more);
    1060        8676 :             if (conn->connhost[i].host == NULL)
    1061           0 :                 goto oom_error;
    1062             :         }
    1063             : 
    1064             :         /* Check for wrong number of host items. */
    1065        8668 :         if (more || i != conn->nconnhost)
    1066             :         {
    1067           0 :             conn->status = CONNECTION_BAD;
    1068           0 :             printfPQExpBuffer(&conn->errorMessage,
    1069           0 :                               libpq_gettext("could not match %d host names to %d hostaddr values\n"),
    1070           0 :                               count_comma_separated_elems(conn->pghost), conn->nconnhost);
    1071           0 :             return false;
    1072             :         }
    1073             :     }
    1074             : 
    1075             :     /*
    1076             :      * Now, for each host slot, identify the type of address spec, and fill in
    1077             :      * the default address if nothing was given.
    1078             :      */
    1079       17344 :     for (i = 0; i < conn->nconnhost; i++)
    1080             :     {
    1081        8676 :         pg_conn_host *ch = &conn->connhost[i];
    1082             : 
    1083        8676 :         if (ch->hostaddr != NULL && ch->hostaddr[0] != '\0')
    1084         120 :             ch->type = CHT_HOST_ADDRESS;
    1085        8556 :         else if (ch->host != NULL && ch->host[0] != '\0')
    1086             :         {
    1087        8556 :             ch->type = CHT_HOST_NAME;
    1088             : #ifdef HAVE_UNIX_SOCKETS
    1089       16814 :             if (is_absolute_path(ch->host))
    1090        8258 :                 ch->type = CHT_UNIX_SOCKET;
    1091             : #endif
    1092             :         }
    1093             :         else
    1094             :         {
    1095           0 :             if (ch->host)
    1096           0 :                 free(ch->host);
    1097             : #ifdef HAVE_UNIX_SOCKETS
    1098           0 :             if (DEFAULT_PGSOCKET_DIR[0])
    1099             :             {
    1100           0 :                 ch->host = strdup(DEFAULT_PGSOCKET_DIR);
    1101           0 :                 ch->type = CHT_UNIX_SOCKET;
    1102             :             }
    1103             :             else
    1104             : #endif
    1105             :             {
    1106           0 :                 ch->host = strdup(DefaultHost);
    1107           0 :                 ch->type = CHT_HOST_NAME;
    1108             :             }
    1109           0 :             if (ch->host == NULL)
    1110           0 :                 goto oom_error;
    1111             :         }
    1112             :     }
    1113             : 
    1114             :     /*
    1115             :      * Next, work out the port number corresponding to each host name.
    1116             :      *
    1117             :      * Note: unlike the above for host names, this could leave the port fields
    1118             :      * as null or empty strings.  We will substitute DEF_PGPORT whenever we
    1119             :      * read such a port field.
    1120             :      */
    1121        8668 :     if (conn->pgport != NULL && conn->pgport[0] != '\0')
    1122             :     {
    1123        8668 :         char       *s = conn->pgport;
    1124        8668 :         bool        more = true;
    1125             : 
    1126       17344 :         for (i = 0; i < conn->nconnhost && more; i++)
    1127             :         {
    1128        8676 :             conn->connhost[i].port = parse_comma_separated_list(&s, &more);
    1129        8676 :             if (conn->connhost[i].port == NULL)
    1130           0 :                 goto oom_error;
    1131             :         }
    1132             : 
    1133             :         /*
    1134             :          * If exactly one port was given, use it for every host.  Otherwise,
    1135             :          * there must be exactly as many ports as there were hosts.
    1136             :          */
    1137       17328 :         if (i == 1 && !more)
    1138             :         {
    1139        8660 :             for (i = 1; i < conn->nconnhost; i++)
    1140             :             {
    1141           0 :                 conn->connhost[i].port = strdup(conn->connhost[0].port);
    1142           0 :                 if (conn->connhost[i].port == NULL)
    1143           0 :                     goto oom_error;
    1144             :             }
    1145             :         }
    1146           8 :         else if (more || i != conn->nconnhost)
    1147             :         {
    1148           0 :             conn->status = CONNECTION_BAD;
    1149           0 :             printfPQExpBuffer(&conn->errorMessage,
    1150           0 :                               libpq_gettext("could not match %d port numbers to %d hosts\n"),
    1151           0 :                               count_comma_separated_elems(conn->pgport), conn->nconnhost);
    1152           0 :             return false;
    1153             :         }
    1154             :     }
    1155             : 
    1156             :     /*
    1157             :      * If user name was not given, fetch it.  (Most likely, the fetch will
    1158             :      * fail, since the only way we get here is if pg_fe_getauthname() failed
    1159             :      * during conninfo_add_defaults().  But now we want an error message.)
    1160             :      */
    1161        8668 :     if (conn->pguser == NULL || conn->pguser[0] == '\0')
    1162             :     {
    1163           0 :         if (conn->pguser)
    1164           0 :             free(conn->pguser);
    1165           0 :         conn->pguser = pg_fe_getauthname(&conn->errorMessage);
    1166           0 :         if (!conn->pguser)
    1167             :         {
    1168           0 :             conn->status = CONNECTION_BAD;
    1169           0 :             return false;
    1170             :         }
    1171             :     }
    1172             : 
    1173             :     /*
    1174             :      * If database name was not given, default it to equal user name
    1175             :      */
    1176        8668 :     if (conn->dbName == NULL || conn->dbName[0] == '\0')
    1177             :     {
    1178          12 :         if (conn->dbName)
    1179           0 :             free(conn->dbName);
    1180          12 :         conn->dbName = strdup(conn->pguser);
    1181          12 :         if (!conn->dbName)
    1182           0 :             goto oom_error;
    1183             :     }
    1184             : 
    1185             :     /*
    1186             :      * If password was not given, try to look it up in password file.  Note
    1187             :      * that the result might be different for each host/port pair.
    1188             :      */
    1189        8668 :     if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
    1190             :     {
    1191             :         /* If password file wasn't specified, use ~/PGPASSFILE */
    1192        8522 :         if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
    1193             :         {
    1194             :             char        homedir[MAXPGPATH];
    1195             : 
    1196        8522 :             if (pqGetHomeDirectory(homedir, sizeof(homedir)))
    1197             :             {
    1198        8522 :                 if (conn->pgpassfile)
    1199           0 :                     free(conn->pgpassfile);
    1200        8522 :                 conn->pgpassfile = malloc(MAXPGPATH);
    1201        8522 :                 if (!conn->pgpassfile)
    1202           0 :                     goto oom_error;
    1203        8522 :                 snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s",
    1204             :                          homedir, PGPASSFILE);
    1205             :             }
    1206             :         }
    1207             : 
    1208        8522 :         if (conn->pgpassfile != NULL && conn->pgpassfile[0] != '\0')
    1209             :         {
    1210       17052 :             for (i = 0; i < conn->nconnhost; i++)
    1211             :             {
    1212             :                 /*
    1213             :                  * Try to get a password for this host from file.  We use host
    1214             :                  * for the hostname search key if given, else hostaddr (at
    1215             :                  * least one of them is guaranteed nonempty by now).
    1216             :                  */
    1217        8530 :                 const char *pwhost = conn->connhost[i].host;
    1218             : 
    1219        8530 :                 if (pwhost == NULL || pwhost[0] == '\0')
    1220           0 :                     pwhost = conn->connhost[i].hostaddr;
    1221             : 
    1222        8530 :                 conn->connhost[i].password =
    1223        8530 :                     passwordFromFile(pwhost,
    1224        8530 :                                      conn->connhost[i].port,
    1225        8530 :                                      conn->dbName,
    1226        8530 :                                      conn->pguser,
    1227        8530 :                                      conn->pgpassfile);
    1228             :             }
    1229             :         }
    1230             :     }
    1231             : 
    1232             :     /*
    1233             :      * validate channel_binding option
    1234             :      */
    1235        8668 :     if (conn->channel_binding)
    1236             :     {
    1237          14 :         if (strcmp(conn->channel_binding, "disable") != 0
    1238          12 :             && strcmp(conn->channel_binding, "prefer") != 0
    1239          12 :             && strcmp(conn->channel_binding, "require") != 0)
    1240             :         {
    1241           2 :             conn->status = CONNECTION_BAD;
    1242           2 :             printfPQExpBuffer(&conn->errorMessage,
    1243           2 :                               libpq_gettext("invalid channel_binding value: \"%s\"\n"),
    1244             :                               conn->channel_binding);
    1245           2 :             return false;
    1246             :         }
    1247             :     }
    1248             :     else
    1249             :     {
    1250        8654 :         conn->channel_binding = strdup(DefaultChannelBinding);
    1251        8654 :         if (!conn->channel_binding)
    1252           0 :             goto oom_error;
    1253             :     }
    1254             : 
    1255             :     /*
    1256             :      * validate sslmode option
    1257             :      */
    1258        8666 :     if (conn->sslmode)
    1259             :     {
    1260        8666 :         if (strcmp(conn->sslmode, "disable") != 0
    1261        8648 :             && strcmp(conn->sslmode, "allow") != 0
    1262        8648 :             && strcmp(conn->sslmode, "prefer") != 0
    1263         112 :             && strcmp(conn->sslmode, "require") != 0
    1264          58 :             && strcmp(conn->sslmode, "verify-ca") != 0
    1265          32 :             && strcmp(conn->sslmode, "verify-full") != 0)
    1266             :         {
    1267           0 :             conn->status = CONNECTION_BAD;
    1268           0 :             printfPQExpBuffer(&conn->errorMessage,
    1269           0 :                               libpq_gettext("invalid sslmode value: \"%s\"\n"),
    1270             :                               conn->sslmode);
    1271           0 :             return false;
    1272             :         }
    1273             : 
    1274             : #ifndef USE_SSL
    1275             :         switch (conn->sslmode[0])
    1276             :         {
    1277             :             case 'a':           /* "allow" */
    1278             :             case 'p':           /* "prefer" */
    1279             : 
    1280             :                 /*
    1281             :                  * warn user that an SSL connection will never be negotiated
    1282             :                  * since SSL was not compiled in?
    1283             :                  */
    1284             :                 break;
    1285             : 
    1286             :             case 'r':           /* "require" */
    1287             :             case 'v':           /* "verify-ca" or "verify-full" */
    1288             :                 conn->status = CONNECTION_BAD;
    1289             :                 printfPQExpBuffer(&conn->errorMessage,
    1290             :                                   libpq_gettext("sslmode value \"%s\" invalid when SSL support is not compiled in\n"),
    1291             :                                   conn->sslmode);
    1292             :                 return false;
    1293             :         }
    1294             : #endif
    1295             :     }
    1296             :     else
    1297             :     {
    1298           0 :         conn->sslmode = strdup(DefaultSSLMode);
    1299           0 :         if (!conn->sslmode)
    1300           0 :             goto oom_error;
    1301             :     }
    1302             : 
    1303             :     /*
    1304             :      * Validate TLS protocol versions for ssl_min_protocol_version and
    1305             :      * ssl_max_protocol_version.
    1306             :      */
    1307        8666 :     if (!sslVerifyProtocolVersion(conn->ssl_min_protocol_version))
    1308             :     {
    1309           2 :         conn->status = CONNECTION_BAD;
    1310           2 :         printfPQExpBuffer(&conn->errorMessage,
    1311           2 :                           libpq_gettext("invalid ssl_min_protocol_version value: \"%s\"\n"),
    1312             :                           conn->ssl_min_protocol_version);
    1313           2 :         return false;
    1314             :     }
    1315        8664 :     if (!sslVerifyProtocolVersion(conn->ssl_max_protocol_version))
    1316             :     {
    1317           2 :         conn->status = CONNECTION_BAD;
    1318           2 :         printfPQExpBuffer(&conn->errorMessage,
    1319           2 :                           libpq_gettext("invalid ssl_max_protocol_version value: \"%s\"\n"),
    1320             :                           conn->ssl_max_protocol_version);
    1321           2 :         return false;
    1322             :     }
    1323             : 
    1324             :     /*
    1325             :      * Check if the range of SSL protocols defined is correct.  This is done
    1326             :      * at this early step because this is independent of the SSL
    1327             :      * implementation used, and this avoids unnecessary cycles with an
    1328             :      * already-built SSL context when the connection is being established, as
    1329             :      * it would be doomed anyway.
    1330             :      */
    1331        8662 :     if (!sslVerifyProtocolRange(conn->ssl_min_protocol_version,
    1332        8662 :                                 conn->ssl_max_protocol_version))
    1333             :     {
    1334           2 :         conn->status = CONNECTION_BAD;
    1335           2 :         printfPQExpBuffer(&conn->errorMessage,
    1336           2 :                           libpq_gettext("invalid SSL protocol version range\n"));
    1337           2 :         return false;
    1338             :     }
    1339             : 
    1340             :     /*
    1341             :      * validate gssencmode option
    1342             :      */
    1343        8660 :     if (conn->gssencmode)
    1344             :     {
    1345        8660 :         if (strcmp(conn->gssencmode, "disable") != 0 &&
    1346           0 :             strcmp(conn->gssencmode, "prefer") != 0 &&
    1347           0 :             strcmp(conn->gssencmode, "require") != 0)
    1348             :         {
    1349           0 :             conn->status = CONNECTION_BAD;
    1350           0 :             printfPQExpBuffer(&conn->errorMessage,
    1351           0 :                               libpq_gettext("invalid gssencmode value: \"%s\"\n"),
    1352             :                               conn->gssencmode);
    1353           0 :             return false;
    1354             :         }
    1355             : #ifndef ENABLE_GSS
    1356        8660 :         if (strcmp(conn->gssencmode, "require") == 0)
    1357             :         {
    1358           0 :             conn->status = CONNECTION_BAD;
    1359           0 :             printfPQExpBuffer(&conn->errorMessage,
    1360           0 :                               libpq_gettext("gssencmode value \"%s\" invalid when GSSAPI support is not compiled in\n"),
    1361             :                               conn->gssencmode);
    1362           0 :             return false;
    1363             :         }
    1364             : #endif
    1365             :     }
    1366             :     else
    1367             :     {
    1368           0 :         conn->gssencmode = strdup(DefaultGSSMode);
    1369           0 :         if (!conn->gssencmode)
    1370           0 :             goto oom_error;
    1371             :     }
    1372             : 
    1373             :     /*
    1374             :      * Resolve special "auto" client_encoding from the locale
    1375             :      */
    1376        8660 :     if (conn->client_encoding_initial &&
    1377        1048 :         strcmp(conn->client_encoding_initial, "auto") == 0)
    1378             :     {
    1379           2 :         free(conn->client_encoding_initial);
    1380           2 :         conn->client_encoding_initial = strdup(pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true)));
    1381           2 :         if (!conn->client_encoding_initial)
    1382           0 :             goto oom_error;
    1383             :     }
    1384             : 
    1385             :     /*
    1386             :      * Validate target_session_attrs option.
    1387             :      */
    1388        8660 :     if (conn->target_session_attrs)
    1389             :     {
    1390        8660 :         if (strcmp(conn->target_session_attrs, "any") != 0
    1391           4 :             && strcmp(conn->target_session_attrs, "read-write") != 0)
    1392             :         {
    1393           0 :             conn->status = CONNECTION_BAD;
    1394           0 :             printfPQExpBuffer(&conn->errorMessage,
    1395           0 :                               libpq_gettext("invalid target_session_attrs value: \"%s\"\n"),
    1396             :                               conn->target_session_attrs);
    1397           0 :             return false;
    1398             :         }
    1399             :     }
    1400             : 
    1401             :     /*
    1402             :      * Only if we get this far is it appropriate to try to connect. (We need a
    1403             :      * state flag, rather than just the boolean result of this function, in
    1404             :      * case someone tries to PQreset() the PGconn.)
    1405             :      */
    1406        8660 :     conn->options_valid = true;
    1407             : 
    1408        8660 :     return true;
    1409             : 
    1410           0 : oom_error:
    1411           0 :     conn->status = CONNECTION_BAD;
    1412           0 :     printfPQExpBuffer(&conn->errorMessage,
    1413           0 :                       libpq_gettext("out of memory\n"));
    1414           0 :     return false;
    1415             : }
    1416             : 
    1417             : /*
    1418             :  *      PQconndefaults
    1419             :  *
    1420             :  * Construct a default connection options array, which identifies all the
    1421             :  * available options and shows any default values that are available from the
    1422             :  * environment etc.  On error (eg out of memory), NULL is returned.
    1423             :  *
    1424             :  * Using this function, an application may determine all possible options
    1425             :  * and their current default values.
    1426             :  *
    1427             :  * NOTE: as of PostgreSQL 7.0, the returned array is dynamically allocated
    1428             :  * and should be freed when no longer needed via PQconninfoFree().  (In prior
    1429             :  * versions, the returned array was static, but that's not thread-safe.)
    1430             :  * Pre-7.0 applications that use this function will see a small memory leak
    1431             :  * until they are updated to call PQconninfoFree.
    1432             :  */
    1433             : PQconninfoOption *
    1434          20 : PQconndefaults(void)
    1435             : {
    1436             :     PQExpBufferData errorBuf;
    1437             :     PQconninfoOption *connOptions;
    1438             : 
    1439             :     /* We don't actually report any errors here, but callees want a buffer */
    1440          20 :     initPQExpBuffer(&errorBuf);
    1441          20 :     if (PQExpBufferDataBroken(errorBuf))
    1442           0 :         return NULL;            /* out of memory already :-( */
    1443             : 
    1444          20 :     connOptions = conninfo_init(&errorBuf);
    1445          20 :     if (connOptions != NULL)
    1446             :     {
    1447             :         /* pass NULL errorBuf to ignore errors */
    1448          20 :         if (!conninfo_add_defaults(connOptions, NULL))
    1449             :         {
    1450           0 :             PQconninfoFree(connOptions);
    1451           0 :             connOptions = NULL;
    1452             :         }
    1453             :     }
    1454             : 
    1455          20 :     termPQExpBuffer(&errorBuf);
    1456          20 :     return connOptions;
    1457             : }
    1458             : 
    1459             : /* ----------------
    1460             :  *      PQsetdbLogin
    1461             :  *
    1462             :  * establishes a connection to a postgres backend through the postmaster
    1463             :  * at the specified host and port.
    1464             :  *
    1465             :  * returns a PGconn* which is needed for all subsequent libpq calls
    1466             :  *
    1467             :  * if the status field of the connection returned is CONNECTION_BAD,
    1468             :  * then only the errorMessage is likely to be useful.
    1469             :  * ----------------
    1470             :  */
    1471             : PGconn *
    1472           0 : PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
    1473             :              const char *pgtty, const char *dbName, const char *login,
    1474             :              const char *pwd)
    1475             : {
    1476             :     PGconn     *conn;
    1477             : 
    1478             :     /*
    1479             :      * Allocate memory for the conn structure
    1480             :      */
    1481           0 :     conn = makeEmptyPGconn();
    1482           0 :     if (conn == NULL)
    1483           0 :         return NULL;
    1484             : 
    1485             :     /*
    1486             :      * If the dbName parameter contains what looks like a connection string,
    1487             :      * parse it into conn struct using connectOptions1.
    1488             :      */
    1489           0 :     if (dbName && recognized_connection_string(dbName))
    1490             :     {
    1491           0 :         if (!connectOptions1(conn, dbName))
    1492           0 :             return conn;
    1493             :     }
    1494             :     else
    1495             :     {
    1496             :         /*
    1497             :          * Old-style path: first, parse an empty conninfo string in order to
    1498             :          * set up the same defaults that PQconnectdb() would use.
    1499             :          */
    1500           0 :         if (!connectOptions1(conn, ""))
    1501           0 :             return conn;
    1502             : 
    1503             :         /* Insert dbName parameter value into struct */
    1504           0 :         if (dbName && dbName[0] != '\0')
    1505             :         {
    1506           0 :             if (conn->dbName)
    1507           0 :                 free(conn->dbName);
    1508           0 :             conn->dbName = strdup(dbName);
    1509           0 :             if (!conn->dbName)
    1510           0 :                 goto oom_error;
    1511             :         }
    1512             :     }
    1513             : 
    1514             :     /*
    1515             :      * Insert remaining parameters into struct, overriding defaults (as well
    1516             :      * as any conflicting data from dbName taken as a conninfo).
    1517             :      */
    1518           0 :     if (pghost && pghost[0] != '\0')
    1519             :     {
    1520           0 :         if (conn->pghost)
    1521           0 :             free(conn->pghost);
    1522           0 :         conn->pghost = strdup(pghost);
    1523           0 :         if (!conn->pghost)
    1524           0 :             goto oom_error;
    1525             :     }
    1526             : 
    1527           0 :     if (pgport && pgport[0] != '\0')
    1528             :     {
    1529           0 :         if (conn->pgport)
    1530           0 :             free(conn->pgport);
    1531           0 :         conn->pgport = strdup(pgport);
    1532           0 :         if (!conn->pgport)
    1533           0 :             goto oom_error;
    1534             :     }
    1535             : 
    1536           0 :     if (pgoptions && pgoptions[0] != '\0')
    1537             :     {
    1538           0 :         if (conn->pgoptions)
    1539           0 :             free(conn->pgoptions);
    1540           0 :         conn->pgoptions = strdup(pgoptions);
    1541           0 :         if (!conn->pgoptions)
    1542           0 :             goto oom_error;
    1543             :     }
    1544             : 
    1545           0 :     if (pgtty && pgtty[0] != '\0')
    1546             :     {
    1547           0 :         if (conn->pgtty)
    1548           0 :             free(conn->pgtty);
    1549           0 :         conn->pgtty = strdup(pgtty);
    1550           0 :         if (!conn->pgtty)
    1551           0 :             goto oom_error;
    1552             :     }
    1553             : 
    1554           0 :     if (login && login[0] != '\0')
    1555             :     {
    1556           0 :         if (conn->pguser)
    1557           0 :             free(conn->pguser);
    1558           0 :         conn->pguser = strdup(login);
    1559           0 :         if (!conn->pguser)
    1560           0 :             goto oom_error;
    1561             :     }
    1562             : 
    1563           0 :     if (pwd && pwd[0] != '\0')
    1564             :     {
    1565           0 :         if (conn->pgpass)
    1566           0 :             free(conn->pgpass);
    1567           0 :         conn->pgpass = strdup(pwd);
    1568           0 :         if (!conn->pgpass)
    1569           0 :             goto oom_error;
    1570             :     }
    1571             : 
    1572             :     /*
    1573             :      * Compute derived options
    1574             :      */
    1575           0 :     if (!connectOptions2(conn))
    1576           0 :         return conn;
    1577             : 
    1578             :     /*
    1579             :      * Connect to the database
    1580             :      */
    1581           0 :     if (connectDBStart(conn))
    1582           0 :         (void) connectDBComplete(conn);
    1583             : 
    1584           0 :     return conn;
    1585             : 
    1586           0 : oom_error:
    1587           0 :     conn->status = CONNECTION_BAD;
    1588           0 :     printfPQExpBuffer(&conn->errorMessage,
    1589           0 :                       libpq_gettext("out of memory\n"));
    1590           0 :     return conn;
    1591             : }
    1592             : 
    1593             : 
    1594             : /* ----------
    1595             :  * connectNoDelay -
    1596             :  * Sets the TCP_NODELAY socket option.
    1597             :  * Returns 1 if successful, 0 if not.
    1598             :  * ----------
    1599             :  */
    1600             : static int
    1601         414 : connectNoDelay(PGconn *conn)
    1602             : {
    1603             : #ifdef  TCP_NODELAY
    1604         414 :     int         on = 1;
    1605             : 
    1606         414 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
    1607             :                    (char *) &on,
    1608             :                    sizeof(on)) < 0)
    1609             :     {
    1610             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    1611             : 
    1612           0 :         appendPQExpBuffer(&conn->errorMessage,
    1613           0 :                           libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
    1614           0 :                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    1615           0 :         return 0;
    1616             :     }
    1617             : #endif
    1618             : 
    1619         414 :     return 1;
    1620             : }
    1621             : 
    1622             : /* ----------
    1623             :  * Write currently connected IP address into host_addr (of len host_addr_len).
    1624             :  * If unable to, set it to the empty string.
    1625             :  * ----------
    1626             :  */
    1627             : static void
    1628        8676 : getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
    1629             : {
    1630        8676 :     struct sockaddr_storage *addr = &conn->raddr.addr;
    1631             : 
    1632        8676 :     if (addr->ss_family == AF_INET)
    1633             :     {
    1634         124 :         if (pg_inet_net_ntop(AF_INET,
    1635         124 :                              &((struct sockaddr_in *) addr)->sin_addr.s_addr,
    1636             :                              32,
    1637             :                              host_addr, host_addr_len) == NULL)
    1638           0 :             host_addr[0] = '\0';
    1639             :     }
    1640             : #ifdef HAVE_IPV6
    1641        8552 :     else if (addr->ss_family == AF_INET6)
    1642             :     {
    1643         300 :         if (pg_inet_net_ntop(AF_INET6,
    1644         300 :                              &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
    1645             :                              128,
    1646             :                              host_addr, host_addr_len) == NULL)
    1647           0 :             host_addr[0] = '\0';
    1648             :     }
    1649             : #endif
    1650             :     else
    1651        8252 :         host_addr[0] = '\0';
    1652        8676 : }
    1653             : 
    1654             : /* ----------
    1655             :  * connectFailureMessage -
    1656             :  * create a friendly error message on connection failure.
    1657             :  * ----------
    1658             :  */
    1659             : static void
    1660         336 : connectFailureMessage(PGconn *conn, int errorno)
    1661             : {
    1662             :     char        sebuf[PG_STRERROR_R_BUFLEN];
    1663             : 
    1664             : #ifdef HAVE_UNIX_SOCKETS
    1665         336 :     if (IS_AF_UNIX(conn->raddr.addr.ss_family))
    1666             :     {
    1667             :         char        service[NI_MAXHOST];
    1668             : 
    1669         326 :         pg_getnameinfo_all(&conn->raddr.addr, conn->raddr.salen,
    1670             :                            NULL, 0,
    1671             :                            service, sizeof(service),
    1672             :                            NI_NUMERICSERV);
    1673         652 :         appendPQExpBuffer(&conn->errorMessage,
    1674         326 :                           libpq_gettext("could not connect to server: %s\n"
    1675             :                                         "\tIs the server running locally and accepting\n"
    1676             :                                         "\tconnections on Unix domain socket \"%s\"?\n"),
    1677             :                           SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
    1678             :                           service);
    1679             :     }
    1680             :     else
    1681             : #endif                          /* HAVE_UNIX_SOCKETS */
    1682             :     {
    1683             :         char        host_addr[NI_MAXHOST];
    1684             :         const char *displayed_host;
    1685             :         const char *displayed_port;
    1686             : 
    1687             :         /*
    1688             :          * Optionally display the network address with the hostname. This is
    1689             :          * useful to distinguish between IPv4 and IPv6 connections.
    1690             :          */
    1691          10 :         getHostaddr(conn, host_addr, NI_MAXHOST);
    1692             : 
    1693             :         /* To which host and port were we actually connecting? */
    1694          10 :         if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
    1695           0 :             displayed_host = conn->connhost[conn->whichhost].hostaddr;
    1696             :         else
    1697          10 :             displayed_host = conn->connhost[conn->whichhost].host;
    1698          10 :         displayed_port = conn->connhost[conn->whichhost].port;
    1699          10 :         if (displayed_port == NULL || displayed_port[0] == '\0')
    1700           0 :             displayed_port = DEF_PGPORT_STR;
    1701             : 
    1702             :         /*
    1703             :          * If the user did not supply an IP address using 'hostaddr', and
    1704             :          * 'host' was missing or does not match our lookup, display the
    1705             :          * looked-up IP address.
    1706             :          */
    1707          10 :         if (conn->connhost[conn->whichhost].type != CHT_HOST_ADDRESS &&
    1708          10 :             strlen(host_addr) > 0 &&
    1709          10 :             strcmp(displayed_host, host_addr) != 0)
    1710          16 :             appendPQExpBuffer(&conn->errorMessage,
    1711           8 :                               libpq_gettext("could not connect to server: %s\n"
    1712             :                                             "\tIs the server running on host \"%s\" (%s) and accepting\n"
    1713             :                                             "\tTCP/IP connections on port %s?\n"),
    1714             :                               SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
    1715             :                               displayed_host, host_addr,
    1716             :                               displayed_port);
    1717             :         else
    1718           4 :             appendPQExpBuffer(&conn->errorMessage,
    1719           2 :                               libpq_gettext("could not connect to server: %s\n"
    1720             :                                             "\tIs the server running on host \"%s\" and accepting\n"
    1721             :                                             "\tTCP/IP connections on port %s?\n"),
    1722             :                               SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
    1723             :                               displayed_host,
    1724             :                               displayed_port);
    1725             :     }
    1726         336 : }
    1727             : 
    1728             : /*
    1729             :  * Should we use keepalives?  Returns 1 if yes, 0 if no, and -1 if
    1730             :  * conn->keepalives is set to a value which is not parseable as an
    1731             :  * integer.
    1732             :  */
    1733             : static int
    1734         414 : useKeepalives(PGconn *conn)
    1735             : {
    1736             :     char       *ep;
    1737             :     int         val;
    1738             : 
    1739         414 :     if (conn->keepalives == NULL)
    1740         414 :         return 1;
    1741           0 :     val = strtol(conn->keepalives, &ep, 10);
    1742           0 :     if (*ep)
    1743           0 :         return -1;
    1744           0 :     return val != 0 ? 1 : 0;
    1745             : }
    1746             : 
    1747             : /*
    1748             :  * Parse and try to interpret "value" as an integer value, and if successful,
    1749             :  * store it in *result, complaining if there is any trailing garbage or an
    1750             :  * overflow.  This allows any number of leading and trailing whitespaces.
    1751             :  */
    1752             : static bool
    1753        8670 : parse_int_param(const char *value, int *result, PGconn *conn,
    1754             :                 const char *context)
    1755             : {
    1756             :     char       *end;
    1757             :     long        numval;
    1758             : 
    1759             :     Assert(value != NULL);
    1760             : 
    1761        8670 :     *result = 0;
    1762             : 
    1763             :     /* strtol(3) skips leading whitespaces */
    1764        8670 :     errno = 0;
    1765        8670 :     numval = strtol(value, &end, 10);
    1766             : 
    1767             :     /*
    1768             :      * If no progress was done during the parsing or an error happened, fail.
    1769             :      * This tests properly for overflows of the result.
    1770             :      */
    1771        8670 :     if (value == end || errno != 0 || numval != (int) numval)
    1772           0 :         goto error;
    1773             : 
    1774             :     /*
    1775             :      * Skip any trailing whitespace; if anything but whitespace remains before
    1776             :      * the terminating character, fail
    1777             :      */
    1778        8674 :     while (*end != '\0' && isspace((unsigned char) *end))
    1779           4 :         end++;
    1780             : 
    1781        8670 :     if (*end != '\0')
    1782           0 :         goto error;
    1783             : 
    1784        8670 :     *result = numval;
    1785        8670 :     return true;
    1786             : 
    1787           0 : error:
    1788           0 :     appendPQExpBuffer(&conn->errorMessage,
    1789           0 :                       libpq_gettext("invalid integer value \"%s\" for connection option \"%s\"\n"),
    1790             :                       value, context);
    1791           0 :     return false;
    1792             : }
    1793             : 
    1794             : #ifndef WIN32
    1795             : /*
    1796             :  * Set the keepalive idle timer.
    1797             :  */
    1798             : static int
    1799         414 : setKeepalivesIdle(PGconn *conn)
    1800             : {
    1801             :     int         idle;
    1802             : 
    1803         414 :     if (conn->keepalives_idle == NULL)
    1804         414 :         return 1;
    1805             : 
    1806           0 :     if (!parse_int_param(conn->keepalives_idle, &idle, conn,
    1807             :                          "keepalives_idle"))
    1808           0 :         return 0;
    1809           0 :     if (idle < 0)
    1810           0 :         idle = 0;
    1811             : 
    1812             : #ifdef PG_TCP_KEEPALIVE_IDLE
    1813           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
    1814             :                    (char *) &idle, sizeof(idle)) < 0)
    1815             :     {
    1816             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    1817             : 
    1818           0 :         appendPQExpBuffer(&conn->errorMessage,
    1819           0 :                           libpq_gettext("setsockopt(%s) failed: %s\n"),
    1820             :                           PG_TCP_KEEPALIVE_IDLE_STR,
    1821           0 :                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    1822           0 :         return 0;
    1823             :     }
    1824             : #endif
    1825             : 
    1826           0 :     return 1;
    1827             : }
    1828             : 
    1829             : /*
    1830             :  * Set the keepalive interval.
    1831             :  */
    1832             : static int
    1833         414 : setKeepalivesInterval(PGconn *conn)
    1834             : {
    1835             :     int         interval;
    1836             : 
    1837         414 :     if (conn->keepalives_interval == NULL)
    1838         414 :         return 1;
    1839             : 
    1840           0 :     if (!parse_int_param(conn->keepalives_interval, &interval, conn,
    1841             :                          "keepalives_interval"))
    1842           0 :         return 0;
    1843           0 :     if (interval < 0)
    1844           0 :         interval = 0;
    1845             : 
    1846             : #ifdef TCP_KEEPINTVL
    1847           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPINTVL,
    1848             :                    (char *) &interval, sizeof(interval)) < 0)
    1849             :     {
    1850             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    1851             : 
    1852           0 :         appendPQExpBuffer(&conn->errorMessage,
    1853           0 :                           libpq_gettext("setsockopt(%s) failed: %s\n"),
    1854             :                           "TCP_KEEPINTVL",
    1855           0 :                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    1856           0 :         return 0;
    1857             :     }
    1858             : #endif
    1859             : 
    1860           0 :     return 1;
    1861             : }
    1862             : 
    1863             : /*
    1864             :  * Set the count of lost keepalive packets that will trigger a connection
    1865             :  * break.
    1866             :  */
    1867             : static int
    1868         414 : setKeepalivesCount(PGconn *conn)
    1869             : {
    1870             :     int         count;
    1871             : 
    1872         414 :     if (conn->keepalives_count == NULL)
    1873         414 :         return 1;
    1874             : 
    1875           0 :     if (!parse_int_param(conn->keepalives_count, &count, conn,
    1876             :                          "keepalives_count"))
    1877           0 :         return 0;
    1878           0 :     if (count < 0)
    1879           0 :         count = 0;
    1880             : 
    1881             : #ifdef TCP_KEEPCNT
    1882           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPCNT,
    1883             :                    (char *) &count, sizeof(count)) < 0)
    1884             :     {
    1885             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    1886             : 
    1887           0 :         appendPQExpBuffer(&conn->errorMessage,
    1888           0 :                           libpq_gettext("setsockopt(%s) failed: %s\n"),
    1889             :                           "TCP_KEEPCNT",
    1890           0 :                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    1891           0 :         return 0;
    1892             :     }
    1893             : #endif
    1894             : 
    1895           0 :     return 1;
    1896             : }
    1897             : #else                           /* WIN32 */
    1898             : #ifdef SIO_KEEPALIVE_VALS
    1899             : /*
    1900             :  * Enable keepalives and set the keepalive values on Win32,
    1901             :  * where they are always set in one batch.
    1902             :  */
    1903             : static int
    1904             : setKeepalivesWin32(PGconn *conn)
    1905             : {
    1906             :     struct tcp_keepalive ka;
    1907             :     DWORD       retsize;
    1908             :     int         idle = 0;
    1909             :     int         interval = 0;
    1910             : 
    1911             :     if (conn->keepalives_idle &&
    1912             :         !parse_int_param(conn->keepalives_idle, &idle, conn,
    1913             :                          "keepalives_idle"))
    1914             :         return 0;
    1915             :     if (idle <= 0)
    1916             :         idle = 2 * 60 * 60;     /* 2 hours = default */
    1917             : 
    1918             :     if (conn->keepalives_interval &&
    1919             :         !parse_int_param(conn->keepalives_interval, &interval, conn,
    1920             :                          "keepalives_interval"))
    1921             :         return 0;
    1922             :     if (interval <= 0)
    1923             :         interval = 1;           /* 1 second = default */
    1924             : 
    1925             :     ka.onoff = 1;
    1926             :     ka.keepalivetime = idle * 1000;
    1927             :     ka.keepaliveinterval = interval * 1000;
    1928             : 
    1929             :     if (WSAIoctl(conn->sock,
    1930             :                  SIO_KEEPALIVE_VALS,
    1931             :                  (LPVOID) &ka,
    1932             :                  sizeof(ka),
    1933             :                  NULL,
    1934             :                  0,
    1935             :                  &retsize,
    1936             :                  NULL,
    1937             :                  NULL)
    1938             :         != 0)
    1939             :     {
    1940             :         appendPQExpBuffer(&conn->errorMessage,
    1941             :                           libpq_gettext("WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n"),
    1942             :                           WSAGetLastError());
    1943             :         return 0;
    1944             :     }
    1945             :     return 1;
    1946             : }
    1947             : #endif                          /* SIO_KEEPALIVE_VALS */
    1948             : #endif                          /* WIN32 */
    1949             : 
    1950             : /*
    1951             :  * Set the TCP user timeout.
    1952             :  */
    1953             : static int
    1954         414 : setTCPUserTimeout(PGconn *conn)
    1955             : {
    1956             :     int         timeout;
    1957             : 
    1958         414 :     if (conn->pgtcp_user_timeout == NULL)
    1959         414 :         return 1;
    1960             : 
    1961           0 :     if (!parse_int_param(conn->pgtcp_user_timeout, &timeout, conn,
    1962             :                          "tcp_user_timeout"))
    1963           0 :         return 0;
    1964             : 
    1965           0 :     if (timeout < 0)
    1966           0 :         timeout = 0;
    1967             : 
    1968             : #ifdef TCP_USER_TIMEOUT
    1969           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_USER_TIMEOUT,
    1970             :                    (char *) &timeout, sizeof(timeout)) < 0)
    1971             :     {
    1972             :         char        sebuf[256];
    1973             : 
    1974           0 :         appendPQExpBuffer(&conn->errorMessage,
    1975           0 :                           libpq_gettext("setsockopt(%s) failed: %s\n"),
    1976             :                           "TCP_USER_TIMEOUT",
    1977           0 :                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    1978           0 :         return 0;
    1979             :     }
    1980             : #endif
    1981             : 
    1982           0 :     return 1;
    1983             : }
    1984             : 
    1985             : /* ----------
    1986             :  * connectDBStart -
    1987             :  *      Begin the process of making a connection to the backend.
    1988             :  *
    1989             :  * Returns 1 if successful, 0 if not.
    1990             :  * ----------
    1991             :  */
    1992             : static int
    1993        8660 : connectDBStart(PGconn *conn)
    1994             : {
    1995        8660 :     if (!conn)
    1996           0 :         return 0;
    1997             : 
    1998        8660 :     if (!conn->options_valid)
    1999           0 :         goto connect_errReturn;
    2000             : 
    2001             :     /*
    2002             :      * Check for bad linking to backend-internal versions of src/common
    2003             :      * functions (see comments in link-canary.c for the reason we need this).
    2004             :      * Nobody but developers should see this message, so we don't bother
    2005             :      * translating it.
    2006             :      */
    2007        8660 :     if (!pg_link_canary_is_frontend())
    2008             :     {
    2009           0 :         printfPQExpBuffer(&conn->errorMessage,
    2010             :                           "libpq is incorrectly linked to backend functions\n");
    2011           0 :         goto connect_errReturn;
    2012             :     }
    2013             : 
    2014             :     /* Ensure our buffers are empty */
    2015        8660 :     conn->inStart = conn->inCursor = conn->inEnd = 0;
    2016        8660 :     conn->outCount = 0;
    2017             : 
    2018             :     /*
    2019             :      * Ensure errorMessage is empty, too.  PQconnectPoll will append messages
    2020             :      * to it in the process of scanning for a working server.  Thus, if we
    2021             :      * fail to connect to multiple hosts, the final error message will include
    2022             :      * details about each failure.
    2023             :      */
    2024        8660 :     resetPQExpBuffer(&conn->errorMessage);
    2025             : 
    2026             : #ifdef ENABLE_GSS
    2027             :     if (conn->gssencmode[0] == 'd') /* "disable" */
    2028             :         conn->try_gss = false;
    2029             : #endif
    2030             : 
    2031             :     /*
    2032             :      * Set up to try to connect to the first host.  (Setting whichhost = -1 is
    2033             :      * a bit of a cheat, but PQconnectPoll will advance it to 0 before
    2034             :      * anything else looks at it.)
    2035             :      */
    2036        8660 :     conn->whichhost = -1;
    2037        8660 :     conn->try_next_addr = false;
    2038        8660 :     conn->try_next_host = true;
    2039        8660 :     conn->status = CONNECTION_NEEDED;
    2040             : 
    2041             :     /*
    2042             :      * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
    2043             :      * so that it can easily be re-executed if needed again during the
    2044             :      * asynchronous startup process.  However, we must run it once here,
    2045             :      * because callers expect a success return from this routine to mean that
    2046             :      * we are in PGRES_POLLING_WRITING connection state.
    2047             :      */
    2048        8660 :     if (PQconnectPoll(conn) == PGRES_POLLING_WRITING)
    2049        8334 :         return 1;
    2050             : 
    2051         326 : connect_errReturn:
    2052             : 
    2053             :     /*
    2054             :      * If we managed to open a socket, close it immediately rather than
    2055             :      * waiting till PQfinish.  (The application cannot have gotten the socket
    2056             :      * from PQsocket yet, so this doesn't risk breaking anything.)
    2057             :      */
    2058         326 :     pqDropConnection(conn, true);
    2059         326 :     conn->status = CONNECTION_BAD;
    2060         326 :     return 0;
    2061             : }
    2062             : 
    2063             : 
    2064             : /*
    2065             :  *      connectDBComplete
    2066             :  *
    2067             :  * Block and complete a connection.
    2068             :  *
    2069             :  * Returns 1 on success, 0 on failure.
    2070             :  */
    2071             : static int
    2072        7974 : connectDBComplete(PGconn *conn)
    2073             : {
    2074        7974 :     PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
    2075        7974 :     time_t      finish_time = ((time_t) -1);
    2076        7974 :     int         timeout = 0;
    2077        7974 :     int         last_whichhost = -2;    /* certainly different from whichhost */
    2078        7974 :     struct addrinfo *last_addr_cur = NULL;
    2079             : 
    2080        7974 :     if (conn == NULL || conn->status == CONNECTION_BAD)
    2081           0 :         return 0;
    2082             : 
    2083             :     /*
    2084             :      * Set up a time limit, if connect_timeout isn't zero.
    2085             :      */
    2086        7974 :     if (conn->connect_timeout != NULL)
    2087             :     {
    2088           8 :         if (!parse_int_param(conn->connect_timeout, &timeout, conn,
    2089             :                              "connect_timeout"))
    2090             :         {
    2091             :             /* mark the connection as bad to report the parsing failure */
    2092           0 :             conn->status = CONNECTION_BAD;
    2093           0 :             return 0;
    2094             :         }
    2095             : 
    2096           8 :         if (timeout > 0)
    2097             :         {
    2098             :             /*
    2099             :              * Rounding could cause connection to fail unexpectedly quickly;
    2100             :              * to prevent possibly waiting hardly-at-all, insist on at least
    2101             :              * two seconds.
    2102             :              */
    2103           8 :             if (timeout < 2)
    2104           0 :                 timeout = 2;
    2105             :         }
    2106             :         else                    /* negative means 0 */
    2107           0 :             timeout = 0;
    2108             :     }
    2109             : 
    2110             :     for (;;)
    2111       17546 :     {
    2112       25520 :         int         ret = 0;
    2113             : 
    2114             :         /*
    2115             :          * (Re)start the connect_timeout timer if it's active and we are
    2116             :          * considering a different host than we were last time through.  If
    2117             :          * we've already succeeded, though, needn't recalculate.
    2118             :          */
    2119       25520 :         if (flag != PGRES_POLLING_OK &&
    2120       17682 :             timeout > 0 &&
    2121          28 :             (conn->whichhost != last_whichhost ||
    2122          20 :              conn->addr_cur != last_addr_cur))
    2123             :         {
    2124           8 :             finish_time = time(NULL) + timeout;
    2125           8 :             last_whichhost = conn->whichhost;
    2126           8 :             last_addr_cur = conn->addr_cur;
    2127             :         }
    2128             : 
    2129             :         /*
    2130             :          * Wait, if necessary.  Note that the initial state (just after
    2131             :          * PQconnectStart) is to wait for the socket to select for writing.
    2132             :          */
    2133       25520 :         switch (flag)
    2134             :         {
    2135        7838 :             case PGRES_POLLING_OK:
    2136             : 
    2137             :                 /*
    2138             :                  * Reset stored error messages since we now have a working
    2139             :                  * connection
    2140             :                  */
    2141        7838 :                 resetPQExpBuffer(&conn->errorMessage);
    2142        7838 :                 return 1;       /* success! */
    2143             : 
    2144        8794 :             case PGRES_POLLING_READING:
    2145        8794 :                 ret = pqWaitTimed(1, 0, conn, finish_time);
    2146        8794 :                 if (ret == -1)
    2147             :                 {
    2148             :                     /* hard failure, eg select() problem, aborts everything */
    2149           0 :                     conn->status = CONNECTION_BAD;
    2150           0 :                     return 0;
    2151             :                 }
    2152        8794 :                 break;
    2153             : 
    2154        8752 :             case PGRES_POLLING_WRITING:
    2155        8752 :                 ret = pqWaitTimed(0, 1, conn, finish_time);
    2156        8752 :                 if (ret == -1)
    2157             :                 {
    2158             :                     /* hard failure, eg select() problem, aborts everything */
    2159           0 :                     conn->status = CONNECTION_BAD;
    2160           0 :                     return 0;
    2161             :                 }
    2162        8752 :                 break;
    2163             : 
    2164         136 :             default:
    2165             :                 /* Just in case we failed to set it in PQconnectPoll */
    2166         136 :                 conn->status = CONNECTION_BAD;
    2167         136 :                 return 0;
    2168             :         }
    2169             : 
    2170       17546 :         if (ret == 1)           /* connect_timeout elapsed */
    2171             :         {
    2172             :             /*
    2173             :              * Give up on current server/address, try the next one.
    2174             :              */
    2175           0 :             conn->try_next_addr = true;
    2176           0 :             conn->status = CONNECTION_NEEDED;
    2177             :         }
    2178             : 
    2179             :         /*
    2180             :          * Now try to advance the state machine.
    2181             :          */
    2182       17546 :         flag = PQconnectPoll(conn);
    2183             :     }
    2184             : }
    2185             : 
    2186             : /*
    2187             :  * This subroutine saves conn->errorMessage, which will be restored back by
    2188             :  * restoreErrorMessage subroutine.  Returns false on OOM failure.
    2189             :  */
    2190             : static bool
    2191          12 : saveErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
    2192             : {
    2193          12 :     initPQExpBuffer(savedMessage);
    2194          12 :     appendPQExpBufferStr(savedMessage,
    2195          12 :                          conn->errorMessage.data);
    2196          12 :     if (PQExpBufferBroken(savedMessage))
    2197             :     {
    2198           0 :         printfPQExpBuffer(&conn->errorMessage,
    2199           0 :                           libpq_gettext("out of memory\n"));
    2200           0 :         return false;
    2201             :     }
    2202             :     /* Clear whatever is in errorMessage now */
    2203          12 :     resetPQExpBuffer(&conn->errorMessage);
    2204          12 :     return true;
    2205             : }
    2206             : 
    2207             : /*
    2208             :  * Restores saved error messages back to conn->errorMessage, prepending them
    2209             :  * to whatever is in conn->errorMessage already.  (This does the right thing
    2210             :  * if anything's been added to conn->errorMessage since saveErrorMessage.)
    2211             :  */
    2212             : static void
    2213           8 : restoreErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
    2214             : {
    2215           8 :     appendPQExpBufferStr(savedMessage, conn->errorMessage.data);
    2216           8 :     resetPQExpBuffer(&conn->errorMessage);
    2217           8 :     appendPQExpBufferStr(&conn->errorMessage, savedMessage->data);
    2218             :     /* If any step above hit OOM, just report that */
    2219           8 :     if (PQExpBufferBroken(savedMessage) ||
    2220           8 :         PQExpBufferBroken(&conn->errorMessage))
    2221           0 :         printfPQExpBuffer(&conn->errorMessage,
    2222           0 :                           libpq_gettext("out of memory\n"));
    2223           8 :     termPQExpBuffer(savedMessage);
    2224           8 : }
    2225             : 
    2226             : /* ----------------
    2227             :  *      PQconnectPoll
    2228             :  *
    2229             :  * Poll an asynchronous connection.
    2230             :  *
    2231             :  * Returns a PostgresPollingStatusType.
    2232             :  * Before calling this function, use select(2) to determine when data
    2233             :  * has arrived..
    2234             :  *
    2235             :  * You must call PQfinish whether or not this fails.
    2236             :  *
    2237             :  * This function and PQconnectStart are intended to allow connections to be
    2238             :  * made without blocking the execution of your program on remote I/O. However,
    2239             :  * there are a number of caveats:
    2240             :  *
    2241             :  *   o  If you call PQtrace, ensure that the stream object into which you trace
    2242             :  *      will not block.
    2243             :  *   o  If you do not supply an IP address for the remote host (i.e. you
    2244             :  *      supply a host name instead) then PQconnectStart will block on
    2245             :  *      gethostbyname.  You will be fine if using Unix sockets (i.e. by
    2246             :  *      supplying neither a host name nor a host address).
    2247             :  *   o  If your backend wants to use Kerberos authentication then you must
    2248             :  *      supply both a host name and a host address, otherwise this function
    2249             :  *      may block on gethostname.
    2250             :  *
    2251             :  * ----------------
    2252             :  */
    2253             : PostgresPollingStatusType
    2254       26924 : PQconnectPoll(PGconn *conn)
    2255             : {
    2256       26924 :     bool        reset_connection_state_machine = false;
    2257       26924 :     bool        need_new_connection = false;
    2258             :     PGresult   *res;
    2259             :     char        sebuf[PG_STRERROR_R_BUFLEN];
    2260             :     int         optval;
    2261             :     PQExpBufferData savedMessage;
    2262             : 
    2263       26924 :     if (conn == NULL)
    2264           0 :         return PGRES_POLLING_FAILED;
    2265             : 
    2266             :     /* Get the new data */
    2267       26924 :     switch (conn->status)
    2268             :     {
    2269             :             /*
    2270             :              * We really shouldn't have been polled in these two cases, but we
    2271             :              * can handle it.
    2272             :              */
    2273           0 :         case CONNECTION_BAD:
    2274           0 :             return PGRES_POLLING_FAILED;
    2275           0 :         case CONNECTION_OK:
    2276           0 :             return PGRES_POLLING_OK;
    2277             : 
    2278             :             /* These are reading states */
    2279        8540 :         case CONNECTION_AWAITING_RESPONSE:
    2280             :         case CONNECTION_AUTH_OK:
    2281             :             {
    2282             :                 /* Load waiting data */
    2283        8540 :                 int         n = pqReadData(conn);
    2284             : 
    2285        8540 :                 if (n < 0)
    2286          14 :                     goto error_return;
    2287        8526 :                 if (n == 0)
    2288         124 :                     return PGRES_POLLING_READING;
    2289             : 
    2290        8402 :                 break;
    2291             :             }
    2292             : 
    2293             :             /* These are writing states, so we just proceed. */
    2294        9112 :         case CONNECTION_STARTED:
    2295             :         case CONNECTION_MADE:
    2296        9112 :             break;
    2297             : 
    2298             :             /* We allow pqSetenvPoll to decide whether to proceed. */
    2299           0 :         case CONNECTION_SETENV:
    2300           0 :             break;
    2301             : 
    2302             :             /* Special cases: proceed without waiting. */
    2303        9272 :         case CONNECTION_SSL_STARTUP:
    2304             :         case CONNECTION_NEEDED:
    2305             :         case CONNECTION_CHECK_WRITABLE:
    2306             :         case CONNECTION_CONSUME:
    2307             :         case CONNECTION_GSS_STARTUP:
    2308        9272 :             break;
    2309             : 
    2310           0 :         default:
    2311           0 :             appendPQExpBufferStr(&conn->errorMessage,
    2312           0 :                                  libpq_gettext("invalid connection state, probably indicative of memory corruption\n"));
    2313           0 :             goto error_return;
    2314             :     }
    2315             : 
    2316             : 
    2317       26786 : keep_going:                     /* We will come back to here until there is
    2318             :                                  * nothing left to do. */
    2319             : 
    2320             :     /* Time to advance to next address, or next host if no more addresses? */
    2321       51580 :     if (conn->try_next_addr)
    2322             :     {
    2323         336 :         if (conn->addr_cur && conn->addr_cur->ai_next)
    2324             :         {
    2325           4 :             conn->addr_cur = conn->addr_cur->ai_next;
    2326           4 :             reset_connection_state_machine = true;
    2327             :         }
    2328             :         else
    2329         332 :             conn->try_next_host = true;
    2330         336 :         conn->try_next_addr = false;
    2331             :     }
    2332             : 
    2333             :     /* Time to advance to next connhost[] entry? */
    2334       51580 :     if (conn->try_next_host)
    2335             :     {
    2336             :         pg_conn_host *ch;
    2337             :         struct addrinfo hint;
    2338             :         int         thisport;
    2339             :         int         ret;
    2340             :         char        portstr[MAXPGPATH];
    2341             : 
    2342        8994 :         if (conn->whichhost + 1 >= conn->nconnhost)
    2343             :         {
    2344             :             /*
    2345             :              * Oops, no more hosts.  An appropriate error message is already
    2346             :              * set up, so just set the right status.
    2347             :              */
    2348         332 :             goto error_return;
    2349             :         }
    2350        8662 :         conn->whichhost++;
    2351             : 
    2352             :         /* Drop any address info for previous host */
    2353        8662 :         release_conn_addrinfo(conn);
    2354             : 
    2355             :         /*
    2356             :          * Look up info for the new host.  On failure, log the problem in
    2357             :          * conn->errorMessage, then loop around to try the next host.  (Note
    2358             :          * we don't clear try_next_host until we've succeeded.)
    2359             :          */
    2360        8662 :         ch = &conn->connhost[conn->whichhost];
    2361             : 
    2362             :         /* Initialize hint structure */
    2363       60634 :         MemSet(&hint, 0, sizeof(hint));
    2364        8662 :         hint.ai_socktype = SOCK_STREAM;
    2365        8662 :         conn->addrlist_family = hint.ai_family = AF_UNSPEC;
    2366             : 
    2367             :         /* Figure out the port number we're going to use. */
    2368        8662 :         if (ch->port == NULL || ch->port[0] == '\0')
    2369           0 :             thisport = DEF_PGPORT;
    2370             :         else
    2371             :         {
    2372        8662 :             if (!parse_int_param(ch->port, &thisport, conn, "port"))
    2373           0 :                 goto error_return;
    2374             : 
    2375        8662 :             if (thisport < 1 || thisport > 65535)
    2376             :             {
    2377           0 :                 appendPQExpBuffer(&conn->errorMessage,
    2378           0 :                                   libpq_gettext("invalid port number: \"%s\"\n"),
    2379             :                                   ch->port);
    2380           0 :                 goto keep_going;
    2381             :             }
    2382             :         }
    2383        8662 :         snprintf(portstr, sizeof(portstr), "%d", thisport);
    2384             : 
    2385             :         /* Use pg_getaddrinfo_all() to resolve the address */
    2386        8662 :         switch (ch->type)
    2387             :         {
    2388         298 :             case CHT_HOST_NAME:
    2389         298 :                 ret = pg_getaddrinfo_all(ch->host, portstr, &hint,
    2390             :                                          &conn->addrlist);
    2391         298 :                 if (ret || !conn->addrlist)
    2392             :                 {
    2393           0 :                     appendPQExpBuffer(&conn->errorMessage,
    2394           0 :                                       libpq_gettext("could not translate host name \"%s\" to address: %s\n"),
    2395             :                                       ch->host, gai_strerror(ret));
    2396           0 :                     goto keep_going;
    2397             :                 }
    2398         298 :                 break;
    2399             : 
    2400         112 :             case CHT_HOST_ADDRESS:
    2401         112 :                 hint.ai_flags = AI_NUMERICHOST;
    2402         112 :                 ret = pg_getaddrinfo_all(ch->hostaddr, portstr, &hint,
    2403             :                                          &conn->addrlist);
    2404         112 :                 if (ret || !conn->addrlist)
    2405             :                 {
    2406           0 :                     appendPQExpBuffer(&conn->errorMessage,
    2407           0 :                                       libpq_gettext("could not parse network address \"%s\": %s\n"),
    2408             :                                       ch->hostaddr, gai_strerror(ret));
    2409           0 :                     goto keep_going;
    2410             :                 }
    2411         112 :                 break;
    2412             : 
    2413        8252 :             case CHT_UNIX_SOCKET:
    2414             : #ifdef HAVE_UNIX_SOCKETS
    2415        8252 :                 conn->addrlist_family = hint.ai_family = AF_UNIX;
    2416        8252 :                 UNIXSOCK_PATH(portstr, thisport, ch->host);
    2417        8252 :                 if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
    2418             :                 {
    2419           0 :                     appendPQExpBuffer(&conn->errorMessage,
    2420           0 :                                       libpq_gettext("Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n"),
    2421             :                                       portstr,
    2422             :                                       (int) (UNIXSOCK_PATH_BUFLEN - 1));
    2423           0 :                     goto keep_going;
    2424             :                 }
    2425             : 
    2426             :                 /*
    2427             :                  * NULL hostname tells pg_getaddrinfo_all to parse the service
    2428             :                  * name as a Unix-domain socket path.
    2429             :                  */
    2430        8252 :                 ret = pg_getaddrinfo_all(NULL, portstr, &hint,
    2431             :                                          &conn->addrlist);
    2432        8252 :                 if (ret || !conn->addrlist)
    2433             :                 {
    2434           0 :                     appendPQExpBuffer(&conn->errorMessage,
    2435           0 :                                       libpq_gettext("could not translate Unix-domain socket path \"%s\" to address: %s\n"),
    2436             :                                       portstr, gai_strerror(ret));
    2437           0 :                     goto keep_going;
    2438             :                 }
    2439             : #else
    2440             :                 Assert(false);
    2441             : #endif
    2442        8252 :                 break;
    2443             :         }
    2444             : 
    2445             :         /* OK, scan this addrlist for a working server address */
    2446        8662 :         conn->addr_cur = conn->addrlist;
    2447        8662 :         reset_connection_state_machine = true;
    2448        8662 :         conn->try_next_host = false;
    2449             :     }
    2450             : 
    2451             :     /* Reset connection state machine? */
    2452       51248 :     if (reset_connection_state_machine)
    2453             :     {
    2454             :         /*
    2455             :          * (Re) initialize our connection control variables for a set of
    2456             :          * connection attempts to a single server address.  These variables
    2457             :          * must persist across individual connection attempts, but we must
    2458             :          * reset them when we start to consider a new server.
    2459             :          */
    2460        8666 :         conn->pversion = PG_PROTOCOL(3, 0);
    2461        8666 :         conn->send_appname = true;
    2462             : #ifdef USE_SSL
    2463             :         /* initialize these values based on SSL mode */
    2464        8666 :         conn->allow_ssl_try = (conn->sslmode[0] != 'd');  /* "disable" */
    2465        8666 :         conn->wait_ssl_try = (conn->sslmode[0] == 'a'); /* "allow" */
    2466             : #endif
    2467             : 
    2468        8666 :         reset_connection_state_machine = false;
    2469        8666 :         need_new_connection = true;
    2470             :     }
    2471             : 
    2472             :     /* Force a new connection (perhaps to the same server as before)? */
    2473       51248 :     if (need_new_connection)
    2474             :     {
    2475             :         /* Drop any existing connection */
    2476        8666 :         pqDropConnection(conn, true);
    2477             : 
    2478             :         /* Reset all state obtained from old server */
    2479        8666 :         pqDropServerData(conn);
    2480             : 
    2481             :         /* Drop any PGresult we might have, too */
    2482        8666 :         conn->asyncStatus = PGASYNC_IDLE;
    2483        8666 :         conn->xactStatus = PQTRANS_IDLE;
    2484        8666 :         pqClearAsyncResult(conn);
    2485             : 
    2486             :         /* Reset conn->status to put the state machine in the right state */
    2487        8666 :         conn->status = CONNECTION_NEEDED;
    2488             : 
    2489        8666 :         need_new_connection = false;
    2490             :     }
    2491             : 
    2492             :     /* Now try to advance the state machine for this connection */
    2493       51248 :     switch (conn->status)
    2494             :     {
    2495        8666 :         case CONNECTION_NEEDED:
    2496             :             {
    2497             :                 /*
    2498             :                  * Try to initiate a connection to one of the addresses
    2499             :                  * returned by pg_getaddrinfo_all().  conn->addr_cur is the
    2500             :                  * next one to try.
    2501             :                  *
    2502             :                  * The extra level of braces here is historical.  It's not
    2503             :                  * worth reindenting this whole switch case to remove 'em.
    2504             :                  */
    2505             :                 {
    2506        8666 :                     struct addrinfo *addr_cur = conn->addr_cur;
    2507             :                     char        host_addr[NI_MAXHOST];
    2508             : 
    2509             :                     /*
    2510             :                      * Advance to next possible host, if we've tried all of
    2511             :                      * the addresses for the current host.
    2512             :                      */
    2513        8666 :                     if (addr_cur == NULL)
    2514             :                     {
    2515           0 :                         conn->try_next_host = true;
    2516        8252 :                         goto keep_going;
    2517             :                     }
    2518             : 
    2519             :                     /* Remember current address for possible error msg */
    2520        8666 :                     memcpy(&conn->raddr.addr, addr_cur->ai_addr,
    2521        8666 :                            addr_cur->ai_addrlen);
    2522        8666 :                     conn->raddr.salen = addr_cur->ai_addrlen;
    2523             : 
    2524             :                     /* set connip */
    2525        8666 :                     if (conn->connip != NULL)
    2526             :                     {
    2527           4 :                         free(conn->connip);
    2528           4 :                         conn->connip = NULL;
    2529             :                     }
    2530             : 
    2531        8666 :                     getHostaddr(conn, host_addr, NI_MAXHOST);
    2532        8666 :                     if (strlen(host_addr) > 0)
    2533         414 :                         conn->connip = strdup(host_addr);
    2534             : 
    2535             :                     /*
    2536             :                      * purposely ignore strdup failure; not a big problem if
    2537             :                      * it fails anyway.
    2538             :                      */
    2539             : 
    2540        8666 :                     conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
    2541        8666 :                     if (conn->sock == PGINVALID_SOCKET)
    2542             :                     {
    2543             :                         /*
    2544             :                          * Silently ignore socket() failure if we have more
    2545             :                          * addresses to try; this reduces useless chatter in
    2546             :                          * cases where the address list includes both IPv4 and
    2547             :                          * IPv6 but kernel only accepts one family.
    2548             :                          */
    2549           0 :                         if (addr_cur->ai_next != NULL ||
    2550           0 :                             conn->whichhost + 1 < conn->nconnhost)
    2551             :                         {
    2552           0 :                             conn->try_next_addr = true;
    2553           0 :                             goto keep_going;
    2554             :                         }
    2555           0 :                         appendPQExpBuffer(&conn->errorMessage,
    2556           0 :                                           libpq_gettext("could not create socket: %s\n"),
    2557           0 :                                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2558           0 :                         goto error_return;
    2559             :                     }
    2560             : 
    2561             :                     /*
    2562             :                      * Select socket options: no delay of outgoing data for
    2563             :                      * TCP sockets, nonblock mode, close-on-exec.  Try the
    2564             :                      * next address if any of this fails.
    2565             :                      */
    2566        8666 :                     if (!IS_AF_UNIX(addr_cur->ai_family))
    2567             :                     {
    2568         414 :                         if (!connectNoDelay(conn))
    2569             :                         {
    2570             :                             /* error message already created */
    2571           0 :                             conn->try_next_addr = true;
    2572           0 :                             goto keep_going;
    2573             :                         }
    2574             :                     }
    2575        8666 :                     if (!pg_set_noblock(conn->sock))
    2576             :                     {
    2577           0 :                         appendPQExpBuffer(&conn->errorMessage,
    2578           0 :                                           libpq_gettext("could not set socket to nonblocking mode: %s\n"),
    2579           0 :                                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2580           0 :                         conn->try_next_addr = true;
    2581           0 :                         goto keep_going;
    2582             :                     }
    2583             : 
    2584             : #ifdef F_SETFD
    2585        8666 :                     if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
    2586             :                     {
    2587           0 :                         appendPQExpBuffer(&conn->errorMessage,
    2588           0 :                                           libpq_gettext("could not set socket to close-on-exec mode: %s\n"),
    2589           0 :                                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2590           0 :                         conn->try_next_addr = true;
    2591           0 :                         goto keep_going;
    2592             :                     }
    2593             : #endif                          /* F_SETFD */
    2594             : 
    2595        8666 :                     if (!IS_AF_UNIX(addr_cur->ai_family))
    2596             :                     {
    2597             : #ifndef WIN32
    2598         414 :                         int         on = 1;
    2599             : #endif
    2600         414 :                         int         usekeepalives = useKeepalives(conn);
    2601         414 :                         int         err = 0;
    2602             : 
    2603         414 :                         if (usekeepalives < 0)
    2604             :                         {
    2605           0 :                             appendPQExpBufferStr(&conn->errorMessage,
    2606           0 :                                                  libpq_gettext("keepalives parameter must be an integer\n"));
    2607           0 :                             err = 1;
    2608             :                         }
    2609         414 :                         else if (usekeepalives == 0)
    2610             :                         {
    2611             :                             /* Do nothing */
    2612             :                         }
    2613             : #ifndef WIN32
    2614         414 :                         else if (setsockopt(conn->sock,
    2615             :                                             SOL_SOCKET, SO_KEEPALIVE,
    2616             :                                             (char *) &on, sizeof(on)) < 0)
    2617             :                         {
    2618           0 :                             appendPQExpBuffer(&conn->errorMessage,
    2619           0 :                                               libpq_gettext("setsockopt(%s) failed: %s\n"),
    2620             :                                               "SO_KEEPALIVE",
    2621           0 :                                               SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2622           0 :                             err = 1;
    2623             :                         }
    2624         414 :                         else if (!setKeepalivesIdle(conn)
    2625         414 :                                  || !setKeepalivesInterval(conn)
    2626         414 :                                  || !setKeepalivesCount(conn))
    2627           0 :                             err = 1;
    2628             : #else                           /* WIN32 */
    2629             : #ifdef SIO_KEEPALIVE_VALS
    2630             :                         else if (!setKeepalivesWin32(conn))
    2631             :                             err = 1;
    2632             : #endif                          /* SIO_KEEPALIVE_VALS */
    2633             : #endif                          /* WIN32 */
    2634         414 :                         else if (!setTCPUserTimeout(conn))
    2635           0 :                             err = 1;
    2636             : 
    2637         414 :                         if (err)
    2638             :                         {
    2639           0 :                             conn->try_next_addr = true;
    2640           0 :                             goto keep_going;
    2641             :                         }
    2642             :                     }
    2643             : 
    2644             :                     /*----------
    2645             :                      * We have three methods of blocking SIGPIPE during
    2646             :                      * send() calls to this socket:
    2647             :                      *
    2648             :                      *  - setsockopt(sock, SO_NOSIGPIPE)
    2649             :                      *  - send(sock, ..., MSG_NOSIGNAL)
    2650             :                      *  - setting the signal mask to SIG_IGN during send()
    2651             :                      *
    2652             :                      * The third method requires three syscalls per send,
    2653             :                      * so we prefer either of the first two, but they are
    2654             :                      * less portable.  The state is tracked in the following
    2655             :                      * members of PGconn:
    2656             :                      *
    2657             :                      * conn->sigpipe_so      - we have set up SO_NOSIGPIPE
    2658             :                      * conn->sigpipe_flag    - we're specifying MSG_NOSIGNAL
    2659             :                      *
    2660             :                      * If we can use SO_NOSIGPIPE, then set sigpipe_so here
    2661             :                      * and we're done.  Otherwise, set sigpipe_flag so that
    2662             :                      * we will try MSG_NOSIGNAL on sends.  If we get an error
    2663             :                      * with MSG_NOSIGNAL, we'll clear that flag and revert to
    2664             :                      * signal masking.
    2665             :                      *----------
    2666             :                      */
    2667        8666 :                     conn->sigpipe_so = false;
    2668             : #ifdef MSG_NOSIGNAL
    2669        8666 :                     conn->sigpipe_flag = true;
    2670             : #else
    2671             :                     conn->sigpipe_flag = false;
    2672             : #endif                          /* MSG_NOSIGNAL */
    2673             : 
    2674             : #ifdef SO_NOSIGPIPE
    2675             :                     optval = 1;
    2676             :                     if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE,
    2677             :                                    (char *) &optval, sizeof(optval)) == 0)
    2678             :                     {
    2679             :                         conn->sigpipe_so = true;
    2680             :                         conn->sigpipe_flag = false;
    2681             :                     }
    2682             : #endif                          /* SO_NOSIGPIPE */
    2683             : 
    2684             :                     /*
    2685             :                      * Start/make connection.  This should not block, since we
    2686             :                      * are in nonblock mode.  If it does, well, too bad.
    2687             :                      */
    2688        8666 :                     if (connect(conn->sock, addr_cur->ai_addr,
    2689             :                                 addr_cur->ai_addrlen) < 0)
    2690             :                     {
    2691         740 :                         if (SOCK_ERRNO == EINPROGRESS ||
    2692             : #ifdef WIN32
    2693             :                             SOCK_ERRNO == EWOULDBLOCK ||
    2694             : #endif
    2695         326 :                             SOCK_ERRNO == EINTR)
    2696             :                         {
    2697             :                             /*
    2698             :                              * This is fine - we're in non-blocking mode, and
    2699             :                              * the connection is in progress.  Tell caller to
    2700             :                              * wait for write-ready on socket.
    2701             :                              */
    2702         414 :                             conn->status = CONNECTION_STARTED;
    2703         414 :                             return PGRES_POLLING_WRITING;
    2704             :                         }
    2705             :                         /* otherwise, trouble */
    2706             :                     }
    2707             :                     else
    2708             :                     {
    2709             :                         /*
    2710             :                          * Hm, we're connected already --- seems the "nonblock
    2711             :                          * connection" wasn't.  Advance the state machine and
    2712             :                          * go do the next stuff.
    2713             :                          */
    2714        7926 :                         conn->status = CONNECTION_STARTED;
    2715        7926 :                         goto keep_going;
    2716             :                     }
    2717             : 
    2718             :                     /*
    2719             :                      * This connection failed.  Add the error report to
    2720             :                      * conn->errorMessage, then try the next address if any.
    2721             :                      */
    2722         326 :                     connectFailureMessage(conn, SOCK_ERRNO);
    2723         326 :                     conn->try_next_addr = true;
    2724         326 :                     goto keep_going;
    2725             :                 }
    2726             :             }
    2727             : 
    2728        8340 :         case CONNECTION_STARTED:
    2729             :             {
    2730        8340 :                 ACCEPT_TYPE_ARG3 optlen = sizeof(optval);
    2731             : 
    2732             :                 /*
    2733             :                  * Write ready, since we've made it here, so the connection
    2734             :                  * has been made ... or has failed.
    2735             :                  */
    2736             : 
    2737             :                 /*
    2738             :                  * Now check (using getsockopt) that there is not an error
    2739             :                  * state waiting for us on the socket.
    2740             :                  */
    2741             : 
    2742        8340 :                 if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
    2743             :                                (char *) &optval, &optlen) == -1)
    2744             :                 {
    2745           0 :                     appendPQExpBuffer(&conn->errorMessage,
    2746           0 :                                       libpq_gettext("could not get socket error status: %s\n"),
    2747           0 :                                       SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2748           0 :                     goto error_return;
    2749             :                 }
    2750        8340 :                 else if (optval != 0)
    2751             :                 {
    2752             :                     /*
    2753             :                      * When using a nonblocking connect, we will typically see
    2754             :                      * connect failures at this point, so provide a friendly
    2755             :                      * error message.
    2756             :                      */
    2757          10 :                     connectFailureMessage(conn, optval);
    2758             : 
    2759             :                     /*
    2760             :                      * Try the next address if any, just as in the case where
    2761             :                      * connect() returned failure immediately.
    2762             :                      */
    2763          10 :                     conn->try_next_addr = true;
    2764          10 :                     goto keep_going;
    2765             :                 }
    2766             : 
    2767             :                 /* Fill in the client address */
    2768        8330 :                 conn->laddr.salen = sizeof(conn->laddr.addr);
    2769        8330 :                 if (getsockname(conn->sock,
    2770        8330 :                                 (struct sockaddr *) &conn->laddr.addr,
    2771             :                                 &conn->laddr.salen) < 0)
    2772             :                 {
    2773           0 :                     appendPQExpBuffer(&conn->errorMessage,
    2774           0 :                                       libpq_gettext("could not get client address from socket: %s\n"),
    2775           0 :                                       SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2776           0 :                     goto error_return;
    2777             :                 }
    2778             : 
    2779             :                 /*
    2780             :                  * Make sure we can write before advancing to next step.
    2781             :                  */
    2782        8330 :                 conn->status = CONNECTION_MADE;
    2783        8330 :                 return PGRES_POLLING_WRITING;
    2784             :             }
    2785             : 
    2786        8698 :         case CONNECTION_MADE:
    2787             :             {
    2788             :                 char       *startpacket;
    2789             :                 int         packetlen;
    2790             : 
    2791             :                 /*
    2792             :                  * Implement requirepeer check, if requested and it's a
    2793             :                  * Unix-domain socket.
    2794             :                  */
    2795        8698 :                 if (conn->requirepeer && conn->requirepeer[0] &&
    2796           0 :                     IS_AF_UNIX(conn->raddr.addr.ss_family))
    2797             :                 {
    2798             : #ifndef WIN32
    2799             :                     char        pwdbuf[BUFSIZ];
    2800             :                     struct passwd pass_buf;
    2801             :                     struct passwd *pass;
    2802             :                     int         passerr;
    2803             : #endif
    2804             :                     uid_t       uid;
    2805             :                     gid_t       gid;
    2806             : 
    2807           0 :                     errno = 0;
    2808           0 :                     if (getpeereid(conn->sock, &uid, &gid) != 0)
    2809             :                     {
    2810             :                         /*
    2811             :                          * Provide special error message if getpeereid is a
    2812             :                          * stub
    2813             :                          */
    2814           0 :                         if (errno == ENOSYS)
    2815           0 :                             appendPQExpBufferStr(&conn->errorMessage,
    2816           0 :                                                  libpq_gettext("requirepeer parameter is not supported on this platform\n"));
    2817             :                         else
    2818           0 :                             appendPQExpBuffer(&conn->errorMessage,
    2819           0 :                                               libpq_gettext("could not get peer credentials: %s\n"),
    2820           0 :                                               strerror_r(errno, sebuf, sizeof(sebuf)));
    2821           0 :                         goto error_return;
    2822             :                     }
    2823             : 
    2824             : #ifndef WIN32
    2825           0 :                     passerr = pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
    2826           0 :                     if (pass == NULL)
    2827             :                     {
    2828           0 :                         if (passerr != 0)
    2829           0 :                             appendPQExpBuffer(&conn->errorMessage,
    2830           0 :                                               libpq_gettext("could not look up local user ID %d: %s\n"),
    2831             :                                               (int) uid,
    2832             :                                               strerror_r(passerr, sebuf, sizeof(sebuf)));
    2833             :                         else
    2834           0 :                             appendPQExpBuffer(&conn->errorMessage,
    2835           0 :                                               libpq_gettext("local user with ID %d does not exist\n"),
    2836             :                                               (int) uid);
    2837           0 :                         goto error_return;
    2838             :                     }
    2839             : 
    2840           0 :                     if (strcmp(pass->pw_name, conn->requirepeer) != 0)
    2841             :                     {
    2842           0 :                         appendPQExpBuffer(&conn->errorMessage,
    2843           0 :                                           libpq_gettext("requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n"),
    2844           0 :                                           conn->requirepeer, pass->pw_name);
    2845           0 :                         goto error_return;
    2846             :                     }
    2847             : #else                           /* WIN32 */
    2848             :                     /* should have failed with ENOSYS above */
    2849             :                     Assert(false);
    2850             : #endif                          /* WIN32 */
    2851             :                 }
    2852             : 
    2853        8698 :                 if (IS_AF_UNIX(conn->raddr.addr.ss_family))
    2854             :                 {
    2855             :                     /* Don't request SSL or GSSAPI over Unix sockets */
    2856             : #ifdef USE_SSL
    2857        7926 :                     conn->allow_ssl_try = false;
    2858             : #endif
    2859             : #ifdef ENABLE_GSS
    2860             :                     conn->try_gss = false;
    2861             : #endif
    2862             :                 }
    2863             : 
    2864             : #ifdef ENABLE_GSS
    2865             : 
    2866             :                 /*
    2867             :                  * If GSSAPI encryption is enabled, then call
    2868             :                  * pg_GSS_have_cred_cache() which will return true if we can
    2869             :                  * acquire credentials (and give us a handle to use in
    2870             :                  * conn->gcred), and then send a packet to the server asking
    2871             :                  * for GSSAPI Encryption (and skip past SSL negotiation and
    2872             :                  * regular startup below).
    2873             :                  */
    2874             :                 if (conn->try_gss && !conn->gctx)
    2875             :                     conn->try_gss = pg_GSS_have_cred_cache(&conn->gcred);
    2876             :                 if (conn->try_gss && !conn->gctx)
    2877             :                 {
    2878             :                     ProtocolVersion pv = pg_hton32(NEGOTIATE_GSS_CODE);
    2879             : 
    2880             :                     if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
    2881             :                     {
    2882             :                         appendPQExpBuffer(&conn->errorMessage,
    2883             :                                           libpq_gettext("could not send GSSAPI negotiation packet: %s\n"),
    2884             :                                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2885             :                         goto error_return;
    2886             :                     }
    2887             : 
    2888             :                     /* Ok, wait for response */
    2889             :                     conn->status = CONNECTION_GSS_STARTUP;
    2890             :                     return PGRES_POLLING_READING;
    2891             :                 }
    2892             :                 else if (!conn->gctx && conn->gssencmode[0] == 'r')
    2893             :                 {
    2894             :                     appendPQExpBufferStr(&conn->errorMessage,
    2895             :                                          libpq_gettext("GSSAPI encryption required but was impossible (possibly no credential cache, no server support, or using a local socket)\n"));
    2896             :                     goto error_return;
    2897             :                 }
    2898             : #endif
    2899             : 
    2900             : #ifdef USE_SSL
    2901             : 
    2902             :                 /*
    2903             :                  * If SSL is enabled and we haven't already got it running,
    2904             :                  * request it instead of sending the startup message.
    2905             :                  */
    2906        8698 :                 if (conn->allow_ssl_try && !conn->wait_ssl_try &&
    2907         478 :                     !conn->ssl_in_use)
    2908             :                 {
    2909             :                     ProtocolVersion pv;
    2910             : 
    2911             :                     /*
    2912             :                      * Send the SSL request packet.
    2913             :                      *
    2914             :                      * Theoretically, this could block, but it really
    2915             :                      * shouldn't since we only got here if the socket is
    2916             :                      * write-ready.
    2917             :                      */
    2918         402 :                     pv = pg_hton32(NEGOTIATE_SSL_CODE);
    2919         402 :                     if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
    2920             :                     {
    2921           0 :                         appendPQExpBuffer(&conn->errorMessage,
    2922           0 :                                           libpq_gettext("could not send SSL negotiation packet: %s\n"),
    2923           0 :                                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2924           0 :                         goto error_return;
    2925             :                     }
    2926             :                     /* Ok, wait for response */
    2927         402 :                     conn->status = CONNECTION_SSL_STARTUP;
    2928         402 :                     return PGRES_POLLING_READING;
    2929             :                 }
    2930             : #endif                          /* USE_SSL */
    2931             : 
    2932             :                 /*
    2933             :                  * Build the startup packet.
    2934             :                  */
    2935        8296 :                 if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
    2936        8296 :                     startpacket = pqBuildStartupPacket3(conn, &packetlen,
    2937             :                                                         EnvironmentOptions);
    2938             :                 else
    2939           0 :                     startpacket = pqBuildStartupPacket2(conn, &packetlen,
    2940             :                                                         EnvironmentOptions);
    2941        8296 :                 if (!startpacket)
    2942             :                 {
    2943             :                     /*
    2944             :                      * will not appendbuffer here, since it's likely to also
    2945             :                      * run out of memory
    2946             :                      */
    2947           0 :                     printfPQExpBuffer(&conn->errorMessage,
    2948           0 :                                       libpq_gettext("out of memory\n"));
    2949           0 :                     goto error_return;
    2950             :                 }
    2951             : 
    2952             :                 /*
    2953             :                  * Send the startup packet.
    2954             :                  *
    2955             :                  * Theoretically, this could block, but it really shouldn't
    2956             :                  * since we only got here if the socket is write-ready.
    2957             :                  */
    2958        8296 :                 if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
    2959             :                 {
    2960           0 :                     appendPQExpBuffer(&conn->errorMessage,
    2961           0 :                                       libpq_gettext("could not send startup packet: %s\n"),
    2962           0 :                                       SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2963           0 :                     free(startpacket);
    2964           0 :                     goto error_return;
    2965             :                 }
    2966             : 
    2967        8296 :                 free(startpacket);
    2968             : 
    2969        8296 :                 conn->status = CONNECTION_AWAITING_RESPONSE;
    2970        8296 :                 return PGRES_POLLING_READING;
    2971             :             }
    2972             : 
    2973             :             /*
    2974             :              * Handle SSL negotiation: wait for postmaster messages and
    2975             :              * respond as necessary.
    2976             :              */
    2977         606 :         case CONNECTION_SSL_STARTUP:
    2978             :             {
    2979             : #ifdef USE_SSL
    2980             :                 PostgresPollingStatusType pollres;
    2981             : 
    2982             :                 /*
    2983             :                  * On first time through, get the postmaster's response to our
    2984             :                  * SSL negotiation packet.
    2985             :                  */
    2986         606 :                 if (!conn->ssl_in_use)
    2987             :                 {
    2988             :                     /*
    2989             :                      * We use pqReadData here since it has the logic to
    2990             :                      * distinguish no-data-yet from connection closure. Since
    2991             :                      * conn->ssl isn't set, a plain recv() will occur.
    2992             :                      */
    2993             :                     char        SSLok;
    2994             :                     int         rdresult;
    2995             : 
    2996         402 :                     rdresult = pqReadData(conn);
    2997         402 :                     if (rdresult < 0)
    2998             :                     {
    2999             :                         /* errorMessage is already filled in */
    3000           0 :                         goto error_return;
    3001             :                     }
    3002         402 :                     if (rdresult == 0)
    3003             :                     {
    3004             :                         /* caller failed to wait for data */
    3005         292 :                         return PGRES_POLLING_READING;
    3006             :                     }
    3007         402 :                     if (pqGetc(&SSLok, conn) < 0)
    3008             :                     {
    3009             :                         /* should not happen really */
    3010           0 :                         return PGRES_POLLING_READING;
    3011             :                     }
    3012         402 :                     if (SSLok == 'S')
    3013             :                     {
    3014             :                         /* mark byte consumed */
    3015         110 :                         conn->inStart = conn->inCursor;
    3016             :                         /* Set up global SSL state if required */
    3017         110 :                         if (pqsecure_initialize(conn) != 0)
    3018           0 :                             goto error_return;
    3019             :                     }
    3020         292 :                     else if (SSLok == 'N')
    3021             :                     {
    3022             :                         /* mark byte consumed */
    3023         292 :                         conn->inStart = conn->inCursor;
    3024             :                         /* OK to do without SSL? */
    3025         292 :                         if (conn->sslmode[0] == 'r' ||   /* "require" */
    3026         292 :                             conn->sslmode[0] == 'v') /* "verify-ca" or
    3027             :                                                          * "verify-full" */
    3028             :                         {
    3029             :                             /* Require SSL, but server does not want it */
    3030           0 :                             appendPQExpBufferStr(&conn->errorMessage,
    3031           0 :                                                  libpq_gettext("server does not support SSL, but SSL was required\n"));
    3032           0 :                             goto error_return;
    3033             :                         }
    3034             :                         /* Otherwise, proceed with normal startup */
    3035         292 :                         conn->allow_ssl_try = false;
    3036         292 :                         conn->status = CONNECTION_MADE;
    3037         292 :                         return PGRES_POLLING_WRITING;
    3038             :                     }
    3039           0 :                     else if (SSLok == 'E')
    3040             :                     {
    3041             :                         /*
    3042             :                          * Server failure of some sort, such as failure to
    3043             :                          * fork a backend process.  We need to process and
    3044             :                          * report the error message, which might be formatted
    3045             :                          * according to either protocol 2 or protocol 3.
    3046             :                          * Rather than duplicate the code for that, we flip
    3047             :                          * into AWAITING_RESPONSE state and let the code there
    3048             :                          * deal with it.  Note we have *not* consumed the "E"
    3049             :                          * byte here.
    3050             :                          */
    3051           0 :                         conn->status = CONNECTION_AWAITING_RESPONSE;
    3052           0 :                         goto keep_going;
    3053             :                     }
    3054             :                     else
    3055             :                     {
    3056           0 :                         appendPQExpBuffer(&conn->errorMessage,
    3057           0 :                                           libpq_gettext("received invalid response to SSL negotiation: %c\n"),
    3058             :                                           SSLok);
    3059           0 :                         goto error_return;
    3060             :                     }
    3061             :                 }
    3062             : 
    3063             :                 /*
    3064             :                  * Begin or continue the SSL negotiation process.
    3065             :                  */
    3066         314 :                 pollres = pqsecure_open_client(conn);
    3067         314 :                 if (pollres == PGRES_POLLING_OK)
    3068             :                 {
    3069             :                     /* SSL handshake done, ready to send startup packet */
    3070          76 :                     conn->status = CONNECTION_MADE;
    3071          76 :                     return PGRES_POLLING_WRITING;
    3072             :                 }
    3073         238 :                 if (pollres == PGRES_POLLING_FAILED)
    3074             :                 {
    3075             :                     /*
    3076             :                      * Failed ... if sslmode is "prefer" then do a non-SSL
    3077             :                      * retry
    3078             :                      */
    3079          34 :                     if (conn->sslmode[0] == 'p' /* "prefer" */
    3080           0 :                         && conn->allow_ssl_try   /* redundant? */
    3081           0 :                         && !conn->wait_ssl_try) /* redundant? */
    3082             :                     {
    3083             :                         /* only retry once */
    3084           0 :                         conn->allow_ssl_try = false;
    3085           0 :                         need_new_connection = true;
    3086           0 :                         goto keep_going;
    3087             :                     }
    3088             :                     /* Else it's a hard failure */
    3089          34 :                     goto error_return;
    3090             :                 }
    3091             :                 /* Else, return POLLING_READING or POLLING_WRITING status */
    3092         204 :                 return pollres;
    3093             : #else                           /* !USE_SSL */
    3094             :                 /* can't get here */
    3095             :                 goto error_return;
    3096             : #endif                          /* USE_SSL */
    3097             :             }
    3098             : 
    3099           0 :         case CONNECTION_GSS_STARTUP:
    3100             :             {
    3101             : #ifdef ENABLE_GSS
    3102             :                 PostgresPollingStatusType pollres;
    3103             : 
    3104             :                 /*
    3105             :                  * If we haven't yet, get the postmaster's response to our
    3106             :                  * negotiation packet
    3107             :                  */
    3108             :                 if (conn->try_gss && !conn->gctx)
    3109             :                 {
    3110             :                     char        gss_ok;
    3111             :                     int         rdresult = pqReadData(conn);
    3112             : 
    3113             :                     if (rdresult < 0)
    3114             :                         /* pqReadData fills in error message */
    3115             :                         goto error_return;
    3116             :                     else if (rdresult == 0)
    3117             :                         /* caller failed to wait for data */
    3118             :                         return PGRES_POLLING_READING;
    3119             :                     if (pqGetc(&gss_ok, conn) < 0)
    3120             :                         /* shouldn't happen... */
    3121             :                         return PGRES_POLLING_READING;
    3122             : 
    3123             :                     if (gss_ok == 'E')
    3124             :                     {
    3125             :                         /*
    3126             :                          * Server failure of some sort.  Assume it's a
    3127             :                          * protocol version support failure, and let's see if
    3128             :                          * we can't recover (if it's not, we'll get a better
    3129             :                          * error message on retry).  Server gets fussy if we
    3130             :                          * don't hang up the socket, though.
    3131             :                          */
    3132             :                         conn->try_gss = false;
    3133             :                         pqDropConnection(conn, true);
    3134             :                         conn->status = CONNECTION_NEEDED;
    3135             :                         goto keep_going;
    3136             :                     }
    3137             : 
    3138             :                     /* mark byte consumed */
    3139             :                     conn->inStart = conn->inCursor;
    3140             : 
    3141             :                     if (gss_ok == 'N')
    3142             :                     {
    3143             :                         /* Server doesn't want GSSAPI; fall back if we can */
    3144             :                         if (conn->gssencmode[0] == 'r')
    3145             :                         {
    3146             :                             appendPQExpBufferStr(&conn->errorMessage,
    3147             :                                                  libpq_gettext("server doesn't support GSSAPI encryption, but it was required\n"));
    3148             :                             goto error_return;
    3149             :                         }
    3150             : 
    3151             :                         conn->try_gss = false;
    3152             :                         conn->status = CONNECTION_MADE;
    3153             :                         return PGRES_POLLING_WRITING;
    3154             :                     }
    3155             :                     else if (gss_ok != 'G')
    3156             :                     {
    3157             :                         appendPQExpBuffer(&conn->errorMessage,
    3158             :                                           libpq_gettext("received invalid response to GSSAPI negotiation: %c\n"),
    3159             :                                           gss_ok);
    3160             :                         goto error_return;
    3161             :                     }
    3162             :                 }
    3163             : 
    3164             :                 /* Begin or continue GSSAPI negotiation */
    3165             :                 pollres = pqsecure_open_gss(conn);
    3166             :                 if (pollres == PGRES_POLLING_OK)
    3167             :                 {
    3168             :                     /* All set for startup packet */
    3169             :                     conn->status = CONNECTION_MADE;
    3170             :                     return PGRES_POLLING_WRITING;
    3171             :                 }
    3172             :                 else if (pollres == PGRES_POLLING_FAILED &&
    3173             :                          conn->gssencmode[0] == 'p')
    3174             :                 {
    3175             :                     /*
    3176             :                      * We failed, but we can retry on "prefer".  Have to drop
    3177             :                      * the current connection to do so, though.
    3178             :                      */
    3179             :                     conn->try_gss = false;
    3180             :                     pqDropConnection(conn, true);
    3181             :                     conn->status = CONNECTION_NEEDED;
    3182             :                     goto keep_going;
    3183             :                 }
    3184             :                 return pollres;
    3185             : #else                           /* !ENABLE_GSS */
    3186             :                 /* unreachable */
    3187           0 :                 goto error_return;
    3188             : #endif                          /* ENABLE_GSS */
    3189             :             }
    3190             : 
    3191             :             /*
    3192             :              * Handle authentication exchange: wait for postmaster messages
    3193             :              * and respond as necessary.
    3194             :              */
    3195        8550 :         case CONNECTION_AWAITING_RESPONSE:
    3196             :             {
    3197             :                 char        beresp;
    3198             :                 int         msgLength;
    3199             :                 int         avail;
    3200             :                 AuthRequest areq;
    3201             :                 int         res;
    3202             : 
    3203             :                 /*
    3204             :                  * Scan the message from current point (note that if we find
    3205             :                  * the message is incomplete, we will return without advancing
    3206             :                  * inStart, and resume here next time).
    3207             :                  */
    3208        8550 :                 conn->inCursor = conn->inStart;
    3209             : 
    3210             :                 /* Read type byte */
    3211        8550 :                 if (pqGetc(&beresp, conn))
    3212             :                 {
    3213             :                     /* We'll come back when there is more data */
    3214         122 :                     return PGRES_POLLING_READING;
    3215             :                 }
    3216             : 
    3217             :                 /*
    3218             :                  * Validate message type: we expect only an authentication
    3219             :                  * request or an error here.  Anything else probably means
    3220             :                  * it's not Postgres on the other end at all.
    3221             :                  */
    3222        8428 :                 if (!(beresp == 'R' || beresp == 'E'))
    3223             :                 {
    3224           0 :                     appendPQExpBuffer(&conn->errorMessage,
    3225           0 :                                       libpq_gettext("expected authentication request from server, but received %c\n"),
    3226             :                                       beresp);
    3227          80 :                     goto error_return;
    3228             :                 }
    3229             : 
    3230        8428 :                 if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
    3231             :                 {
    3232             :                     /* Read message length word */
    3233        8428 :                     if (pqGetInt(&msgLength, 4, conn))
    3234             :                     {
    3235             :                         /* We'll come back when there is more data */
    3236           0 :                         return PGRES_POLLING_READING;
    3237             :                     }
    3238             :                 }
    3239             :                 else
    3240             :                 {
    3241             :                     /* Set phony message length to disable checks below */
    3242           0 :                     msgLength = 8;
    3243             :                 }
    3244             : 
    3245             :                 /*
    3246             :                  * Try to validate message length before using it.
    3247             :                  * Authentication requests can't be very large, although GSS
    3248             :                  * auth requests may not be that small.  Errors can be a
    3249             :                  * little larger, but not huge.  If we see a large apparent
    3250             :                  * length in an error, it means we're really talking to a
    3251             :                  * pre-3.0-protocol server; cope.
    3252             :                  */
    3253        8428 :                 if (beresp == 'R' && (msgLength < 8 || msgLength > 2000))
    3254             :                 {
    3255           0 :                     appendPQExpBuffer(&conn->errorMessage,
    3256           0 :                                       libpq_gettext("expected authentication request from server, but received %c\n"),
    3257             :                                       beresp);
    3258           0 :                     goto error_return;
    3259             :                 }
    3260             : 
    3261        8428 :                 if (beresp == 'E' && (msgLength < 8 || msgLength > 30000))
    3262             :                 {
    3263             :                     /* Handle error from a pre-3.0 server */
    3264           0 :                     conn->inCursor = conn->inStart + 1; /* reread data */
    3265           0 :                     if (pqGets_append(&conn->errorMessage, conn))
    3266             :                     {
    3267             :                         /* We'll come back when there is more data */
    3268           0 :                         return PGRES_POLLING_READING;
    3269             :                     }
    3270             :                     /* OK, we read the message; mark data consumed */
    3271           0 :                     conn->inStart = conn->inCursor;
    3272             : 
    3273             :                     /*
    3274             :                      * The postmaster typically won't end its message with a
    3275             :                      * newline, so add one to conform to libpq conventions.
    3276             :                      */
    3277           0 :                     appendPQExpBufferChar(&conn->errorMessage, '\n');
    3278             : 
    3279             :                     /*
    3280             :                      * If we tried to open the connection in 3.0 protocol,
    3281             :                      * fall back to 2.0 protocol.
    3282             :                      */
    3283           0 :                     if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
    3284             :                     {
    3285           0 :                         conn->pversion = PG_PROTOCOL(2, 0);
    3286           0 :                         need_new_connection = true;
    3287        8348 :                         goto keep_going;
    3288             :                     }
    3289             : 
    3290           0 :                     goto error_return;
    3291             :                 }
    3292             : 
    3293             :                 /*
    3294             :                  * Can't process if message body isn't all here yet.
    3295             :                  *
    3296             :                  * (In protocol 2.0 case, we are assuming messages carry at
    3297             :                  * least 4 bytes of data.)
    3298             :                  */
    3299        8428 :                 msgLength -= 4;
    3300        8428 :                 avail = conn->inEnd - conn->inCursor;
    3301        8428 :                 if (avail < msgLength)
    3302             :                 {
    3303             :                     /*
    3304             :                      * Before returning, try to enlarge the input buffer if
    3305             :                      * needed to hold the whole message; see notes in
    3306             :                      * pqParseInput3.
    3307             :                      */
    3308           0 :                     if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
    3309             :                                              conn))
    3310           0 :                         goto error_return;
    3311             :                     /* We'll come back when there is more data */
    3312           0 :                     return PGRES_POLLING_READING;
    3313             :                 }
    3314             : 
    3315             :                 /* Handle errors. */
    3316        8428 :                 if (beresp == 'E')
    3317             :                 {
    3318          72 :                     if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
    3319             :                     {
    3320          72 :                         if (pqGetErrorNotice3(conn, true))
    3321             :                         {
    3322             :                             /* We'll come back when there is more data */
    3323           0 :                             return PGRES_POLLING_READING;
    3324             :                         }
    3325             :                     }
    3326             :                     else
    3327             :                     {
    3328           0 :                         if (pqGets_append(&conn->errorMessage, conn))
    3329             :                         {
    3330             :                             /* We'll come back when there is more data */
    3331           0 :                             return PGRES_POLLING_READING;
    3332             :                         }
    3333             :                     }
    3334             :                     /* OK, we read the message; mark data consumed */
    3335          72 :                     conn->inStart = conn->inCursor;
    3336             : 
    3337             :                     /* Check to see if we should mention pgpassfile */
    3338          72 :                     pgpassfileWarning(conn);
    3339             : 
    3340             : #ifdef ENABLE_GSS
    3341             : 
    3342             :                     /*
    3343             :                      * If gssencmode is "prefer" and we're using GSSAPI, retry
    3344             :                      * without it.
    3345             :                      */
    3346             :                     if (conn->gssenc && conn->gssencmode[0] == 'p')
    3347             :                     {
    3348             :                         OM_uint32   minor;
    3349             : 
    3350             :                         /* postmaster expects us to drop the connection */
    3351             :                         conn->try_gss = false;
    3352             :                         conn->gssenc = false;
    3353             :                         gss_delete_sec_context(&minor, &conn->gctx, NULL);
    3354             :                         pqDropConnection(conn, true);
    3355             :                         conn->status = CONNECTION_NEEDED;
    3356             :                         goto keep_going;
    3357             :                     }
    3358             : #endif
    3359             : 
    3360             : #ifdef USE_SSL
    3361             : 
    3362             :                     /*
    3363             :                      * if sslmode is "allow" and we haven't tried an SSL
    3364             :                      * connection already, then retry with an SSL connection
    3365             :                      */
    3366          72 :                     if (conn->sslmode[0] == 'a' /* "allow" */
    3367           0 :                         && !conn->ssl_in_use
    3368           0 :                         && conn->allow_ssl_try
    3369           0 :                         && conn->wait_ssl_try)
    3370             :                     {
    3371             :                         /* only retry once */
    3372           0 :                         conn->wait_ssl_try = false;
    3373           0 :                         need_new_connection = true;
    3374           0 :                         goto keep_going;
    3375             :                     }
    3376             : 
    3377             :                     /*
    3378             :                      * if sslmode is "prefer" and we're in an SSL connection,
    3379             :                      * then do a non-SSL retry
    3380             :                      */
    3381          72 :                     if (conn->sslmode[0] == 'p' /* "prefer" */
    3382          64 :                         && conn->ssl_in_use
    3383           0 :                         && conn->allow_ssl_try   /* redundant? */
    3384           0 :                         && !conn->wait_ssl_try) /* redundant? */
    3385             :                     {
    3386             :                         /* only retry once */
    3387           0 :                         conn->allow_ssl_try = false;
    3388           0 :                         need_new_connection = true;
    3389           0 :                         goto keep_going;
    3390             :                     }
    3391             : #endif
    3392             : 
    3393          72 :                     goto error_return;
    3394             :                 }
    3395             : 
    3396             :                 /* It is an authentication request. */
    3397        8356 :                 conn->auth_req_received = true;
    3398             : 
    3399             :                 /* Get the type of request. */
    3400        8356 :                 if (pqGetInt((int *) &areq, 4, conn))
    3401             :                 {
    3402             :                     /* We'll come back when there are more data */
    3403           0 :                     return PGRES_POLLING_READING;
    3404             :                 }
    3405        8356 :                 msgLength -= 4;
    3406             : 
    3407             :                 /*
    3408             :                  * Ensure the password salt is in the input buffer, if it's an
    3409             :                  * MD5 request.  All the other authentication methods that
    3410             :                  * contain extra data in the authentication request are only
    3411             :                  * supported in protocol version 3, in which case we already
    3412             :                  * read the whole message above.
    3413             :                  */
    3414        8356 :                 if (areq == AUTH_REQ_MD5 && PG_PROTOCOL_MAJOR(conn->pversion) < 3)
    3415             :                 {
    3416           0 :                     msgLength += 4;
    3417             : 
    3418           0 :                     avail = conn->inEnd - conn->inCursor;
    3419           0 :                     if (avail < 4)
    3420             :                     {
    3421             :                         /*
    3422             :                          * Before returning, try to enlarge the input buffer
    3423             :                          * if needed to hold the whole message; see notes in
    3424             :                          * pqParseInput3.
    3425             :                          */
    3426           0 :                         if (pqCheckInBufferSpace(conn->inCursor + (size_t) 4,
    3427             :                                                  conn))
    3428           0 :                             goto error_return;
    3429             :                         /* We'll come back when there is more data */
    3430           0 :                         return PGRES_POLLING_READING;
    3431             :                     }
    3432             :                 }
    3433             : 
    3434             :                 /*
    3435             :                  * Process the rest of the authentication request message, and
    3436             :                  * respond to it if necessary.
    3437             :                  *
    3438             :                  * Note that conn->pghost must be non-NULL if we are going to
    3439             :                  * avoid the Kerberos code doing a hostname look-up.
    3440             :                  */
    3441        8356 :                 res = pg_fe_sendauth(areq, msgLength, conn);
    3442        8356 :                 conn->errorMessage.len = strlen(conn->errorMessage.data);
    3443             : 
    3444             :                 /* OK, we have processed the message; mark data consumed */
    3445        8356 :                 conn->inStart = conn->inCursor;
    3446             : 
    3447        8356 :                 if (res != STATUS_OK)
    3448           8 :                     goto error_return;
    3449             : 
    3450             :                 /*
    3451             :                  * Just make sure that any data sent by pg_fe_sendauth is
    3452             :                  * flushed out.  Although this theoretically could block, it
    3453             :                  * really shouldn't since we don't send large auth responses.
    3454             :                  */
    3455        8348 :                 if (pqFlush(conn))
    3456           0 :                     goto error_return;
    3457             : 
    3458        8348 :                 if (areq == AUTH_REQ_OK)
    3459             :                 {
    3460             :                     /* We are done with authentication exchange */
    3461        8200 :                     conn->status = CONNECTION_AUTH_OK;
    3462             : 
    3463             :                     /*
    3464             :                      * Set asyncStatus so that PQgetResult will think that
    3465             :                      * what comes back next is the result of a query.  See
    3466             :                      * below.
    3467             :                      */
    3468        8200 :                     conn->asyncStatus = PGASYNC_BUSY;
    3469             :                 }
    3470             : 
    3471             :                 /* Look to see if we have more data yet. */
    3472        8348 :                 goto keep_going;
    3473             :             }
    3474             : 
    3475        8200 :         case CONNECTION_AUTH_OK:
    3476             :             {
    3477             :                 /*
    3478             :                  * Now we expect to hear from the backend. A ReadyForQuery
    3479             :                  * message indicates that startup is successful, but we might
    3480             :                  * also get an Error message indicating failure. (Notice
    3481             :                  * messages indicating nonfatal warnings are also allowed by
    3482             :                  * the protocol, as are ParameterStatus and BackendKeyData
    3483             :                  * messages.) Easiest way to handle this is to let
    3484             :                  * PQgetResult() read the messages. We just have to fake it
    3485             :                  * out about the state of the connection, by setting
    3486             :                  * asyncStatus = PGASYNC_BUSY (done above).
    3487             :                  */
    3488             : 
    3489        8200 :                 if (PQisBusy(conn))
    3490           0 :                     return PGRES_POLLING_READING;
    3491             : 
    3492        8200 :                 res = PQgetResult(conn);
    3493             : 
    3494             :                 /*
    3495             :                  * NULL return indicating we have gone to IDLE state is
    3496             :                  * expected
    3497             :                  */
    3498        8200 :                 if (res)
    3499             :                 {
    3500          22 :                     if (res->resultStatus != PGRES_FATAL_ERROR)
    3501           0 :                         appendPQExpBufferStr(&conn->errorMessage,
    3502           0 :                                              libpq_gettext("unexpected message from server during startup\n"));
    3503          22 :                     else if (conn->send_appname &&
    3504          22 :                              (conn->appname || conn->fbappname))
    3505             :                     {
    3506             :                         /*
    3507             :                          * If we tried to send application_name, check to see
    3508             :                          * if the error is about that --- pre-9.0 servers will
    3509             :                          * reject it at this stage of the process.  If so,
    3510             :                          * close the connection and retry without sending
    3511             :                          * application_name.  We could possibly get a false
    3512             :                          * SQLSTATE match here and retry uselessly, but there
    3513             :                          * seems no great harm in that; we'll just get the
    3514             :                          * same error again if it's unrelated.
    3515             :                          */
    3516             :                         const char *sqlstate;
    3517             : 
    3518          22 :                         sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
    3519          22 :                         if (sqlstate &&
    3520          22 :                             strcmp(sqlstate, ERRCODE_APPNAME_UNKNOWN) == 0)
    3521             :                         {
    3522           0 :                             PQclear(res);
    3523           0 :                             conn->send_appname = false;
    3524           0 :                             need_new_connection = true;
    3525           0 :                             goto keep_going;
    3526             :                         }
    3527             :                     }
    3528             : 
    3529             :                     /*
    3530             :                      * if the resultStatus is FATAL, then conn->errorMessage
    3531             :                      * already has a copy of the error; needn't copy it back.
    3532             :                      * But add a newline if it's not there already, since
    3533             :                      * postmaster error messages may not have one.
    3534             :                      */
    3535          22 :                     if (conn->errorMessage.len <= 0 ||
    3536          22 :                         conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
    3537           0 :                         appendPQExpBufferChar(&conn->errorMessage, '\n');
    3538          22 :                     PQclear(res);
    3539          22 :                     goto error_return;
    3540             :                 }
    3541             : 
    3542             :                 /* Fire up post-connection housekeeping if needed */
    3543        8178 :                 if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
    3544             :                 {
    3545           0 :                     conn->status = CONNECTION_SETENV;
    3546           0 :                     conn->setenv_state = SETENV_STATE_CLIENT_ENCODING_SEND;
    3547           0 :                     conn->next_eo = EnvironmentOptions;
    3548           0 :                     return PGRES_POLLING_WRITING;
    3549             :                 }
    3550             : 
    3551             :                 /* Almost there now ... */
    3552        8178 :                 conn->status = CONNECTION_CHECK_TARGET;
    3553        8178 :                 goto keep_going;
    3554             :             }
    3555             : 
    3556        8178 :         case CONNECTION_CHECK_TARGET:
    3557             :             {
    3558             :                 /*
    3559             :                  * If a read-write connection is required, see if we have one.
    3560             :                  *
    3561             :                  * Servers before 7.4 lack the transaction_read_only GUC, but
    3562             :                  * by the same token they don't have any read-only mode, so we
    3563             :                  * may just skip the test in that case.
    3564             :                  */
    3565        8178 :                 if (conn->sversion >= 70400 &&
    3566        8178 :                     conn->target_session_attrs != NULL &&
    3567        8178 :                     strcmp(conn->target_session_attrs, "read-write") == 0)
    3568             :                 {
    3569             :                     /*
    3570             :                      * Save existing error messages across the PQsendQuery
    3571             :                      * attempt.  This is necessary because PQsendQuery is
    3572             :                      * going to reset conn->errorMessage, so we would lose
    3573             :                      * error messages related to previous hosts we have tried
    3574             :                      * and failed to connect to.
    3575             :                      */
    3576           6 :                     if (!saveErrorMessage(conn, &savedMessage))
    3577           0 :                         goto error_return;
    3578             : 
    3579           6 :                     conn->status = CONNECTION_OK;
    3580           6 :                     if (!PQsendQuery(conn,
    3581             :                                      "SHOW transaction_read_only"))
    3582             :                     {
    3583           0 :                         restoreErrorMessage(conn, &savedMessage);
    3584           0 :                         goto error_return;
    3585             :                     }
    3586           6 :                     conn->status = CONNECTION_CHECK_WRITABLE;
    3587           6 :                     restoreErrorMessage(conn, &savedMessage);
    3588           6 :                     return PGRES_POLLING_READING;
    3589             :                 }
    3590             : 
    3591             :                 /* We can release the address list now. */
    3592        8172 :                 release_conn_addrinfo(conn);
    3593             : 
    3594             :                 /* We are open for business! */
    3595        8172 :                 conn->status = CONNECTION_OK;
    3596        8172 :                 return PGRES_POLLING_OK;
    3597             :             }
    3598             : 
    3599           0 :         case CONNECTION_SETENV:
    3600             :             {
    3601             :                 /*
    3602             :                  * Do post-connection housekeeping (only needed in protocol
    3603             :                  * 2.0).
    3604             :                  *
    3605             :                  * We pretend that the connection is OK for the duration of
    3606             :                  * these queries.
    3607             :                  */
    3608           0 :                 conn->status = CONNECTION_OK;
    3609             : 
    3610           0 :                 switch (pqSetenvPoll(conn))
    3611             :                 {
    3612           0 :                     case PGRES_POLLING_OK:  /* Success */
    3613           0 :                         break;
    3614             : 
    3615           0 :                     case PGRES_POLLING_READING: /* Still going */
    3616           0 :                         conn->status = CONNECTION_SETENV;
    3617           0 :                         return PGRES_POLLING_READING;
    3618             : 
    3619           0 :                     case PGRES_POLLING_WRITING: /* Still going */
    3620           0 :                         conn->status = CONNECTION_SETENV;
    3621           0 :                         return PGRES_POLLING_WRITING;
    3622             : 
    3623           0 :                     default:
    3624           0 :                         goto error_return;
    3625             :                 }
    3626             : 
    3627             :                 /* Almost there now ... */
    3628           0 :                 conn->status = CONNECTION_CHECK_TARGET;
    3629           0 :                 goto keep_going;
    3630             :             }
    3631             : 
    3632           4 :         case CONNECTION_CONSUME:
    3633             :             {
    3634           4 :                 conn->status = CONNECTION_OK;
    3635           4 :                 if (!PQconsumeInput(conn))
    3636           0 :                     goto error_return;
    3637             : 
    3638           4 :                 if (PQisBusy(conn))
    3639             :                 {
    3640           0 :                     conn->status = CONNECTION_CONSUME;
    3641           0 :                     return PGRES_POLLING_READING;
    3642             :                 }
    3643             : 
    3644             :                 /*
    3645             :                  * Call PQgetResult() again to consume NULL result.
    3646             :                  */
    3647           4 :                 res = PQgetResult(conn);
    3648           4 :                 if (res != NULL)
    3649             :                 {
    3650           0 :                     PQclear(res);
    3651           0 :                     conn->status = CONNECTION_CONSUME;
    3652           0 :                     goto keep_going;
    3653             :                 }
    3654             : 
    3655             :                 /* We can release the address list now. */
    3656           4 :                 release_conn_addrinfo(conn);
    3657             : 
    3658             :                 /* We are open for business! */
    3659           4 :                 conn->status = CONNECTION_OK;
    3660           4 :                 return PGRES_POLLING_OK;
    3661             :             }
    3662           6 :         case CONNECTION_CHECK_WRITABLE:
    3663             :             {
    3664             :                 const char *displayed_host;
    3665             :                 const char *displayed_port;
    3666             : 
    3667           6 :                 if (!saveErrorMessage(conn, &savedMessage))
    3668           0 :                     goto error_return;
    3669             : 
    3670           6 :                 conn->status = CONNECTION_OK;
    3671           6 :                 if (!PQconsumeInput(conn))
    3672             :                 {
    3673           0 :                     restoreErrorMessage(conn, &savedMessage);
    3674           0 :                     goto error_return;
    3675             :                 }
    3676             : 
    3677           6 :                 if (PQisBusy(conn))
    3678             :                 {
    3679           0 :                     conn->status = CONNECTION_CHECK_WRITABLE;
    3680           0 :                     restoreErrorMessage(conn, &savedMessage);
    3681           0 :                     return PGRES_POLLING_READING;
    3682             :                 }
    3683             : 
    3684           6 :                 res = PQgetResult(conn);
    3685          12 :                 if (res && (PQresultStatus(res) == PGRES_TUPLES_OK) &&
    3686           6 :                     PQntuples(res) == 1)
    3687             :                 {
    3688             :                     char       *val;
    3689             : 
    3690           6 :                     val = PQgetvalue(res, 0, 0);
    3691           6 :                     if (strncmp(val, "on", 2) == 0)
    3692             :                     {
    3693             :                         /* Not writable; fail this connection. */
    3694           2 :                         PQclear(res);
    3695           2 :                         restoreErrorMessage(conn, &savedMessage);
    3696             : 
    3697             :                         /* Append error report to conn->errorMessage. */
    3698           2 :                         if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
    3699           0 :                             displayed_host = conn->connhost[conn->whichhost].hostaddr;
    3700             :                         else
    3701           2 :                             displayed_host = conn->connhost[conn->whichhost].host;
    3702           2 :                         displayed_port = conn->connhost[conn->whichhost].port;
    3703           2 :                         if (displayed_port == NULL || displayed_port[0] == '\0')
    3704           0 :                             displayed_port = DEF_PGPORT_STR;
    3705             : 
    3706           2 :                         appendPQExpBuffer(&conn->errorMessage,
    3707           2 :                                           libpq_gettext("could not make a writable "
    3708             :                                                         "connection to server "
    3709             :                                                         "\"%s:%s\"\n"),
    3710             :                                           displayed_host, displayed_port);
    3711             : 
    3712             :                         /* Close connection politely. */
    3713           2 :                         conn->status = CONNECTION_OK;
    3714           2 :                         sendTerminateConn(conn);
    3715             : 
    3716             :                         /*
    3717             :                          * Try next host if any, but we don't want to consider
    3718             :                          * additional addresses for this host.
    3719             :                          */
    3720           2 :                         conn->try_next_host = true;
    3721           2 :                         goto keep_going;
    3722             :                     }
    3723             : 
    3724             :                     /* Session is read-write, so we're good. */
    3725           4 :                     PQclear(res);
    3726           4 :                     termPQExpBuffer(&savedMessage);
    3727             : 
    3728             :                     /*
    3729             :                      * Finish reading any remaining messages before being
    3730             :                      * considered as ready.
    3731             :                      */
    3732           4 :                     conn->status = CONNECTION_CONSUME;
    3733           4 :                     goto keep_going;
    3734             :                 }
    3735             : 
    3736             :                 /*
    3737             :                  * Something went wrong with "SHOW transaction_read_only". We
    3738             :                  * should try next addresses.
    3739             :                  */
    3740           0 :                 if (res)
    3741           0 :                     PQclear(res);
    3742           0 :                 restoreErrorMessage(conn, &savedMessage);
    3743             : 
    3744             :                 /* Append error report to conn->errorMessage. */
    3745           0 :                 if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
    3746           0 :                     displayed_host = conn->connhost[conn->whichhost].hostaddr;
    3747             :                 else
    3748           0 :                     displayed_host = conn->connhost[conn->whichhost].host;
    3749           0 :                 displayed_port = conn->connhost[conn->whichhost].port;
    3750           0 :                 if (displayed_port == NULL || displayed_port[0] == '\0')
    3751           0 :                     displayed_port = DEF_PGPORT_STR;
    3752           0 :                 appendPQExpBuffer(&conn->errorMessage,
    3753           0 :                                   libpq_gettext("test \"SHOW transaction_read_only\" failed "
    3754             :                                                 "on server \"%s:%s\"\n"),
    3755             :                                   displayed_host, displayed_port);
    3756             : 
    3757             :                 /* Close connection politely. */
    3758           0 :                 conn->status = CONNECTION_OK;
    3759           0 :                 sendTerminateConn(conn);
    3760             : 
    3761             :                 /* Try next address */
    3762           0 :                 conn->try_next_addr = true;
    3763           0 :                 goto keep_going;
    3764             :             }
    3765             : 
    3766           0 :         default:
    3767           0 :             appendPQExpBuffer(&conn->errorMessage,
    3768           0 :                               libpq_gettext("invalid connection state %d, "
    3769             :                                             "probably indicative of memory corruption\n"),
    3770           0 :                               conn->status);
    3771           0 :             goto error_return;
    3772             :     }
    3773             : 
    3774             :     /* Unreachable */
    3775             : 
    3776         482 : error_return:
    3777             : 
    3778             :     /*
    3779             :      * We used to close the socket at this point, but that makes it awkward
    3780             :      * for those above us if they wish to remove this socket from their own
    3781             :      * records (an fd_set for example).  We'll just have this socket closed
    3782             :      * when PQfinish is called (which is compulsory even after an error, since
    3783             :      * the connection structure must be freed).
    3784             :      */
    3785         482 :     conn->status = CONNECTION_BAD;
    3786         482 :     return PGRES_POLLING_FAILED;
    3787             : }
    3788             : 
    3789             : 
    3790             : /*
    3791             :  * internal_ping
    3792             :  *      Determine if a server is running and if we can connect to it.
    3793             :  *
    3794             :  * The argument is a connection that's been started, but not completed.
    3795             :  */
    3796             : static PGPing
    3797           4 : internal_ping(PGconn *conn)
    3798             : {
    3799             :     /* Say "no attempt" if we never got to PQconnectPoll */
    3800           4 :     if (!conn || !conn->options_valid)
    3801           0 :         return PQPING_NO_ATTEMPT;
    3802             : 
    3803             :     /* Attempt to complete the connection */
    3804           4 :     if (conn->status != CONNECTION_BAD)
    3805           2 :         (void) connectDBComplete(conn);
    3806             : 
    3807             :     /* Definitely OK if we succeeded */
    3808           4 :     if (conn->status != CONNECTION_BAD)
    3809           2 :         return PQPING_OK;
    3810             : 
    3811             :     /*
    3812             :      * Here begins the interesting part of "ping": determine the cause of the
    3813             :      * failure in sufficient detail to decide what to return.  We do not want
    3814             :      * to report that the server is not up just because we didn't have a valid
    3815             :      * password, for example.  In fact, any sort of authentication request
    3816             :      * implies the server is up.  (We need this check since the libpq side of
    3817             :      * things might have pulled the plug on the connection before getting an
    3818             :      * error as such from the postmaster.)
    3819             :      */
    3820           2 :     if (conn->auth_req_received)
    3821           0 :         return PQPING_OK;
    3822             : 
    3823             :     /*
    3824             :      * If we failed to get any ERROR response from the postmaster, report
    3825             :      * PQPING_NO_RESPONSE.  This result could be somewhat misleading for a
    3826             :      * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
    3827             :      * out of support.  Another corner case where the server could return a
    3828             :      * failure without a SQLSTATE is fork failure, but PQPING_NO_RESPONSE
    3829             :      * isn't totally unreasonable for that anyway.  We expect that every other
    3830             :      * failure case in a modern server will produce a report with a SQLSTATE.
    3831             :      *
    3832             :      * NOTE: whenever we get around to making libpq generate SQLSTATEs for
    3833             :      * client-side errors, we should either not store those into
    3834             :      * last_sqlstate, or add an extra flag so we can tell client-side errors
    3835             :      * apart from server-side ones.
    3836             :      */
    3837           2 :     if (strlen(conn->last_sqlstate) != 5)
    3838           2 :         return PQPING_NO_RESPONSE;
    3839             : 
    3840             :     /*
    3841             :      * Report PQPING_REJECT if server says it's not accepting connections. (We
    3842             :      * distinguish this case mainly for the convenience of pg_ctl.)
    3843             :      */
    3844           0 :     if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
    3845           0 :         return PQPING_REJECT;
    3846             : 
    3847             :     /*
    3848             :      * Any other SQLSTATE can be taken to indicate that the server is up.
    3849             :      * Presumably it didn't like our username, password, or database name; or
    3850             :      * perhaps it had some transient failure, but that should not be taken as
    3851             :      * meaning "it's down".
    3852             :      */
    3853           0 :     return PQPING_OK;
    3854             : }
    3855             : 
    3856             : 
    3857             : /*
    3858             :  * makeEmptyPGconn
    3859             :  *   - create a PGconn data structure with (as yet) no interesting data
    3860             :  */
    3861             : static PGconn *
    3862        8672 : makeEmptyPGconn(void)
    3863             : {
    3864             :     PGconn     *conn;
    3865             : 
    3866             : #ifdef WIN32
    3867             : 
    3868             :     /*
    3869             :      * Make sure socket support is up and running.
    3870             :      */
    3871             :     WSADATA     wsaData;
    3872             : 
    3873             :     if (WSAStartup(MAKEWORD(1, 1), &wsaData))
    3874             :         return NULL;
    3875             :     WSASetLastError(0);
    3876             : #endif
    3877             : 
    3878        8672 :     conn = (PGconn *) malloc(sizeof(PGconn));
    3879        8672 :     if (conn == NULL)
    3880             :     {
    3881             : #ifdef WIN32
    3882             :         WSACleanup();
    3883             : #endif
    3884           0 :         return conn;
    3885             :     }
    3886             : 
    3887             :     /* Zero all pointers and booleans */
    3888     1057984 :     MemSet(conn, 0, sizeof(PGconn));
    3889             : 
    3890             :     /* install default notice hooks */
    3891        8672 :     conn->noticeHooks.noticeRec = defaultNoticeReceiver;
    3892        8672 :     conn->noticeHooks.noticeProc = defaultNoticeProcessor;
    3893             : 
    3894        8672 :     conn->status = CONNECTION_BAD;
    3895        8672 :     conn->asyncStatus = PGASYNC_IDLE;
    3896        8672 :     conn->xactStatus = PQTRANS_IDLE;
    3897        8672 :     conn->options_valid = false;
    3898        8672 :     conn->nonblocking = false;
    3899        8672 :     conn->setenv_state = SETENV_STATE_IDLE;
    3900        8672 :     conn->client_encoding = PG_SQL_ASCII;
    3901        8672 :     conn->std_strings = false;   /* unless server says differently */
    3902        8672 :     conn->verbosity = PQERRORS_DEFAULT;
    3903        8672 :     conn->show_context = PQSHOW_CONTEXT_ERRORS;
    3904        8672 :     conn->sock = PGINVALID_SOCKET;
    3905             : #ifdef ENABLE_GSS
    3906             :     conn->try_gss = true;
    3907             : #endif
    3908             : 
    3909             :     /*
    3910             :      * We try to send at least 8K at a time, which is the usual size of pipe
    3911             :      * buffers on Unix systems.  That way, when we are sending a large amount
    3912             :      * of data, we avoid incurring extra kernel context swaps for partial
    3913             :      * bufferloads.  The output buffer is initially made 16K in size, and we
    3914             :      * try to dump it after accumulating 8K.
    3915             :      *
    3916             :      * With the same goal of minimizing context swaps, the input buffer will
    3917             :      * be enlarged anytime it has less than 8K free, so we initially allocate
    3918             :      * twice that.
    3919             :      */
    3920        8672 :     conn->inBufSize = 16 * 1024;
    3921        8672 :     conn->inBuffer = (char *) malloc(conn->inBufSize);
    3922        8672 :     conn->outBufSize = 16 * 1024;
    3923        8672 :     conn->outBuffer = (char *) malloc(conn->outBufSize);
    3924        8672 :     conn->rowBufLen = 32;
    3925        8672 :     conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
    3926        8672 :     initPQExpBuffer(&conn->errorMessage);
    3927        8672 :     initPQExpBuffer(&conn->workBuffer);
    3928             : 
    3929        8672 :     if (conn->inBuffer == NULL ||
    3930        8672 :         conn->outBuffer == NULL ||
    3931        8672 :         conn->rowBuf == NULL ||
    3932        8672 :         PQExpBufferBroken(&conn->errorMessage) ||
    3933        8672 :         PQExpBufferBroken(&conn->workBuffer))
    3934             :     {
    3935             :         /* out of memory already :-( */
    3936           0 :         freePGconn(conn);
    3937           0 :         conn = NULL;
    3938             :     }
    3939             : 
    3940        8672 :     return conn;
    3941             : }
    3942             : 
    3943             : /*
    3944             :  * freePGconn
    3945             :  *   - free an idle (closed) PGconn data structure
    3946             :  *
    3947             :  * NOTE: this should not overlap any functionality with closePGconn().
    3948             :  * Clearing/resetting of transient state belongs there; what we do here is
    3949             :  * release data that is to be held for the life of the PGconn structure.
    3950             :  * If a value ought to be cleared/freed during PQreset(), do it there not here.
    3951             :  */
    3952             : static void
    3953        8366 : freePGconn(PGconn *conn)
    3954             : {
    3955             :     int         i;
    3956             : 
    3957             :     /* let any event procs clean up their state data */
    3958        8366 :     for (i = 0; i < conn->nEvents; i++)
    3959             :     {
    3960             :         PGEventConnDestroy evt;
    3961             : 
    3962           0 :         evt.conn = conn;
    3963           0 :         (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
    3964           0 :                                     conn->events[i].passThrough);
    3965           0 :         free(conn->events[i].name);
    3966             :     }
    3967             : 
    3968             :     /* clean up pg_conn_host structures */
    3969        8366 :     if (conn->connhost != NULL)
    3970             :     {
    3971       16732 :         for (i = 0; i < conn->nconnhost; ++i)
    3972             :         {
    3973        8370 :             if (conn->connhost[i].host != NULL)
    3974        8370 :                 free(conn->connhost[i].host);
    3975        8370 :             if (conn->connhost[i].hostaddr != NULL)
    3976         120 :                 free(conn->connhost[i].hostaddr);
    3977        8370 :             if (conn->connhost[i].port != NULL)
    3978        8370 :                 free(conn->connhost[i].port);
    3979        8370 :             if (conn->connhost[i].password != NULL)
    3980             :             {
    3981           0 :                 explicit_bzero(conn->connhost[i].password, strlen(conn->connhost[i].password));
    3982           0 :                 free(conn->connhost[i].password);
    3983             :             }
    3984             :         }
    3985        8362 :         free(conn->connhost);
    3986             :     }
    3987             : 
    3988        8366 :     if (conn->client_encoding_initial)
    3989         996 :         free(conn->client_encoding_initial);
    3990        8366 :     if (conn->events)
    3991           0 :         free(conn->events);
    3992        8366 :     if (conn->pghost)
    3993        8362 :         free(conn->pghost);
    3994        8366 :     if (conn->pghostaddr)
    3995         120 :         free(conn->pghostaddr);
    3996        8366 :     if (conn->pgport)
    3997        8362 :         free(conn->pgport);
    3998        8366 :     if (conn->pgtty)
    3999        8362 :         free(conn->pgtty);
    4000        8366 :     if (conn->connect_timeout)
    4001          10 :         free(conn->connect_timeout);
    4002        8366 :     if (conn->pgtcp_user_timeout)
    4003           0 :         free(conn->pgtcp_user_timeout);
    4004        8366 :     if (conn->pgoptions)
    4005        8362 :         free(conn->pgoptions);
    4006        8366 :     if (conn->appname)
    4007        7796 :         free(conn->appname);
    4008        8366 :     if (conn->fbappname)
    4009        7046 :         free(conn->fbappname);
    4010        8366 :     if (conn->dbName)
    4011        8362 :         free(conn->dbName);
    4012        8366 :     if (conn->replication)
    4013         772 :         free(conn->replication);
    4014        8366 :     if (conn->pguser)
    4015        8362 :         free(conn->pguser);
    4016        8366 :     if (conn->pgpass)
    4017             :     {
    4018         142 :         explicit_bzero(conn->pgpass, strlen(conn->pgpass));
    4019         142 :         free(conn->pgpass);
    4020             :     }
    4021        8366 :     if (conn->pgpassfile)
    4022        8220 :         free(conn->pgpassfile);
    4023        8366 :     if (conn->channel_binding)
    4024        8362 :         free(conn->channel_binding);
    4025        8366 :     if (conn->keepalives)
    4026           0 :         free(conn->keepalives);
    4027        8366 :     if (conn->keepalives_idle)
    4028           0 :         free(conn->keepalives_idle);
    4029        8366 :     if (conn->keepalives_interval)
    4030           0 :         free(conn->keepalives_interval);
    4031        8366 :     if (conn->keepalives_count)
    4032           0 :         free(conn->keepalives_count);
    4033        8366 :     if (conn->sslmode)
    4034        8362 :         free(conn->sslmode);
    4035        8366 :     if (conn->sslcert)
    4036         120 :         free(conn->sslcert);
    4037        8366 :     if (conn->sslkey)
    4038          30 :         free(conn->sslkey);
    4039        8366 :     if (conn->sslpassword)
    4040             :     {
    4041           6 :         explicit_bzero(conn->sslpassword, strlen(conn->sslpassword));
    4042           6 :         free(conn->sslpassword);
    4043             :     }
    4044        8366 :     if (conn->sslrootcert)
    4045         116 :         free(conn->sslrootcert);
    4046        8366 :     if (conn->sslcrl)
    4047           8 :         free(conn->sslcrl);
    4048        8366 :     if (conn->sslcompression)
    4049        8362 :         free(conn->sslcompression);
    4050        8366 :     if (conn->requirepeer)
    4051           0 :         free(conn->requirepeer);
    4052        8366 :     if (conn->ssl_min_protocol_version)
    4053           6 :         free(conn->ssl_min_protocol_version);
    4054        8366 :     if (conn->ssl_max_protocol_version)
    4055           6 :         free(conn->ssl_max_protocol_version);
    4056        8366 :     if (conn->gssencmode)
    4057        8362 :         free(conn->gssencmode);
    4058        8366 :     if (conn->krbsrvname)
    4059        8362 :         free(conn->krbsrvname);
    4060        8366 :     if (conn->gsslib)
    4061           0 :         free(conn->gsslib);
    4062        8366 :     if (conn->connip)
    4063         398 :         free(conn->connip);
    4064             : #ifdef ENABLE_GSS
    4065             :     if (conn->gcred != GSS_C_NO_CREDENTIAL)
    4066             :     {
    4067             :         OM_uint32   minor;
    4068             : 
    4069             :         gss_release_cred(&minor, &conn->gcred);
    4070             :         conn->gcred = GSS_C_NO_CREDENTIAL;
    4071             :     }
    4072             :     if (conn->gctx)
    4073             :     {
    4074             :         OM_uint32   minor;
    4075             : 
    4076             :         gss_delete_sec_context(&minor, &conn->gctx, GSS_C_NO_BUFFER);
    4077             :         conn->gctx = NULL;
    4078             :     }
    4079             : #endif
    4080             :     /* Note that conn->Pfdebug is not ours to close or free */
    4081        8366 :     if (conn->last_query)
    4082        7538 :         free(conn->last_query);
    4083        8366 :     if (conn->write_err_msg)
    4084           0 :         free(conn->write_err_msg);
    4085        8366 :     if (conn->inBuffer)
    4086        8366 :         free(conn->inBuffer);
    4087        8366 :     if (conn->outBuffer)
    4088        8366 :         free(conn->outBuffer);
    4089        8366 :     if (conn->rowBuf)
    4090        8366 :         free(conn->rowBuf);
    4091        8366 :     if (conn->target_session_attrs)
    4092        8362 :         free(conn->target_session_attrs);
    4093        8366 :     termPQExpBuffer(&conn->errorMessage);
    4094        8366 :     termPQExpBuffer(&conn->workBuffer);
    4095             : 
    4096        8366 :     free(conn);
    4097             : 
    4098             : #ifdef WIN32
    4099             :     WSACleanup();
    4100             : #endif
    4101        8366 : }
    4102             : 
    4103             : /*
    4104             :  * release_conn_addrinfo
    4105             :  *   - Free any addrinfo list in the PGconn.
    4106             :  */
    4107             : static void
    4108       25204 : release_conn_addrinfo(PGconn *conn)
    4109             : {
    4110       25204 :     if (conn->addrlist)
    4111             :     {
    4112        8562 :         pg_freeaddrinfo_all(conn->addrlist_family, conn->addrlist);
    4113        8562 :         conn->addrlist = NULL;
    4114        8562 :         conn->addr_cur = NULL;   /* for safety */
    4115             :     }
    4116       25204 : }
    4117             : 
    4118             : /*
    4119             :  * sendTerminateConn
    4120             :  *   - Send a terminate message to backend.
    4121             :  */
    4122             : static void
    4123        8368 : sendTerminateConn(PGconn *conn)
    4124             : {
    4125             :     /*
    4126             :      * Note that the protocol doesn't allow us to send Terminate messages
    4127             :      * during the startup phase.
    4128             :      */
    4129        8368 :     if (conn->sock != PGINVALID_SOCKET && conn->status == CONNECTION_OK)
    4130             :     {
    4131             :         /*
    4132             :          * Try to send "close connection" message to backend. Ignore any
    4133             :          * error.
    4134             :          */
    4135        7888 :         pqPutMsgStart('X', false, conn);
    4136        7888 :         pqPutMsgEnd(conn);
    4137        7888 :         (void) pqFlush(conn);
    4138             :     }
    4139        8368 : }
    4140             : 
    4141             : /*
    4142             :  * closePGconn
    4143             :  *   - properly close a connection to the backend
    4144             :  *
    4145             :  * This should reset or release all transient state, but NOT the connection
    4146             :  * parameters.  On exit, the PGconn should be in condition to start a fresh
    4147             :  * connection with the same parameters (see PQreset()).
    4148             :  */
    4149             : static void
    4150        8366 : closePGconn(PGconn *conn)
    4151             : {
    4152             :     /*
    4153             :      * If possible, send Terminate message to close the connection politely.
    4154             :      */
    4155        8366 :     sendTerminateConn(conn);
    4156             : 
    4157             :     /*
    4158             :      * Must reset the blocking status so a possible reconnect will work.
    4159             :      *
    4160             :      * Don't call PQsetnonblocking() because it will fail if it's unable to
    4161             :      * flush the connection.
    4162             :      */
    4163        8366 :     conn->nonblocking = false;
    4164             : 
    4165             :     /*
    4166             :      * Close the connection, reset all transient state, flush I/O buffers.
    4167             :      */
    4168        8366 :     pqDropConnection(conn, true);
    4169        8366 :     conn->status = CONNECTION_BAD;   /* Well, not really _bad_ - just absent */
    4170        8366 :     conn->asyncStatus = PGASYNC_IDLE;
    4171        8366 :     conn->xactStatus = PQTRANS_IDLE;
    4172        8366 :     pqClearAsyncResult(conn);   /* deallocate result */
    4173        8366 :     resetPQExpBuffer(&conn->errorMessage);
    4174        8366 :     release_conn_addrinfo(conn);
    4175             : 
    4176             :     /* Reset all state obtained from server, too */
    4177        8366 :     pqDropServerData(conn);
    4178        8366 : }
    4179             : 
    4180             : /*
    4181             :  * PQfinish: properly close a connection to the backend. Also frees
    4182             :  * the PGconn data structure so it shouldn't be re-used after this.
    4183             :  */
    4184             : void
    4185        8366 : PQfinish(PGconn *conn)
    4186             : {
    4187        8366 :     if (conn)
    4188             :     {
    4189        8366 :         closePGconn(conn);
    4190        8366 :         freePGconn(conn);
    4191             :     }
    4192        8366 : }
    4193             : 
    4194             : /*
    4195             :  * PQreset: resets the connection to the backend by closing the
    4196             :  * existing connection and creating a new one.
    4197             :  */
    4198             : void
    4199           0 : PQreset(PGconn *conn)
    4200             : {
    4201           0 :     if (conn)
    4202             :     {
    4203           0 :         closePGconn(conn);
    4204             : 
    4205           0 :         if (connectDBStart(conn) && connectDBComplete(conn))
    4206             :         {
    4207             :             /*
    4208             :              * Notify event procs of successful reset.  We treat an event proc
    4209             :              * failure as disabling the connection ... good idea?
    4210             :              */
    4211             :             int         i;
    4212             : 
    4213           0 :             for (i = 0; i < conn->nEvents; i++)
    4214             :             {
    4215             :                 PGEventConnReset evt;
    4216             : 
    4217           0 :                 evt.conn = conn;
    4218           0 :                 if (!conn->events[i].proc(PGEVT_CONNRESET, &evt,
    4219           0 :                                           conn->events[i].passThrough))
    4220             :                 {
    4221           0 :                     conn->status = CONNECTION_BAD;
    4222           0 :                     printfPQExpBuffer(&conn->errorMessage,
    4223           0 :                                       libpq_gettext("PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n"),
    4224           0 :                                       conn->events[i].name);
    4225           0 :                     break;
    4226             :                 }
    4227             :             }
    4228             :         }
    4229             :     }
    4230           0 : }
    4231             : 
    4232             : 
    4233             : /*
    4234             :  * PQresetStart:
    4235             :  * resets the connection to the backend
    4236             :  * closes the existing connection and makes a new one
    4237             :  * Returns 1 on success, 0 on failure.
    4238             :  */
    4239             : int
    4240           0 : PQresetStart(PGconn *conn)
    4241             : {
    4242           0 :     if (conn)
    4243             :     {
    4244           0 :         closePGconn(conn);
    4245             : 
    4246           0 :         return connectDBStart(conn);
    4247             :     }
    4248             : 
    4249           0 :     return 0;
    4250             : }
    4251             : 
    4252             : 
    4253             : /*
    4254             :  * PQresetPoll:
    4255             :  * resets the connection to the backend
    4256             :  * closes the existing connection and makes a new one
    4257             :  */
    4258             : PostgresPollingStatusType
    4259           0 : PQresetPoll(PGconn *conn)
    4260             : {
    4261           0 :     if (conn)
    4262             :     {
    4263           0 :         PostgresPollingStatusType status = PQconnectPoll(conn);
    4264             : 
    4265           0 :         if (status == PGRES_POLLING_OK)
    4266             :         {
    4267             :             /*
    4268             :              * Notify event procs of successful reset.  We treat an event proc
    4269             :              * failure as disabling the connection ... good idea?
    4270             :              */
    4271             :             int         i;
    4272             : 
    4273           0 :             for (i = 0; i < conn->nEvents; i++)
    4274             :             {
    4275             :                 PGEventConnReset evt;
    4276             : 
    4277           0 :                 evt.conn = conn;
    4278           0 :                 if (!conn->events[i].proc(PGEVT_CONNRESET, &evt,
    4279           0 :                                           conn->events[i].passThrough))
    4280             :                 {
    4281           0 :                     conn->status = CONNECTION_BAD;
    4282           0 :                     printfPQExpBuffer(&conn->errorMessage,
    4283           0 :                                       libpq_gettext("PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n"),
    4284           0 :                                       conn->events[i].name);
    4285           0 :                     return PGRES_POLLING_FAILED;
    4286             :                 }
    4287             :             }
    4288             :         }
    4289             : 
    4290           0 :         return status;
    4291             :     }
    4292             : 
    4293           0 :     return PGRES_POLLING_FAILED;
    4294             : }
    4295             : 
    4296             : /*
    4297             :  * PQgetCancel: get a PGcancel structure corresponding to a connection.
    4298             :  *
    4299             :  * A copy is needed to be able to cancel a running query from a different
    4300             :  * thread. If the same structure is used all structure members would have
    4301             :  * to be individually locked (if the entire structure was locked, it would
    4302             :  * be impossible to cancel a synchronous query because the structure would
    4303             :  * have to stay locked for the duration of the query).
    4304             :  */
    4305             : PGcancel *
    4306      184546 : PQgetCancel(PGconn *conn)
    4307             : {
    4308             :     PGcancel   *cancel;
    4309             : 
    4310      184546 :     if (!conn)
    4311          28 :         return NULL;
    4312             : 
    4313      184518 :     if (conn->sock == PGINVALID_SOCKET)
    4314           0 :         return NULL;
    4315             : 
    4316      184518 :     cancel = malloc(sizeof(PGcancel));
    4317      184518 :     if (cancel == NULL)
    4318           0 :         return NULL;
    4319             : 
    4320      184518 :     memcpy(&cancel->raddr, &conn->raddr, sizeof(SockAddr));
    4321      184518 :     cancel->be_pid = conn->be_pid;
    4322      184518 :     cancel->be_key = conn->be_key;
    4323             : 
    4324      184518 :     return cancel;
    4325             : }
    4326             : 
    4327             : /* PQfreeCancel: free a cancel structure */
    4328             : void
    4329      184518 : PQfreeCancel(PGcancel *cancel)
    4330             : {
    4331      184518 :     if (cancel)
    4332      184518 :         free(cancel);
    4333      184518 : }
    4334             : 
    4335             : 
    4336             : /*
    4337             :  * PQcancel and PQrequestCancel: attempt to request cancellation of the
    4338             :  * current operation.
    4339             :  *
    4340             :  * The return value is true if the cancel request was successfully
    4341             :  * dispatched, false if not (in which case an error message is available).
    4342             :  * Note: successful dispatch is no guarantee that there will be any effect at
    4343             :  * the backend.  The application must read the operation result as usual.
    4344             :  *
    4345             :  * CAUTION: we want this routine to be safely callable from a signal handler
    4346             :  * (for example, an application might want to call it in a SIGINT handler).
    4347             :  * This means we cannot use any C library routine that might be non-reentrant.
    4348             :  * malloc/free are often non-reentrant, and anything that might call them is
    4349             :  * just as dangerous.  We avoid sprintf here for that reason.  Building up
    4350             :  * error messages with strcpy/strcat is tedious but should be quite safe.
    4351             :  * We also save/restore errno in case the signal handler support doesn't.
    4352             :  *
    4353             :  * internal_cancel() is an internal helper function to make code-sharing
    4354             :  * between the two versions of the cancel function possible.
    4355             :  */
    4356             : static int
    4357           2 : internal_cancel(SockAddr *raddr, int be_pid, int be_key,
    4358             :                 char *errbuf, int errbufsize)
    4359             : {
    4360           2 :     int         save_errno = SOCK_ERRNO;
    4361           2 :     pgsocket    tmpsock = PGINVALID_SOCKET;
    4362             :     char        sebuf[PG_STRERROR_R_BUFLEN];
    4363             :     int         maxlen;
    4364             :     struct
    4365             :     {
    4366             :         uint32      packetlen;
    4367             :         CancelRequestPacket cp;
    4368             :     }           crp;
    4369             : 
    4370             :     /*
    4371             :      * We need to open a temporary connection to the postmaster. Do this with
    4372             :      * only kernel calls.
    4373             :      */
    4374           2 :     if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
    4375             :     {
    4376           0 :         strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
    4377           0 :         goto cancel_errReturn;
    4378             :     }
    4379           2 : retry3:
    4380           2 :     if (connect(tmpsock, (struct sockaddr *) &raddr->addr,
    4381             :                 raddr->salen) < 0)
    4382             :     {
    4383           0 :         if (SOCK_ERRNO == EINTR)
    4384             :             /* Interrupted system call - we'll just try again */
    4385           0 :             goto retry3;
    4386           0 :         strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
    4387           0 :         goto cancel_errReturn;
    4388             :     }
    4389             : 
    4390             :     /*
    4391             :      * We needn't set nonblocking I/O or NODELAY options here.
    4392             :      */
    4393             : 
    4394             :     /* Create and send the cancel request packet. */
    4395             : 
    4396           2 :     crp.packetlen = pg_hton32((uint32) sizeof(crp));
    4397           2 :     crp.cp.cancelRequestCode = (MsgType) pg_hton32(CANCEL_REQUEST_CODE);
    4398           2 :     crp.cp.backendPID = pg_hton32(be_pid);
    4399           2 :     crp.cp.cancelAuthCode = pg_hton32(be_key);
    4400             : 
    4401           2 : retry4:
    4402           2 :     if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
    4403             :     {
    4404           0 :         if (SOCK_ERRNO == EINTR)
    4405             :             /* Interrupted system call - we'll just try again */
    4406           0 :             goto retry4;
    4407           0 :         strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
    4408           0 :         goto cancel_errReturn;
    4409             :     }
    4410             : 
    4411             :     /*
    4412             :      * Wait for the postmaster to close the connection, which indicates that
    4413             :      * it's processed the request.  Without this delay, we might issue another
    4414             :      * command only to find that our cancel zaps that command instead of the
    4415             :      * one we thought we were canceling.  Note we don't actually expect this
    4416             :      * read to obtain any data, we are just waiting for EOF to be signaled.
    4417             :      */
    4418           2 : retry5:
    4419           2 :     if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
    4420             :     {
    4421           0 :         if (SOCK_ERRNO == EINTR)
    4422             :             /* Interrupted system call - we'll just try again */
    4423           0 :             goto retry5;
    4424             :         /* we ignore other error conditions */
    4425             :     }
    4426             : 
    4427             :     /* All done */
    4428           2 :     closesocket(tmpsock);
    4429           2 :     SOCK_ERRNO_SET(save_errno);
    4430           2 :     return true;
    4431             : 
    4432           0 : cancel_errReturn:
    4433             : 
    4434             :     /*
    4435             :      * Make sure we don't overflow the error buffer. Leave space for the \n at
    4436             :      * the end, and for the terminating zero.
    4437             :      */
    4438           0 :     maxlen = errbufsize - strlen(errbuf) - 2;
    4439           0 :     if (maxlen >= 0)
    4440             :     {
    4441           0 :         strncat(errbuf, SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)),
    4442             :                 maxlen);
    4443           0 :         strcat(errbuf, "\n");
    4444             :     }
    4445           0 :     if (tmpsock != PGINVALID_SOCKET)
    4446           0 :         closesocket(tmpsock);
    4447           0 :     SOCK_ERRNO_SET(save_errno);
    4448           0 :     return false;
    4449             : }
    4450             : 
    4451             : /*
    4452             :  * PQcancel: request query cancel
    4453             :  *
    4454             :  * Returns true if able to send the cancel request, false if not.
    4455             :  *
    4456             :  * On failure, an error message is stored in *errbuf, which must be of size
    4457             :  * errbufsize (recommended size is 256 bytes).  *errbuf is not changed on
    4458             :  * success return.
    4459             :  */
    4460             : int
    4461           2 : PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
    4462             : {
    4463           2 :     if (!cancel)
    4464             :     {
    4465           0 :         strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
    4466           0 :         return false;
    4467             :     }
    4468             : 
    4469           2 :     return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
    4470             :                            errbuf, errbufsize);
    4471             : }
    4472             : 
    4473             : /*
    4474             :  * PQrequestCancel: old, not thread-safe function for requesting query cancel
    4475             :  *
    4476             :  * Returns true if able to send the cancel request, false if not.
    4477             :  *
    4478             :  * On failure, the error message is saved in conn->errorMessage; this means
    4479             :  * that this can't be used when there might be other active operations on
    4480             :  * the connection object.
    4481             :  *
    4482             :  * NOTE: error messages will be cut off at the current size of the
    4483             :  * error message buffer, since we dare not try to expand conn->errorMessage!
    4484             :  */
    4485             : int
    4486           0 : PQrequestCancel(PGconn *conn)
    4487             : {
    4488             :     int         r;
    4489             : 
    4490             :     /* Check we have an open connection */
    4491           0 :     if (!conn)
    4492           0 :         return false;
    4493             : 
    4494           0 :     if (conn->sock == PGINVALID_SOCKET)
    4495             :     {
    4496           0 :         strlcpy(conn->errorMessage.data,
    4497             :                 "PQrequestCancel() -- connection is not open\n",
    4498             :                 conn->errorMessage.maxlen);
    4499           0 :         conn->errorMessage.len = strlen(conn->errorMessage.data);
    4500             : 
    4501           0 :         return false;
    4502             :     }
    4503             : 
    4504           0 :     r = internal_cancel(&conn->raddr, conn->be_pid, conn->be_key,
    4505           0 :                         conn->errorMessage.data, conn->errorMessage.maxlen);
    4506             : 
    4507           0 :     if (!r)
    4508           0 :         conn->errorMessage.len = strlen(conn->errorMessage.data);
    4509             : 
    4510           0 :     return r;
    4511             : }
    4512             : 
    4513             : 
    4514             : /*
    4515             :  * pqPacketSend() -- convenience routine to send a message to server.
    4516             :  *
    4517             :  * pack_type: the single-byte message type code.  (Pass zero for startup
    4518             :  * packets, which have no message type code.)
    4519             :  *
    4520             :  * buf, buf_len: contents of message.  The given length includes only what
    4521             :  * is in buf; the message type and message length fields are added here.
    4522             :  *
    4523             :  * RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
    4524             :  * SIDE_EFFECTS: may block.
    4525             :  *
    4526             :  * Note: all messages sent with this routine have a length word, whether
    4527             :  * it's protocol 2.0 or 3.0.
    4528             :  */
    4529             : int
    4530        8784 : pqPacketSend(PGconn *conn, char pack_type,
    4531             :              const void *buf, size_t buf_len)
    4532             : {
    4533             :     /* Start the message. */
    4534        8784 :     if (pqPutMsgStart(pack_type, true, conn))
    4535           0 :         return STATUS_ERROR;
    4536             : 
    4537             :     /* Send the message body. */
    4538        8784 :     if (pqPutnchar(buf, buf_len, conn))
    4539           0 :         return STATUS_ERROR;
    4540             : 
    4541             :     /* Finish the message. */
    4542        8784 :     if (pqPutMsgEnd(conn))
    4543           0 :         return STATUS_ERROR;
    4544             : 
    4545             :     /* Flush to ensure backend gets it. */
    4546        8784 :     if (pqFlush(conn))
    4547           0 :         return STATUS_ERROR;
    4548             : 
    4549        8784 :     return STATUS_OK;
    4550             : }
    4551             : 
    4552             : #ifdef USE_LDAP
    4553             : 
    4554             : #define LDAP_URL    "ldap://"
    4555             : #define LDAP_DEF_PORT   389
    4556             : #define PGLDAP_TIMEOUT 2
    4557             : 
    4558             : #define ld_is_sp_tab(x) ((x) == ' ' || (x) == '\t')
    4559             : #define ld_is_nl_cr(x) ((x) == '\r' || (x) == '\n')
    4560             : 
    4561             : 
    4562             : /*
    4563             :  *      ldapServiceLookup
    4564             :  *
    4565             :  * Search the LDAP URL passed as first argument, treat the result as a
    4566             :  * string of connection options that are parsed and added to the array of
    4567             :  * options passed as second argument.
    4568             :  *
    4569             :  * LDAP URLs must conform to RFC 1959 without escape sequences.
    4570             :  *  ldap://host:port/dn?attributes?scope?filter?extensions
    4571             :  *
    4572             :  * Returns
    4573             :  *  0 if the lookup was successful,
    4574             :  *  1 if the connection to the LDAP server could be established but
    4575             :  *    the search was unsuccessful,
    4576             :  *  2 if a connection could not be established, and
    4577             :  *  3 if a fatal error occurred.
    4578             :  *
    4579             :  * An error message is returned in the third argument for return codes 1 and 3.
    4580             :  */
    4581             : static int
    4582           2 : ldapServiceLookup(const char *purl, PQconninfoOption *options,
    4583             :                   PQExpBuffer errorMessage)
    4584             : {
    4585           2 :     int         port = LDAP_DEF_PORT,
    4586             :                 scope,
    4587             :                 rc,
    4588             :                 size,
    4589             :                 state,
    4590             :                 oldstate,
    4591             :                 i;
    4592             : #ifndef WIN32
    4593             :     int         msgid;
    4594             : #endif
    4595             :     bool        found_keyword;
    4596             :     char       *url,
    4597             :                *hostname,
    4598             :                *portstr,
    4599             :                *endptr,
    4600             :                *dn,
    4601             :                *scopestr,
    4602             :                *filter,
    4603             :                *result,
    4604             :                *p,
    4605           2 :                *p1 = NULL,
    4606           2 :                *optname = NULL,
    4607           2 :                *optval = NULL;
    4608           2 :     char       *attrs[2] = {NULL, NULL};
    4609           2 :     LDAP       *ld = NULL;
    4610             :     LDAPMessage *res,
    4611             :                *entry;
    4612             :     struct berval **values;
    4613           2 :     LDAP_TIMEVAL time = {PGLDAP_TIMEOUT, 0};
    4614             : 
    4615           2 :     if ((url = strdup(purl)) == NULL)
    4616             :     {
    4617           0 :         printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
    4618           0 :         return 3;
    4619             :     }
    4620             : 
    4621             :     /*
    4622             :      * Parse URL components, check for correctness.  Basically, url has '\0'
    4623             :      * placed at component boundaries and variables are pointed at each
    4624             :      * component.
    4625             :      */
    4626             : 
    4627           2 :     if (pg_strncasecmp(url, LDAP_URL, strlen(LDAP_URL)) != 0)
    4628             :     {
    4629           0 :         printfPQExpBuffer(errorMessage,
    4630           0 :                           libpq_gettext("invalid LDAP URL \"%s\": scheme must be ldap://\n"), purl);
    4631           0 :         free(url);
    4632           0 :         return 3;
    4633             :     }
    4634             : 
    4635             :     /* hostname */
    4636           2 :     hostname = url + strlen(LDAP_URL);
    4637           2 :     if (*hostname == '/')       /* no hostname? */
    4638           0 :         hostname = DefaultHost; /* the default */
    4639             : 
    4640             :     /* dn, "distinguished name" */
    4641           2 :     p = strchr(url + strlen(LDAP_URL), '/');
    4642           2 :     if (p == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    4643             :     {
    4644           0 :         printfPQExpBuffer(errorMessage,
    4645           0 :                           libpq_gettext("invalid LDAP URL \"%s\": missing distinguished name\n"),
    4646             :                           purl);
    4647           0 :         free(url);
    4648           0 :         return 3;
    4649             :     }
    4650           2 :     *p = '\0';                  /* terminate hostname */
    4651           2 :     dn = p + 1;
    4652             : 
    4653             :     /* attribute */
    4654           2 :     if ((p = strchr(dn, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    4655             :     {
    4656           0 :         printfPQExpBuffer(errorMessage,
    4657           0 :                           libpq_gettext("invalid LDAP URL \"%s\": must have exactly one attribute\n"),
    4658             :                           purl);
    4659           0 :         free(url);
    4660           0 :         return 3;
    4661             :     }
    4662           2 :     *p = '\0';
    4663           2 :     attrs[0] = p + 1;
    4664             : 
    4665             :     /* scope */
    4666           2 :     if ((p = strchr(attrs[0], '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    4667             :     {
    4668           0 :         printfPQExpBuffer(errorMessage, libpq_gettext("invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n"), purl);
    4669           0 :         free(url);
    4670           0 :         return 3;
    4671             :     }
    4672           2 :     *p = '\0';
    4673           2 :     scopestr = p + 1;
    4674             : 
    4675             :     /* filter */
    4676           2 :     if ((p = strchr(scopestr, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    4677             :     {
    4678           0 :         printfPQExpBuffer(errorMessage,
    4679           0 :                           libpq_gettext("invalid LDAP URL \"%s\": no filter\n"), purl);
    4680           0 :         free(url);
    4681           0 :         return 3;
    4682             :     }
    4683           2 :     *p = '\0';
    4684           2 :     filter = p + 1;
    4685           2 :     if ((p = strchr(filter, '?')) != NULL)
    4686           0 :         *p = '\0';
    4687             : 
    4688             :     /* port number? */
    4689           2 :     if ((p1 = strchr(hostname, ':')) != NULL)
    4690             :     {
    4691             :         long        lport;
    4692             : 
    4693           2 :         *p1 = '\0';
    4694           2 :         portstr = p1 + 1;
    4695           2 :         errno = 0;
    4696           2 :         lport = strtol(portstr, &endptr, 10);
    4697           2 :         if (*portstr == '\0' || *endptr != '\0' || errno || lport < 0 || lport > 65535)
    4698             :         {
    4699           0 :             printfPQExpBuffer(errorMessage,
    4700           0 :                               libpq_gettext("invalid LDAP URL \"%s\": invalid port number\n"),
    4701             :                               purl);
    4702           0 :             free(url);
    4703           0 :             return 3;
    4704             :         }
    4705           2 :         port = (int) lport;
    4706             :     }
    4707             : 
    4708             :     /* Allow only one attribute */
    4709           2 :     if (strchr(attrs[0], ',') != NULL)
    4710             :     {
    4711           0 :         printfPQExpBuffer(errorMessage,
    4712           0 :                           libpq_gettext("invalid LDAP URL \"%s\": must have exactly one attribute\n"),
    4713             :                           purl);
    4714           0 :         free(url);
    4715           0 :         return 3;
    4716             :     }
    4717             : 
    4718             :     /* set scope */
    4719           2 :     if (pg_strcasecmp(scopestr, "base") == 0)
    4720           0 :         scope = LDAP_SCOPE_BASE;
    4721           2 :     else if (pg_strcasecmp(scopestr, "one") == 0)
    4722           2 :         scope = LDAP_SCOPE_ONELEVEL;
    4723           0 :     else if (pg_strcasecmp(scopestr, "sub") == 0)
    4724           0 :         scope = LDAP_SCOPE_SUBTREE;
    4725             :     else
    4726             :     {
    4727           0 :         printfPQExpBuffer(errorMessage, libpq_gettext("invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n"), purl);
    4728           0 :         free(url);
    4729           0 :         return 3;
    4730             :     }
    4731             : 
    4732             :     /* initialize LDAP structure */
    4733           2 :     if ((ld = ldap_init(hostname, port)) == NULL)
    4734             :     {
    4735           0 :         printfPQExpBuffer(errorMessage,
    4736           0 :                           libpq_gettext("could not create LDAP structure\n"));
    4737           0 :         free(url);
    4738           0 :         return 3;
    4739             :     }
    4740             : 
    4741             :     /*
    4742             :      * Perform an explicit anonymous bind.
    4743             :      *
    4744             :      * LDAP does not require that an anonymous bind is performed explicitly,
    4745             :      * but we want to distinguish between the case where LDAP bind does not
    4746             :      * succeed within PGLDAP_TIMEOUT seconds (return 2 to continue parsing the
    4747             :      * service control file) and the case where querying the LDAP server fails
    4748             :      * (return 1 to end parsing).
    4749             :      *
    4750             :      * Unfortunately there is no way of setting a timeout that works for both
    4751             :      * Windows and OpenLDAP.
    4752             :      */
    4753             : #ifdef WIN32
    4754             :     /* the nonstandard ldap_connect function performs an anonymous bind */
    4755             :     if (ldap_connect(ld, &time) != LDAP_SUCCESS)
    4756             :     {
    4757             :         /* error or timeout in ldap_connect */
    4758             :         free(url);
    4759             :         ldap_unbind(ld);
    4760             :         return 2;
    4761             :     }
    4762             : #else                           /* !WIN32 */
    4763             :     /* in OpenLDAP, use the LDAP_OPT_NETWORK_TIMEOUT option */
    4764           2 :     if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
    4765             :     {
    4766           0 :         free(url);
    4767           0 :         ldap_unbind(ld);
    4768           0 :         return 3;
    4769             :     }
    4770             : 
    4771             :     /* anonymous bind */
    4772           2 :     if ((msgid = ldap_simple_bind(ld, NULL, NULL)) == -1)
    4773             :     {
    4774             :         /* error or network timeout */
    4775           2 :         free(url);
    4776           2 :         ldap_unbind(ld);
    4777           2 :         return 2;
    4778             :     }
    4779             : 
    4780             :     /* wait some time for the connection to succeed */
    4781           0 :     res = NULL;
    4782           0 :     if ((rc = ldap_result(ld, msgid, LDAP_MSG_ALL, &time, &res)) == -1 ||
    4783           0 :         res == NULL)
    4784             :     {
    4785             :         /* error or timeout */
    4786           0 :         if (res != NULL)
    4787           0 :             ldap_msgfree(res);
    4788           0 :         free(url);
    4789           0 :         ldap_unbind(ld);
    4790           0 :         return 2;
    4791             :     }
    4792           0 :     ldap_msgfree(res);
    4793             : 
    4794             :     /* reset timeout */
    4795           0 :     time.tv_sec = -1;
    4796           0 :     if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
    4797             :     {
    4798           0 :         free(url);
    4799           0 :         ldap_unbind(ld);
    4800           0 :         return 3;
    4801             :     }
    4802             : #endif                          /* WIN32 */
    4803             : 
    4804             :     /* search */
    4805           0 :     res = NULL;
    4806           0 :     if ((rc = ldap_search_st(ld, dn, scope, filter, attrs, 0, &time, &res))
    4807             :         != LDAP_SUCCESS)
    4808             :     {
    4809           0 :         if (res != NULL)
    4810           0 :             ldap_msgfree(res);
    4811           0 :         printfPQExpBuffer(errorMessage,
    4812           0 :                           libpq_gettext("lookup on LDAP server failed: %s\n"),
    4813             :                           ldap_err2string(rc));
    4814           0 :         ldap_unbind(ld);
    4815           0 :         free(url);
    4816           0 :         return 1;
    4817             :     }
    4818             : 
    4819             :     /* complain if there was not exactly one result */
    4820           0 :     if ((rc = ldap_count_entries(ld, res)) != 1)
    4821             :     {
    4822           0 :         printfPQExpBuffer(errorMessage,
    4823           0 :                           rc ? libpq_gettext("more than one entry found on LDAP lookup\n")
    4824           0 :                           : libpq_gettext("no entry found on LDAP lookup\n"));
    4825           0 :         ldap_msgfree(res);
    4826           0 :         ldap_unbind(ld);
    4827           0 :         free(url);
    4828           0 :         return 1;
    4829             :     }
    4830             : 
    4831             :     /* get entry */
    4832           0 :     if ((entry = ldap_first_entry(ld, res)) == NULL)
    4833             :     {
    4834             :         /* should never happen */
    4835           0 :         printfPQExpBuffer(errorMessage,
    4836           0 :                           libpq_gettext("no entry found on LDAP lookup\n"));
    4837           0 :         ldap_msgfree(res);
    4838           0 :         ldap_unbind(ld);
    4839           0 :         free(url);
    4840           0 :         return 1;
    4841             :     }
    4842             : 
    4843             :     /* get values */
    4844           0 :     if ((values = ldap_get_values_len(ld, entry, attrs[0])) == NULL)
    4845             :     {
    4846           0 :         printfPQExpBuffer(errorMessage,
    4847           0 :                           libpq_gettext("attribute has no values on LDAP lookup\n"));
    4848           0 :         ldap_msgfree(res);
    4849           0 :         ldap_unbind(ld);
    4850           0 :         free(url);
    4851           0 :         return 1;
    4852             :     }
    4853             : 
    4854           0 :     ldap_msgfree(res);
    4855           0 :     free(url);
    4856             : 
    4857           0 :     if (values[0] == NULL)
    4858             :     {
    4859           0 :         printfPQExpBuffer(errorMessage,
    4860           0 :                           libpq_gettext("attribute has no values on LDAP lookup\n"));
    4861           0 :         ldap_value_free_len(values);
    4862           0 :         ldap_unbind(ld);
    4863           0 :         return 1;
    4864             :     }
    4865             : 
    4866             :     /* concatenate values into a single string with newline terminators */
    4867           0 :     size = 1;                   /* for the trailing null */
    4868           0 :     for (i = 0; values[i] != NULL; i++)
    4869           0 :         size += values[i]->bv_len + 1;
    4870           0 :     if ((result = malloc(size)) == NULL)
    4871             :     {
    4872           0 :         printfPQExpBuffer(errorMessage,
    4873           0 :                           libpq_gettext("out of memory\n"));
    4874           0 :         ldap_value_free_len(values);
    4875           0 :         ldap_unbind(ld);
    4876           0 :         return 3;
    4877             :     }
    4878           0 :     p = result;
    4879           0 :     for (i = 0; values[i] != NULL; i++)
    4880             :     {
    4881           0 :         memcpy(p, values[i]->bv_val, values[i]->bv_len);
    4882           0 :         p += values[i]->bv_len;
    4883           0 :         *(p++) = '\n';
    4884             :     }
    4885           0 :     *p = '\0';
    4886             : 
    4887           0 :     ldap_value_free_len(values);
    4888           0 :     ldap_unbind(ld);
    4889             : 
    4890             :     /* parse result string */
    4891           0 :     oldstate = state = 0;
    4892           0 :     for (p = result; *p != '\0'; ++p)
    4893             :     {
    4894           0 :         switch (state)
    4895             :         {
    4896           0 :             case 0:             /* between entries */
    4897           0 :                 if (!ld_is_sp_tab(*p) && !ld_is_nl_cr(*p))
    4898             :                 {
    4899           0 :                     optname = p;
    4900           0 :                     state = 1;
    4901             :                 }
    4902           0 :                 break;
    4903           0 :             case 1:             /* in option name */
    4904           0 :                 if (ld_is_sp_tab(*p))
    4905             :                 {
    4906           0 :                     *p = '\0';
    4907           0 :                     state = 2;
    4908             :                 }
    4909           0 :                 else if (ld_is_nl_cr(*p))
    4910             :                 {
    4911           0 :                     printfPQExpBuffer(errorMessage,
    4912           0 :                                       libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
    4913             :                                       optname);
    4914           0 :                     free(result);
    4915           0 :                     return 3;
    4916             :                 }
    4917           0 :                 else if (*p == '=')
    4918             :                 {
    4919           0 :                     *p = '\0';
    4920           0 :                     state = 3;
    4921             :                 }
    4922           0 :                 break;
    4923           0 :             case 2:             /* after option name */
    4924           0 :                 if (*p == '=')
    4925             :                 {
    4926           0 :                     state = 3;
    4927             :                 }
    4928           0 :                 else if (!ld_is_sp_tab(*p))
    4929             :                 {
    4930           0 :                     printfPQExpBuffer(errorMessage,
    4931           0 :                                       libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
    4932             :                                       optname);
    4933           0 :                     free(result);
    4934           0 :                     return 3;
    4935             :                 }
    4936           0 :                 break;
    4937           0 :             case 3:             /* before option value */
    4938           0 :                 if (*p == '\'')
    4939             :                 {
    4940           0 :                     optval = p + 1;
    4941           0 :                     p1 = p + 1;
    4942           0 :                     state = 5;
    4943             :                 }
    4944           0 :                 else if (ld_is_nl_cr(*p))
    4945             :                 {
    4946           0 :                     optval = optname + strlen(optname); /* empty */
    4947           0 :                     state = 0;
    4948             :                 }
    4949           0 :                 else if (!ld_is_sp_tab(*p))
    4950             :                 {
    4951           0 :                     optval = p;
    4952           0 :                     state = 4;
    4953             :                 }
    4954           0 :                 break;
    4955           0 :             case 4:             /* in unquoted option value */
    4956           0 :                 if (ld_is_sp_tab(*p) || ld_is_nl_cr(*p))
    4957             :                 {
    4958           0 :                     *p = '\0';
    4959           0 :                     state = 0;
    4960             :                 }
    4961           0 :                 break;
    4962           0 :             case 5:             /* in quoted option value */
    4963           0 :                 if (*p == '\'')
    4964             :                 {
    4965           0 :                     *p1 = '\0';
    4966           0 :                     state = 0;
    4967             :                 }
    4968           0 :                 else if (*p == '\\')
    4969           0 :                     state = 6;
    4970             :                 else
    4971           0 :                     *(p1++) = *p;
    4972           0 :                 break;
    4973           0 :             case 6:             /* in quoted option value after escape */
    4974           0 :                 *(p1++) = *p;
    4975           0 :                 state = 5;
    4976           0 :                 break;
    4977             :         }
    4978             : 
    4979           0 :         if (state == 0 && oldstate != 0)
    4980             :         {
    4981           0 :             found_keyword = false;
    4982           0 :             for (i = 0; options[i].keyword; i++)
    4983             :             {
    4984           0 :                 if (strcmp(options[i].keyword, optname) == 0)
    4985             :                 {
    4986           0 :                     if (options[i].val == NULL)
    4987             :                     {
    4988           0 :                         options[i].val = strdup(optval);
    4989           0 :                         if (!options[i].val)
    4990             :                         {
    4991           0 :                             printfPQExpBuffer(errorMessage,
    4992           0 :                                               libpq_gettext("out of memory\n"));
    4993           0 :                             free(result);
    4994           0 :                             return 3;
    4995             :                         }
    4996             :                     }
    4997           0 :                     found_keyword = true;
    4998           0 :                     break;
    4999             :                 }
    5000             :             }
    5001           0 :             if (!found_keyword)
    5002             :             {
    5003           0 :                 printfPQExpBuffer(errorMessage,
    5004           0 :                                   libpq_gettext("invalid connection option \"%s\"\n"),
    5005             :                                   optname);
    5006           0 :                 free(result);
    5007           0 :                 return 1;
    5008             :             }
    5009           0 :             optname = NULL;
    5010           0 :             optval = NULL;
    5011             :         }
    5012           0 :         oldstate = state;
    5013             :     }
    5014             : 
    5015           0 :     free(result);
    5016             : 
    5017           0 :     if (state == 5 || state == 6)
    5018             :     {
    5019           0 :         printfPQExpBuffer(errorMessage,
    5020           0 :                           libpq_gettext("unterminated quoted string in connection info string\n"));
    5021           0 :         return 3;
    5022             :     }
    5023             : 
    5024           0 :     return 0;
    5025             : }
    5026             : 
    5027             : #endif                          /* USE_LDAP */
    5028             : 
    5029             : #define MAXBUFSIZE 256
    5030             : 
    5031             : /*
    5032             :  * parseServiceInfo: if a service name has been given, look it up and absorb
    5033             :  * connection options from it into *options.
    5034             :  *
    5035             :  * Returns 0 on success, nonzero on failure.  On failure, if errorMessage
    5036             :  * isn't null, also store an error message there.  (Note: the only reason
    5037             :  * this function and related ones don't dump core on errorMessage == NULL
    5038             :  * is the undocumented fact that printfPQExpBuffer does nothing when passed
    5039             :  * a null PQExpBuffer pointer.)
    5040             :  */
    5041             : static int
    5042        8688 : parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
    5043             : {
    5044        8688 :     const char *service = conninfo_getval(options, "service");
    5045             :     char        serviceFile[MAXPGPATH];
    5046             :     char       *env;
    5047        8688 :     bool        group_found = false;
    5048             :     int         status;
    5049             :     struct stat stat_buf;
    5050             : 
    5051             :     /*
    5052             :      * We have to special-case the environment variable PGSERVICE here, since
    5053             :      * this is and should be called before inserting environment defaults for
    5054             :      * other connection options.
    5055             :      */
    5056        8688 :     if (service == NULL)
    5057        8686 :         service = getenv("PGSERVICE");
    5058             : 
    5059             :     /* If no service name given, nothing to do */
    5060        8688 :     if (service == NULL)
    5061        8686 :         return 0;
    5062             : 
    5063             :     /*
    5064             :      * Try PGSERVICEFILE if specified, else try ~/.pg_service.conf (if that
    5065             :      * exists).
    5066             :      */
    5067           2 :     if ((env = getenv("PGSERVICEFILE")) != NULL)
    5068           2 :         strlcpy(serviceFile, env, sizeof(serviceFile));
    5069             :     else
    5070             :     {
    5071             :         char        homedir[MAXPGPATH];
    5072             : 
    5073           0 :         if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
    5074           0 :             goto next_file;
    5075           0 :         snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
    5076           0 :         if (stat(serviceFile, &stat_buf) != 0)
    5077           0 :             goto next_file;
    5078             :     }
    5079             : 
    5080           2 :     status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
    5081           2 :     if (group_found || status != 0)
    5082           2 :         return status;
    5083             : 
    5084           0 : next_file:
    5085             : 
    5086             :     /*
    5087             :      * This could be used by any application so we can't use the binary
    5088             :      * location to find our config files.
    5089             :      */
    5090           0 :     snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
    5091           0 :              getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
    5092           0 :     if (stat(serviceFile, &stat_buf) != 0)
    5093           0 :         goto last_file;
    5094             : 
    5095           0 :     status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
    5096           0 :     if (status != 0)
    5097           0 :         return status;
    5098             : 
    5099           0 : last_file:
    5100           0 :     if (!group_found)
    5101             :     {
    5102           0 :         printfPQExpBuffer(errorMessage,
    5103           0 :                           libpq_gettext("definition of service \"%s\" not found\n"), service);
    5104           0 :         return 3;
    5105             :     }
    5106             : 
    5107           0 :     return 0;
    5108             : }
    5109             : 
    5110             : static int
    5111           2 : parseServiceFile(const char *serviceFile,
    5112             :                  const char *service,
    5113             :                  PQconninfoOption *options,
    5114             :                  PQExpBuffer errorMessage,
    5115             :                  bool *group_found)
    5116             : {
    5117           2 :     int         linenr = 0,
    5118             :                 i;
    5119             :     FILE       *f;
    5120             :     char        buf[MAXBUFSIZE],
    5121             :                *line;
    5122             : 
    5123           2 :     f = fopen(serviceFile, "r");
    5124           2 :     if (f == NULL)
    5125             :     {
    5126           0 :         printfPQExpBuffer(errorMessage, libpq_gettext("service file \"%s\" not found\n"),
    5127             :                           serviceFile);
    5128           0 :         return 1;
    5129             :     }
    5130             : 
    5131          16 :     while ((line = fgets(buf, sizeof(buf), f)) != NULL)
    5132             :     {
    5133             :         int         len;
    5134             : 
    5135          14 :         linenr++;
    5136             : 
    5137          14 :         if (strlen(line) >= sizeof(buf) - 1)
    5138             :         {
    5139           0 :             fclose(f);
    5140           0 :             printfPQExpBuffer(errorMessage,
    5141           0 :                               libpq_gettext("line %d too long in service file \"%s\"\n"),
    5142             :                               linenr,
    5143             :                               serviceFile);
    5144           0 :             return 2;
    5145             :         }
    5146             : 
    5147             :         /* ignore whitespace at end of line, especially the newline */
    5148          14 :         len = strlen(line);
    5149          28 :         while (len > 0 && isspace((unsigned char) line[len - 1]))
    5150          14 :             line[--len] = '\0';
    5151             : 
    5152             :         /* ignore leading whitespace too */
    5153          14 :         while (*line && isspace((unsigned char) line[0]))
    5154           0 :             line++;
    5155             : 
    5156             :         /* ignore comments and empty lines */
    5157          14 :         if (line[0] == '\0' || line[0] == '#')
    5158          10 :             continue;
    5159             : 
    5160             :         /* Check for right groupname */
    5161           4 :         if (line[0] == '[')
    5162             :         {
    5163           2 :             if (*group_found)
    5164             :             {
    5165             :                 /* group info already read */
    5166           0 :                 fclose(f);
    5167           0 :                 return 0;
    5168             :             }
    5169             : 
    5170           2 :             if (strncmp(line + 1, service, strlen(service)) == 0 &&
    5171           2 :                 line[strlen(service) + 1] == ']')
    5172           2 :                 *group_found = true;
    5173             :             else
    5174           0 :                 *group_found = false;
    5175             :         }
    5176             :         else
    5177             :         {
    5178           2 :             if (*group_found)
    5179             :             {
    5180             :                 /*
    5181             :                  * Finally, we are in the right group and can parse the line
    5182             :                  */
    5183             :                 char       *key,
    5184             :                            *val;
    5185             :                 bool        found_keyword;
    5186             : 
    5187             : #ifdef USE_LDAP
    5188           2 :                 if (strncmp(line, "ldap", 4) == 0)
    5189             :                 {
    5190           2 :                     int         rc = ldapServiceLookup(line, options, errorMessage);
    5191             : 
    5192             :                     /* if rc = 2, go on reading for fallback */
    5193           2 :                     switch (rc)
    5194             :                     {
    5195           0 :                         case 0:
    5196           0 :                             fclose(f);
    5197           0 :                             return 0;
    5198           0 :                         case 1:
    5199             :                         case 3:
    5200           0 :                             fclose(f);
    5201           0 :                             return 3;
    5202           2 :                         case 2:
    5203           2 :                             continue;
    5204             :                     }
    5205             :                 }
    5206             : #endif
    5207             : 
    5208           0 :                 key = line;
    5209           0 :                 val = strchr(line, '=');
    5210           0 :                 if (val == NULL)
    5211             :                 {
    5212           0 :                     printfPQExpBuffer(errorMessage,
    5213           0 :                                       libpq_gettext("syntax error in service file \"%s\", line %d\n"),
    5214             :                                       serviceFile,
    5215             :                                       linenr);
    5216           0 :                     fclose(f);
    5217           0 :                     return 3;
    5218             :                 }
    5219           0 :                 *val++ = '\0';
    5220             : 
    5221           0 :                 if (strcmp(key, "service") == 0)
    5222             :                 {
    5223           0 :                     printfPQExpBuffer(errorMessage,
    5224           0 :                                       libpq_gettext("nested service specifications not supported in service file \"%s\", line %d\n"),
    5225             :                                       serviceFile,
    5226             :                                       linenr);
    5227           0 :                     fclose(f);
    5228           0 :                     return 3;
    5229             :                 }
    5230             : 
    5231             :                 /*
    5232             :                  * Set the parameter --- but don't override any previous
    5233             :                  * explicit setting.
    5234             :                  */
    5235           0 :                 found_keyword = false;
    5236           0 :                 for (i = 0; options[i].keyword; i++)
    5237             :                 {
    5238           0 :                     if (strcmp(options[i].keyword, key) == 0)
    5239             :                     {
    5240           0 :                         if (options[i].val == NULL)
    5241           0 :                             options[i].val = strdup(val);
    5242           0 :                         if (!options[i].val)
    5243             :                         {
    5244           0 :                             printfPQExpBuffer(errorMessage,
    5245           0 :                                               libpq_gettext("out of memory\n"));
    5246           0 :                             fclose(f);
    5247           0 :                             return 3;
    5248             :                         }
    5249           0 :                         found_keyword = true;
    5250           0 :                         break;
    5251             :                     }
    5252             :                 }
    5253             : 
    5254           0 :                 if (!found_keyword)
    5255             :                 {
    5256           0 :                     printfPQExpBuffer(errorMessage,
    5257           0 :                                       libpq_gettext("syntax error in service file \"%s\", line %d\n"),
    5258             :                                       serviceFile,
    5259             :                                       linenr);
    5260           0 :                     fclose(f);
    5261           0 :                     return 3;
    5262             :                 }
    5263             :             }
    5264             :         }
    5265             :     }
    5266             : 
    5267           2 :     fclose(f);
    5268             : 
    5269           2 :     return 0;
    5270             : }
    5271             : 
    5272             : 
    5273             : /*
    5274             :  *      PQconninfoParse
    5275             :  *
    5276             :  * Parse a string like PQconnectdb() would do and return the
    5277             :  * resulting connection options array.  NULL is returned on failure.
    5278             :  * The result contains only options specified directly in the string,
    5279             :  * not any possible default values.
    5280             :  *
    5281             :  * If errmsg isn't NULL, *errmsg is set to NULL on success, or a malloc'd
    5282             :  * string on failure (use PQfreemem to free it).  In out-of-memory conditions
    5283             :  * both *errmsg and the result could be NULL.
    5284             :  *
    5285             :  * NOTE: the returned array is dynamically allocated and should
    5286             :  * be freed when no longer needed via PQconninfoFree().
    5287             :  */
    5288             : PQconninfoOption *
    5289         106 : PQconninfoParse(const char *conninfo, char **errmsg)
    5290             : {
    5291             :     PQExpBufferData errorBuf;
    5292             :     PQconninfoOption *connOptions;
    5293             : 
    5294         106 :     if (errmsg)
    5295         104 :         *errmsg = NULL;         /* default */
    5296         106 :     initPQExpBuffer(&errorBuf);
    5297         106 :     if (PQExpBufferDataBroken(errorBuf))
    5298           0 :         return NULL;            /* out of memory already :-( */
    5299         106 :     connOptions = parse_connection_string(conninfo, &errorBuf, false);
    5300         106 :     if (connOptions == NULL && errmsg)
    5301           8 :         *errmsg = errorBuf.data;
    5302             :     else
    5303          98 :         termPQExpBuffer(&errorBuf);
    5304         106 :     return connOptions;
    5305             : }
    5306             : 
    5307             : /*
    5308             :  * Build a working copy of the constant PQconninfoOptions array.
    5309             :  */
    5310             : static PQconninfoOption *
    5311       12982 : conninfo_init(PQExpBuffer errorMessage)
    5312             : {
    5313             :     PQconninfoOption *options;
    5314             :     PQconninfoOption *opt_dest;
    5315             :     const internalPQconninfoOption *cur_opt;
    5316             : 
    5317             :     /*
    5318             :      * Get enough memory for all options in PQconninfoOptions, even if some
    5319             :      * end up being filtered out.
    5320             :      */
    5321       12982 :     options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
    5322       12982 :     if (options == NULL)
    5323             :     {
    5324           0 :         printfPQExpBuffer(errorMessage,
    5325           0 :                           libpq_gettext("out of memory\n"));
    5326           0 :         return NULL;
    5327             :     }
    5328       12982 :     opt_dest = options;
    5329             : 
    5330      480334 :     for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
    5331             :     {
    5332             :         /* Only copy the public part of the struct, not the full internal */
    5333      467352 :         memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
    5334      467352 :         opt_dest++;
    5335             :     }
    5336      103856 :     MemSet(opt_dest, 0, sizeof(PQconninfoOption));
    5337             : 
    5338       12982 :     return options;
    5339             : }
    5340             : 
    5341             : /*
    5342             :  * Connection string parser
    5343             :  *
    5344             :  * Returns a malloc'd PQconninfoOption array, if parsing is successful.
    5345             :  * Otherwise, NULL is returned and an error message is left in errorMessage.
    5346             :  *
    5347             :  * If use_defaults is true, default values are filled in (from a service file,
    5348             :  * environment variables, etc).
    5349             :  */
    5350             : static PQconninfoOption *
    5351        4810 : parse_connection_string(const char *connstr, PQExpBuffer errorMessage,
    5352             :                         bool use_defaults)
    5353             : {
    5354             :     /* Parse as URI if connection string matches URI prefix */
    5355        4810 :     if (uri_prefix_length(connstr) != 0)
    5356           0 :         return conninfo_uri_parse(connstr, errorMessage, use_defaults);
    5357             : 
    5358             :     /* Parse as default otherwise */
    5359        4810 :     return conninfo_parse(connstr, errorMessage, use_defaults);
    5360             : }
    5361             : 
    5362             : /*
    5363             :  * Checks if connection string starts with either of the valid URI prefix
    5364             :  * designators.
    5365             :  *
    5366             :  * Returns the URI prefix length, 0 if the string doesn't contain a URI prefix.
    5367             :  *
    5368             :  * XXX this is duplicated in psql/common.c.
    5369             :  */
    5370             : static int
    5371       12072 : uri_prefix_length(const char *connstr)
    5372             : {
    5373       12072 :     if (strncmp(connstr, uri_designator,
    5374             :                 sizeof(uri_designator) - 1) == 0)
    5375           0 :         return sizeof(uri_designator) - 1;
    5376             : 
    5377       12072 :     if (strncmp(connstr, short_uri_designator,
    5378             :                 sizeof(short_uri_designator) - 1) == 0)
    5379           0 :         return sizeof(short_uri_designator) - 1;
    5380             : 
    5381       12072 :     return 0;
    5382             : }
    5383             : 
    5384             : /*
    5385             :  * Recognized connection string either starts with a valid URI prefix or
    5386             :  * contains a "=" in it.
    5387             :  *
    5388             :  * Must be consistent with parse_connection_string: anything for which this
    5389             :  * returns true should at least look like it's parseable by that routine.
    5390             :  *
    5391             :  * XXX this is duplicated in psql/common.c
    5392             :  */
    5393             : static bool
    5394        7262 : recognized_connection_string(const char *connstr)
    5395             : {
    5396        7262 :     return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
    5397             : }
    5398             : 
    5399             : /*
    5400             :  * Subroutine for parse_connection_string
    5401             :  *
    5402             :  * Deal with a string containing key=value pairs.
    5403             :  */
    5404             : static PQconninfoOption *
    5405        4810 : conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
    5406             :                bool use_defaults)
    5407             : {
    5408             :     char       *pname;
    5409             :     char       *pval;
    5410             :     char       *buf;
    5411             :     char       *cp;
    5412             :     char       *cp2;
    5413             :     PQconninfoOption *options;
    5414             : 
    5415             :     /* Make a working copy of PQconninfoOptions */
    5416        4810 :     options = conninfo_init(errorMessage);
    5417        4810 :     if (options == NULL)
    5418           0 :         return NULL;
    5419             : 
    5420             :     /* Need a modifiable copy of the input string */
    5421        4810 :     if ((buf = strdup(conninfo)) == NULL)
    5422             :     {
    5423           0 :         printfPQExpBuffer(errorMessage,
    5424           0 :                           libpq_gettext("out of memory\n"));
    5425           0 :         PQconninfoFree(options);
    5426           0 :         return NULL;
    5427             :     }
    5428        4810 :     cp = buf;
    5429             : 
    5430       17444 :     while (*cp)
    5431             :     {
    5432             :         /* Skip blanks before the parameter name */
    5433       12646 :         if (isspace((unsigned char) *cp))
    5434             :         {
    5435         128 :             cp++;
    5436         128 :             continue;
    5437             :         }
    5438             : 
    5439             :         /* Get the parameter name */
    5440       12518 :         pname = cp;
    5441       74464 :         while (*cp)
    5442             :         {
    5443       74452 :             if (*cp == '=')
    5444       12506 :                 break;
    5445       61946 :             if (isspace((unsigned char) *cp))
    5446             :             {
    5447           0 :                 *cp++ = '\0';
    5448           0 :                 while (*cp)
    5449             :                 {
    5450           0 :                     if (!isspace((unsigned char) *cp))
    5451           0 :                         break;
    5452           0 :                     cp++;
    5453             :                 }
    5454           0 :                 break;
    5455             :             }
    5456       61946 :             cp++;
    5457             :         }
    5458             : 
    5459             :         /* Check that there is a following '=' */
    5460       12518 :         if (*cp != '=')
    5461             :         {
    5462          12 :             printfPQExpBuffer(errorMessage,
    5463          12 :                               libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
    5464             :                               pname);
    5465          12 :             PQconninfoFree(options);
    5466          12 :             free(buf);
    5467          12 :             return NULL;
    5468             :         }
    5469       12506 :         *cp++ = '\0';
    5470             : 
    5471             :         /* Skip blanks after the '=' */
    5472       12506 :         while (*cp)
    5473             :         {
    5474       12506 :             if (!isspace((unsigned char) *cp))
    5475       12506 :                 break;
    5476           0 :             cp++;
    5477             :         }
    5478             : 
    5479             :         /* Get the parameter value */
    5480       12506 :         pval = cp;
    5481             : 
    5482       12506 :         if (*cp != '\'')
    5483             :         {
    5484        9290 :             cp2 = pval;
    5485      109948 :             while (*cp)
    5486             :             {
    5487      108308 :                 if (isspace((unsigned char) *cp))
    5488             :                 {
    5489        7650 :                     *cp++ = '\0';
    5490        7650 :                     break;
    5491             :                 }
    5492      100658 :                 if (*cp == '\\')
    5493             :                 {
    5494           0 :                     cp++;
    5495           0 :                     if (*cp != '\0')
    5496           0 :                         *cp2++ = *cp++;
    5497             :                 }
    5498             :                 else
    5499      100658 :                     *cp2++ = *cp++;
    5500             :             }
    5501        9290 :             *cp2 = '\0';
    5502             :         }
    5503             :         else
    5504             :         {
    5505        3216 :             cp2 = pval;
    5506        3216 :             cp++;
    5507             :             for (;;)
    5508             :             {
    5509       41068 :                 if (*cp == '\0')
    5510             :                 {
    5511           0 :                     printfPQExpBuffer(errorMessage,
    5512           0 :                                       libpq_gettext("unterminated quoted string in connection info string\n"));
    5513           0 :                     PQconninfoFree(options);
    5514           0 :                     free(buf);
    5515           0 :                     return NULL;
    5516             :                 }
    5517       41068 :                 if (*cp == '\\')
    5518             :                 {
    5519         280 :                     cp++;
    5520         280 :                     if (*cp != '\0')
    5521         280 :                         *cp2++ = *cp++;
    5522         280 :                     continue;
    5523             :                 }
    5524       40788 :                 if (*cp == '\'')
    5525             :                 {
    5526        3216 :                     *cp2 = '\0';
    5527        3216 :                     cp++;
    5528        3216 :                     break;
    5529             :                 }
    5530       37572 :                 *cp2++ = *cp++;
    5531             :             }
    5532             :         }
    5533             : 
    5534             :         /*
    5535             :          * Now that we have the name and the value, store the record.
    5536             :          */
    5537       12506 :         if (!conninfo_storeval(options, pname, pval, errorMessage, false, false))
    5538             :         {
    5539           0 :             PQconninfoFree(options);
    5540           0 :             free(buf);
    5541           0 :             return NULL;
    5542             :         }
    5543             :     }
    5544             : 
    5545             :     /* Done with the modifiable input string */
    5546        4798 :     free(buf);
    5547             : 
    5548             :     /*
    5549             :      * Add in defaults if the caller wants that.
    5550             :      */
    5551        4798 :     if (use_defaults)
    5552             :     {
    5553         818 :         if (!conninfo_add_defaults(options, errorMessage))
    5554             :         {
    5555           0 :             PQconninfoFree(options);
    5556           0 :             return NULL;
    5557             :         }
    5558             :     }
    5559             : 
    5560        4798 :     return options;
    5561             : }
    5562             : 
    5563             : /*
    5564             :  * Conninfo array parser routine
    5565             :  *
    5566             :  * If successful, a malloc'd PQconninfoOption array is returned.
    5567             :  * If not successful, NULL is returned and an error message is
    5568             :  * left in errorMessage.
    5569             :  * Defaults are supplied (from a service file, environment variables, etc)
    5570             :  * for unspecified options, but only if use_defaults is true.
    5571             :  *
    5572             :  * If expand_dbname is non-zero, and the value passed for the first occurrence
    5573             :  * of "dbname" keyword is a connection string (as indicated by
    5574             :  * recognized_connection_string) then parse and process it, overriding any
    5575             :  * previously processed conflicting keywords. Subsequent keywords will take
    5576             :  * precedence, however. In-tree programs generally specify expand_dbname=true,
    5577             :  * so command-line arguments naming a database can use a connection string.
    5578             :  * Some code acquires arbitrary database names from known-literal sources like
    5579             :  * PQdb(), PQconninfoParse() and pg_database.datname.  When connecting to such
    5580             :  * a database, in-tree code first wraps the name in a connection string.
    5581             :  */
    5582             : static PQconninfoOption *
    5583        7850 : conninfo_array_parse(const char *const *keywords, const char *const *values,
    5584             :                      PQExpBuffer errorMessage, bool use_defaults,
    5585             :                      int expand_dbname)
    5586             : {
    5587             :     PQconninfoOption *options;
    5588        7850 :     PQconninfoOption *dbname_options = NULL;
    5589             :     PQconninfoOption *option;
    5590        7850 :     int         i = 0;
    5591             : 
    5592             :     /*
    5593             :      * If expand_dbname is non-zero, check keyword "dbname" to see if val is
    5594             :      * actually a recognized connection string.
    5595             :      */
    5596       32770 :     while (expand_dbname && keywords[i])
    5597             :     {
    5598       32182 :         const char *pname = keywords[i];
    5599       32182 :         const char *pvalue = values[i];
    5600             : 
    5601             :         /* first find "dbname" if any */
    5602       32182 :         if (strcmp(pname, "dbname") == 0 && pvalue)
    5603             :         {
    5604             :             /*
    5605             :              * If value is a connection string, parse it, but do not use
    5606             :              * defaults here -- those get picked up later. We only want to
    5607             :              * override for those parameters actually passed.
    5608             :              */
    5609        7262 :             if (recognized_connection_string(pvalue))
    5610             :             {
    5611        3882 :                 dbname_options = parse_connection_string(pvalue, errorMessage, false);
    5612        3882 :                 if (dbname_options == NULL)
    5613           0 :                     return NULL;
    5614             :             }
    5615        7262 :             break;
    5616             :         }
    5617       24920 :         ++i;
    5618             :     }
    5619             : 
    5620             :     /* Make a working copy of PQconninfoOptions */
    5621        7850 :     options = conninfo_init(errorMessage);
    5622        7850 :     if (options == NULL)
    5623             :     {
    5624           0 :         PQconninfoFree(dbname_options);
    5625           0 :         return NULL;
    5626             :     }
    5627             : 
    5628             :     /* Parse the keywords/values arrays */
    5629        7850 :     i = 0;
    5630       55360 :     while (keywords[i])
    5631             :     {
    5632       47510 :         const char *pname = keywords[i];
    5633       47510 :         const char *pvalue = values[i];
    5634             : 
    5635       47510 :         if (pvalue != NULL && pvalue[0] != '\0')
    5636             :         {
    5637             :             /* Search for the param record */
    5638      241394 :             for (option = options; option->keyword != NULL; option++)
    5639             :             {
    5640      241394 :                 if (strcmp(option->keyword, pname) == 0)
    5641       19148 :                     break;
    5642             :             }
    5643             : 
    5644             :             /* Check for invalid connection option */
    5645       19148 :             if (option->keyword == NULL)
    5646             :             {
    5647           0 :                 printfPQExpBuffer(errorMessage,
    5648           0 :                                   libpq_gettext("invalid connection option \"%s\"\n"),
    5649             :                                   pname);
    5650           0 :                 PQconninfoFree(options);
    5651           0 :                 PQconninfoFree(dbname_options);
    5652           0 :                 return NULL;
    5653             :             }
    5654             : 
    5655             :             /*
    5656             :              * If we are on the first dbname parameter, and we have a parsed
    5657             :              * connection string, copy those parameters across, overriding any
    5658             :              * existing previous settings.
    5659             :              */
    5660       19148 :             if (strcmp(pname, "dbname") == 0 && dbname_options)
    5661        3882 :             {
    5662             :                 PQconninfoOption *str_option;
    5663             : 
    5664      143634 :                 for (str_option = dbname_options; str_option->keyword != NULL; str_option++)
    5665             :                 {
    5666      139752 :                     if (str_option->val != NULL)
    5667             :                     {
    5668             :                         int         k;
    5669             : 
    5670      110152 :                         for (k = 0; options[k].keyword; k++)
    5671             :                         {
    5672      110152 :                             if (strcmp(options[k].keyword, str_option->keyword) == 0)
    5673             :                             {
    5674       11186 :                                 if (options[k].val)
    5675           0 :                                     free(options[k].val);
    5676       11186 :                                 options[k].val = strdup(str_option->val);
    5677       11186 :                                 if (!options[k].val)
    5678             :                                 {
    5679           0 :                                     printfPQExpBuffer(errorMessage,
    5680           0 :                                                       libpq_gettext("out of memory\n"));
    5681           0 :                                     PQconninfoFree(options);
    5682           0 :                                     PQconninfoFree(dbname_options);
    5683           0 :                                     return NULL;
    5684             :                                 }
    5685       11186 :                                 break;
    5686             :                             }
    5687             :                         }
    5688             :                     }
    5689             :                 }
    5690             : 
    5691             :                 /*
    5692             :                  * Forget the parsed connection string, so that any subsequent
    5693             :                  * dbname parameters will not be expanded.
    5694             :                  */
    5695        3882 :                 PQconninfoFree(dbname_options);
    5696        3882 :                 dbname_options = NULL;
    5697             :             }
    5698             :             else
    5699             :             {
    5700             :                 /*
    5701             :                  * Store the value, overriding previous settings
    5702             :                  */
    5703       15266 :                 if (option->val)
    5704           0 :                     free(option->val);
    5705       15266 :                 option->val = strdup(pvalue);
    5706       15266 :                 if (!option->val)
    5707             :                 {
    5708           0 :                     printfPQExpBuffer(errorMessage,
    5709           0 :                                       libpq_gettext("out of memory\n"));
    5710           0 :                     PQconninfoFree(options);
    5711           0 :                     PQconninfoFree(dbname_options);
    5712           0 :                     return NULL;
    5713             :                 }
    5714             :             }
    5715             :         }
    5716       47510 :         ++i;
    5717             :     }
    5718        7850 :     PQconninfoFree(dbname_options);
    5719             : 
    5720             :     /*
    5721             :      * Add in defaults if the caller wants that.
    5722             :      */
    5723        7850 :     if (use_defaults)
    5724             :     {
    5725        7850 :         if (!conninfo_add_defaults(options, errorMessage))
    5726             :         {
    5727           0 :             PQconninfoFree(options);
    5728           0 :             return NULL;
    5729             :         }
    5730             :     }
    5731             : 
    5732        7850 :     return options;
    5733             : }
    5734             : 
    5735             : /*
    5736             :  * Add the default values for any unspecified options to the connection
    5737             :  * options array.
    5738             :  *
    5739             :  * Defaults are obtained from a service file, environment variables, etc.
    5740             :  *
    5741             :  * Returns true if successful, otherwise false; errorMessage, if supplied,
    5742             :  * is filled in upon failure.  Note that failure to locate a default value
    5743             :  * is not an error condition here --- we just leave the option's value as
    5744             :  * NULL.
    5745             :  */
    5746             : static bool
    5747        8688 : conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
    5748             : {
    5749             :     PQconninfoOption *option;
    5750             :     char       *tmp;
    5751             : 
    5752             :     /*
    5753             :      * If there's a service spec, use it to obtain any not-explicitly-given
    5754             :      * parameters.  Ignore error if no error message buffer is passed because
    5755             :      * there is no way to pass back the failure message.
    5756             :      */
    5757        8688 :     if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
    5758           0 :         return false;
    5759             : 
    5760             :     /*
    5761             :      * Get the fallback resources for parameters not specified in the conninfo
    5762             :      * string nor the service.
    5763             :      */
    5764      321456 :     for (option = options; option->keyword != NULL; option++)
    5765             :     {
    5766      312768 :         if (option->val != NULL)
    5767       27596 :             continue;           /* Value was in conninfo or service */
    5768             : 
    5769             :         /*
    5770             :          * Try to get the environment variable fallback
    5771             :          */
    5772      285172 :         if (option->envvar != NULL)
    5773             :         {
    5774      224014 :             if ((tmp = getenv(option->envvar)) != NULL)
    5775             :             {
    5776       20920 :                 option->val = strdup(tmp);
    5777       20920 :                 if (!option->val)
    5778             :                 {
    5779           0 :                     if (errorMessage)
    5780           0 :                         printfPQExpBuffer(errorMessage,
    5781           0 :                                           libpq_gettext("out of memory\n"));
    5782           0 :                     return false;
    5783             :                 }
    5784       20920 :                 continue;
    5785             :             }
    5786             :         }
    5787             : 
    5788             :         /*
    5789             :          * Interpret the deprecated PGREQUIRESSL environment variable.  Per
    5790             :          * tradition, translate values starting with "1" to sslmode=require,
    5791             :          * and ignore other values.  Given both PGREQUIRESSL=1 and PGSSLMODE,
    5792             :          * PGSSLMODE takes precedence; the opposite was true before v9.3.
    5793             :          */
    5794      264252 :         if (strcmp(option->keyword, "sslmode") == 0)
    5795             :         {
    5796        8556 :             const char *requiresslenv = getenv("PGREQUIRESSL");
    5797             : 
    5798        8556 :             if (requiresslenv != NULL && requiresslenv[0] == '1')
    5799             :             {
    5800           0 :                 option->val = strdup("require");
    5801           0 :                 if (!option->val)
    5802             :                 {
    5803           0 :                     if (errorMessage)
    5804           0 :                         printfPQExpBuffer(errorMessage,
    5805           0 :                                           libpq_gettext("out of memory\n"));
    5806           0 :                     return false;
    5807             :                 }
    5808           0 :                 continue;
    5809             :             }
    5810             :         }
    5811             : 
    5812             :         /*
    5813             :          * No environment variable specified or the variable isn't set - try
    5814             :          * compiled-in default
    5815             :          */
    5816      264252 :         if (option->compiled != NULL)
    5817             :         {
    5818       65726 :             option->val = strdup(option->compiled);
    5819       65726 :             if (!option->val)
    5820             :             {
    5821           0 :                 if (errorMessage)
    5822           0 :                     printfPQExpBuffer(errorMessage,
    5823           0 :                                       libpq_gettext("out of memory\n"));
    5824           0 :                 return false;
    5825             :             }
    5826       65726 :             continue;
    5827             :         }
    5828             : 
    5829             :         /*
    5830             :          * Special handling for "user" option.  Note that if pg_fe_getauthname
    5831             :          * fails, we just leave the value as NULL; there's no need for this to
    5832             :          * be an error condition if the caller provides a user name.  The only
    5833             :          * reason we do this now at all is so that callers of PQconndefaults
    5834             :          * will see a correct default (barring error, of course).
    5835             :          */
    5836      198526 :         if (strcmp(option->keyword, "user") == 0)
    5837             :         {
    5838        7978 :             option->val = pg_fe_getauthname(NULL);
    5839        7978 :             continue;
    5840             :         }
    5841             :     }
    5842             : 
    5843        8688 :     return true;
    5844             : }
    5845             : 
    5846             : /*
    5847             :  * Subroutine for parse_connection_string
    5848             :  *
    5849             :  * Deal with a URI connection string.
    5850             :  */
    5851             : static PQconninfoOption *
    5852           0 : conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage,
    5853             :                    bool use_defaults)
    5854             : {
    5855             :     PQconninfoOption *options;
    5856             : 
    5857             :     /* Make a working copy of PQconninfoOptions */
    5858           0 :     options = conninfo_init(errorMessage);
    5859           0 :     if (options == NULL)
    5860           0 :         return NULL;
    5861             : 
    5862           0 :     if (!conninfo_uri_parse_options(options, uri, errorMessage))
    5863             :     {
    5864           0 :         PQconninfoFree(options);
    5865           0 :         return NULL;
    5866             :     }
    5867             : 
    5868             :     /*
    5869             :      * Add in defaults if the caller wants that.
    5870             :      */
    5871           0 :     if (use_defaults)
    5872             :     {
    5873           0 :         if (!conninfo_add_defaults(options, errorMessage))
    5874             :         {
    5875           0 :             PQconninfoFree(options);
    5876           0 :             return NULL;
    5877             :         }
    5878             :     }
    5879             : 
    5880           0 :     return options;
    5881             : }
    5882             : 
    5883             : /*
    5884             :  * conninfo_uri_parse_options
    5885             :  *      Actual URI parser.
    5886             :  *
    5887             :  * If successful, returns true while the options array is filled with parsed
    5888             :  * options from the URI.
    5889             :  * If not successful, returns false and fills errorMessage accordingly.
    5890             :  *
    5891             :  * Parses the connection URI string in 'uri' according to the URI syntax (RFC
    5892             :  * 3986):
    5893             :  *
    5894             :  * postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
    5895             :  *
    5896             :  * where "netloc" is a hostname, an IPv4 address, or an IPv6 address surrounded
    5897             :  * by literal square brackets.  As an extension, we also allow multiple
    5898             :  * netloc[:port] specifications, separated by commas:
    5899             :  *
    5900             :  * postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...]
    5901             :  *
    5902             :  * Any of the URI parts might use percent-encoding (%xy).
    5903             :  */
    5904             : static bool
    5905           0 : conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
    5906             :                            PQExpBuffer errorMessage)
    5907             : {
    5908             :     int         prefix_len;
    5909             :     char       *p;
    5910           0 :     char       *buf = NULL;
    5911             :     char       *start;
    5912           0 :     char        prevchar = '\0';
    5913           0 :     char       *user = NULL;
    5914           0 :     char       *host = NULL;
    5915           0 :     bool        retval = false;
    5916             :     PQExpBufferData hostbuf;
    5917             :     PQExpBufferData portbuf;
    5918             : 
    5919           0 :     initPQExpBuffer(&hostbuf);
    5920           0 :     initPQExpBuffer(&portbuf);
    5921           0 :     if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
    5922             :     {
    5923           0 :         printfPQExpBuffer(errorMessage,
    5924           0 :                           libpq_gettext("out of memory\n"));
    5925           0 :         goto cleanup;
    5926             :     }
    5927             : 
    5928             :     /* need a modifiable copy of the input URI */
    5929           0 :     buf = strdup(uri);
    5930           0 :     if (buf == NULL)
    5931             :     {
    5932           0 :         printfPQExpBuffer(errorMessage,
    5933           0 :                           libpq_gettext("out of memory\n"));
    5934           0 :         goto cleanup;
    5935             :     }
    5936           0 :     start = buf;
    5937             : 
    5938             :     /* Skip the URI prefix */
    5939           0 :     prefix_len = uri_prefix_length(uri);
    5940           0 :     if (prefix_len == 0)
    5941             :     {
    5942             :         /* Should never happen */
    5943           0 :         printfPQExpBuffer(errorMessage,
    5944           0 :                           libpq_gettext("invalid URI propagated to internal parser routine: \"%s\"\n"),
    5945             :                           uri);
    5946           0 :         goto cleanup;
    5947             :     }
    5948           0 :     start += prefix_len;
    5949           0 :     p = start;
    5950             : 
    5951             :     /* Look ahead for possible user credentials designator */
    5952           0 :     while (*p && *p != '@' && *p != '/')
    5953           0 :         ++p;
    5954           0 :     if (*p == '@')
    5955             :     {
    5956             :         /*
    5957             :          * Found username/password designator, so URI should be of the form
    5958             :          * "scheme://user[:password]@[netloc]".
    5959             :          */
    5960           0 :         user = start;
    5961             : 
    5962           0 :         p = user;
    5963           0 :         while (*p != ':' && *p != '@')
    5964           0 :             ++p;
    5965             : 
    5966             :         /* Save last char and cut off at end of user name */
    5967           0 :         prevchar = *p;
    5968           0 :         *p = '\0';
    5969             : 
    5970           0 :         if (*user &&
    5971           0 :             !conninfo_storeval(options, "user", user,
    5972             :                                errorMessage, false, true))
    5973           0 :             goto cleanup;
    5974             : 
    5975           0 :         if (prevchar == ':')
    5976             :         {
    5977           0 :             const char *password = p + 1;
    5978             : 
    5979           0 :             while (*p != '@')
    5980           0 :                 ++p;
    5981           0 :             *p = '\0';
    5982             : 
    5983           0 :             if (*password &&
    5984           0 :                 !conninfo_storeval(options, "password", password,
    5985             :                                    errorMessage, false, true))
    5986           0 :                 goto cleanup;
    5987             :         }
    5988             : 
    5989             :         /* Advance past end of parsed user name or password token */
    5990           0 :         ++p;
    5991             :     }
    5992             :     else
    5993             :     {
    5994             :         /*
    5995             :          * No username/password designator found.  Reset to start of URI.
    5996             :          */
    5997           0 :         p = start;
    5998             :     }
    5999             : 
    6000             :     /*
    6001             :      * There may be multiple netloc[:port] pairs, each separated from the next
    6002             :      * by a comma.  When we initially enter this loop, "p" has been
    6003             :      * incremented past optional URI credential information at this point and
    6004             :      * now points at the "netloc" part of the URI.  On subsequent loop
    6005             :      * iterations, "p" has been incremented past the comma separator and now
    6006             :      * points at the start of the next "netloc".
    6007             :      */
    6008             :     for (;;)
    6009             :     {
    6010             :         /*
    6011             :          * Look for IPv6 address.
    6012             :          */
    6013           0 :         if (*p == '[')
    6014             :         {
    6015           0 :             host = ++p;
    6016           0 :             while (*p && *p != ']')
    6017           0 :                 ++p;
    6018           0 :             if (!*p)
    6019             :             {
    6020           0 :                 printfPQExpBuffer(errorMessage,
    6021           0 :                                   libpq_gettext("end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n"),
    6022             :                                   uri);
    6023           0 :                 goto cleanup;
    6024             :             }
    6025           0 :             if (p == host)
    6026             :             {
    6027           0 :                 printfPQExpBuffer(errorMessage,
    6028           0 :                                   libpq_gettext("IPv6 host address may not be empty in URI: \"%s\"\n"),
    6029             :                                   uri);
    6030           0 :                 goto cleanup;
    6031             :             }
    6032             : 
    6033             :             /* Cut off the bracket and advance */
    6034           0 :             *(p++) = '\0';
    6035             : 
    6036             :             /*
    6037             :              * The address may be followed by a port specifier or a slash or a
    6038             :              * query or a separator comma.
    6039             :              */
    6040           0 :             if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
    6041             :             {
    6042           0 :                 printfPQExpBuffer(errorMessage,
    6043           0 :                                   libpq_gettext("unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n"),
    6044           0 :                                   *p, (int) (p - buf + 1), uri);
    6045           0 :                 goto cleanup;
    6046             :             }
    6047             :         }
    6048             :         else
    6049             :         {
    6050             :             /* not an IPv6 address: DNS-named or IPv4 netloc */
    6051           0 :             host = p;
    6052             : 
    6053             :             /*
    6054             :              * Look for port specifier (colon) or end of host specifier
    6055             :              * (slash) or query (question mark) or host separator (comma).
    6056             :              */
    6057           0 :             while (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
    6058           0 :                 ++p;
    6059             :         }
    6060             : 
    6061             :         /* Save the hostname terminator before we null it */
    6062           0 :         prevchar = *p;
    6063           0 :         *p = '\0';
    6064             : 
    6065           0 :         appendPQExpBufferStr(&hostbuf, host);
    6066             : 
    6067           0 :         if (prevchar == ':')
    6068             :         {
    6069           0 :             const char *port = ++p; /* advance past host terminator */
    6070             : 
    6071           0 :             while (*p && *p != '/' && *p != '?' && *p != ',')
    6072           0 :                 ++p;
    6073             : 
    6074           0 :             prevchar = *p;
    6075           0 :             *p = '\0';
    6076             : 
    6077           0 :             appendPQExpBufferStr(&portbuf, port);
    6078             :         }
    6079             : 
    6080           0 :         if (prevchar != ',')
    6081           0 :             break;
    6082           0 :         ++p;                    /* advance past comma separator */
    6083           0 :         appendPQExpBufferChar(&hostbuf, ',');
    6084           0 :         appendPQExpBufferChar(&portbuf, ',');
    6085             :     }
    6086             : 
    6087             :     /* Save final values for host and port. */
    6088           0 :     if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
    6089           0 :         goto cleanup;
    6090           0 :     if (hostbuf.data[0] &&
    6091           0 :         !conninfo_storeval(options, "host", hostbuf.data,
    6092             :                            errorMessage, false, true))
    6093           0 :         goto cleanup;
    6094           0 :     if (portbuf.data[0] &&
    6095           0 :         !conninfo_storeval(options, "port", portbuf.data,
    6096             :                            errorMessage, false, true))
    6097           0 :         goto cleanup;
    6098             : 
    6099           0 :     if (prevchar && prevchar != '?')
    6100             :     {
    6101           0 :         const char *dbname = ++p;   /* advance past host terminator */
    6102             : 
    6103             :         /* Look for query parameters */
    6104           0 :         while (*p && *p != '?')
    6105           0 :             ++p;
    6106             : 
    6107           0 :         prevchar = *p;
    6108           0 :         *p = '\0';
    6109             : 
    6110             :         /*
    6111             :          * Avoid setting dbname to an empty string, as it forces the default
    6112             :          * value (username) and ignores $PGDATABASE, as opposed to not setting
    6113             :          * it at all.
    6114             :          */
    6115           0 :         if (*dbname &&
    6116           0 :             !conninfo_storeval(options, "dbname", dbname,
    6117             :                                errorMessage, false, true))
    6118           0 :             goto cleanup;
    6119             :     }
    6120             : 
    6121           0 :     if (prevchar)
    6122             :     {
    6123           0 :         ++p;                    /* advance past terminator */
    6124             : 
    6125           0 :         if (!conninfo_uri_parse_params(p, options, errorMessage))
    6126           0 :             goto cleanup;
    6127             :     }
    6128             : 
    6129             :     /* everything parsed okay */
    6130           0 :     retval = true;
    6131             : 
    6132           0 : cleanup:
    6133           0 :     termPQExpBuffer(&hostbuf);
    6134           0 :     termPQExpBuffer(&portbuf);
    6135           0 :     if (buf)
    6136           0 :         free(buf);
    6137           0 :     return retval;
    6138             : }
    6139             : 
    6140             : /*
    6141             :  * Connection URI parameters parser routine
    6142             :  *
    6143             :  * If successful, returns true while connOptions is filled with parsed
    6144             :  * parameters.  Otherwise, returns false and fills errorMessage appropriately.
    6145             :  *
    6146             :  * Destructively modifies 'params' buffer.
    6147             :  */
    6148             : static bool
    6149           0 : conninfo_uri_parse_params(char *params,
    6150             :                           PQconninfoOption *connOptions,
    6151             :                           PQExpBuffer errorMessage)
    6152             : {
    6153           0 :     while (*params)
    6154             :     {
    6155           0 :         char       *keyword = params;
    6156           0 :         char       *value = NULL;
    6157           0 :         char       *p = params;
    6158           0 :         bool        malloced = false;
    6159             : 
    6160             :         /*
    6161             :          * Scan the params string for '=' and '&', marking the end of keyword
    6162             :          * and value respectively.
    6163             :          */
    6164             :         for (;;)
    6165             :         {
    6166           0 :             if (*p == '=')
    6167             :             {
    6168             :                 /* Was there '=' already? */
    6169           0 :                 if (value != NULL)
    6170             :                 {
    6171           0 :                     printfPQExpBuffer(errorMessage,
    6172           0 :                                       libpq_gettext("extra key/value separator \"=\" in URI query parameter: \"%s\"\n"),
    6173             :                                       keyword);
    6174           0 :                     return false;
    6175             :                 }
    6176             :                 /* Cut off keyword, advance to value */
    6177           0 :                 *p++ = '\0';
    6178           0 :                 value = p;
    6179             :             }
    6180           0 :             else if (*p == '&' || *p == '\0')
    6181             :             {
    6182             :                 /*
    6183             :                  * If not at the end, cut off value and advance; leave p
    6184             :                  * pointing to start of the next parameter, if any.
    6185             :                  */
    6186           0 :                 if (*p != '\0')
    6187           0 :                     *p++ = '\0';
    6188             :                 /* Was there '=' at all? */
    6189           0 :                 if (value == NULL)
    6190             :                 {
    6191           0 :                     printfPQExpBuffer(errorMessage,
    6192           0 :                                       libpq_gettext("missing key/value separator \"=\" in URI query parameter: \"%s\"\n"),
    6193             :                                       keyword);
    6194           0 :                     return false;
    6195             :                 }
    6196             :                 /* Got keyword and value, go process them. */
    6197           0 :                 break;
    6198             :             }
    6199             :             else
    6200           0 :                 ++p;            /* Advance over all other bytes. */
    6201             :         }
    6202             : 
    6203           0 :         keyword = conninfo_uri_decode(keyword, errorMessage);
    6204           0 :         if (keyword == NULL)
    6205             :         {
    6206             :             /* conninfo_uri_decode already set an error message */
    6207           0 :             return false;
    6208             :         }
    6209           0 :         value = conninfo_uri_decode(value, errorMessage);
    6210           0 :         if (value == NULL)
    6211             :         {
    6212             :             /* conninfo_uri_decode already set an error message */
    6213           0 :             free(keyword);
    6214           0 :             return false;
    6215             :         }
    6216           0 :         malloced = true;
    6217             : 
    6218             :         /*
    6219             :          * Special keyword handling for improved JDBC compatibility.
    6220             :          */
    6221           0 :         if (strcmp(keyword, "ssl") == 0 &&
    6222           0 :             strcmp(value, "true") == 0)
    6223             :         {
    6224           0 :             free(keyword);
    6225           0 :             free(value);
    6226           0 :             malloced = false;
    6227             : 
    6228           0 :             keyword = "sslmode";
    6229           0 :             value = "require";
    6230             :         }
    6231             : 
    6232             :         /*
    6233             :          * Store the value if the corresponding option exists; ignore
    6234             :          * otherwise.  At this point both keyword and value are not
    6235             :          * URI-encoded.
    6236             :          */
    6237           0 :         if (!conninfo_storeval(connOptions, keyword, value,
    6238             :                                errorMessage, true, false))
    6239             :         {
    6240             :             /* Insert generic message if conninfo_storeval didn't give one. */
    6241           0 :             if (errorMessage->len == 0)
    6242           0 :                 printfPQExpBuffer(errorMessage,
    6243           0 :                                   libpq_gettext("invalid URI query parameter: \"%s\"\n"),
    6244             :                                   keyword);
    6245             :             /* And fail. */
    6246           0 :             if (malloced)
    6247             :             {
    6248           0 :                 free(keyword);
    6249           0 :                 free(value);
    6250             :             }
    6251           0 :             return false;
    6252             :         }
    6253             : 
    6254           0 :         if (malloced)
    6255             :         {
    6256           0 :             free(keyword);
    6257           0 :             free(value);
    6258             :         }
    6259             : 
    6260             :         /* Proceed to next key=value pair, if any */
    6261           0 :         params = p;
    6262             :     }
    6263             : 
    6264           0 :     return true;
    6265             : }
    6266             : 
    6267             : /*
    6268             :  * Connection URI decoder routine
    6269             :  *
    6270             :  * If successful, returns the malloc'd decoded string.
    6271             :  * If not successful, returns NULL and fills errorMessage accordingly.
    6272             :  *
    6273             :  * The string is decoded by replacing any percent-encoded tokens with
    6274             :  * corresponding characters, while preserving any non-encoded characters.  A
    6275             :  * percent-encoded token is a character triplet: a percent sign, followed by a
    6276             :  * pair of hexadecimal digits (0-9A-F), where lower- and upper-case letters are
    6277             :  * treated identically.
    6278             :  */
    6279             : static char *
    6280           0 : conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
    6281             : {
    6282             :     char       *buf;
    6283             :     char       *p;
    6284           0 :     const char *q = str;
    6285             : 
    6286           0 :     buf = malloc(strlen(str) + 1);
    6287           0 :     if (buf == NULL)
    6288             :     {
    6289           0 :         printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
    6290           0 :         return NULL;
    6291             :     }
    6292           0 :     p = buf;
    6293             : 
    6294             :     for (;;)
    6295             :     {
    6296           0 :         if (*q != '%')
    6297             :         {
    6298             :             /* copy and check for NUL terminator */
    6299           0 :             if (!(*(p++) = *(q++)))
    6300           0 :                 break;
    6301             :         }
    6302             :         else
    6303             :         {
    6304             :             int         hi;
    6305             :             int         lo;
    6306             :             int         c;
    6307             : 
    6308           0 :             ++q;                /* skip the percent sign itself */
    6309             : 
    6310             :             /*
    6311             :              * Possible EOL will be caught by the first call to
    6312             :              * get_hexdigit(), so we never dereference an invalid q pointer.
    6313             :              */
    6314           0 :             if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
    6315             :             {
    6316           0 :                 printfPQExpBuffer(errorMessage,
    6317           0 :                                   libpq_gettext("invalid percent-encoded token: \"%s\"\n"),
    6318             :                                   str);
    6319           0 :                 free(buf);
    6320           0 :                 return NULL;
    6321             :             }
    6322             : 
    6323           0 :             c = (hi << 4) | lo;
    6324           0 :             if (c == 0)
    6325             :             {
    6326           0 :                 printfPQExpBuffer(errorMessage,
    6327           0 :                                   libpq_gettext("forbidden value %%00 in percent-encoded value: \"%s\"\n"),
    6328             :                                   str);
    6329           0 :                 free(buf);
    6330           0 :                 return NULL;
    6331             :             }
    6332           0 :             *(p++) = c;
    6333             :         }
    6334             :     }
    6335             : 
    6336           0 :     return buf;
    6337             : }
    6338             : 
    6339             : /*
    6340             :  * Convert hexadecimal digit character to its integer value.
    6341             :  *
    6342             :  * If successful, returns true and value is filled with digit's base 16 value.
    6343             :  * If not successful, returns false.
    6344             :  *
    6345             :  * Lower- and upper-case letters in the range A-F are treated identically.
    6346             :  */
    6347             : static bool
    6348           0 : get_hexdigit(char digit, int *value)
    6349             : {
    6350           0 :     if ('0' <= digit && digit <= '9')
    6351           0 :         *value = digit - '0';
    6352           0 :     else if ('A' <= digit && digit <= 'F')
    6353           0 :         *value = digit - 'A' + 10;
    6354           0 :     else if ('a' <= digit && digit <= 'f')
    6355           0 :         *value = digit - 'a' + 10;
    6356             :     else
    6357           0 :         return false;
    6358             : 
    6359           0 :     return true;
    6360             : }
    6361             : 
    6362             : /*
    6363             :  * Find an option value corresponding to the keyword in the connOptions array.
    6364             :  *
    6365             :  * If successful, returns a pointer to the corresponding option's value.
    6366             :  * If not successful, returns NULL.
    6367             :  */
    6368             : static const char *
    6369      303400 : conninfo_getval(PQconninfoOption *connOptions,
    6370             :                 const char *keyword)
    6371             : {
    6372             :     PQconninfoOption *option;
    6373             : 
    6374      303400 :     option = conninfo_find(connOptions, keyword);
    6375             : 
    6376      303400 :     return option ? option->val : NULL;
    6377             : }
    6378             : 
    6379             : /*
    6380             :  * Store a (new) value for an option corresponding to the keyword in
    6381             :  * connOptions array.
    6382             :  *
    6383             :  * If uri_decode is true, the value is URI-decoded.  The keyword is always
    6384             :  * assumed to be non URI-encoded.
    6385             :  *
    6386             :  * If successful, returns a pointer to the corresponding PQconninfoOption,
    6387             :  * which value is replaced with a strdup'd copy of the passed value string.
    6388             :  * The existing value for the option is free'd before replacing, if any.
    6389             :  *
    6390             :  * If not successful, returns NULL and fills errorMessage accordingly.
    6391             :  * However, if the reason of failure is an invalid keyword being passed and
    6392             :  * ignoreMissing is true, errorMessage will be left untouched.
    6393             :  */
    6394             : static PQconninfoOption *
    6395       17060 : conninfo_storeval(PQconninfoOption *connOptions,
    6396             :                   const char *keyword, const char *value,
    6397             :                   PQExpBuffer errorMessage, bool ignoreMissing,
    6398             :                   bool uri_decode)
    6399             : {
    6400             :     PQconninfoOption *option;
    6401             :     char       *value_copy;
    6402             : 
    6403             :     /*
    6404             :      * For backwards compatibility, requiressl=1 gets translated to
    6405             :      * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
    6406             :      * (which is the default for sslmode).
    6407             :      */
    6408       17060 :     if (strcmp(keyword, "requiressl") == 0)
    6409             :     {
    6410           0 :         keyword = "sslmode";
    6411           0 :         if (value[0] == '1')
    6412           0 :             value = "require";
    6413             :         else
    6414           0 :             value = "prefer";
    6415             :     }
    6416             : 
    6417       17060 :     option = conninfo_find(connOptions, keyword);
    6418       17060 :     if (option == NULL)
    6419             :     {
    6420           0 :         if (!ignoreMissing)
    6421           0 :             printfPQExpBuffer(errorMessage,
    6422           0 :                               libpq_gettext("invalid connection option \"%s\"\n"),
    6423             :                               keyword);
    6424           0 :         return NULL;
    6425             :     }
    6426             : 
    6427       17060 :     if (uri_decode)
    6428             :     {
    6429           0 :         value_copy = conninfo_uri_decode(value, errorMessage);
    6430           0 :         if (value_copy == NULL)
    6431             :             /* conninfo_uri_decode already set an error message */
    6432           0 :             return NULL;
    6433             :     }
    6434             :     else
    6435             :     {
    6436       17060 :         value_copy = strdup(value);
    6437       17060 :         if (value_copy == NULL)
    6438             :         {
    6439           0 :             printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
    6440           0 :             return NULL;
    6441             :         }
    6442             :     }
    6443             : 
    6444       17060 :     if (option->val)
    6445           0 :         free(option->val);
    6446       17060 :     option->val = value_copy;
    6447             : 
    6448       17060 :     return option;
    6449             : }
    6450             : 
    6451             : /*
    6452             :  * Find a PQconninfoOption option corresponding to the keyword in the
    6453             :  * connOptions array.
    6454             :  *
    6455             :  * If successful, returns a pointer to the corresponding PQconninfoOption
    6456             :  * structure.
    6457             :  * If not successful, returns NULL.
    6458             :  */
    6459             : static PQconninfoOption *
    6460      320460 : conninfo_find(PQconninfoOption *connOptions, const char *keyword)
    6461             : {
    6462             :     PQconninfoOption *option;
    6463             : 
    6464     5962352 :     for (option = connOptions; option->keyword != NULL; option++)
    6465             :     {
    6466     5962352 :         if (strcmp(option->keyword, keyword) == 0)
    6467      320460 :             return option;
    6468             :     }
    6469             : 
    6470           0 :     return NULL;
    6471             : }
    6472             : 
    6473             : 
    6474             : /*
    6475             :  * Return the connection options used for the connection
    6476             :  */
    6477             : PQconninfoOption *
    6478         302 : PQconninfo(PGconn *conn)
    6479             : {
    6480             :     PQExpBufferData errorBuf;
    6481             :     PQconninfoOption *connOptions;
    6482             : 
    6483         302 :     if (conn == NULL)
    6484           0 :         return NULL;
    6485             : 
    6486             :     /* We don't actually report any errors here, but callees want a buffer */
    6487         302 :     initPQExpBuffer(&errorBuf);
    6488         302 :     if (PQExpBufferDataBroken(errorBuf))
    6489           0 :         return NULL;            /* out of memory already :-( */
    6490             : 
    6491         302 :     connOptions = conninfo_init(&errorBuf);
    6492             : 
    6493         302 :     if (connOptions != NULL)
    6494             :     {
    6495             :         const internalPQconninfoOption *option;
    6496             : 
    6497       11174 :         for (option = PQconninfoOptions; option->keyword; option++)
    6498             :         {
    6499             :             char      **connmember;
    6500             : 
    6501       10872 :             if (option->connofs < 0)
    6502         604 :                 continue;
    6503             : 
    6504       10268 :             connmember = (char **) ((char *) conn + option->connofs);
    6505             : 
    6506       10268 :             if (*connmember)
    6507        4554 :                 conninfo_storeval(connOptions, option->keyword, *connmember,
    6508             :                                   &errorBuf, true, false);
    6509             :         }
    6510             :     }
    6511             : 
    6512         302 :     termPQExpBuffer(&errorBuf);
    6513             : 
    6514         302 :     return connOptions;
    6515             : }
    6516             : 
    6517             : 
    6518             : void
    6519       20814 : PQconninfoFree(PQconninfoOption *connOptions)
    6520             : {
    6521             :     PQconninfoOption *option;
    6522             : 
    6523       20814 :     if (connOptions == NULL)
    6524        7850 :         return;
    6525             : 
    6526      479668 :     for (option = connOptions; option->keyword != NULL; option++)
    6527             :     {
    6528      466704 :         if (option->val != NULL)
    6529      137916 :             free(option->val);
    6530             :     }
    6531       12964 :     free(connOptions);
    6532             : }
    6533             : 
    6534             : 
    6535             : /* =========== accessor functions for PGconn ========= */
    6536             : char *
    6537        5232 : PQdb(const PGconn *conn)
    6538             : {
    6539        5232 :     if (!conn)
    6540           0 :         return NULL;
    6541        5232 :     return conn->dbName;
    6542             : }
    6543             : 
    6544             : char *
    6545        5368 : PQuser(const PGconn *conn)
    6546             : {
    6547        5368 :     if (!conn)
    6548           0 :         return NULL;
    6549        5368 :     return conn->pguser;
    6550             : }
    6551             : 
    6552             : char *
    6553         518 : PQpass(const PGconn *conn)
    6554             : {
    6555         518 :     char       *password = NULL;
    6556             : 
    6557         518 :     if (!conn)
    6558           0 :         return NULL;
    6559         518 :     if (conn->connhost != NULL)
    6560         518 :         password = conn->connhost[conn->whichhost].password;
    6561         518 :     if (password == NULL)
    6562         518 :         password = conn->pgpass;
    6563             :     /* Historically we've returned "" not NULL for no password specified */
    6564         518 :     if (password == NULL)
    6565         478 :         password = "";
    6566         518 :     return password;
    6567             : }
    6568             : 
    6569             : char *
    6570        5514 : PQhost(const PGconn *conn)
    6571             : {
    6572        5514 :     if (!conn)
    6573           0 :         return NULL;
    6574             : 
    6575        5514 :     if (conn->connhost != NULL)
    6576             :     {
    6577             :         /*
    6578             :          * Return the verbatim host value provided by user, or hostaddr in its
    6579             :          * lack.
    6580             :          */
    6581        5514 :         if (conn->connhost[conn->whichhost].host != NULL &&
    6582        5514 :             conn->connhost[conn->whichhost].host[0] != '\0')
    6583        5514 :             return conn->connhost[conn->whichhost].host;
    6584           0 :         else if (conn->connhost[conn->whichhost].hostaddr != NULL &&
    6585           0 :                  conn->connhost[conn->whichhost].hostaddr[0] != '\0')
    6586           0 :             return conn->connhost[conn->whichhost].hostaddr;
    6587             :     }
    6588             : 
    6589           0 :     return "";
    6590             : }
    6591             : 
    6592             : char *
    6593           0 : PQhostaddr(const PGconn *conn)
    6594             : {
    6595           0 :     if (!conn)
    6596           0 :         return NULL;
    6597             : 
    6598             :     /* Return the parsed IP address */
    6599           0 :     if (conn->connhost != NULL && conn->connip != NULL)
    6600           0 :         return conn->connip;
    6601             : 
    6602           0 :     return "";
    6603             : }
    6604             : 
    6605             : char *
    6606        5514 : PQport(const PGconn *conn)
    6607             : {
    6608        5514 :     if (!conn)
    6609           0 :         return NULL;
    6610             : 
    6611        5514 :     if (conn->connhost != NULL)
    6612        5514 :         return conn->connhost[conn->whichhost].port;
    6613             : 
    6614           0 :     return "";
    6615             : }
    6616             : 
    6617             : char *
    6618           0 : PQtty(const PGconn *conn)
    6619             : {
    6620           0 :     if (!conn)
    6621           0 :         return NULL;
    6622           0 :     return conn->pgtty;
    6623             : }
    6624             : 
    6625             : char *
    6626           0 : PQoptions(const PGconn *conn)
    6627             : {
    6628           0 :     if (!conn)
    6629           0 :         return NULL;
    6630           0 :     return conn->pgoptions;
    6631             : }
    6632             : 
    6633             : ConnStatusType
    6634       36996 : PQstatus(const PGconn *conn)
    6635             : {
    6636       36996 :     if (!conn)
    6637           0 :         return CONNECTION_BAD;
    6638       36996 :     return conn->status;
    6639             : }
    6640             : 
    6641             : PGTransactionStatusType
    6642      172910 : PQtransactionStatus(const PGconn *conn)
    6643             : {
    6644      172910 :     if (!conn || conn->status != CONNECTION_OK)
    6645           0 :         return PQTRANS_UNKNOWN;
    6646      172910 :     if (conn->asyncStatus != PGASYNC_IDLE)
    6647           2 :         return PQTRANS_ACTIVE;
    6648      172908 :     return conn->xactStatus;
    6649             : }
    6650             : 
    6651             : const char *
    6652      317474 : PQparameterStatus(const PGconn *conn, const char *paramName)
    6653             : {
    6654             :     const pgParameterStatus *pstatus;
    6655             : 
    6656      317474 :     if (!conn || !paramName)
    6657           0 :         return NULL;
    6658      726000 :     for (pstatus = conn->pstatus; pstatus != NULL; pstatus = pstatus->next)
    6659             :     {
    6660      726000 :         if (strcmp(pstatus->name, paramName) == 0)
    6661      317474 :             return pstatus->value;
    6662             :     }
    6663           0 :     return NULL;
    6664             : }
    6665             : 
    6666             : int
    6667           0 : PQprotocolVersion(const PGconn *conn)
    6668             : {
    6669           0 :     if (!conn)
    6670           0 :         return 0;
    6671           0 :     if (conn->status == CONNECTION_BAD)
    6672           0 :         return 0;
    6673           0 :     return PG_PROTOCOL_MAJOR(conn->pversion);
    6674             : }
    6675             : 
    6676             : int
    6677       19946 : PQserverVersion(const PGconn *conn)
    6678             : {
    6679       19946 :     if (!conn)
    6680           0 :         return 0;
    6681       19946 :     if (conn->status == CONNECTION_BAD)
    6682           0 :         return 0;
    6683       19946 :     return conn->sversion;
    6684             : }
    6685             : 
    6686             : char *
    6687       18632 : PQerrorMessage(const PGconn *conn)
    6688             : {
    6689       18632 :     if (!conn)
    6690           0 :         return libpq_gettext("connection pointer is NULL\n");
    6691             : 
    6692       18632 :     return conn->errorMessage.data;
    6693             : }
    6694             : 
    6695             : /*
    6696             :  * In Windows, socket values are unsigned, and an invalid socket value
    6697             :  * (INVALID_SOCKET) is ~0, which equals -1 in comparisons (with no compiler
    6698             :  * warning). Ideally we would return an unsigned value for PQsocket() on
    6699             :  * Windows, but that would cause the function's return value to differ from
    6700             :  * Unix, so we just return -1 for invalid sockets.
    6701             :  * http://msdn.microsoft.com/en-us/library/windows/desktop/cc507522%28v=vs.85%29.aspx
    6702             :  * http://stackoverflow.com/questions/10817252/why-is-invalid-socket-defined-as-0-in-winsock2-h-c
    6703             :  */
    6704             : int
    6705       99222 : PQsocket(const PGconn *conn)
    6706             : {
    6707       99222 :     if (!conn)
    6708           0 :         return -1;
    6709       99222 :     return (conn->sock != PGINVALID_SOCKET) ? conn->sock : -1;
    6710             : }
    6711             : 
    6712             : int
    6713         932 : PQbackendPID(const PGconn *conn)
    6714             : {
    6715         932 :     if (!conn || conn->status != CONNECTION_OK)
    6716           0 :         return 0;
    6717         932 :     return conn->be_pid;
    6718             : }
    6719             : 
    6720             : int
    6721         370 : PQconnectionNeedsPassword(const PGconn *conn)
    6722             : {
    6723             :     char       *password;
    6724             : 
    6725         370 :     if (!conn)
    6726           0 :         return false;
    6727         370 :     password = PQpass(conn);
    6728         370 :     if (conn->password_needed &&
    6729          30 :         (password == NULL || password[0] == '\0'))
    6730           0 :         return true;
    6731             :     else
    6732         370 :         return false;
    6733             : }
    6734             : 
    6735             : int
    6736         272 : PQconnectionUsedPassword(const PGconn *conn)
    6737             : {
    6738         272 :     if (!conn)
    6739           0 :         return false;
    6740         272 :     if (conn->password_needed)
    6741           0 :         return true;
    6742             :     else
    6743         272 :         return false;
    6744             : }
    6745             : 
    6746             : int
    6747      166474 : PQclientEncoding(const PGconn *conn)
    6748             : {
    6749      166474 :     if (!conn || conn->status != CONNECTION_OK)
    6750           0 :         return -1;
    6751      166474 :     return conn->client_encoding;
    6752             : }
    6753             : 
    6754             : int
    6755          20 : PQsetClientEncoding(PGconn *conn, const char *encoding)
    6756             : {
    6757             :     char        qbuf[128];
    6758             :     static const char query[] = "set client_encoding to '%s'";
    6759             :     PGresult   *res;
    6760             :     int         status;
    6761             : 
    6762          20 :     if (!conn || conn->status != CONNECTION_OK)
    6763           0 :         return -1;
    6764             : 
    6765          20 :     if (!encoding)
    6766           0 :         return -1;
    6767             : 
    6768             :     /* Resolve special "auto" value from the locale */
    6769          20 :     if (strcmp(encoding, "auto") == 0)
    6770           0 :         encoding = pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true));
    6771             : 
    6772             :     /* check query buffer overflow */
    6773          20 :     if (sizeof(qbuf) < (sizeof(query) + strlen(encoding)))
    6774           0 :         return -1;
    6775             : 
    6776             :     /* ok, now send a query */
    6777          20 :     sprintf(qbuf, query, encoding);
    6778          20 :     res = PQexec(conn, qbuf);
    6779             : 
    6780          20 :     if (res == NULL)
    6781           0 :         return -1;
    6782          20 :     if (res->resultStatus != PGRES_COMMAND_OK)
    6783           0 :         status = -1;
    6784             :     else
    6785             :     {
    6786             :         /*
    6787             :          * In protocol 2 we have to assume the setting will stick, and adjust
    6788             :          * our state immediately.  In protocol 3 and up we can rely on the
    6789             :          * backend to report the parameter value, and we'll change state at
    6790             :          * that time.
    6791             :          */
    6792          20 :         if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
    6793           0 :             pqSaveParameterStatus(conn, "client_encoding", encoding);
    6794          20 :         status = 0;             /* everything is ok */
    6795             :     }
    6796          20 :     PQclear(res);
    6797          20 :     return status;
    6798             : }
    6799             : 
    6800             : PGVerbosity
    6801        4898 : PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
    6802             : {
    6803             :     PGVerbosity old;
    6804             : 
    6805        4898 :     if (!conn)
    6806           0 :         return PQERRORS_DEFAULT;
    6807        4898 :     old = conn->verbosity;
    6808        4898 :     conn->verbosity = verbosity;
    6809        4898 :     return old;
    6810             : }
    6811             : 
    6812             : PGContextVisibility
    6813        4868 : PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
    6814             : {
    6815             :     PGContextVisibility old;
    6816             : 
    6817        4868 :     if (!conn)
    6818           0 :         return PQSHOW_CONTEXT_ERRORS;
    6819        4868 :     old = conn->show_context;
    6820        4868 :     conn->show_context = show_context;
    6821        4868 :     return old;
    6822             : }
    6823             : 
    6824             : void
    6825           0 : PQtrace(PGconn *conn, FILE *debug_port)
    6826             : {
    6827           0 :     if (conn == NULL)
    6828           0 :         return;
    6829           0 :     PQuntrace(conn);
    6830           0 :     conn->Pfdebug = debug_port;
    6831             : }
    6832             : 
    6833             : void
    6834           0 : PQuntrace(PGconn *conn)
    6835             : {
    6836           0 :     if (conn == NULL)
    6837           0 :         return;
    6838           0 :     if (conn->Pfdebug)
    6839             :     {
    6840           0 :         fflush(conn->Pfdebug);
    6841           0 :         conn->Pfdebug = NULL;
    6842             :     }
    6843             : }
    6844             : 
    6845             : PQnoticeReceiver
    6846         506 : PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
    6847             : {
    6848             :     PQnoticeReceiver old;
    6849             : 
    6850         506 :     if (conn == NULL)
    6851           0 :         return NULL;
    6852             : 
    6853         506 :     old = conn->noticeHooks.noticeRec;
    6854         506 :     if (proc)
    6855             :     {
    6856         506 :         conn->noticeHooks.noticeRec = proc;
    6857         506 :         conn->noticeHooks.noticeRecArg = arg;
    6858             :     }
    6859         506 :     return old;
    6860             : }
    6861             : 
    6862             : PQnoticeProcessor
    6863        5794 : PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
    6864             : {
    6865             :     PQnoticeProcessor old;
    6866             : 
    6867        5794 :     if (conn == NULL)
    6868           0 :         return NULL;
    6869             : 
    6870        5794 :     old = conn->noticeHooks.noticeProc;
    6871        5794 :     if (proc)
    6872             :     {
    6873        5794 :         conn->noticeHooks.noticeProc = proc;
    6874        5794 :         conn->noticeHooks.noticeProcArg = arg;
    6875             :     }
    6876        5794 :     return old;
    6877             : }
    6878             : 
    6879             : /*
    6880             :  * The default notice message receiver just gets the standard notice text
    6881             :  * and sends it to the notice processor.  This two-level setup exists
    6882             :  * mostly for backwards compatibility; perhaps we should deprecate use of
    6883             :  * PQsetNoticeProcessor?
    6884             :  */
    6885             : static void
    6886       12662 : defaultNoticeReceiver(void *arg, const PGresult *res)
    6887             : {
    6888             :     (void) arg;                 /* not used */
    6889       12662 :     if (res->noticeHooks.noticeProc != NULL)
    6890       12662 :         res->noticeHooks.noticeProc(res->noticeHooks.noticeProcArg,
    6891       12662 :                                     PQresultErrorMessage(res));
    6892       12662 : }
    6893             : 
    6894             : /*
    6895             :  * The default notice message processor just prints the
    6896             :  * message on stderr.  Applications can override this if they
    6897             :  * want the messages to go elsewhere (a window, for example).
    6898             :  * Note that simply discarding notices is probably a bad idea.
    6899             :  */
    6900             : static void
    6901         108 : defaultNoticeProcessor(void *arg, const char *message)
    6902             : {
    6903             :     (void) arg;                 /* not used */
    6904             :     /* Note: we expect the supplied string to end with a newline already. */
    6905         108 :     fprintf(stderr, "%s", message);
    6906         108 : }
    6907             : 
    6908             : /*
    6909             :  * returns a pointer to the next token or NULL if the current
    6910             :  * token doesn't match
    6911             :  */
    6912             : static char *
    6913           0 : pwdfMatchesString(char *buf, const char *token)
    6914             : {
    6915             :     char       *tbuf;
    6916             :     const char *ttok;
    6917           0 :     bool        bslash = false;
    6918             : 
    6919           0 :     if (buf == NULL || token == NULL)
    6920           0 :         return NULL;
    6921           0 :     tbuf = buf;
    6922           0 :     ttok = token;
    6923           0 :     if (tbuf[0] == '*' && tbuf[1] == ':')
    6924           0 :         return tbuf + 2;
    6925           0 :     while (*tbuf != 0)
    6926             :     {
    6927           0 :         if (*tbuf == '\\' && !bslash)
    6928             :         {
    6929           0 :             tbuf++;
    6930           0 :             bslash = true;
    6931             :         }
    6932           0 :         if (*tbuf == ':' && *ttok == 0 && !bslash)
    6933           0 :             return tbuf + 1;
    6934           0 :         bslash = false;
    6935           0 :         if (*ttok == 0)
    6936           0 :             return NULL;
    6937           0 :         if (*tbuf == *ttok)
    6938             :         {
    6939           0 :             tbuf++;
    6940           0 :             ttok++;
    6941             :         }
    6942             :         else
    6943           0 :             return NULL;
    6944             :     }
    6945           0 :     return NULL;
    6946             : }
    6947             : 
    6948             : /* Get a password from the password file. Return value is malloc'd. */
    6949             : static char *
    6950        8530 : passwordFromFile(const char *hostname, const char *port, const char *dbname,
    6951             :                  const char *username, const char *pgpassfile)
    6952             : {
    6953             :     FILE       *fp;
    6954             :     struct stat stat_buf;
    6955        8530 :     int         line_number = 0;
    6956             : 
    6957             : #define LINELEN NAMEDATALEN*5
    6958             :     char        buf[LINELEN];
    6959             : 
    6960        8530 :     if (dbname == NULL || dbname[0] == '\0')
    6961           0 :         return NULL;
    6962             : 
    6963        8530 :     if (username == NULL || username[0] == '\0')
    6964           0 :         return NULL;
    6965             : 
    6966             :     /* 'localhost' matches pghost of '' or the default socket directory */
    6967        8530 :     if (hostname == NULL || hostname[0] == '\0')
    6968           0 :         hostname = DefaultHost;
    6969        8530 :     else if (is_absolute_path(hostname))
    6970             : 
    6971             :         /*
    6972             :          * We should probably use canonicalize_path(), but then we have to
    6973             :          * bring path.c into libpq, and it doesn't seem worth it.
    6974             :          */
    6975        8180 :         if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
    6976           0 :             hostname = DefaultHost;
    6977             : 
    6978        8530 :     if (port == NULL || port[0] == '\0')
    6979           0 :         port = DEF_PGPORT_STR;
    6980             : 
    6981             :     /* If password file cannot be opened, ignore it. */
    6982        8530 :     if (stat(pgpassfile, &stat_buf) != 0)
    6983        8530 :         return NULL;
    6984             : 
    6985             : #ifndef WIN32
    6986           0 :     if (!S_ISREG(stat_buf.st_mode))
    6987             :     {
    6988           0 :         fprintf(stderr,
    6989           0 :                 libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
    6990             :                 pgpassfile);
    6991           0 :         return NULL;
    6992             :     }
    6993             : 
    6994             :     /* If password file is insecure, alert the user and ignore it. */
    6995           0 :     if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
    6996             :     {
    6997           0 :         fprintf(stderr,
    6998           0 :                 libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
    6999             :                 pgpassfile);
    7000           0 :         return NULL;
    7001             :     }
    7002             : #else
    7003             : 
    7004             :     /*
    7005             :      * On Win32, the directory is protected, so we don't have to check the
    7006             :      * file.
    7007             :      */
    7008             : #endif
    7009             : 
    7010           0 :     fp = fopen(pgpassfile, "r");
    7011           0 :     if (fp == NULL)
    7012           0 :         return NULL;
    7013             : 
    7014           0 :     while (!feof(fp) && !ferror(fp))
    7015             :     {
    7016           0 :         char       *t = buf,
    7017             :                    *ret,
    7018             :                    *p1,
    7019             :                    *p2;
    7020             :         int         len;
    7021             :         int         buflen;
    7022             : 
    7023           0 :         if (fgets(buf, sizeof(buf), fp) == NULL)
    7024           0 :             break;
    7025             : 
    7026           0 :         line_number++;
    7027           0 :         buflen = strlen(buf);
    7028           0 :         if (buflen >= sizeof(buf) - 1 && buf[buflen - 1] != '\n')
    7029             :         {
    7030             :             char        rest[LINELEN];
    7031             :             int         restlen;
    7032             : 
    7033             :             /*
    7034             :              * Warn if this password setting line is too long, because it's
    7035             :              * unexpectedly truncated.
    7036             :              */
    7037           0 :             if (buf[0] != '#')
    7038           0 :                 fprintf(stderr,
    7039           0 :                         libpq_gettext("WARNING: line %d too long in password file \"%s\"\n"),
    7040             :                         line_number, pgpassfile);
    7041             : 
    7042             :             /* eat rest of the line */
    7043           0 :             while (!feof(fp) && !ferror(fp))
    7044             :             {
    7045           0 :                 if (fgets(rest, sizeof(rest), fp) == NULL)
    7046           0 :                     break;
    7047           0 :                 restlen = strlen(rest);
    7048           0 :                 if (restlen < sizeof(rest) - 1 || rest[restlen - 1] == '\n')
    7049             :                     break;
    7050             :             }
    7051             :         }
    7052             : 
    7053             :         /* ignore comments */
    7054           0 :         if (buf[0] == '#')
    7055           0 :             continue;
    7056             : 
    7057             :         /* strip trailing newline and carriage return */
    7058           0 :         len = pg_strip_crlf(buf);
    7059             : 
    7060           0 :         if (len == 0)
    7061           0 :             continue;
    7062             : 
    7063           0 :         if ((t = pwdfMatchesString(t, hostname)) == NULL ||
    7064           0 :             (t = pwdfMatchesString(t, port)) == NULL ||
    7065           0 :             (t = pwdfMatchesString(t, dbname)) == NULL ||
    7066           0 :             (t = pwdfMatchesString(t, username)) == NULL)
    7067           0 :             continue;
    7068             : 
    7069             :         /* Found a match. */
    7070           0 :         ret = strdup(t);
    7071           0 :         fclose(fp);
    7072             : 
    7073           0 :         if (!ret)
    7074             :         {
    7075             :             /* Out of memory. XXX: an error message would be nice. */
    7076           0 :             explicit_bzero(buf, sizeof(buf));
    7077           0 :             return NULL;
    7078             :         }
    7079             : 
    7080             :         /* De-escape password. */
    7081           0 :         for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
    7082             :         {
    7083           0 :             if (*p1 == '\\' && p1[1] != '\0')
    7084           0 :                 ++p1;
    7085           0 :             *p2 = *p1;
    7086             :         }
    7087           0 :         *p2 = '\0';
    7088             : 
    7089           0 :         return ret;
    7090             :     }
    7091             : 
    7092           0 :     fclose(fp);
    7093           0 :     explicit_bzero(buf, sizeof(buf));
    7094           0 :     return NULL;
    7095             : 
    7096             : #undef LINELEN
    7097             : }
    7098             : 
    7099             : 
    7100             : /*
    7101             :  *  If the connection failed due to bad password, we should mention
    7102             :  *  if we got the password from the pgpassfile.
    7103             :  */
    7104             : static void
    7105          72 : pgpassfileWarning(PGconn *conn)
    7106             : {
    7107             :     /* If it was 'invalid authorization', add pgpassfile mention */
    7108             :     /* only works with >= 9.0 servers */
    7109          72 :     if (conn->password_needed &&
    7110          30 :         conn->connhost[conn->whichhost].password != NULL &&
    7111           0 :         conn->result)
    7112             :     {
    7113           0 :         const char *sqlstate = PQresultErrorField(conn->result,
    7114             :                                                   PG_DIAG_SQLSTATE);
    7115             : 
    7116           0 :         if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
    7117           0 :             appendPQExpBuffer(&conn->errorMessage,
    7118           0 :                               libpq_gettext("password retrieved from file \"%s\"\n"),
    7119             :                               conn->pgpassfile);
    7120             :     }
    7121          72 : }
    7122             : 
    7123             : /*
    7124             :  * Check if the SSL procotol value given in input is valid or not.
    7125             :  * This is used as a sanity check routine for the connection parameters
    7126             :  * ssl_min_protocol_version and ssl_max_protocol_version.
    7127             :  */
    7128             : static bool
    7129       17330 : sslVerifyProtocolVersion(const char *version)
    7130             : {
    7131             :     /*
    7132             :      * An empty string and a NULL value are considered valid as it is
    7133             :      * equivalent to ignoring the parameter.
    7134             :      */
    7135       17330 :     if (!version || strlen(version) == 0)
    7136       17318 :         return true;
    7137             : 
    7138          24 :     if (pg_strcasecmp(version, "TLSv1") == 0 ||
    7139          22 :         pg_strcasecmp(version, "TLSv1.1") == 0 ||
    7140          14 :         pg_strcasecmp(version, "TLSv1.2") == 0 ||
    7141           4 :         pg_strcasecmp(version, "TLSv1.3") == 0)
    7142           8 :         return true;
    7143             : 
    7144             :     /* anything else is wrong */
    7145           4 :     return false;
    7146             : }
    7147             : 
    7148             : 
    7149             : /*
    7150             :  * Ensure that the SSL protocol range given in input is correct.  The check
    7151             :  * is performed on the input string to keep it TLS backend agnostic.  Input
    7152             :  * to this function is expected verified with sslVerifyProtocolVersion().
    7153             :  */
    7154             : static bool
    7155        8662 : sslVerifyProtocolRange(const char *min, const char *max)
    7156             : {
    7157             :     Assert(sslVerifyProtocolVersion(min) &&
    7158             :            sslVerifyProtocolVersion(max));
    7159             : 
    7160             :     /* If at least one of the bounds is not set, the range is valid */
    7161        8662 :     if (min == NULL || max == NULL || strlen(min) == 0 || strlen(max) == 0)
    7162        8658 :         return true;
    7163             : 
    7164             :     /*
    7165             :      * If the minimum version is the lowest one we accept, then all options
    7166             :      * for the maximum are valid.
    7167             :      */
    7168           4 :     if (pg_strcasecmp(min, "TLSv1") == 0)
    7169           0 :         return true;
    7170             : 
    7171             :     /*
    7172             :      * The minimum bound is valid, and cannot be TLSv1, so using TLSv1 for the
    7173             :      * maximum is incorrect.
    7174             :      */
    7175           4 :     if (pg_strcasecmp(max, "TLSv1") == 0)
    7176           0 :         return false;
    7177             : 
    7178             :     /*
    7179             :      * At this point we know that we have a mix of TLSv1.1 through 1.3
    7180             :      * versions.
    7181             :      */
    7182           4 :     if (pg_strcasecmp(min, max) > 0)
    7183           2 :         return false;
    7184             : 
    7185           2 :     return true;
    7186             : }
    7187             : 
    7188             : 
    7189             : /*
    7190             :  * Obtain user's home directory, return in given buffer
    7191             :  *
    7192             :  * On Unix, this actually returns the user's home directory.  On Windows
    7193             :  * it returns the PostgreSQL-specific application data folder.
    7194             :  *
    7195             :  * This is essentially the same as get_home_path(), but we don't use that
    7196             :  * because we don't want to pull path.c into libpq (it pollutes application
    7197             :  * namespace).
    7198             :  *
    7199             :  * Returns true on success, false on failure to obtain the directory name.
    7200             :  *
    7201             :  * CAUTION: although in most situations failure is unexpected, there are users
    7202             :  * who like to run applications in a home-directory-less environment.  On
    7203             :  * failure, you almost certainly DO NOT want to report an error.  Just act as
    7204             :  * though whatever file you were hoping to find in the home directory isn't
    7205             :  * there (which it isn't).
    7206             :  */
    7207             : bool
    7208        8632 : pqGetHomeDirectory(char *buf, int bufsize)
    7209             : {
    7210             : #ifndef WIN32
    7211             :     char        pwdbuf[BUFSIZ];
    7212             :     struct passwd pwdstr;
    7213        8632 :     struct passwd *pwd = NULL;
    7214             : 
    7215        8632 :     (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
    7216        8632 :     if (pwd == NULL)
    7217           0 :         return false;
    7218        8632 :     strlcpy(buf, pwd->pw_dir, bufsize);
    7219        8632 :     return true;
    7220             : #else
    7221             :     char        tmppath[MAX_PATH];
    7222             : 
    7223             :     ZeroMemory(tmppath, sizeof(tmppath));
    7224             :     if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
    7225             :         return false;
    7226             :     snprintf(buf, bufsize, "%s/postgresql", tmppath);
    7227             :     return true;
    7228             : #endif
    7229             : }
    7230             : 
    7231             : /*
    7232             :  * To keep the API consistent, the locking stubs are always provided, even
    7233             :  * if they are not required.
    7234             :  */
    7235             : 
    7236             : static void
    7237       15956 : default_threadlock(int acquire)
    7238             : {
    7239             : #ifdef ENABLE_THREAD_SAFETY
    7240             : #ifndef WIN32
    7241             :     static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
    7242             : #else
    7243             :     static pthread_mutex_t singlethread_lock = NULL;
    7244             :     static long mutex_initlock = 0;
    7245             : 
    7246             :     if (singlethread_lock == NULL)
    7247             :     {
    7248             :         while (InterlockedExchange(&mutex_initlock, 1) == 1)
    7249             :              /* loop, another thread own the lock */ ;
    7250             :         if (singlethread_lock == NULL)
    7251             :         {
    7252             :             if (pthread_mutex_init(&singlethread_lock, NULL))
    7253             :                 PGTHREAD_ERROR("failed to initialize mutex");
    7254             :         }
    7255             :         InterlockedExchange(&mutex_initlock, 0);
    7256             :     }
    7257             : #endif
    7258       15956 :     if (acquire)
    7259             :     {
    7260        7978 :         if (pthread_mutex_lock(&singlethread_lock))
    7261           0 :             PGTHREAD_ERROR("failed to lock mutex");
    7262             :     }
    7263             :     else
    7264             :     {
    7265        7978 :         if (pthread_mutex_unlock(&singlethread_lock))
    7266           0 :             PGTHREAD_ERROR("failed to unlock mutex");
    7267             :     }
    7268             : #endif
    7269       15956 : }
    7270             : 
    7271             : pgthreadlock_t
    7272           0 : PQregisterThreadLock(pgthreadlock_t newhandler)
    7273             : {
    7274           0 :     pgthreadlock_t prev = pg_g_threadlock;
    7275             : 
    7276           0 :     if (newhandler)
    7277           0 :         pg_g_threadlock = newhandler;
    7278             :     else
    7279           0 :         pg_g_threadlock = default_threadlock;
    7280             : 
    7281           0 :     return prev;
    7282             : }

Generated by: LCOV version 1.13