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

Generated by: LCOV version 1.11