PostgreSQL Source Code git master
libpq-int.h File Reference
#include "libpq-events.h"
#include <netdb.h>
#include <sys/socket.h>
#include <time.h>
#include <pthread.h>
#include <signal.h>
#include "libpq/pqcomm.h"
#include "fe-auth-sasl.h"
#include "pqexpbuffer.h"
#include "libpq/pg-gssapi.h"
#include "common/pg_prng.h"
Include dependency graph for libpq-int.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

union  pgresult_data
 
struct  pgresParamDesc
 
struct  pgresAttValue
 
struct  pgMessageField
 
struct  PGNoticeHooks
 
struct  PGEvent
 
struct  pg_result
 
struct  PQEnvironmentOption
 
struct  pgParameterStatus
 
struct  pgLobjfuncs
 
struct  pgDataValue
 
struct  PGcmdQueueEntry
 
struct  pg_conn_host
 
struct  pg_conn
 

Macros

#define CMDSTATUS_LEN   64 /* should match COMPLETION_TAG_BUFSIZE */
 
#define NULL_LEN   (-1) /* pg_result len for NULL value */
 
#define ENC_ERROR   0
 
#define ENC_PLAINTEXT   0x01
 
#define ENC_GSSAPI   0x02
 
#define ENC_SSL   0x04
 
#define AUTH_RESPONSE_GSS   'G'
 
#define AUTH_RESPONSE_PASSWORD   'P'
 
#define AUTH_RESPONSE_SASL_INITIAL   'I'
 
#define AUTH_RESPONSE_SASL   'S'
 
#define pglock_thread()   pg_g_threadlock(true)
 
#define pgunlock_thread()   pg_g_threadlock(false)
 
#define pqClearConnErrorState(conn)
 
#define pgHavePendingResult(conn)    ((conn)->result != NULL || (conn)->error_result)
 
#define pqIsnonblocking(conn)   ((conn)->nonblocking)
 
#define OUTBUFFER_THRESHOLD   65536
 
#define libpq_gettext(x)   (x)
 
#define libpq_ngettext(s, p, n)   ((n) == 1 ? (s) : (p))
 
#define SOCK_ERRNO   errno
 
#define SOCK_STRERROR   strerror_r
 
#define SOCK_ERRNO_SET(e)   (errno = (e))
 

Typedefs

typedef union pgresult_data PGresult_data
 
typedef struct pgresParamDesc PGresParamDesc
 
typedef struct pgresAttValue PGresAttValue
 
typedef struct pgMessageField PGMessageField
 
typedef struct PGEvent PGEvent
 
typedef struct PQEnvironmentOption PQEnvironmentOption
 
typedef struct pgParameterStatus pgParameterStatus
 
typedef struct pgLobjfuncs PGlobjfuncs
 
typedef struct pgDataValue PGdataValue
 
typedef enum pg_conn_host_type pg_conn_host_type
 
typedef struct PGcmdQueueEntry PGcmdQueueEntry
 
typedef struct pg_conn_host pg_conn_host
 

Enumerations

enum  PGAsyncStatusType {
  PGASYNC_IDLE , PGASYNC_BUSY , PGASYNC_READY , PGASYNC_READY_MORE ,
  PGASYNC_COPY_IN , PGASYNC_COPY_OUT , PGASYNC_COPY_BOTH , PGASYNC_PIPELINE_IDLE
}
 
enum  PGTargetServerType {
  SERVER_TYPE_ANY = 0 , SERVER_TYPE_READ_WRITE , SERVER_TYPE_READ_ONLY , SERVER_TYPE_PRIMARY ,
  SERVER_TYPE_STANDBY , SERVER_TYPE_PREFER_STANDBY , SERVER_TYPE_PREFER_STANDBY_PASS2
}
 
enum  PGLoadBalanceType { LOAD_BALANCE_DISABLE = 0 , LOAD_BALANCE_RANDOM }
 
enum  PGTernaryBool {
  PG_BOOL_UNKNOWN = 0 , PG_BOOL_YES , PG_BOOL_NO , PG_BOOL_UNKNOWN = 0 ,
  PG_BOOL_YES , PG_BOOL_NO
}
 
enum  pg_conn_host_type { CHT_HOST_NAME , CHT_HOST_ADDRESS , CHT_UNIX_SOCKET }
 
enum  PGQueryClass {
  PGQUERY_SIMPLE , PGQUERY_EXTENDED , PGQUERY_PREPARE , PGQUERY_DESCRIBE ,
  PGQUERY_SYNC , PGQUERY_CLOSE
}
 

Functions

void pqDropConnection (PGconn *conn, bool flushInput)
 
bool pqConnectOptions2 (PGconn *conn)
 
int pqConnectDBStart (PGconn *conn)
 
int pqConnectDBComplete (PGconn *conn)
 
PGconnpqMakeEmptyPGconn (void)
 
void pqReleaseConnHosts (PGconn *conn)
 
void pqClosePGconn (PGconn *conn)
 
int pqPacketSend (PGconn *conn, char pack_type, const void *buf, size_t buf_len)
 
bool pqGetHomeDirectory (char *buf, int bufsize)
 
bool pqCopyPGconn (PGconn *srcConn, PGconn *dstConn)
 
bool pqParseIntParam (const char *value, int *result, PGconn *conn, const char *context)
 
void pqSetResultError (PGresult *res, PQExpBuffer errorMessage, int offset)
 
void * pqResultAlloc (PGresult *res, size_t nBytes, bool isBinary)
 
char * pqResultStrdup (PGresult *res, const char *str)
 
void pqClearAsyncResult (PGconn *conn)
 
void pqSaveErrorResult (PGconn *conn)
 
PGresultpqPrepareAsyncResult (PGconn *conn)
 
void pqInternalNotice (const PGNoticeHooks *hooks, const char *fmt,...) pg_attribute_printf(2
 
void void pqSaveMessageField (PGresult *res, char code, const char *value)
 
int pqSaveParameterStatus (PGconn *conn, const char *name, const char *value)
 
int pqRowProcessor (PGconn *conn, const char **errmsgp)
 
void pqCommandQueueAdvance (PGconn *conn, bool isReadyForQuery, bool gotSync)
 
int PQsendQueryContinue (PGconn *conn, const char *query)
 
char * pqBuildStartupPacket3 (PGconn *conn, int *packetlen, const PQEnvironmentOption *options)
 
void pqParseInput3 (PGconn *conn)
 
int pqGetErrorNotice3 (PGconn *conn, bool isError)
 
void pqBuildErrorMessage3 (PQExpBuffer msg, const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
 
int pqGetNegotiateProtocolVersion3 (PGconn *conn)
 
int pqGetCopyData3 (PGconn *conn, char **buffer, int async)
 
int pqGetline3 (PGconn *conn, char *s, int maxlen)
 
int pqGetlineAsync3 (PGconn *conn, char *buffer, int bufsize)
 
int pqEndcopy3 (PGconn *conn)
 
PGresultpqFunctionCall3 (PGconn *conn, Oid fnid, int *result_buf, int *actual_result_len, int result_is_int, const PQArgBlock *args, int nargs)
 
int PQsendCancelRequest (PGconn *cancelConn)
 
int pqCheckOutBufferSpace (size_t bytes_needed, PGconn *conn)
 
int pqCheckInBufferSpace (size_t bytes_needed, PGconn *conn)
 
void pqParseDone (PGconn *conn, int newInStart)
 
int pqGetc (char *result, PGconn *conn)
 
int pqPutc (char c, PGconn *conn)
 
int pqGets (PQExpBuffer buf, PGconn *conn)
 
int pqGets_append (PQExpBuffer buf, PGconn *conn)
 
int pqPuts (const char *s, PGconn *conn)
 
int pqGetnchar (void *s, size_t len, PGconn *conn)
 
int pqSkipnchar (size_t len, PGconn *conn)
 
int pqPutnchar (const void *s, size_t len, PGconn *conn)
 
int pqGetInt (int *result, size_t bytes, PGconn *conn)
 
int pqPutInt (int value, size_t bytes, PGconn *conn)
 
int pqPutMsgStart (char msg_type, PGconn *conn)
 
int pqPutMsgEnd (PGconn *conn)
 
int pqReadData (PGconn *conn)
 
int pqFlush (PGconn *conn)
 
int pqWait (int forRead, int forWrite, PGconn *conn)
 
int pqWaitTimed (int forRead, int forWrite, PGconn *conn, pg_usec_time_t end_time)
 
int pqReadReady (PGconn *conn)
 
int pqWriteReady (PGconn *conn)
 
PostgresPollingStatusType pqsecure_open_client (PGconn *)
 
void pqsecure_close (PGconn *)
 
ssize_t pqsecure_read (PGconn *, void *ptr, size_t len)
 
ssize_t pqsecure_write (PGconn *, const void *ptr, size_t len)
 
ssize_t pqsecure_raw_read (PGconn *, void *ptr, size_t len)
 
ssize_t pqsecure_raw_write (PGconn *, const void *ptr, size_t len)
 
int pq_block_sigpipe (sigset_t *osigset, bool *sigpipe_pending)
 
void pq_reset_sigpipe (sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
 
PostgresPollingStatusType pgtls_open_client (PGconn *conn)
 
void pgtls_close (PGconn *conn)
 
ssize_t pgtls_read (PGconn *conn, void *ptr, size_t len)
 
bool pgtls_read_pending (PGconn *conn)
 
ssize_t pgtls_write (PGconn *conn, const void *ptr, size_t len)
 
char * pgtls_get_peer_certificate_hash (PGconn *conn, size_t *len)
 
int pgtls_verify_peer_name_matches_certificate_guts (PGconn *conn, int *names_examined, char **first_name)
 
void pqTraceOutputMessage (PGconn *conn, const char *message, bool toServer)
 
void pqTraceOutputNoTypeByteMessage (PGconn *conn, const char *message)
 
void pqTraceOutputCharResponse (PGconn *conn, const char *responseType, char response)
 
void libpq_append_error (PQExpBuffer errorMessage, const char *fmt,...) pg_attribute_printf(2
 
void void libpq_append_conn_error (PGconn *conn, const char *fmt,...) pg_attribute_printf(2
 

Variables

char *const pgresStatus []
 
pgthreadlock_t pg_g_threadlock
 

Macro Definition Documentation

◆ AUTH_RESPONSE_GSS

#define AUTH_RESPONSE_GSS   'G'

Definition at line 335 of file libpq-int.h.

◆ AUTH_RESPONSE_PASSWORD

#define AUTH_RESPONSE_PASSWORD   'P'

Definition at line 336 of file libpq-int.h.

◆ AUTH_RESPONSE_SASL

#define AUTH_RESPONSE_SASL   'S'

Definition at line 338 of file libpq-int.h.

◆ AUTH_RESPONSE_SASL_INITIAL

#define AUTH_RESPONSE_SASL_INITIAL   'I'

Definition at line 337 of file libpq-int.h.

◆ CMDSTATUS_LEN

#define CMDSTATUS_LEN   64 /* should match COMPLETION_TAG_BUFSIZE */

Definition at line 83 of file libpq-int.h.

◆ ENC_ERROR

#define ENC_ERROR   0

Definition at line 229 of file libpq-int.h.

◆ ENC_GSSAPI

#define ENC_GSSAPI   0x02

Definition at line 231 of file libpq-int.h.

◆ ENC_PLAINTEXT

#define ENC_PLAINTEXT   0x01

Definition at line 230 of file libpq-int.h.

◆ ENC_SSL

#define ENC_SSL   0x04

Definition at line 232 of file libpq-int.h.

◆ libpq_gettext

#define libpq_gettext (   x)    (x)

Definition at line 950 of file libpq-int.h.

◆ libpq_ngettext

#define libpq_ngettext (   s,
  p,
 
)    ((n) == 1 ? (s) : (p))

Definition at line 951 of file libpq-int.h.

◆ NULL_LEN

#define NULL_LEN   (-1) /* pg_result len for NULL value */

Definition at line 130 of file libpq-int.h.

◆ OUTBUFFER_THRESHOLD

#define OUTBUFFER_THRESHOLD   65536

Definition at line 944 of file libpq-int.h.

◆ pgHavePendingResult

#define pgHavePendingResult (   conn)     ((conn)->result != NULL || (conn)->error_result)

Definition at line 932 of file libpq-int.h.

◆ pglock_thread

#define pglock_thread ( )    pg_g_threadlock(true)

Definition at line 744 of file libpq-int.h.

◆ pgunlock_thread

#define pgunlock_thread ( )    pg_g_threadlock(false)

Definition at line 745 of file libpq-int.h.

◆ pqClearConnErrorState

#define pqClearConnErrorState (   conn)
Value:
(resetPQExpBuffer(&(conn)->errorMessage), \
(conn)->errorReported = 0)
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
PGconn * conn
Definition: streamutil.c:52

Definition at line 923 of file libpq-int.h.

◆ pqIsnonblocking

#define pqIsnonblocking (   conn)    ((conn)->nonblocking)

Definition at line 939 of file libpq-int.h.

◆ SOCK_ERRNO

#define SOCK_ERRNO   errno

Definition at line 971 of file libpq-int.h.

◆ SOCK_ERRNO_SET

#define SOCK_ERRNO_SET (   e)    (errno = (e))

Definition at line 973 of file libpq-int.h.

◆ SOCK_STRERROR

#define SOCK_STRERROR   strerror_r

Definition at line 972 of file libpq-int.h.

Typedef Documentation

◆ pg_conn_host

typedef struct pg_conn_host pg_conn_host

◆ pg_conn_host_type

◆ PGcmdQueueEntry

◆ PGdataValue

typedef struct pgDataValue PGdataValue

◆ PGEvent

typedef struct PGEvent PGEvent

◆ PGlobjfuncs

typedef struct pgLobjfuncs PGlobjfuncs

◆ PGMessageField

◆ pgParameterStatus

◆ PGresAttValue

typedef struct pgresAttValue PGresAttValue

◆ PGresParamDesc

◆ PGresult_data

Definition at line 98 of file libpq-int.h.

◆ PQEnvironmentOption

Enumeration Type Documentation

◆ pg_conn_host_type

Enumerator
CHT_HOST_NAME 
CHT_HOST_ADDRESS 
CHT_UNIX_SOCKET 

Definition at line 307 of file libpq-int.h.

308{
pg_conn_host_type
Definition: libpq-int.h:308
@ CHT_UNIX_SOCKET
Definition: libpq-int.h:311
@ CHT_HOST_ADDRESS
Definition: libpq-int.h:310
@ CHT_HOST_NAME
Definition: libpq-int.h:309

◆ PGAsyncStatusType

Enumerator
PGASYNC_IDLE 
PGASYNC_BUSY 
PGASYNC_READY 
PGASYNC_READY_MORE 
PGASYNC_COPY_IN 
PGASYNC_COPY_OUT 
PGASYNC_COPY_BOTH 
PGASYNC_PIPELINE_IDLE 

Definition at line 213 of file libpq-int.h.

214{
215 PGASYNC_IDLE, /* nothing's happening, dude */
216 PGASYNC_BUSY, /* query in progress */
217 PGASYNC_READY, /* query done, waiting for client to fetch
218 * result */
219 PGASYNC_READY_MORE, /* query done, waiting for client to fetch
220 * result, more results expected from this
221 * query */
222 PGASYNC_COPY_IN, /* Copy In data transfer in progress */
223 PGASYNC_COPY_OUT, /* Copy Out data transfer in progress */
224 PGASYNC_COPY_BOTH, /* Copy In/Out data transfer in progress */
225 PGASYNC_PIPELINE_IDLE, /* "Idle" between commands in pipeline mode */
PGAsyncStatusType
Definition: libpq-int.h:214
@ PGASYNC_COPY_OUT
Definition: libpq-int.h:223
@ PGASYNC_READY_MORE
Definition: libpq-int.h:219
@ PGASYNC_READY
Definition: libpq-int.h:217
@ PGASYNC_COPY_BOTH
Definition: libpq-int.h:224
@ PGASYNC_IDLE
Definition: libpq-int.h:215
@ PGASYNC_COPY_IN
Definition: libpq-int.h:222
@ PGASYNC_BUSY
Definition: libpq-int.h:216
@ PGASYNC_PIPELINE_IDLE
Definition: libpq-int.h:225

◆ PGLoadBalanceType

Enumerator
LOAD_BALANCE_DISABLE 
LOAD_BALANCE_RANDOM 

Definition at line 247 of file libpq-int.h.

248{
249 LOAD_BALANCE_DISABLE = 0, /* Use the existing host order (default) */
250 LOAD_BALANCE_RANDOM, /* Randomly shuffle the hosts */
PGLoadBalanceType
Definition: libpq-int.h:248
@ LOAD_BALANCE_DISABLE
Definition: libpq-int.h:249
@ LOAD_BALANCE_RANDOM
Definition: libpq-int.h:250

◆ PGQueryClass

Enumerator
PGQUERY_SIMPLE 
PGQUERY_EXTENDED 
PGQUERY_PREPARE 
PGQUERY_DESCRIBE 
PGQUERY_SYNC 
PGQUERY_CLOSE 

Definition at line 318 of file libpq-int.h.

319{
320 PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */
321 PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */
322 PGQUERY_PREPARE, /* Parse only (PQprepare) */
323 PGQUERY_DESCRIBE, /* Describe Statement or Portal */
324 PGQUERY_SYNC, /* Sync (at end of a pipeline) */
325 PGQUERY_CLOSE /* Close Statement or Portal */
PGQueryClass
Definition: libpq-int.h:319
@ PGQUERY_SIMPLE
Definition: libpq-int.h:320
@ PGQUERY_SYNC
Definition: libpq-int.h:324
@ PGQUERY_EXTENDED
Definition: libpq-int.h:321
@ PGQUERY_DESCRIBE
Definition: libpq-int.h:323
@ PGQUERY_CLOSE
Definition: libpq-int.h:325
@ PGQUERY_PREPARE
Definition: libpq-int.h:322

◆ PGTargetServerType

Enumerator
SERVER_TYPE_ANY 
SERVER_TYPE_READ_WRITE 
SERVER_TYPE_READ_ONLY 
SERVER_TYPE_PRIMARY 
SERVER_TYPE_STANDBY 
SERVER_TYPE_PREFER_STANDBY 
SERVER_TYPE_PREFER_STANDBY_PASS2 

Definition at line 235 of file libpq-int.h.

236{
237 SERVER_TYPE_ANY = 0, /* Any server (default) */
238 SERVER_TYPE_READ_WRITE, /* Read-write server */
239 SERVER_TYPE_READ_ONLY, /* Read-only server */
240 SERVER_TYPE_PRIMARY, /* Primary server */
241 SERVER_TYPE_STANDBY, /* Standby server */
242 SERVER_TYPE_PREFER_STANDBY, /* Prefer standby server */
243 SERVER_TYPE_PREFER_STANDBY_PASS2 /* second pass - behaves same as ANY */
PGTargetServerType
Definition: libpq-int.h:236
@ SERVER_TYPE_STANDBY
Definition: libpq-int.h:241
@ SERVER_TYPE_PRIMARY
Definition: libpq-int.h:240
@ SERVER_TYPE_ANY
Definition: libpq-int.h:237
@ SERVER_TYPE_READ_WRITE
Definition: libpq-int.h:238
@ SERVER_TYPE_PREFER_STANDBY_PASS2
Definition: libpq-int.h:243
@ SERVER_TYPE_PREFER_STANDBY
Definition: libpq-int.h:242
@ SERVER_TYPE_READ_ONLY
Definition: libpq-int.h:239

◆ PGTernaryBool

Enumerator
PG_BOOL_UNKNOWN 
PG_BOOL_YES 
PG_BOOL_NO 
PG_BOOL_UNKNOWN 
PG_BOOL_YES 
PG_BOOL_NO 

Definition at line 254 of file libpq-int.h.

255{
256 PG_BOOL_UNKNOWN = 0, /* Currently unknown */
257 PG_BOOL_YES, /* Yes (true) */
258 PG_BOOL_NO /* No (false) */
PGTernaryBool
Definition: libpq-int.h:255
@ PG_BOOL_YES
Definition: libpq-int.h:257
@ PG_BOOL_NO
Definition: libpq-int.h:258
@ PG_BOOL_UNKNOWN
Definition: libpq-int.h:256

Function Documentation

◆ libpq_append_conn_error()

void void libpq_append_conn_error ( PGconn conn,
const char *  fmt,
  ... 
)

◆ libpq_append_error()

void libpq_append_error ( PQExpBuffer  errorMessage,
const char *  fmt,
  ... 
)

◆ pgtls_close()

void pgtls_close ( PGconn conn)

Definition at line 1502 of file fe-secure-openssl.c.

1503{
1504 if (conn->ssl_in_use)
1505 {
1506 if (conn->ssl)
1507 {
1508 /*
1509 * We can't destroy everything SSL-related here due to the
1510 * possible later calls to OpenSSL routines which may need our
1511 * thread callbacks, so set a flag here and check at the end.
1512 */
1513
1514 SSL_shutdown(conn->ssl);
1515 SSL_free(conn->ssl);
1516 conn->ssl = NULL;
1517 conn->ssl_in_use = false;
1518 conn->ssl_handshake_started = false;
1519 }
1520
1521 if (conn->peer)
1522 {
1523 X509_free(conn->peer);
1524 conn->peer = NULL;
1525 }
1526
1527#ifdef USE_SSL_ENGINE
1528 if (conn->engine)
1529 {
1530 ENGINE_finish(conn->engine);
1531 ENGINE_free(conn->engine);
1532 conn->engine = NULL;
1533 }
1534#endif
1535 }
1536}
bool ssl_handshake_started
Definition: libpq-int.h:621
bool ssl_in_use
Definition: libpq-int.h:620

References conn, pg_conn::ssl_handshake_started, and pg_conn::ssl_in_use.

Referenced by open_client_SSL(), pgtls_open_client(), and pqsecure_close().

◆ pgtls_get_peer_certificate_hash()

char * pgtls_get_peer_certificate_hash ( PGconn conn,
size_t *  len 
)

Definition at line 340 of file fe-secure-openssl.c.

341{
342 X509 *peer_cert;
343 const EVP_MD *algo_type;
344 unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */
345 unsigned int hash_size;
346 int algo_nid;
347 char *cert_hash;
348
349 *len = 0;
350
351 if (!conn->peer)
352 return NULL;
353
354 peer_cert = conn->peer;
355
356 /*
357 * Get the signature algorithm of the certificate to determine the hash
358 * algorithm to use for the result. Prefer X509_get_signature_info(),
359 * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
360 */
361#if HAVE_X509_GET_SIGNATURE_INFO
362 if (!X509_get_signature_info(peer_cert, &algo_nid, NULL, NULL, NULL))
363#else
364 if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert),
365 &algo_nid, NULL))
366#endif
367 {
368 libpq_append_conn_error(conn, "could not determine server certificate signature algorithm");
369 return NULL;
370 }
371
372 /*
373 * The TLS server's certificate bytes need to be hashed with SHA-256 if
374 * its signature algorithm is MD5 or SHA-1 as per RFC 5929
375 * (https://tools.ietf.org/html/rfc5929#section-4.1). If something else
376 * is used, the same hash as the signature algorithm is used.
377 */
378 switch (algo_nid)
379 {
380 case NID_md5:
381 case NID_sha1:
382 algo_type = EVP_sha256();
383 break;
384 default:
385 algo_type = EVP_get_digestbynid(algo_nid);
386 if (algo_type == NULL)
387 {
388 libpq_append_conn_error(conn, "could not find digest for NID %s",
389 OBJ_nid2sn(algo_nid));
390 return NULL;
391 }
392 break;
393 }
394
395 if (!X509_digest(peer_cert, algo_type, hash, &hash_size))
396 {
397 libpq_append_conn_error(conn, "could not generate peer certificate hash");
398 return NULL;
399 }
400
401 /* save result */
402 cert_hash = malloc(hash_size);
403 if (cert_hash == NULL)
404 {
405 libpq_append_conn_error(conn, "out of memory");
406 return NULL;
407 }
408 memcpy(cert_hash, hash, hash_size);
409 *len = hash_size;
410
411 return cert_hash;
412}
#define malloc(a)
Definition: header.h:50
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: oauth-utils.c:95
const void size_t len
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715

References conn, hash(), len, libpq_append_conn_error(), and malloc.

Referenced by build_client_final_message().

◆ pgtls_open_client()

PostgresPollingStatusType pgtls_open_client ( PGconn conn)

Definition at line 96 of file fe-secure-openssl.c.

97{
98 /* First time through? */
99 if (conn->ssl == NULL)
100 {
101 /*
102 * Create a connection-specific SSL object, and load client
103 * certificate, private key, and trusted CA certs.
104 */
105 if (initialize_SSL(conn) != 0)
106 {
107 /* initialize_SSL already put a message in conn->errorMessage */
110 }
111 }
112
113 /* Begin or continue the actual handshake */
114 return open_client_SSL(conn);
115}
static int initialize_SSL(PGconn *conn)
static PostgresPollingStatusType open_client_SSL(PGconn *conn)
void pgtls_close(PGconn *conn)
@ PGRES_POLLING_FAILED
Definition: libpq-fe.h:115

References conn, initialize_SSL(), open_client_SSL(), PGRES_POLLING_FAILED, and pgtls_close().

Referenced by pqsecure_open_client().

◆ pgtls_read()

ssize_t pgtls_read ( PGconn conn,
void *  ptr,
size_t  len 
)

Definition at line 118 of file fe-secure-openssl.c.

119{
120 ssize_t n;
121 int result_errno = 0;
122 char sebuf[PG_STRERROR_R_BUFLEN];
123 int err;
124 unsigned long ecode;
125
126rloop:
127
128 /*
129 * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
130 * queue. In general, the current thread's error queue must be empty
131 * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
132 * not work reliably. Since the possibility exists that other OpenSSL
133 * clients running in the same thread but not under our control will fail
134 * to call ERR_get_error() themselves (after their own I/O operations),
135 * pro-actively clear the per-thread error queue now.
136 */
138 ERR_clear_error();
139 n = SSL_read(conn->ssl, ptr, len);
140 err = SSL_get_error(conn->ssl, n);
141
142 /*
143 * Other clients of OpenSSL may fail to call ERR_get_error(), but we
144 * always do, so as to not cause problems for OpenSSL clients that don't
145 * call ERR_clear_error() defensively. Be sure that this happens by
146 * calling now. SSL_get_error() relies on the OpenSSL per-thread error
147 * queue being intact, so this is the earliest possible point
148 * ERR_get_error() may be called.
149 */
150 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
151 switch (err)
152 {
153 case SSL_ERROR_NONE:
154 if (n < 0)
155 {
156 /* Not supposed to happen, so we don't translate the msg */
158 "SSL_read failed but did not provide error information\n");
159 /* assume the connection is broken */
160 result_errno = ECONNRESET;
161 }
162 break;
163 case SSL_ERROR_WANT_READ:
164 n = 0;
165 break;
166 case SSL_ERROR_WANT_WRITE:
167
168 /*
169 * Returning 0 here would cause caller to wait for read-ready,
170 * which is not correct since what SSL wants is wait for
171 * write-ready. The former could get us stuck in an infinite
172 * wait, so don't risk it; busy-loop instead.
173 */
174 goto rloop;
175 case SSL_ERROR_SYSCALL:
176 if (n < 0 && SOCK_ERRNO != 0)
177 {
178 result_errno = SOCK_ERRNO;
179 if (result_errno == EPIPE ||
180 result_errno == ECONNRESET)
181 libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
182 "\tThis probably means the server terminated abnormally\n"
183 "\tbefore or while processing the request.");
184 else
185 libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
186 SOCK_STRERROR(result_errno,
187 sebuf, sizeof(sebuf)));
188 }
189 else
190 {
191 libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
192 /* assume the connection is broken */
193 result_errno = ECONNRESET;
194 n = -1;
195 }
196 break;
197 case SSL_ERROR_SSL:
198 {
199 char *errm = SSLerrmessage(ecode);
200
201 libpq_append_conn_error(conn, "SSL error: %s", errm);
202 SSLerrfree(errm);
203 /* assume the connection is broken */
204 result_errno = ECONNRESET;
205 n = -1;
206 break;
207 }
208 case SSL_ERROR_ZERO_RETURN:
209
210 /*
211 * Per OpenSSL documentation, this error code is only returned for
212 * a clean connection closure, so we should not report it as a
213 * server crash.
214 */
215 libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly");
216 result_errno = ECONNRESET;
217 n = -1;
218 break;
219 default:
220 libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
221 /* assume the connection is broken */
222 result_errno = ECONNRESET;
223 n = -1;
224 break;
225 }
226
227 /* ensure we return the intended errno to caller */
228 SOCK_ERRNO_SET(result_errno);
229
230 return n;
231}
void err(int eval, const char *fmt,...)
Definition: err.c:43
static void SSLerrfree(char *buf)
static char * SSLerrmessage(unsigned long ecode)
#define SOCK_STRERROR
Definition: libpq-int.h:972
#define SOCK_ERRNO
Definition: oauth-utils.c:164
#define SOCK_ERRNO_SET(e)
Definition: oauth-utils.c:165
#define PG_STRERROR_R_BUFLEN
Definition: port.h:278
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
PQExpBufferData errorMessage
Definition: libpq-int.h:683
#define ECONNRESET
Definition: win32_port.h:374

References appendPQExpBufferStr(), conn, ECONNRESET, err(), pg_conn::errorMessage, len, libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, SSLerrfree(), and SSLerrmessage().

Referenced by pqsecure_read().

◆ pgtls_read_pending()

bool pgtls_read_pending ( PGconn conn)

Definition at line 234 of file fe-secure-openssl.c.

235{
236 return SSL_pending(conn->ssl) > 0;
237}

References conn.

Referenced by pqSocketCheck().

◆ pgtls_verify_peer_name_matches_certificate_guts()

int pgtls_verify_peer_name_matches_certificate_guts ( PGconn conn,
int *  names_examined,
char **  first_name 
)

Definition at line 544 of file fe-secure-openssl.c.

547{
548 STACK_OF(GENERAL_NAME) * peer_san;
549 int i;
550 int rc = 0;
551 char *host = conn->connhost[conn->whichhost].host;
552 int host_type;
553 bool check_cn = true;
554
555 Assert(host && host[0]); /* should be guaranteed by caller */
556
557 /*
558 * We try to match the NSS behavior here, which is a slight departure from
559 * the spec but seems to make more intuitive sense:
560 *
561 * If connhost contains a DNS name, and the certificate's SANs contain any
562 * dNSName entries, then we'll ignore the Subject Common Name entirely;
563 * otherwise, we fall back to checking the CN. (This behavior matches the
564 * RFC.)
565 *
566 * If connhost contains an IP address, and the SANs contain iPAddress
567 * entries, we again ignore the CN. Otherwise, we allow the CN to match,
568 * EVEN IF there is a dNSName in the SANs. (RFC 6125 prohibits this: "A
569 * client MUST NOT seek a match for a reference identifier of CN-ID if the
570 * presented identifiers include a DNS-ID, SRV-ID, URI-ID, or any
571 * application-specific identifier types supported by the client.")
572 *
573 * NOTE: Prior versions of libpq did not consider iPAddress entries at
574 * all, so this new behavior might break a certificate that has different
575 * IP addresses in the Subject CN and the SANs.
576 */
577 if (is_ip_address(host))
578 host_type = GEN_IPADD;
579 else
580 host_type = GEN_DNS;
581
582 /*
583 * First, get the Subject Alternative Names (SANs) from the certificate,
584 * and compare them against the originally given hostname.
585 */
586 peer_san = (STACK_OF(GENERAL_NAME) *)
587 X509_get_ext_d2i(conn->peer, NID_subject_alt_name, NULL, NULL);
588
589 if (peer_san)
590 {
591 int san_len = sk_GENERAL_NAME_num(peer_san);
592
593 for (i = 0; i < san_len; i++)
594 {
595 const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, i);
596 char *alt_name = NULL;
597
598 if (name->type == host_type)
599 {
600 /*
601 * This SAN is of the same type (IP or DNS) as our host name,
602 * so don't allow a fallback check of the CN.
603 */
604 check_cn = false;
605 }
606
607 if (name->type == GEN_DNS)
608 {
609 (*names_examined)++;
611 name->d.dNSName,
612 &alt_name);
613 }
614 else if (name->type == GEN_IPADD)
615 {
616 (*names_examined)++;
618 name->d.iPAddress,
619 &alt_name);
620 }
621
622 if (alt_name)
623 {
624 if (!*first_name)
625 *first_name = alt_name;
626 else
627 free(alt_name);
628 }
629
630 if (rc != 0)
631 {
632 /*
633 * Either we hit an error or a match, and either way we should
634 * not fall back to the CN.
635 */
636 check_cn = false;
637 break;
638 }
639 }
640 sk_GENERAL_NAME_pop_free(peer_san, GENERAL_NAME_free);
641 }
642
643 /*
644 * If there is no subjectAltName extension of the matching type, check the
645 * Common Name.
646 *
647 * (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type
648 * dNSName is present, the CN must be ignored. We break this rule if host
649 * is an IP address; see the comment above.)
650 */
651 if (check_cn)
652 {
653 X509_NAME *subject_name;
654
655 subject_name = X509_get_subject_name(conn->peer);
656 if (subject_name != NULL)
657 {
658 int cn_index;
659
660 cn_index = X509_NAME_get_index_by_NID(subject_name,
661 NID_commonName, -1);
662 if (cn_index >= 0)
663 {
664 char *common_name = NULL;
665
666 (*names_examined)++;
668 X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)),
669 &common_name);
670
671 if (common_name)
672 {
673 if (!*first_name)
674 *first_name = common_name;
675 else
676 free(common_name);
677 }
678 }
679 }
680 }
681
682 return rc;
683}
static int openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry, char **store_name)
static int openssl_verify_peer_name_matches_certificate_ip(PGconn *conn, ASN1_OCTET_STRING *addr_entry, char **store_name)
static bool is_ip_address(const char *host)
Assert(PointerIsAligned(start, uint64))
#define free(a)
Definition: header.h:65
int i
Definition: isn.c:77
char * host
Definition: libpq-int.h:358
int whichhost
Definition: libpq-int.h:481
pg_conn_host * connhost
Definition: libpq-int.h:482
const char * name

References Assert(), conn, pg_conn::connhost, free, pg_conn_host::host, i, is_ip_address(), name, openssl_verify_peer_name_matches_certificate_ip(), openssl_verify_peer_name_matches_certificate_name(), and pg_conn::whichhost.

Referenced by pq_verify_peer_name_matches_certificate().

◆ pgtls_write()

ssize_t pgtls_write ( PGconn conn,
const void *  ptr,
size_t  len 
)

Definition at line 240 of file fe-secure-openssl.c.

241{
242 ssize_t n;
243 int result_errno = 0;
244 char sebuf[PG_STRERROR_R_BUFLEN];
245 int err;
246 unsigned long ecode;
247
249 ERR_clear_error();
250 n = SSL_write(conn->ssl, ptr, len);
251 err = SSL_get_error(conn->ssl, n);
252 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
253 switch (err)
254 {
255 case SSL_ERROR_NONE:
256 if (n < 0)
257 {
258 /* Not supposed to happen, so we don't translate the msg */
260 "SSL_write failed but did not provide error information\n");
261 /* assume the connection is broken */
262 result_errno = ECONNRESET;
263 }
264 break;
265 case SSL_ERROR_WANT_READ:
266
267 /*
268 * Returning 0 here causes caller to wait for write-ready, which
269 * is not really the right thing, but it's the best we can do.
270 */
271 n = 0;
272 break;
273 case SSL_ERROR_WANT_WRITE:
274 n = 0;
275 break;
276 case SSL_ERROR_SYSCALL:
277
278 /*
279 * If errno is still zero then assume it's a read EOF situation,
280 * and report EOF. (This seems possible because SSL_write can
281 * also do reads.)
282 */
283 if (n < 0 && SOCK_ERRNO != 0)
284 {
285 result_errno = SOCK_ERRNO;
286 if (result_errno == EPIPE || result_errno == ECONNRESET)
287 libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
288 "\tThis probably means the server terminated abnormally\n"
289 "\tbefore or while processing the request.");
290 else
291 libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
292 SOCK_STRERROR(result_errno,
293 sebuf, sizeof(sebuf)));
294 }
295 else
296 {
297 libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
298 /* assume the connection is broken */
299 result_errno = ECONNRESET;
300 n = -1;
301 }
302 break;
303 case SSL_ERROR_SSL:
304 {
305 char *errm = SSLerrmessage(ecode);
306
307 libpq_append_conn_error(conn, "SSL error: %s", errm);
308 SSLerrfree(errm);
309 /* assume the connection is broken */
310 result_errno = ECONNRESET;
311 n = -1;
312 break;
313 }
314 case SSL_ERROR_ZERO_RETURN:
315
316 /*
317 * Per OpenSSL documentation, this error code is only returned for
318 * a clean connection closure, so we should not report it as a
319 * server crash.
320 */
321 libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly");
322 result_errno = ECONNRESET;
323 n = -1;
324 break;
325 default:
326 libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
327 /* assume the connection is broken */
328 result_errno = ECONNRESET;
329 n = -1;
330 break;
331 }
332
333 /* ensure we return the intended errno to caller */
334 SOCK_ERRNO_SET(result_errno);
335
336 return n;
337}

References appendPQExpBufferStr(), conn, ECONNRESET, err(), pg_conn::errorMessage, len, libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, SSLerrfree(), and SSLerrmessage().

Referenced by pqsecure_write().

◆ pq_block_sigpipe()

int pq_block_sigpipe ( sigset_t *  osigset,
bool *  sigpipe_pending 
)

Definition at line 172 of file oauth-utils.c.

173{
174 sigset_t sigpipe_sigset;
175 sigset_t sigset;
176
177 sigemptyset(&sigpipe_sigset);
178 sigaddset(&sigpipe_sigset, SIGPIPE);
179
180 /* Block SIGPIPE and save previous mask for later reset */
181 SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
182 if (SOCK_ERRNO)
183 return -1;
184
185 /* We can have a pending SIGPIPE only if it was blocked before */
186 if (sigismember(osigset, SIGPIPE))
187 {
188 /* Is there a pending SIGPIPE? */
189 if (sigpending(&sigset) != 0)
190 return -1;
191
192 if (sigismember(&sigset, SIGPIPE))
193 *sigpipe_pending = true;
194 else
195 *sigpipe_pending = false;
196 }
197 else
198 *sigpipe_pending = false;
199
200 return 0;
201}
#define SIGPIPE
Definition: win32_port.h:163

References SIGPIPE, SOCK_ERRNO, and SOCK_ERRNO_SET.

Referenced by pg_fe_run_oauth_flow(), and PQprint().

◆ pq_reset_sigpipe()

void pq_reset_sigpipe ( sigset_t *  osigset,
bool  sigpipe_pending,
bool  got_epipe 
)

Definition at line 208 of file oauth-utils.c.

209{
210 int save_errno = SOCK_ERRNO;
211 int signo;
212 sigset_t sigset;
213
214 /* Clear SIGPIPE only if none was pending */
215 if (got_epipe && !sigpipe_pending)
216 {
217 if (sigpending(&sigset) == 0 &&
218 sigismember(&sigset, SIGPIPE))
219 {
220 sigset_t sigpipe_sigset;
221
222 sigemptyset(&sigpipe_sigset);
223 sigaddset(&sigpipe_sigset, SIGPIPE);
224
225 sigwait(&sigpipe_sigset, &signo);
226 }
227 }
228
229 /* Restore saved block mask */
230 pthread_sigmask(SIG_SETMASK, osigset, NULL);
231
232 SOCK_ERRNO_SET(save_errno);
233}

References SIGPIPE, SOCK_ERRNO, and SOCK_ERRNO_SET.

Referenced by pg_fe_run_oauth_flow(), and PQprint().

◆ pqBuildErrorMessage3()

void pqBuildErrorMessage3 ( PQExpBuffer  msg,
const PGresult res,
PGVerbosity  verbosity,
PGContextVisibility  show_context 
)

Definition at line 1030 of file fe-protocol3.c.

1032{
1033 const char *val;
1034 const char *querytext = NULL;
1035 int querypos = 0;
1036
1037 /* If we couldn't allocate a PGresult, just say "out of memory" */
1038 if (res == NULL)
1039 {
1040 appendPQExpBufferStr(msg, libpq_gettext("out of memory\n"));
1041 return;
1042 }
1043
1044 /*
1045 * If we don't have any broken-down fields, just return the base message.
1046 * This mainly applies if we're given a libpq-generated error result.
1047 */
1048 if (res->errFields == NULL)
1049 {
1050 if (res->errMsg && res->errMsg[0])
1051 appendPQExpBufferStr(msg, res->errMsg);
1052 else
1053 appendPQExpBufferStr(msg, libpq_gettext("no error message available\n"));
1054 return;
1055 }
1056
1057 /* Else build error message from relevant fields */
1059 if (val)
1060 appendPQExpBuffer(msg, "%s: ", val);
1061
1062 if (verbosity == PQERRORS_SQLSTATE)
1063 {
1064 /*
1065 * If we have a SQLSTATE, print that and nothing else. If not (which
1066 * shouldn't happen for server-generated errors, but might possibly
1067 * happen for libpq-generated ones), fall back to TERSE format, as
1068 * that seems better than printing nothing at all.
1069 */
1071 if (val)
1072 {
1073 appendPQExpBuffer(msg, "%s\n", val);
1074 return;
1075 }
1076 verbosity = PQERRORS_TERSE;
1077 }
1078
1079 if (verbosity == PQERRORS_VERBOSE)
1080 {
1082 if (val)
1083 appendPQExpBuffer(msg, "%s: ", val);
1084 }
1086 if (val)
1089 if (val)
1090 {
1091 if (verbosity != PQERRORS_TERSE && res->errQuery != NULL)
1092 {
1093 /* emit position as a syntax cursor display */
1094 querytext = res->errQuery;
1095 querypos = atoi(val);
1096 }
1097 else
1098 {
1099 /* emit position as text addition to primary message */
1100 /* translator: %s represents a digit string */
1101 appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1102 val);
1103 }
1104 }
1105 else
1106 {
1108 if (val)
1109 {
1111 if (verbosity != PQERRORS_TERSE && querytext != NULL)
1112 {
1113 /* emit position as a syntax cursor display */
1114 querypos = atoi(val);
1115 }
1116 else
1117 {
1118 /* emit position as text addition to primary message */
1119 /* translator: %s represents a digit string */
1120 appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1121 val);
1122 }
1123 }
1124 }
1125 appendPQExpBufferChar(msg, '\n');
1126 if (verbosity != PQERRORS_TERSE)
1127 {
1128 if (querytext && querypos > 0)
1129 reportErrorPosition(msg, querytext, querypos,
1130 res->client_encoding);
1132 if (val)
1133 appendPQExpBuffer(msg, libpq_gettext("DETAIL: %s\n"), val);
1135 if (val)
1136 appendPQExpBuffer(msg, libpq_gettext("HINT: %s\n"), val);
1138 if (val)
1139 appendPQExpBuffer(msg, libpq_gettext("QUERY: %s\n"), val);
1140 if (show_context == PQSHOW_CONTEXT_ALWAYS ||
1141 (show_context == PQSHOW_CONTEXT_ERRORS &&
1143 {
1145 if (val)
1146 appendPQExpBuffer(msg, libpq_gettext("CONTEXT: %s\n"),
1147 val);
1148 }
1149 }
1150 if (verbosity == PQERRORS_VERBOSE)
1151 {
1153 if (val)
1155 libpq_gettext("SCHEMA NAME: %s\n"), val);
1157 if (val)
1159 libpq_gettext("TABLE NAME: %s\n"), val);
1161 if (val)
1163 libpq_gettext("COLUMN NAME: %s\n"), val);
1165 if (val)
1167 libpq_gettext("DATATYPE NAME: %s\n"), val);
1169 if (val)
1171 libpq_gettext("CONSTRAINT NAME: %s\n"), val);
1172 }
1173 if (verbosity == PQERRORS_VERBOSE)
1174 {
1175 const char *valf;
1176 const char *vall;
1177
1181 if (val || valf || vall)
1182 {
1183 appendPQExpBufferStr(msg, libpq_gettext("LOCATION: "));
1184 if (val)
1185 appendPQExpBuffer(msg, libpq_gettext("%s, "), val);
1186 if (valf && vall) /* unlikely we'd have just one */
1187 appendPQExpBuffer(msg, libpq_gettext("%s:%s"),
1188 valf, vall);
1189 appendPQExpBufferChar(msg, '\n');
1190 }
1191 }
1192}
static void reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding)
long val
Definition: informix.c:689
#define PQresultErrorField
Definition: libpq-be-fe.h:249
@ PGRES_FATAL_ERROR
Definition: libpq-fe.h:136
@ PQSHOW_CONTEXT_ALWAYS
Definition: libpq-fe.h:166
@ PQSHOW_CONTEXT_ERRORS
Definition: libpq-fe.h:165
@ PQERRORS_VERBOSE
Definition: libpq-fe.h:158
@ PQERRORS_TERSE
Definition: libpq-fe.h:156
@ PQERRORS_SQLSTATE
Definition: libpq-fe.h:159
#define libpq_gettext(x)
Definition: oauth-utils.h:86
#define PG_DIAG_INTERNAL_QUERY
Definition: postgres_ext.h:63
#define PG_DIAG_SCHEMA_NAME
Definition: postgres_ext.h:65
#define PG_DIAG_CONSTRAINT_NAME
Definition: postgres_ext.h:69
#define PG_DIAG_DATATYPE_NAME
Definition: postgres_ext.h:68
#define PG_DIAG_SOURCE_LINE
Definition: postgres_ext.h:71
#define PG_DIAG_STATEMENT_POSITION
Definition: postgres_ext.h:61
#define PG_DIAG_SOURCE_FILE
Definition: postgres_ext.h:70
#define PG_DIAG_MESSAGE_HINT
Definition: postgres_ext.h:60
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
#define PG_DIAG_TABLE_NAME
Definition: postgres_ext.h:66
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
#define PG_DIAG_COLUMN_NAME
Definition: postgres_ext.h:67
#define PG_DIAG_MESSAGE_DETAIL
Definition: postgres_ext.h:59
#define PG_DIAG_CONTEXT
Definition: postgres_ext.h:64
#define PG_DIAG_SEVERITY
Definition: postgres_ext.h:55
#define PG_DIAG_SOURCE_FUNCTION
Definition: postgres_ext.h:72
#define PG_DIAG_INTERNAL_POSITION
Definition: postgres_ext.h:62
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
char * errMsg
Definition: libpq-int.h:193
PGMessageField * errFields
Definition: libpq-int.h:194
ExecStatusType resultStatus
Definition: libpq-int.h:174
char * errQuery
Definition: libpq-int.h:195
int client_encoding
Definition: libpq-int.h:186

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), pg_result::client_encoding, pg_result::errFields, pg_result::errMsg, pg_result::errQuery, libpq_gettext, PG_DIAG_COLUMN_NAME, PG_DIAG_CONSTRAINT_NAME, PG_DIAG_CONTEXT, PG_DIAG_DATATYPE_NAME, PG_DIAG_INTERNAL_POSITION, PG_DIAG_INTERNAL_QUERY, PG_DIAG_MESSAGE_DETAIL, PG_DIAG_MESSAGE_HINT, PG_DIAG_MESSAGE_PRIMARY, PG_DIAG_SCHEMA_NAME, PG_DIAG_SEVERITY, PG_DIAG_SOURCE_FILE, PG_DIAG_SOURCE_FUNCTION, PG_DIAG_SOURCE_LINE, PG_DIAG_SQLSTATE, PG_DIAG_STATEMENT_POSITION, PG_DIAG_TABLE_NAME, PGRES_FATAL_ERROR, PQERRORS_SQLSTATE, PQERRORS_TERSE, PQERRORS_VERBOSE, PQresultErrorField, PQSHOW_CONTEXT_ALWAYS, PQSHOW_CONTEXT_ERRORS, reportErrorPosition(), pg_result::resultStatus, and val.

Referenced by pqGetErrorNotice3(), and PQresultVerboseErrorMessage().

◆ pqBuildStartupPacket3()

char * pqBuildStartupPacket3 ( PGconn conn,
int *  packetlen,
const PQEnvironmentOption options 
)

Definition at line 2387 of file fe-protocol3.c.

2389{
2390 char *startpacket;
2391 size_t len;
2392
2394 if (len == 0 || len > INT_MAX)
2395 return NULL;
2396
2397 *packetlen = len;
2398 startpacket = (char *) malloc(*packetlen);
2399 if (!startpacket)
2400 return NULL;
2401
2402 len = build_startup_packet(conn, startpacket, options);
2403 Assert(*packetlen == len);
2404
2405 return startpacket;
2406}
static size_t build_startup_packet(const PGconn *conn, char *packet, const PQEnvironmentOption *options)

References Assert(), build_startup_packet(), conn, len, and malloc.

Referenced by PQconnectPoll().

◆ pqCheckInBufferSpace()

int pqCheckInBufferSpace ( size_t  bytes_needed,
PGconn conn 
)

Definition at line 351 of file fe-misc.c.

352{
353 int newsize = conn->inBufSize;
354 char *newbuf;
355
356 /* Quick exit if we have enough space */
357 if (bytes_needed <= (size_t) newsize)
358 return 0;
359
360 /*
361 * Before concluding that we need to enlarge the buffer, left-justify
362 * whatever is in it and recheck. The caller's value of bytes_needed
363 * includes any data to the left of inStart, but we can delete that in
364 * preference to enlarging the buffer. It's slightly ugly to have this
365 * function do this, but it's better than making callers worry about it.
366 */
367 bytes_needed -= conn->inStart;
368
369 if (conn->inStart < conn->inEnd)
370 {
371 if (conn->inStart > 0)
372 {
373 memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
374 conn->inEnd - conn->inStart);
375 conn->inEnd -= conn->inStart;
377 conn->inStart = 0;
378 }
379 }
380 else
381 {
382 /* buffer is logically empty, reset it */
383 conn->inStart = conn->inCursor = conn->inEnd = 0;
384 }
385
386 /* Recheck whether we have enough space */
387 if (bytes_needed <= (size_t) newsize)
388 return 0;
389
390 /*
391 * If we need to enlarge the buffer, we first try to double it in size; if
392 * that doesn't work, enlarge in multiples of 8K. This avoids thrashing
393 * the malloc pool by repeated small enlargements.
394 *
395 * Note: tests for newsize > 0 are to catch integer overflow.
396 */
397 do
398 {
399 newsize *= 2;
400 } while (newsize > 0 && bytes_needed > (size_t) newsize);
401
402 if (newsize > 0 && bytes_needed <= (size_t) newsize)
403 {
404 newbuf = realloc(conn->inBuffer, newsize);
405 if (newbuf)
406 {
407 /* realloc succeeded */
408 conn->inBuffer = newbuf;
409 conn->inBufSize = newsize;
410 return 0;
411 }
412 }
413
414 newsize = conn->inBufSize;
415 do
416 {
417 newsize += 8192;
418 } while (newsize > 0 && bytes_needed > (size_t) newsize);
419
420 if (newsize > 0 && bytes_needed <= (size_t) newsize)
421 {
422 newbuf = realloc(conn->inBuffer, newsize);
423 if (newbuf)
424 {
425 /* realloc succeeded */
426 conn->inBuffer = newbuf;
427 conn->inBufSize = newsize;
428 return 0;
429 }
430 }
431
432 /* realloc failed. Probably out of memory */
434 "cannot allocate memory for input buffer\n");
435 return EOF;
436}
#define realloc(a, b)
Definition: header.h:60
char * inBuffer
Definition: libpq-int.h:576
int inCursor
Definition: libpq-int.h:579
int inEnd
Definition: libpq-int.h:580
int inBufSize
Definition: libpq-int.h:577
int inStart
Definition: libpq-int.h:578

References appendPQExpBufferStr(), conn, pg_conn::errorMessage, pg_conn::inBuffer, pg_conn::inBufSize, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, and realloc.

Referenced by getCopyDataMessage(), PQconnectPoll(), pqFunctionCall3(), pqParseInput3(), and pqReadData().

◆ pqCheckOutBufferSpace()

int pqCheckOutBufferSpace ( size_t  bytes_needed,
PGconn conn 
)

Definition at line 287 of file fe-misc.c.

288{
289 int newsize = conn->outBufSize;
290 char *newbuf;
291
292 /* Quick exit if we have enough space */
293 if (bytes_needed <= (size_t) newsize)
294 return 0;
295
296 /*
297 * If we need to enlarge the buffer, we first try to double it in size; if
298 * that doesn't work, enlarge in multiples of 8K. This avoids thrashing
299 * the malloc pool by repeated small enlargements.
300 *
301 * Note: tests for newsize > 0 are to catch integer overflow.
302 */
303 do
304 {
305 newsize *= 2;
306 } while (newsize > 0 && bytes_needed > (size_t) newsize);
307
308 if (newsize > 0 && bytes_needed <= (size_t) newsize)
309 {
310 newbuf = realloc(conn->outBuffer, newsize);
311 if (newbuf)
312 {
313 /* realloc succeeded */
314 conn->outBuffer = newbuf;
315 conn->outBufSize = newsize;
316 return 0;
317 }
318 }
319
320 newsize = conn->outBufSize;
321 do
322 {
323 newsize += 8192;
324 } while (newsize > 0 && bytes_needed > (size_t) newsize);
325
326 if (newsize > 0 && bytes_needed <= (size_t) newsize)
327 {
328 newbuf = realloc(conn->outBuffer, newsize);
329 if (newbuf)
330 {
331 /* realloc succeeded */
332 conn->outBuffer = newbuf;
333 conn->outBufSize = newsize;
334 return 0;
335 }
336 }
337
338 /* realloc failed. Probably out of memory */
340 "cannot allocate memory for output buffer\n");
341 return EOF;
342}
int outBufSize
Definition: libpq-int.h:584
char * outBuffer
Definition: libpq-int.h:583

References appendPQExpBufferStr(), conn, pg_conn::errorMessage, pg_conn::outBuffer, pg_conn::outBufSize, and realloc.

Referenced by PQputCopyData(), pqPutMsgBytes(), and pqPutMsgStart().

◆ pqClearAsyncResult()

void pqClearAsyncResult ( PGconn conn)

Definition at line 785 of file fe-exec.c.

786{
788 conn->result = NULL;
789 conn->error_result = false;
791 conn->saved_result = NULL;
792}
void PQclear(PGresult *res)
Definition: fe-exec.c:727
PGresult * result
Definition: libpq-int.h:606
PGresult * saved_result
Definition: libpq-int.h:608
bool error_result
Definition: libpq-int.h:607

References conn, pg_conn::error_result, PQclear(), pg_conn::result, and pg_conn::saved_result.

Referenced by getAnotherTuple(), getParamDescriptions(), getRowDescriptions(), pqClosePGconn(), PQconnectPoll(), pqGetErrorNotice3(), pqPipelineProcessQueue(), pqSaveErrorResult(), and PQsendQueryStart().

◆ pqClosePGconn()

void pqClosePGconn ( PGconn conn)

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

5270{
5271 /*
5272 * If possible, send Terminate message to close the connection politely.
5273 */
5275
5276 /*
5277 * Must reset the blocking status so a possible reconnect will work.
5278 *
5279 * Don't call PQsetnonblocking() because it will fail if it's unable to
5280 * flush the connection.
5281 */
5282 conn->nonblocking = false;
5283
5284 /*
5285 * Close the connection, reset all transient state, flush I/O buffers.
5286 * Note that this includes clearing conn's error state; we're no longer
5287 * interested in any failures associated with the old connection, and we
5288 * want a clean slate for any new connection attempt.
5289 */
5290 pqDropConnection(conn, true);
5291 conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just absent */
5296 pqClearAsyncResult(conn); /* deallocate result */
5298
5299 /*
5300 * Release addrinfo, but since cancel requests never change their addrinfo
5301 * we don't do that. Otherwise we would have to rebuild it during a
5302 * PQcancelReset.
5303 */
5304 if (!conn->cancelRequest)
5306
5307 /* Reset all state obtained from server, too */
5309}
void pqClearOAuthToken(PGconn *conn)
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:532
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:5235
static void release_conn_addrinfo(PGconn *conn)
Definition: fe-connect.c:5221
static void pqDropServerData(PGconn *conn)
Definition: fe-connect.c:658
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:785
@ CONNECTION_BAD
Definition: libpq-fe.h:85
@ PQTRANS_IDLE
Definition: libpq-fe.h:147
@ PQ_PIPELINE_OFF
Definition: libpq-fe.h:187
#define pqClearConnErrorState(conn)
Definition: libpq-int.h:923
PGTransactionStatusType xactStatus
Definition: libpq-int.h:464
bool cancelRequest
Definition: libpq-int.h:434
bool nonblocking
Definition: libpq-int.h:467
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:463
PGpipelineStatus pipelineStatus
Definition: libpq-int.h:469
ConnStatusType status
Definition: libpq-int.h:462

References pg_conn::asyncStatus, pg_conn::cancelRequest, conn, CONNECTION_BAD, pg_conn::nonblocking, PGASYNC_IDLE, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, pqClearAsyncResult(), pqClearConnErrorState, pqClearOAuthToken(), pqDropConnection(), pqDropServerData(), PQTRANS_IDLE, release_conn_addrinfo(), sendTerminateConn(), pg_conn::status, and pg_conn::xactStatus.

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

◆ pqCommandQueueAdvance()

void pqCommandQueueAdvance ( PGconn conn,
bool  isReadyForQuery,
bool  gotSync 
)

Definition at line 3159 of file fe-exec.c.

3160{
3161 PGcmdQueueEntry *prevquery;
3162
3163 if (conn->cmd_queue_head == NULL)
3164 return;
3165
3166 /*
3167 * If processing a query of simple query protocol, we only advance the
3168 * queue when we receive the ReadyForQuery message for it.
3169 */
3170 if (conn->cmd_queue_head->queryclass == PGQUERY_SIMPLE && !isReadyForQuery)
3171 return;
3172
3173 /*
3174 * If we're waiting for a SYNC, don't advance the queue until we get one.
3175 */
3176 if (conn->cmd_queue_head->queryclass == PGQUERY_SYNC && !gotSync)
3177 return;
3178
3179 /* delink element from queue */
3180 prevquery = conn->cmd_queue_head;
3182
3183 /* If the queue is now empty, reset the tail too */
3184 if (conn->cmd_queue_head == NULL)
3185 conn->cmd_queue_tail = NULL;
3186
3187 /* and make the queue element recyclable */
3188 prevquery->next = NULL;
3189 pqRecycleCmdQueueEntry(conn, prevquery);
3190}
static void pqRecycleCmdQueueEntry(PGconn *conn, PGcmdQueueEntry *entry)
Definition: fe-exec.c:1403
PGQueryClass queryclass
Definition: libpq-int.h:345
struct PGcmdQueueEntry * next
Definition: libpq-int.h:347
PGcmdQueueEntry * cmd_queue_tail
Definition: libpq-int.h:490
PGcmdQueueEntry * cmd_queue_head
Definition: libpq-int.h:489

References pg_conn::cmd_queue_head, pg_conn::cmd_queue_tail, conn, PGcmdQueueEntry::next, PGQUERY_SIMPLE, PGQUERY_SYNC, pqRecycleCmdQueueEntry(), and PGcmdQueueEntry::queryclass.

Referenced by PQgetResult(), and pqParseInput3().

◆ pqConnectDBComplete()

int pqConnectDBComplete ( PGconn conn)

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

2797{
2800 int timeout = 0;
2801 int last_whichhost = -2; /* certainly different from whichhost */
2802 int last_whichaddr = -2; /* certainly different from whichaddr */
2803
2804 if (conn == NULL || conn->status == CONNECTION_BAD)
2805 return 0;
2806
2807 /*
2808 * Set up a time limit, if connect_timeout is greater than zero.
2809 */
2810 if (conn->connect_timeout != NULL)
2811 {
2812 if (!pqParseIntParam(conn->connect_timeout, &timeout, conn,
2813 "connect_timeout"))
2814 {
2815 /* mark the connection as bad to report the parsing failure */
2817 return 0;
2818 }
2819 }
2820
2821 for (;;)
2822 {
2823 int ret = 0;
2824
2825 /*
2826 * (Re)start the connect_timeout timer if it's active and we are
2827 * considering a different host than we were last time through. If
2828 * we've already succeeded, though, needn't recalculate.
2829 */
2830 if (flag != PGRES_POLLING_OK &&
2831 timeout > 0 &&
2832 (conn->whichhost != last_whichhost ||
2833 conn->whichaddr != last_whichaddr))
2834 {
2835 end_time = PQgetCurrentTimeUSec() + (pg_usec_time_t) timeout * 1000000;
2836 last_whichhost = conn->whichhost;
2837 last_whichaddr = conn->whichaddr;
2838 }
2839
2840 /*
2841 * Wait, if necessary. Note that the initial state (just after
2842 * PQconnectStart) is to wait for the socket to select for writing.
2843 */
2844 switch (flag)
2845 {
2846 case PGRES_POLLING_OK:
2847 return 1; /* success! */
2848
2850 ret = pqWaitTimed(1, 0, conn, end_time);
2851 if (ret == -1)
2852 {
2853 /* hard failure, eg select() problem, aborts everything */
2855 return 0;
2856 }
2857 break;
2858
2860 ret = pqWaitTimed(0, 1, conn, end_time);
2861 if (ret == -1)
2862 {
2863 /* hard failure, eg select() problem, aborts everything */
2865 return 0;
2866 }
2867 break;
2868
2869 default:
2870 /* Just in case we failed to set it in PQconnectPoll */
2872 return 0;
2873 }
2874
2875 if (ret == 1) /* connect_timeout elapsed */
2876 {
2877 /*
2878 * Give up on current server/address, try the next one.
2879 */
2880 conn->try_next_addr = true;
2882 }
2883
2884 /*
2885 * Now try to advance the state machine.
2886 */
2887 if (conn->cancelRequest)
2889 else
2891 }
2892}
PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn)
Definition: fe-cancel.c:226
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:2922
bool pqParseIntParam(const char *value, int *result, PGconn *conn, const char *context)
Definition: fe-connect.c:8273
pg_usec_time_t PQgetCurrentTimeUSec(void)
Definition: fe-misc.c:1235
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, pg_usec_time_t end_time)
Definition: fe-misc.c:1035
@ CONNECTION_NEEDED
Definition: libpq-fe.h:100
int64_t pg_usec_time_t
Definition: libpq-fe.h:238
PostgresPollingStatusType
Definition: libpq-fe.h:114
@ PGRES_POLLING_OK
Definition: libpq-fe.h:118
@ PGRES_POLLING_READING
Definition: libpq-fe.h:116
@ PGRES_POLLING_WRITING
Definition: libpq-fe.h:117
static int64 end_time
Definition: pgbench.c:176
int whichaddr
Definition: libpq-int.h:540
char * connect_timeout
Definition: libpq-int.h:384
bool try_next_addr
Definition: libpq-int.h:537
char * flag(int b)
Definition: test-ctype.c:33

References pg_conn::cancelRequest, conn, pg_conn::connect_timeout, CONNECTION_BAD, CONNECTION_NEEDED, end_time, flag(), PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PQcancelPoll(), PQconnectPoll(), PQgetCurrentTimeUSec(), pqParseIntParam(), pqWaitTimed(), pg_conn::status, pg_conn::try_next_addr, pg_conn::whichaddr, and pg_conn::whichhost.

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

◆ pqConnectDBStart()

int pqConnectDBStart ( PGconn conn)

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

2719{
2720 if (!conn)
2721 return 0;
2722
2723 if (!conn->options_valid)
2724 goto connect_errReturn;
2725
2726 /*
2727 * Check for bad linking to backend-internal versions of src/common
2728 * functions (see comments in link-canary.c for the reason we need this).
2729 * Nobody but developers should see this message, so we don't bother
2730 * translating it.
2731 */
2733 {
2735 "libpq is incorrectly linked to backend functions\n");
2736 goto connect_errReturn;
2737 }
2738
2739 /* Ensure our buffers are empty */
2740 conn->inStart = conn->inCursor = conn->inEnd = 0;
2741 conn->outCount = 0;
2742
2743 /*
2744 * Set up to try to connect to the first host. (Setting whichhost = -1 is
2745 * a bit of a cheat, but PQconnectPoll will advance it to 0 before
2746 * anything else looks at it.)
2747 *
2748 * Cancel requests are special though, they should only try one host and
2749 * address, and these fields have already been set up in PQcancelCreate,
2750 * so leave these fields alone for cancel requests.
2751 */
2752 if (!conn->cancelRequest)
2753 {
2754 conn->whichhost = -1;
2755 conn->try_next_host = true;
2756 conn->try_next_addr = false;
2757 }
2758
2760
2761 /* Also reset the target_server_type state if needed */
2764
2765 /*
2766 * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
2767 * so that it can easily be re-executed if needed again during the
2768 * asynchronous startup process. However, we must run it once here,
2769 * because callers expect a success return from this routine to mean that
2770 * we are in PGRES_POLLING_WRITING connection state.
2771 */
2773 return 1;
2774
2775connect_errReturn:
2776
2777 /*
2778 * If we managed to open a socket, close it immediately rather than
2779 * waiting till PQfinish. (The application cannot have gotten the socket
2780 * from PQsocket yet, so this doesn't risk breaking anything.)
2781 */
2782 pqDropConnection(conn, true);
2784 return 0;
2785}
bool try_next_host
Definition: libpq-int.h:538
bool options_valid
Definition: libpq-int.h:466
PGTargetServerType target_server_type
Definition: libpq-int.h:534
int outCount
Definition: libpq-int.h:585

References appendPQExpBufferStr(), pg_conn::cancelRequest, conn, CONNECTION_BAD, CONNECTION_NEEDED, pg_conn::errorMessage, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, pg_conn::options_valid, pg_conn::outCount, pg_link_canary_is_frontend(), PGRES_POLLING_WRITING, PQconnectPoll(), pqDropConnection(), SERVER_TYPE_PREFER_STANDBY, SERVER_TYPE_PREFER_STANDBY_PASS2, pg_conn::status, pg_conn::target_server_type, pg_conn::try_next_addr, pg_conn::try_next_host, and pg_conn::whichhost.

Referenced by PQcancelStart(), PQconnectStart(), PQconnectStartParams(), PQreset(), PQresetStart(), and PQsetdbLogin().

◆ pqConnectOptions2()

bool pqConnectOptions2 ( PGconn conn)

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

1253{
1254 int i;
1255
1256 /*
1257 * Allocate memory for details about each host to which we might possibly
1258 * try to connect. For that, count the number of elements in the hostaddr
1259 * or host options. If neither is given, assume one host.
1260 */
1261 conn->whichhost = 0;
1262 if (conn->pghostaddr && conn->pghostaddr[0] != '\0')
1264 else if (conn->pghost && conn->pghost[0] != '\0')
1266 else
1267 conn->nconnhost = 1;
1269 calloc(conn->nconnhost, sizeof(pg_conn_host));
1270 if (conn->connhost == NULL)
1271 goto oom_error;
1272
1273 /*
1274 * We now have one pg_conn_host structure per possible host. Fill in the
1275 * host and hostaddr fields for each, by splitting the parameter strings.
1276 */
1277 if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
1278 {
1279 char *s = conn->pghostaddr;
1280 bool more = true;
1281
1282 for (i = 0; i < conn->nconnhost && more; i++)
1283 {
1285 if (conn->connhost[i].hostaddr == NULL)
1286 goto oom_error;
1287 }
1288
1289 /*
1290 * If hostaddr was given, the array was allocated according to the
1291 * number of elements in the hostaddr list, so it really should be the
1292 * right size.
1293 */
1294 Assert(!more);
1295 Assert(i == conn->nconnhost);
1296 }
1297
1298 if (conn->pghost != NULL && conn->pghost[0] != '\0')
1299 {
1300 char *s = conn->pghost;
1301 bool more = true;
1302
1303 for (i = 0; i < conn->nconnhost && more; i++)
1304 {
1306 if (conn->connhost[i].host == NULL)
1307 goto oom_error;
1308 }
1309
1310 /* Check for wrong number of host items. */
1311 if (more || i != conn->nconnhost)
1312 {
1314 libpq_append_conn_error(conn, "could not match %d host names to %d hostaddr values",
1316 return false;
1317 }
1318 }
1319
1320 /*
1321 * Now, for each host slot, identify the type of address spec, and fill in
1322 * the default address if nothing was given.
1323 */
1324 for (i = 0; i < conn->nconnhost; i++)
1325 {
1326 pg_conn_host *ch = &conn->connhost[i];
1327
1328 if (ch->hostaddr != NULL && ch->hostaddr[0] != '\0')
1329 ch->type = CHT_HOST_ADDRESS;
1330 else if (ch->host != NULL && ch->host[0] != '\0')
1331 {
1332 ch->type = CHT_HOST_NAME;
1333 if (is_unixsock_path(ch->host))
1334 ch->type = CHT_UNIX_SOCKET;
1335 }
1336 else
1337 {
1338 free(ch->host);
1339
1340 /*
1341 * This bit selects the default host location. If you change
1342 * this, see also pg_regress.
1343 */
1344 if (DEFAULT_PGSOCKET_DIR[0])
1345 {
1346 ch->host = strdup(DEFAULT_PGSOCKET_DIR);
1347 ch->type = CHT_UNIX_SOCKET;
1348 }
1349 else
1350 {
1351 ch->host = strdup(DefaultHost);
1352 ch->type = CHT_HOST_NAME;
1353 }
1354 if (ch->host == NULL)
1355 goto oom_error;
1356 }
1357 }
1358
1359 /*
1360 * Next, work out the port number corresponding to each host name.
1361 *
1362 * Note: unlike the above for host names, this could leave the port fields
1363 * as null or empty strings. We will substitute DEF_PGPORT whenever we
1364 * read such a port field.
1365 */
1366 if (conn->pgport != NULL && conn->pgport[0] != '\0')
1367 {
1368 char *s = conn->pgport;
1369 bool more = true;
1370
1371 for (i = 0; i < conn->nconnhost && more; i++)
1372 {
1374 if (conn->connhost[i].port == NULL)
1375 goto oom_error;
1376 }
1377
1378 /*
1379 * If exactly one port was given, use it for every host. Otherwise,
1380 * there must be exactly as many ports as there were hosts.
1381 */
1382 if (i == 1 && !more)
1383 {
1384 for (i = 1; i < conn->nconnhost; i++)
1385 {
1386 conn->connhost[i].port = strdup(conn->connhost[0].port);
1387 if (conn->connhost[i].port == NULL)
1388 goto oom_error;
1389 }
1390 }
1391 else if (more || i != conn->nconnhost)
1392 {
1394 libpq_append_conn_error(conn, "could not match %d port numbers to %d hosts",
1396 return false;
1397 }
1398 }
1399
1400 /*
1401 * If user name was not given, fetch it. (Most likely, the fetch will
1402 * fail, since the only way we get here is if pg_fe_getauthname() failed
1403 * during conninfo_add_defaults(). But now we want an error message.)
1404 */
1405 if (conn->pguser == NULL || conn->pguser[0] == '\0')
1406 {
1407 free(conn->pguser);
1409 if (!conn->pguser)
1410 {
1412 return false;
1413 }
1414 }
1415
1416 /*
1417 * If database name was not given, default it to equal user name
1418 */
1419 if (conn->dbName == NULL || conn->dbName[0] == '\0')
1420 {
1421 free(conn->dbName);
1422 conn->dbName = strdup(conn->pguser);
1423 if (!conn->dbName)
1424 goto oom_error;
1425 }
1426
1427 /*
1428 * If password was not given, try to look it up in password file. Note
1429 * that the result might be different for each host/port pair.
1430 */
1431 if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
1432 {
1433 /* If password file wasn't specified, use ~/PGPASSFILE */
1434 if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
1435 {
1436 char homedir[MAXPGPATH];
1437
1438 if (pqGetHomeDirectory(homedir, sizeof(homedir)))
1439 {
1442 if (!conn->pgpassfile)
1443 goto oom_error;
1444 snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s",
1445 homedir, PGPASSFILE);
1446 }
1447 }
1448
1449 if (conn->pgpassfile != NULL && conn->pgpassfile[0] != '\0')
1450 {
1451 for (i = 0; i < conn->nconnhost; i++)
1452 {
1453 /*
1454 * Try to get a password for this host from file. We use host
1455 * for the hostname search key if given, else hostaddr (at
1456 * least one of them is guaranteed nonempty by now).
1457 */
1458 const char *pwhost = conn->connhost[i].host;
1459 const char *password_errmsg = NULL;
1460
1461 if (pwhost == NULL || pwhost[0] == '\0')
1462 pwhost = conn->connhost[i].hostaddr;
1463
1465 passwordFromFile(pwhost,
1466 conn->connhost[i].port,
1467 conn->dbName,
1468 conn->pguser,
1470 &password_errmsg);
1471
1472 if (password_errmsg != NULL)
1473 {
1475 libpq_append_conn_error(conn, "%s", password_errmsg);
1476 return false;
1477 }
1478 }
1479 }
1480 }
1481
1482 /*
1483 * parse and validate require_auth option
1484 */
1485 if (conn->require_auth && conn->require_auth[0])
1486 {
1487 char *s = conn->require_auth;
1488 bool first,
1489 more;
1490 bool negated = false;
1491
1492 /*
1493 * By default, start from an empty set of allowed methods and
1494 * mechanisms, and add to it.
1495 */
1496 conn->auth_required = true;
1499
1500 for (first = true, more = true; more; first = false)
1501 {
1502 char *method,
1503 *part;
1504 uint32 bits = 0;
1505 const pg_fe_sasl_mech *mech = NULL;
1506
1507 part = parse_comma_separated_list(&s, &more);
1508 if (part == NULL)
1509 goto oom_error;
1510
1511 /*
1512 * Check for negation, e.g. '!password'. If one element is
1513 * negated, they all have to be.
1514 */
1515 method = part;
1516 if (*method == '!')
1517 {
1518 if (first)
1519 {
1520 /*
1521 * Switch to a permissive set of allowed methods and
1522 * mechanisms, and subtract from it.
1523 */
1524 conn->auth_required = false;
1527 }
1528 else if (!negated)
1529 {
1531 libpq_append_conn_error(conn, "negative require_auth method \"%s\" cannot be mixed with non-negative methods",
1532 method);
1533
1534 free(part);
1535 return false;
1536 }
1537
1538 negated = true;
1539 method++;
1540 }
1541 else if (negated)
1542 {
1544 libpq_append_conn_error(conn, "require_auth method \"%s\" cannot be mixed with negative methods",
1545 method);
1546
1547 free(part);
1548 return false;
1549 }
1550
1551 /*
1552 * First group: methods that can be handled solely with the
1553 * authentication request codes.
1554 */
1555 if (strcmp(method, "password") == 0)
1556 {
1557 bits = (1 << AUTH_REQ_PASSWORD);
1558 }
1559 else if (strcmp(method, "md5") == 0)
1560 {
1561 bits = (1 << AUTH_REQ_MD5);
1562 }
1563 else if (strcmp(method, "gss") == 0)
1564 {
1565 bits = (1 << AUTH_REQ_GSS);
1566 bits |= (1 << AUTH_REQ_GSS_CONT);
1567 }
1568 else if (strcmp(method, "sspi") == 0)
1569 {
1570 bits = (1 << AUTH_REQ_SSPI);
1571 bits |= (1 << AUTH_REQ_GSS_CONT);
1572 }
1573
1574 /*
1575 * Next group: SASL mechanisms. All of these use the same request
1576 * codes, so the list of allowed mechanisms is tracked separately.
1577 *
1578 * supported_sasl_mechs must contain all mechanisms handled here.
1579 */
1580 else if (strcmp(method, "scram-sha-256") == 0)
1581 {
1582 mech = &pg_scram_mech;
1583 }
1584 else if (strcmp(method, "oauth") == 0)
1585 {
1586 mech = &pg_oauth_mech;
1587 }
1588
1589 /*
1590 * Final group: meta-options.
1591 */
1592 else if (strcmp(method, "none") == 0)
1593 {
1594 /*
1595 * Special case: let the user explicitly allow (or disallow)
1596 * connections where the server does not send an explicit
1597 * authentication challenge, such as "trust" and "cert" auth.
1598 */
1599 if (negated) /* "!none" */
1600 {
1601 if (conn->auth_required)
1602 goto duplicate;
1603
1604 conn->auth_required = true;
1605 }
1606 else /* "none" */
1607 {
1608 if (!conn->auth_required)
1609 goto duplicate;
1610
1611 conn->auth_required = false;
1612 }
1613
1614 free(part);
1615 continue; /* avoid the bitmask manipulation below */
1616 }
1617 else
1618 {
1620 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1621 "require_auth", method);
1622
1623 free(part);
1624 return false;
1625 }
1626
1627 if (mech)
1628 {
1629 /*
1630 * Update the mechanism set only. The method bitmask will be
1631 * updated for SASL further down.
1632 */
1633 Assert(!bits);
1634
1635 if (negated)
1636 {
1637 /* Remove the existing mechanism from the list. */
1639 if (i < 0)
1640 goto duplicate;
1641
1642 conn->allowed_sasl_mechs[i] = NULL;
1643 }
1644 else
1645 {
1646 /*
1647 * Find a space to put the new mechanism (after making
1648 * sure it's not already there).
1649 */
1651 if (i >= 0)
1652 goto duplicate;
1653
1655 if (i < 0)
1656 {
1657 /* Should not happen; the pointer list is corrupted. */
1658 Assert(false);
1659
1662 "internal error: no space in allowed_sasl_mechs");
1663 free(part);
1664 return false;
1665 }
1666
1667 conn->allowed_sasl_mechs[i] = mech;
1668 }
1669 }
1670 else
1671 {
1672 /* Update the method bitmask. */
1673 Assert(bits);
1674
1675 if (negated)
1676 {
1677 if ((conn->allowed_auth_methods & bits) == 0)
1678 goto duplicate;
1679
1680 conn->allowed_auth_methods &= ~bits;
1681 }
1682 else
1683 {
1684 if ((conn->allowed_auth_methods & bits) == bits)
1685 goto duplicate;
1686
1687 conn->allowed_auth_methods |= bits;
1688 }
1689 }
1690
1691 free(part);
1692 continue;
1693
1694 duplicate:
1695
1696 /*
1697 * A duplicated method probably indicates a typo in a setting
1698 * where typos are extremely risky.
1699 */
1701 libpq_append_conn_error(conn, "require_auth method \"%s\" is specified more than once",
1702 part);
1703
1704 free(part);
1705 return false;
1706 }
1707
1708 /*
1709 * Finally, allow SASL authentication requests if (and only if) we've
1710 * allowed any mechanisms.
1711 */
1712 {
1713 bool allowed = false;
1714 const uint32 sasl_bits =
1715 (1 << AUTH_REQ_SASL)
1716 | (1 << AUTH_REQ_SASL_CONT)
1717 | (1 << AUTH_REQ_SASL_FIN);
1718
1719 for (i = 0; i < lengthof(conn->allowed_sasl_mechs); i++)
1720 {
1722 {
1723 allowed = true;
1724 break;
1725 }
1726 }
1727
1728 /*
1729 * For the standard case, add the SASL bits to the (default-empty)
1730 * set if needed. For the negated case, remove them.
1731 */
1732 if (!negated && allowed)
1733 conn->allowed_auth_methods |= sasl_bits;
1734 else if (negated && !allowed)
1735 conn->allowed_auth_methods &= ~sasl_bits;
1736 }
1737 }
1738
1739 /*
1740 * validate channel_binding option
1741 */
1742 if (conn->channel_binding)
1743 {
1744 if (strcmp(conn->channel_binding, "disable") != 0
1745 && strcmp(conn->channel_binding, "prefer") != 0
1746 && strcmp(conn->channel_binding, "require") != 0)
1747 {
1749 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1750 "channel_binding", conn->channel_binding);
1751 return false;
1752 }
1753 }
1754 else
1755 {
1757 if (!conn->channel_binding)
1758 goto oom_error;
1759 }
1760
1761#ifndef USE_SSL
1762
1763 /*
1764 * sslrootcert=system is not supported. Since setting this changes the
1765 * default sslmode, check this _before_ we validate sslmode, to avoid
1766 * confusing the user with errors for an option they may not have set.
1767 */
1768 if (conn->sslrootcert
1769 && strcmp(conn->sslrootcert, "system") == 0)
1770 {
1772 libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1773 "sslrootcert", conn->sslrootcert);
1774 return false;
1775 }
1776#endif
1777
1778 /*
1779 * validate sslmode option
1780 */
1781 if (conn->sslmode)
1782 {
1783 if (strcmp(conn->sslmode, "disable") != 0
1784 && strcmp(conn->sslmode, "allow") != 0
1785 && strcmp(conn->sslmode, "prefer") != 0
1786 && strcmp(conn->sslmode, "require") != 0
1787 && strcmp(conn->sslmode, "verify-ca") != 0
1788 && strcmp(conn->sslmode, "verify-full") != 0)
1789 {
1791 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1792 "sslmode", conn->sslmode);
1793 return false;
1794 }
1795
1796#ifndef USE_SSL
1797 switch (conn->sslmode[0])
1798 {
1799 case 'a': /* "allow" */
1800 case 'p': /* "prefer" */
1801
1802 /*
1803 * warn user that an SSL connection will never be negotiated
1804 * since SSL was not compiled in?
1805 */
1806 break;
1807
1808 case 'r': /* "require" */
1809 case 'v': /* "verify-ca" or "verify-full" */
1811 libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1812 "sslmode", conn->sslmode);
1813 return false;
1814 }
1815#endif
1816 }
1817 else
1818 {
1819 conn->sslmode = strdup(DefaultSSLMode);
1820 if (!conn->sslmode)
1821 goto oom_error;
1822 }
1823
1824 /*
1825 * validate sslnegotiation option, default is "postgres" for the postgres
1826 * style negotiated connection with an extra round trip but more options.
1827 */
1828 if (conn->sslnegotiation)
1829 {
1830 if (strcmp(conn->sslnegotiation, "postgres") != 0
1831 && strcmp(conn->sslnegotiation, "direct") != 0)
1832 {
1834 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1835 "sslnegotiation", conn->sslnegotiation);
1836 return false;
1837 }
1838
1839#ifndef USE_SSL
1840 if (conn->sslnegotiation[0] != 'p')
1841 {
1843 libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1844 "sslnegotiation", conn->sslnegotiation);
1845 return false;
1846 }
1847#endif
1848
1849 /*
1850 * Don't allow direct SSL negotiation with sslmode='prefer', because
1851 * that poses a risk of unintentional fallback to plaintext connection
1852 * when connecting to a pre-v17 server that does not support direct
1853 * SSL connections. To keep things simple, don't allow it with
1854 * sslmode='allow' or sslmode='disable' either. If a user goes through
1855 * the trouble of setting sslnegotiation='direct', they probably
1856 * intend to use SSL, and sslmode=disable or allow is probably a user
1857 * mistake anyway.
1858 */
1859 if (conn->sslnegotiation[0] == 'd' &&
1860 conn->sslmode[0] != 'r' && conn->sslmode[0] != 'v')
1861 {
1863 libpq_append_conn_error(conn, "weak sslmode \"%s\" may not be used with sslnegotiation=direct (use \"require\", \"verify-ca\", or \"verify-full\")",
1864 conn->sslmode);
1865 return false;
1866 }
1867 }
1868 else
1869 {
1871 if (!conn->sslnegotiation)
1872 goto oom_error;
1873 }
1874
1875#ifdef USE_SSL
1876
1877 /*
1878 * If sslrootcert=system, make sure our chosen sslmode is compatible.
1879 */
1880 if (conn->sslrootcert
1881 && strcmp(conn->sslrootcert, "system") == 0
1882 && strcmp(conn->sslmode, "verify-full") != 0)
1883 {
1885 libpq_append_conn_error(conn, "weak sslmode \"%s\" may not be used with sslrootcert=system (use \"verify-full\")",
1886 conn->sslmode);
1887 return false;
1888 }
1889#endif
1890
1891 /*
1892 * Validate TLS protocol versions for ssl_min_protocol_version and
1893 * ssl_max_protocol_version.
1894 */
1896 {
1898 libpq_append_conn_error(conn, "invalid \"%s\" value: \"%s\"",
1899 "ssl_min_protocol_version",
1901 return false;
1902 }
1904 {
1906 libpq_append_conn_error(conn, "invalid \"%s\" value: \"%s\"",
1907 "ssl_max_protocol_version",
1909 return false;
1910 }
1911
1912 /*
1913 * Check if the range of SSL protocols defined is correct. This is done
1914 * at this early step because this is independent of the SSL
1915 * implementation used, and this avoids unnecessary cycles with an
1916 * already-built SSL context when the connection is being established, as
1917 * it would be doomed anyway.
1918 */
1921 {
1923 libpq_append_conn_error(conn, "invalid SSL protocol version range");
1924 return false;
1925 }
1926
1927 /*
1928 * validate sslcertmode option
1929 */
1930 if (conn->sslcertmode)
1931 {
1932 if (strcmp(conn->sslcertmode, "disable") != 0 &&
1933 strcmp(conn->sslcertmode, "allow") != 0 &&
1934 strcmp(conn->sslcertmode, "require") != 0)
1935 {
1937 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
1938 "sslcertmode", conn->sslcertmode);
1939 return false;
1940 }
1941#ifndef USE_SSL
1942 if (strcmp(conn->sslcertmode, "require") == 0)
1943 {
1945 libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
1946 "sslcertmode", conn->sslcertmode);
1947 return false;
1948 }
1949#endif
1950#ifndef HAVE_SSL_CTX_SET_CERT_CB
1951
1952 /*
1953 * Without a certificate callback, the current implementation can't
1954 * figure out if a certificate was actually requested, so "require" is
1955 * useless.
1956 */
1957 if (strcmp(conn->sslcertmode, "require") == 0)
1958 {
1960 libpq_append_conn_error(conn, "%s value \"%s\" is not supported (check OpenSSL version)",
1961 "sslcertmode", conn->sslcertmode);
1962 return false;
1963 }
1964#endif
1965 }
1966 else
1967 {
1969 if (!conn->sslcertmode)
1970 goto oom_error;
1971 }
1972
1973 /*
1974 * validate gssencmode option
1975 */
1976 if (conn->gssencmode)
1977 {
1978 if (strcmp(conn->gssencmode, "disable") != 0 &&
1979 strcmp(conn->gssencmode, "prefer") != 0 &&
1980 strcmp(conn->gssencmode, "require") != 0)
1981 {
1983 libpq_append_conn_error(conn, "invalid %s value: \"%s\"", "gssencmode", conn->gssencmode);
1984 return false;
1985 }
1986#ifndef ENABLE_GSS
1987 if (strcmp(conn->gssencmode, "require") == 0)
1988 {
1990 libpq_append_conn_error(conn, "gssencmode value \"%s\" invalid when GSSAPI support is not compiled in",
1991 conn->gssencmode);
1992 return false;
1993 }
1994#endif
1995 }
1996 else
1997 {
1998 conn->gssencmode = strdup(DefaultGSSMode);
1999 if (!conn->gssencmode)
2000 goto oom_error;
2001 }
2002
2003 /*
2004 * validate target_session_attrs option, and set target_server_type
2005 */
2007 {
2008 if (strcmp(conn->target_session_attrs, "any") == 0)
2010 else if (strcmp(conn->target_session_attrs, "read-write") == 0)
2012 else if (strcmp(conn->target_session_attrs, "read-only") == 0)
2014 else if (strcmp(conn->target_session_attrs, "primary") == 0)
2016 else if (strcmp(conn->target_session_attrs, "standby") == 0)
2018 else if (strcmp(conn->target_session_attrs, "prefer-standby") == 0)
2020 else
2021 {
2023 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
2024 "target_session_attrs",
2026 return false;
2027 }
2028 }
2029 else
2031
2033 {
2034 int len;
2035
2039 goto oom_error;
2042 if (len < 0)
2043 {
2044 libpq_append_conn_error(conn, "invalid SCRAM client key");
2045 return false;
2046 }
2047 if (len != SCRAM_MAX_KEY_LEN)
2048 {
2049 libpq_append_conn_error(conn, "invalid SCRAM client key length: %d", len);
2050 return false;
2051 }
2053 }
2054
2056 {
2057 int len;
2058
2062 goto oom_error;
2065 if (len < 0)
2066 {
2067 libpq_append_conn_error(conn, "invalid SCRAM server key");
2068 return false;
2069 }
2070 if (len != SCRAM_MAX_KEY_LEN)
2071 {
2072 libpq_append_conn_error(conn, "invalid SCRAM server key length: %d", len);
2073 return false;
2074 }
2076 }
2077
2078 /*
2079 * validate load_balance_hosts option, and set load_balance_type
2080 */
2082 {
2083 if (strcmp(conn->load_balance_hosts, "disable") == 0)
2085 else if (strcmp(conn->load_balance_hosts, "random") == 0)
2087 else
2088 {
2090 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
2091 "load_balance_hosts",
2093 return false;
2094 }
2095 }
2096 else
2098
2100 {
2102
2103 /*
2104 * This is the "inside-out" variant of the Fisher-Yates shuffle
2105 * algorithm. Notionally, we append each new value to the array and
2106 * then swap it with a randomly-chosen array element (possibly
2107 * including itself, else we fail to generate permutations with the
2108 * last integer last). The swap step can be optimized by combining it
2109 * with the insertion.
2110 */
2111 for (i = 1; i < conn->nconnhost; i++)
2112 {
2113 int j = pg_prng_uint64_range(&conn->prng_state, 0, i);
2114 pg_conn_host temp = conn->connhost[j];
2115
2116 conn->connhost[j] = conn->connhost[i];
2117 conn->connhost[i] = temp;
2118 }
2119 }
2120
2122 {
2123 if (!pqParseProtocolVersion(conn->min_protocol_version, &conn->min_pversion, conn, "min_protocol_version"))
2124 {
2126 return false;
2127 }
2128 }
2129 else
2130 {
2132 }
2133
2135 {
2136 if (!pqParseProtocolVersion(conn->max_protocol_version, &conn->max_pversion, conn, "max_protocol_version"))
2137 {
2139 return false;
2140 }
2141 }
2142 else
2143 {
2144 /*
2145 * To not break connecting to older servers/poolers that do not yet
2146 * support NegotiateProtocolVersion, default to the 3.0 protocol at
2147 * least for a while longer. Except when min_protocol_version is set
2148 * to something larger, then we might as well default to the latest.
2149 */
2150 if (conn->min_pversion > PG_PROTOCOL(3, 0))
2152 else
2153 conn->max_pversion = PG_PROTOCOL(3, 0);
2154 }
2155
2157 {
2159 libpq_append_conn_error(conn, "\"%s\" is greater than \"%s\"", "min_protocol_version", "max_protocol_version");
2160 return false;
2161 }
2162
2163 /*
2164 * Resolve special "auto" client_encoding from the locale
2165 */
2167 strcmp(conn->client_encoding_initial, "auto") == 0)
2168 {
2172 goto oom_error;
2173 }
2174
2175 /*
2176 * Only if we get this far is it appropriate to try to connect. (We need a
2177 * state flag, rather than just the boolean result of this function, in
2178 * case someone tries to PQreset() the PGconn.)
2179 */
2180 conn->options_valid = true;
2181
2182 return true;
2183
2184oom_error:
2186 libpq_append_conn_error(conn, "out of memory");
2187 return false;
2188}
int pg_b64_dec_len(int srclen)
Definition: base64.c:239
int pg_b64_decode(const char *src, int len, uint8 *dst, int dstlen)
Definition: base64.c:116
uint32_t uint32
Definition: c.h:541
#define lengthof(array)
Definition: c.h:790
const pg_fe_sasl_mech pg_oauth_mech
Definition: fe-auth-oauth.c:40
const pg_fe_sasl_mech pg_scram_mech
Definition: fe-auth-scram.c:33
char * pg_fe_getauthname(PQExpBuffer errorMessage)
Definition: fe-auth.c:1344
static bool pqParseProtocolVersion(const char *value, ProtocolVersion *result, PGconn *conn, const char *context)
Definition: fe-connect.c:8318
#define DefaultHost
Definition: fe-connect.c:120
static bool sslVerifyProtocolRange(const char *min, const char *max)
Definition: fe-connect.c:8179
static void libpq_prng_init(PGconn *conn)
Definition: fe-connect.c:1174
static char * passwordFromFile(const char *hostname, const char *port, const char *dbname, const char *username, const char *pgpassfile, const char **errmsg)
Definition: fe-connect.c:7977
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:8232
#define DefaultSSLMode
Definition: fe-connect.c:133
#define DefaultGSSMode
Definition: fe-connect.c:141
static int count_comma_separated_elems(const char *input)
Definition: fe-connect.c:1115
static void clear_allowed_sasl_mechs(PGconn *conn)
Definition: fe-connect.c:1221
static void fill_allowed_sasl_mechs(PGconn *conn)
Definition: fe-connect.c:1197
#define DefaultChannelBinding
Definition: fe-connect.c:125
static int index_of_allowed_sasl_mech(PGconn *conn, const pg_fe_sasl_mech *mech)
Definition: fe-connect.c:1232
static bool sslVerifyProtocolVersion(const char *version)
Definition: fe-connect.c:8153
#define DefaultSSLNegotiation
Definition: fe-connect.c:136
#define PGPASSFILE
Definition: fe-connect.c:79
#define DefaultSSLCertMode
Definition: fe-connect.c:134
static char * parse_comma_separated_list(char **startptr, bool *more)
Definition: fe-connect.c:1139
#define calloc(a, b)
Definition: header.h:55
int j
Definition: isn.c:78
#define MAXPGPATH
#define DEFAULT_PGSOCKET_DIR
uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)
Definition: pg_prng.c:144
#define pg_encoding_to_char
Definition: pg_wchar.h:630
#define snprintf
Definition: port.h:260
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:301
#define PG_PROTOCOL_EARLIEST
Definition: pqcomm.h:94
static bool is_unixsock_path(const char *path)
Definition: pqcomm.h:66
#define PG_PROTOCOL_LATEST
Definition: pqcomm.h:95
#define PG_PROTOCOL(m, n)
Definition: pqcomm.h:89
#define AUTH_REQ_SSPI
Definition: protocol.h:105
#define AUTH_REQ_SASL_CONT
Definition: protocol.h:107
#define AUTH_REQ_GSS
Definition: protocol.h:103
#define AUTH_REQ_MD5
Definition: protocol.h:101
#define AUTH_REQ_PASSWORD
Definition: protocol.h:99
#define AUTH_REQ_GSS_CONT
Definition: protocol.h:104
#define AUTH_REQ_SASL
Definition: protocol.h:106
#define AUTH_REQ_SASL_FIN
Definition: protocol.h:108
#define SCRAM_MAX_KEY_LEN
Definition: scram-common.h:30
char * password
Definition: libpq-int.h:362
char * port
Definition: libpq-int.h:360
char * hostaddr
Definition: libpq-int.h:359
pg_conn_host_type type
Definition: libpq-int.h:357
uint8 * scram_client_key_binary
Definition: libpq-int.h:545
char * sslrootcert
Definition: libpq-int.h:413
char * sslnegotiation
Definition: libpq-int.h:407
int nconnhost
Definition: libpq-int.h:480
char * require_auth
Definition: libpq-int.h:428
char * channel_binding
Definition: libpq-int.h:398
char * pghost
Definition: libpq-int.h:374
size_t scram_client_key_len
Definition: libpq-int.h:544
char * ssl_max_protocol_version
Definition: libpq-int.h:426
uint8 * scram_server_key_binary
Definition: libpq-int.h:547
char * pgpass
Definition: libpq-int.h:396
ProtocolVersion min_pversion
Definition: libpq-int.h:548
char * dbName
Definition: libpq-int.h:390
char * sslcertmode
Definition: libpq-int.h:412
uint32 allowed_auth_methods
Definition: libpq-int.h:517
char * target_session_attrs
Definition: libpq-int.h:427
bool auth_required
Definition: libpq-int.h:515
char * max_protocol_version
Definition: libpq-int.h:424
char * load_balance_hosts
Definition: libpq-int.h:429
char * pguser
Definition: libpq-int.h:395
char * min_protocol_version
Definition: libpq-int.h:423
char * client_encoding_initial
Definition: libpq-int.h:386
char * sslmode
Definition: libpq-int.h:406
pg_prng_state prng_state
Definition: libpq-int.h:563
char * ssl_min_protocol_version
Definition: libpq-int.h:425
char * gssencmode
Definition: libpq-int.h:418
char * scram_server_key
Definition: libpq-int.h:431
char * pghostaddr
Definition: libpq-int.h:378
char * scram_client_key
Definition: libpq-int.h:430
ProtocolVersion max_pversion
Definition: libpq-int.h:549
char * pgpassfile
Definition: libpq-int.h:397
PGLoadBalanceType load_balance_type
Definition: libpq-int.h:535
size_t scram_server_key_len
Definition: libpq-int.h:546
char * pgport
Definition: libpq-int.h:382
const pg_fe_sasl_mech * allowed_sasl_mechs[2]
Definition: libpq-int.h:519

References pg_conn::allowed_auth_methods, pg_conn::allowed_sasl_mechs, Assert(), AUTH_REQ_GSS, AUTH_REQ_GSS_CONT, AUTH_REQ_MD5, AUTH_REQ_PASSWORD, AUTH_REQ_SASL, AUTH_REQ_SASL_CONT, AUTH_REQ_SASL_FIN, AUTH_REQ_SSPI, pg_conn::auth_required, calloc, pg_conn::channel_binding, CHT_HOST_ADDRESS, CHT_HOST_NAME, CHT_UNIX_SOCKET, clear_allowed_sasl_mechs(), pg_conn::client_encoding_initial, conn, CONNECTION_BAD, pg_conn::connhost, count_comma_separated_elems(), pg_conn::dbName, DEFAULT_PGSOCKET_DIR, DefaultChannelBinding, DefaultGSSMode, DefaultHost, DefaultSSLCertMode, DefaultSSLMode, DefaultSSLNegotiation, pg_conn::errorMessage, fill_allowed_sasl_mechs(), free, pg_conn::gssencmode, pg_conn_host::host, pg_conn_host::hostaddr, i, index_of_allowed_sasl_mech(), is_unixsock_path(), j, len, lengthof, libpq_append_conn_error(), libpq_prng_init(), LOAD_BALANCE_DISABLE, pg_conn::load_balance_hosts, LOAD_BALANCE_RANDOM, pg_conn::load_balance_type, malloc, pg_conn::max_protocol_version, pg_conn::max_pversion, MAXPGPATH, pg_conn::min_protocol_version, pg_conn::min_pversion, pg_conn::nconnhost, pg_conn::options_valid, parse_comma_separated_list(), pg_conn_host::password, passwordFromFile(), pg_b64_dec_len(), pg_b64_decode(), pg_encoding_to_char, pg_fe_getauthname(), pg_get_encoding_from_locale(), pg_oauth_mech, pg_prng_uint64_range(), PG_PROTOCOL, PG_PROTOCOL_EARLIEST, PG_PROTOCOL_LATEST, pg_scram_mech, pg_conn::pghost, pg_conn::pghostaddr, pg_conn::pgpass, PGPASSFILE, pg_conn::pgpassfile, pg_conn::pgport, pg_conn::pguser, pg_conn_host::port, pqGetHomeDirectory(), pqParseProtocolVersion(), pg_conn::prng_state, pg_conn::require_auth, pg_conn::scram_client_key, pg_conn::scram_client_key_binary, pg_conn::scram_client_key_len, SCRAM_MAX_KEY_LEN, pg_conn::scram_server_key, pg_conn::scram_server_key_binary, pg_conn::scram_server_key_len, SERVER_TYPE_ANY, SERVER_TYPE_PREFER_STANDBY, SERVER_TYPE_PRIMARY, SERVER_TYPE_READ_ONLY, SERVER_TYPE_READ_WRITE, SERVER_TYPE_STANDBY, snprintf, pg_conn::ssl_max_protocol_version, pg_conn::ssl_min_protocol_version, pg_conn::sslcertmode, pg_conn::sslmode, pg_conn::sslnegotiation, pg_conn::sslrootcert, sslVerifyProtocolRange(), sslVerifyProtocolVersion(), pg_conn::status, pg_conn::target_server_type, pg_conn::target_session_attrs, pg_conn_host::type, and pg_conn::whichhost.

Referenced by PQcancelCreate(), PQconnectStart(), PQconnectStartParams(), and PQsetdbLogin().

◆ pqCopyPGconn()

bool pqCopyPGconn ( PGconn srcConn,
PGconn dstConn 
)

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

1038{
1040
1041 /* copy over connection options */
1042 for (option = PQconninfoOptions; option->keyword; option++)
1043 {
1044 if (option->connofs >= 0)
1045 {
1046 const char **tmp = (const char **) ((char *) srcConn + option->connofs);
1047
1048 if (*tmp)
1049 {
1050 char **dstConnmember = (char **) ((char *) dstConn + option->connofs);
1051
1052 if (*dstConnmember)
1053 free(*dstConnmember);
1054 *dstConnmember = strdup(*tmp);
1055 if (*dstConnmember == NULL)
1056 {
1057 libpq_append_conn_error(dstConn, "out of memory");
1058 return false;
1059 }
1060 }
1061 }
1062 }
1063 return true;
1064}
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:200

References free, libpq_append_conn_error(), and PQconninfoOptions.

Referenced by PQcancelCreate().

◆ pqDropConnection()

void pqDropConnection ( PGconn conn,
bool  flushInput 
)

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

533{
534 /* Drop any SSL state */
536
537 /* Close the socket itself */
538 if (conn->sock != PGINVALID_SOCKET)
541
542 /* Optionally discard any unread data */
543 if (flushInput)
544 conn->inStart = conn->inCursor = conn->inEnd = 0;
545
546 /* Always discard any unsent data */
547 conn->outCount = 0;
548
549 /* Likewise, discard any pending pipelined commands */
553 conn->cmd_queue_recycle = NULL;
554
555 /* Free authentication/encryption state */
557 {
558 /*
559 * Any in-progress async authentication should be torn down first so
560 * that cleanup_async_auth() can depend on the other authentication
561 * state if necessary.
562 */
564 conn->cleanup_async_auth = NULL;
565 }
566 conn->async_auth = NULL;
567 /* cleanup_async_auth() should have done this, but make sure */
569#ifdef ENABLE_GSS
570 {
571 OM_uint32 min_s;
572
573 if (conn->gcred != GSS_C_NO_CREDENTIAL)
574 {
575 gss_release_cred(&min_s, &conn->gcred);
576 conn->gcred = GSS_C_NO_CREDENTIAL;
577 }
578 if (conn->gctx)
579 gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
580 if (conn->gtarg_nam)
581 gss_release_name(&min_s, &conn->gtarg_nam);
582 if (conn->gss_SendBuffer)
583 {
584 free(conn->gss_SendBuffer);
585 conn->gss_SendBuffer = NULL;
586 }
587 if (conn->gss_RecvBuffer)
588 {
589 free(conn->gss_RecvBuffer);
590 conn->gss_RecvBuffer = NULL;
591 }
592 if (conn->gss_ResultBuffer)
593 {
594 free(conn->gss_ResultBuffer);
595 conn->gss_ResultBuffer = NULL;
596 }
597 conn->gssenc = false;
598 }
599#endif
600#ifdef ENABLE_SSPI
601 if (conn->sspitarget)
602 {
603 free(conn->sspitarget);
604 conn->sspitarget = NULL;
605 }
606 if (conn->sspicred)
607 {
608 FreeCredentialsHandle(conn->sspicred);
609 free(conn->sspicred);
610 conn->sspicred = NULL;
611 }
612 if (conn->sspictx)
613 {
614 DeleteSecurityContext(conn->sspictx);
615 free(conn->sspictx);
616 conn->sspictx = NULL;
617 }
618 conn->usesspi = 0;
619#endif
620 if (conn->sasl_state)
621 {
623 conn->sasl_state = NULL;
624 }
625}
static void pqFreeCommandQueue(PGcmdQueueEntry *queue)
Definition: fe-connect.c:632
void pqsecure_close(PGconn *conn)
Definition: fe-secure.c:152
#define PGINVALID_SOCKET
Definition: port.h:31
#define closesocket
Definition: port.h:398
pgsocket sock
Definition: libpq-int.h:499
const pg_fe_sasl_mech * sasl
Definition: libpq-int.h:611
void(* cleanup_async_auth)(PGconn *conn)
Definition: libpq-int.h:529
PGcmdQueueEntry * cmd_queue_recycle
Definition: libpq-int.h:496
pgsocket altsock
Definition: libpq-int.h:530
PostgresPollingStatusType(* async_auth)(PGconn *conn)
Definition: libpq-int.h:528
void * sasl_state
Definition: libpq-int.h:612
void(* free)(void *state)
Definition: fe-auth-sasl.h:149

References pg_conn::altsock, pg_conn::async_auth, pg_conn::cleanup_async_auth, closesocket, pg_conn::cmd_queue_head, pg_conn::cmd_queue_recycle, pg_conn::cmd_queue_tail, conn, free, pg_fe_sasl_mech::free, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, pg_conn::outCount, PGINVALID_SOCKET, pqFreeCommandQueue(), pqsecure_close(), pg_conn::sasl, pg_conn::sasl_state, and pg_conn::sock.

Referenced by handleFatalError(), pqClosePGconn(), pqConnectDBStart(), PQconnectPoll(), and pqReadData().

◆ pqEndcopy3()

int pqEndcopy3 ( PGconn conn)

Definition at line 2064 of file fe-protocol3.c.

2065{
2066 PGresult *result;
2067
2071 {
2072 libpq_append_conn_error(conn, "no COPY in progress");
2073 return 1;
2074 }
2075
2076 /* Send the CopyDone message if needed */
2079 {
2080 if (pqPutMsgStart(PqMsg_CopyDone, conn) < 0 ||
2081 pqPutMsgEnd(conn) < 0)
2082 return 1;
2083
2084 /*
2085 * If we sent the COPY command in extended-query mode, we must issue a
2086 * Sync as well.
2087 */
2088 if (conn->cmd_queue_head &&
2090 {
2091 if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
2092 pqPutMsgEnd(conn) < 0)
2093 return 1;
2094 }
2095 }
2096
2097 /*
2098 * make sure no data is waiting to be sent, abort if we are non-blocking
2099 * and the flush fails
2100 */
2102 return 1;
2103
2104 /* Return to active duty */
2106
2107 /*
2108 * Non blocking connections may have to abort at this point. If everyone
2109 * played the game there should be no problem, but in error scenarios the
2110 * expected messages may not have arrived yet. (We are assuming that the
2111 * backend's packetizing will ensure that CommandComplete arrives along
2112 * with the CopyDone; are there corner cases where that doesn't happen?)
2113 */
2115 return 1;
2116
2117 /* Wait for the completion response */
2118 result = PQgetResult(conn);
2119
2120 /* Expecting a successful result */
2121 if (result && result->resultStatus == PGRES_COMMAND_OK)
2122 {
2123 PQclear(result);
2124 return 0;
2125 }
2126
2127 /*
2128 * Trouble. For backwards-compatibility reasons, we issue the error
2129 * message as if it were a notice (would be nice to get rid of this
2130 * silliness, but too many apps probably don't handle errors from
2131 * PQendcopy reasonably). Note that the app can still obtain the error
2132 * status from the PGconn object.
2133 */
2134 if (conn->errorMessage.len > 0)
2135 {
2136 /* We have to strip the trailing newline ... pain in neck... */
2137 char svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
2138
2139 if (svLast == '\n')
2140 conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
2142 conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
2143 }
2144
2145 PQclear(result);
2146
2147 return 1;
2148}
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:944
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:2048
int pqFlush(PGconn *conn)
Definition: fe-misc.c:994
int pqPutMsgStart(char msg_type, PGconn *conn)
Definition: fe-misc.c:473
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:532
#define PQgetResult
Definition: libpq-be-fe.h:246
#define PQclear
Definition: libpq-be-fe.h:245
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:125
#define pqIsnonblocking(conn)
Definition: libpq-int.h:939
#define PqMsg_CopyDone
Definition: protocol.h:64
#define PqMsg_Sync
Definition: protocol.h:27
PGNoticeHooks noticeHooks
Definition: libpq-int.h:454

References pg_conn::asyncStatus, pg_conn::cmd_queue_head, conn, PQExpBufferData::data, pg_conn::errorMessage, PQExpBufferData::len, libpq_append_conn_error(), pg_conn::noticeHooks, PGASYNC_BUSY, PGASYNC_COPY_BOTH, PGASYNC_COPY_IN, PGASYNC_COPY_OUT, PGQUERY_SIMPLE, PGRES_COMMAND_OK, PQclear, pqFlush(), PQgetResult, pqInternalNotice(), PQisBusy(), pqIsnonblocking, PqMsg_CopyDone, PqMsg_Sync, pqPutMsgEnd(), pqPutMsgStart(), PGcmdQueueEntry::queryclass, and pg_result::resultStatus.

Referenced by PQendcopy().

◆ pqFlush()

int pqFlush ( PGconn conn)

Definition at line 994 of file fe-misc.c.

995{
996 if (conn->outCount > 0)
997 {
998 if (conn->Pfdebug)
999 fflush(conn->Pfdebug);
1000
1001 return pqSendSome(conn, conn->outCount);
1002 }
1003
1004 return 0;
1005}
static int pqSendSome(PGconn *conn, int len)
Definition: fe-misc.c:825
FILE * Pfdebug
Definition: libpq-int.h:450

References conn, pg_conn::outCount, pg_conn::Pfdebug, and pqSendSome().

Referenced by pg_SASL_init(), PQconnectPoll(), PQconsumeInput(), pqEndcopy3(), PQexitPipelineMode(), PQflush(), pqFunctionCall3(), PQgetResult(), pqPacketSend(), pqPipelineFlush(), pqPipelineSyncInternal(), PQputCopyData(), PQputCopyEnd(), PQsendCancelRequest(), PQsendQueryInternal(), PQsetnonblocking(), and sendTerminateConn().

◆ pqFunctionCall3()

PGresult * pqFunctionCall3 ( PGconn conn,
Oid  fnid,
int *  result_buf,
int *  actual_result_len,
int  result_is_int,
const PQArgBlock args,
int  nargs 
)

Definition at line 2157 of file fe-protocol3.c.

2161{
2162 bool needInput = false;
2164 char id;
2165 int msgLength;
2166 int avail;
2167 int i;
2168
2169 /* already validated by PQfn */
2171
2172 /* PQfn already validated connection state */
2173
2175 pqPutInt(fnid, 4, conn) < 0 || /* function id */
2176 pqPutInt(1, 2, conn) < 0 || /* # of format codes */
2177 pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */
2178 pqPutInt(nargs, 2, conn) < 0) /* # of args */
2179 {
2180 /* error message should be set up already */
2181 return NULL;
2182 }
2183
2184 for (i = 0; i < nargs; ++i)
2185 { /* len.int4 + contents */
2186 if (pqPutInt(args[i].len, 4, conn))
2187 return NULL;
2188 if (args[i].len == -1)
2189 continue; /* it's NULL */
2190
2191 if (args[i].isint)
2192 {
2193 if (pqPutInt(args[i].u.integer, args[i].len, conn))
2194 return NULL;
2195 }
2196 else
2197 {
2198 if (pqPutnchar(args[i].u.ptr, args[i].len, conn))
2199 return NULL;
2200 }
2201 }
2202
2203 if (pqPutInt(1, 2, conn) < 0) /* result format code: BINARY */
2204 return NULL;
2205
2206 if (pqPutMsgEnd(conn) < 0 ||
2207 pqFlush(conn))
2208 return NULL;
2209
2210 for (;;)
2211 {
2212 if (needInput)
2213 {
2214 /* Wait for some data to arrive (or for the channel to close) */
2215 if (pqWait(true, false, conn) ||
2216 pqReadData(conn) < 0)
2217 break;
2218 }
2219
2220 /*
2221 * Scan the message. If we run out of data, loop around to try again.
2222 */
2223 needInput = true;
2224
2226 if (pqGetc(&id, conn))
2227 continue;
2228 if (pqGetInt(&msgLength, 4, conn))
2229 continue;
2230
2231 /*
2232 * Try to validate message type/length here. A length less than 4 is
2233 * definitely broken. Large lengths should only be believed for a few
2234 * message types.
2235 */
2236 if (msgLength < 4)
2237 {
2238 handleSyncLoss(conn, id, msgLength);
2239 break;
2240 }
2241 if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
2242 {
2243 handleSyncLoss(conn, id, msgLength);
2244 break;
2245 }
2246
2247 /*
2248 * Can't process if message body isn't all here yet.
2249 */
2250 msgLength -= 4;
2251 avail = conn->inEnd - conn->inCursor;
2252 if (avail < msgLength)
2253 {
2254 /*
2255 * Before looping, enlarge the input buffer if needed to hold the
2256 * whole message. See notes in parseInput.
2257 */
2258 if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
2259 conn))
2260 {
2261 /*
2262 * Abandon the connection. There's not much else we can
2263 * safely do; we can't just ignore the message or we could
2264 * miss important changes to the connection state.
2265 * pqCheckInBufferSpace() already reported the error.
2266 */
2268 break;
2269 }
2270 continue;
2271 }
2272
2273 /*
2274 * We should see V or E response to the command, but might get N
2275 * and/or A notices first. We also need to swallow the final Z before
2276 * returning.
2277 */
2278 switch (id)
2279 {
2281 if (pqGetInt(actual_result_len, 4, conn))
2282 continue;
2283 if (*actual_result_len != -1)
2284 {
2285 if (result_is_int)
2286 {
2287 if (pqGetInt(result_buf, *actual_result_len, conn))
2288 continue;
2289 }
2290 else
2291 {
2292 if (pqGetnchar(result_buf,
2293 *actual_result_len,
2294 conn))
2295 continue;
2296 }
2297 }
2298 /* correctly finished function result message */
2299 status = PGRES_COMMAND_OK;
2300 break;
2302 if (pqGetErrorNotice3(conn, true))
2303 continue;
2304 status = PGRES_FATAL_ERROR;
2305 break;
2307 /* handle notify and go back to processing return values */
2308 if (getNotify(conn))
2309 continue;
2310 break;
2312 /* handle notice and go back to processing return values */
2313 if (pqGetErrorNotice3(conn, false))
2314 continue;
2315 break;
2318 continue;
2319
2320 /* consume the message */
2321 pqParseDone(conn, conn->inStart + 5 + msgLength);
2322
2323 /*
2324 * If we already have a result object (probably an error), use
2325 * that. Otherwise, if we saw a function result message,
2326 * report COMMAND_OK. Otherwise, the backend violated the
2327 * protocol, so complain.
2328 */
2330 {
2331 if (status == PGRES_COMMAND_OK)
2332 {
2333 conn->result = PQmakeEmptyPGresult(conn, status);
2334 if (!conn->result)
2335 {
2336 libpq_append_conn_error(conn, "out of memory");
2338 }
2339 }
2340 else
2341 {
2342 libpq_append_conn_error(conn, "protocol error: no function result");
2344 }
2345 }
2346 /* and we're out */
2347 return pqPrepareAsyncResult(conn);
2350 continue;
2351 break;
2352 default:
2353 /* The backend violates the protocol. */
2354 libpq_append_conn_error(conn, "protocol error: id=0x%x", id);
2356
2357 /*
2358 * We can't call parsing done due to the protocol violation
2359 * (so message tracing wouldn't work), but trust the specified
2360 * message length as what to skip.
2361 */
2362 conn->inStart += 5 + msgLength;
2363 return pqPrepareAsyncResult(conn);
2364 }
2365
2366 /* Completed parsing this message, keep going */
2367 pqParseDone(conn, conn->inStart + 5 + msgLength);
2368 needInput = false;
2369 }
2370
2371 /*
2372 * We fall out of the loop only upon failing to read data.
2373 * conn->errorMessage has been set by pqWait or pqReadData. We want to
2374 * append it to any already-received error message.
2375 */
2377 return pqPrepareAsyncResult(conn);
2378}
PGresult * pqPrepareAsyncResult(PGconn *conn)
Definition: fe-exec.c:857
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:809
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:160
int pqReadData(PGconn *conn)
Definition: fe-misc.c:606
int pqPutInt(int value, size_t bytes, PGconn *conn)
Definition: fe-misc.c:253
void pqParseDone(PGconn *conn, int newInStart)
Definition: fe-misc.c:443
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:77
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:216
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:1019
int pqPutnchar(const void *s, size_t len, PGconn *conn)
Definition: fe-misc.c:202
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:351
int pqGetnchar(void *s, size_t len, PGconn *conn)
Definition: fe-misc.c:165
static int getNotify(PGconn *conn)
static int getParameterStatus(PGconn *conn)
static void handleFatalError(PGconn *conn)
Definition: fe-protocol3.c:487
#define VALID_LONG_MESSAGE_TYPE(id)
Definition: fe-protocol3.c:38
static void handleSyncLoss(PGconn *conn, char id, int msgLength)
Definition: fe-protocol3.c:503
static int getReadyForQuery(PGconn *conn)
int pqGetErrorNotice3(PGconn *conn, bool isError)
Definition: fe-protocol3.c:898
ExecStatusType
Definition: libpq-fe.h:123
#define pgHavePendingResult(conn)
Definition: libpq-int.h:932
#define PqMsg_NotificationResponse
Definition: protocol.h:41
#define PqMsg_FunctionCall
Definition: protocol.h:23
#define PqMsg_FunctionCallResponse
Definition: protocol.h:53
#define PqMsg_ReadyForQuery
Definition: protocol.h:55
#define PqMsg_ParameterStatus
Definition: protocol.h:51
#define PqMsg_ErrorResponse
Definition: protocol.h:44
#define PqMsg_NoticeResponse
Definition: protocol.h:49

References generate_unaccent_rules::args, Assert(), conn, getNotify(), getParameterStatus(), getReadyForQuery(), handleFatalError(), handleSyncLoss(), i, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, len, libpq_append_conn_error(), pgHavePendingResult, PGRES_COMMAND_OK, PGRES_FATAL_ERROR, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, pqCheckInBufferSpace(), pqFlush(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGetnchar(), PQmakeEmptyPGresult(), PqMsg_ErrorResponse, PqMsg_FunctionCall, PqMsg_FunctionCallResponse, PqMsg_NoticeResponse, PqMsg_NotificationResponse, PqMsg_ParameterStatus, PqMsg_ReadyForQuery, pqParseDone(), pqPrepareAsyncResult(), pqPutInt(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), pqReadData(), pqSaveErrorResult(), pqWait(), pg_conn::result, and VALID_LONG_MESSAGE_TYPE.

Referenced by PQfn().

◆ pqGetc()

int pqGetc ( char *  result,
PGconn conn 
)

Definition at line 77 of file fe-misc.c.

78{
79 if (conn->inCursor >= conn->inEnd)
80 return EOF;
81
82 *result = conn->inBuffer[conn->inCursor++];
83
84 return 0;
85}

References conn, pg_conn::inBuffer, pg_conn::inCursor, and pg_conn::inEnd.

Referenced by getCopyDataMessage(), getCopyStart(), getReadyForQuery(), PQconnectPoll(), pqFunctionCall3(), pqGetErrorNotice3(), and pqParseInput3().

◆ pqGetCopyData3()

int pqGetCopyData3 ( PGconn conn,
char **  buffer,
int  async 
)

Definition at line 1899 of file fe-protocol3.c.

1900{
1901 int msgLength;
1902
1903 for (;;)
1904 {
1905 /*
1906 * Collect the next input message. To make life simpler for async
1907 * callers, we keep returning 0 until the next message is fully
1908 * available, even if it is not Copy Data.
1909 */
1910 msgLength = getCopyDataMessage(conn);
1911 if (msgLength < 0)
1912 return msgLength; /* end-of-copy or error */
1913 if (msgLength == 0)
1914 {
1915 /* Don't block if async read requested */
1916 if (async)
1917 return 0;
1918 /* Need to load more data */
1919 if (pqWait(true, false, conn) ||
1920 pqReadData(conn) < 0)
1921 return -2;
1922 continue;
1923 }
1924
1925 /*
1926 * Drop zero-length messages (shouldn't happen anyway). Otherwise
1927 * pass the data back to the caller.
1928 */
1929 msgLength -= 4;
1930 if (msgLength > 0)
1931 {
1932 *buffer = (char *) malloc(msgLength + 1);
1933 if (*buffer == NULL)
1934 {
1935 libpq_append_conn_error(conn, "out of memory");
1936 return -2;
1937 }
1938 memcpy(*buffer, &conn->inBuffer[conn->inCursor], msgLength);
1939 (*buffer)[msgLength] = '\0'; /* Add terminating null */
1940
1941 /* Mark message consumed */
1942 pqParseDone(conn, conn->inCursor + msgLength);
1943
1944 return msgLength;
1945 }
1946
1947 /* Empty, so drop it and loop around for another */
1949 }
1950}
static int getCopyDataMessage(PGconn *conn)

References conn, getCopyDataMessage(), pg_conn::inBuffer, pg_conn::inCursor, libpq_append_conn_error(), malloc, pqParseDone(), pqReadData(), and pqWait().

Referenced by PQgetCopyData().

◆ pqGetErrorNotice3()

int pqGetErrorNotice3 ( PGconn conn,
bool  isError 
)

Definition at line 898 of file fe-protocol3.c.

899{
900 PGresult *res = NULL;
901 bool have_position = false;
902 PQExpBufferData workBuf;
903 char id;
904
905 /* If in pipeline mode, set error indicator for it */
906 if (isError && conn->pipelineStatus != PQ_PIPELINE_OFF)
908
909 /*
910 * If this is an error message, pre-emptively clear any incomplete query
911 * result we may have. We'd just throw it away below anyway, and
912 * releasing it before collecting the error might avoid out-of-memory.
913 */
914 if (isError)
916
917 /*
918 * Since the fields might be pretty long, we create a temporary
919 * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended
920 * for stuff that is expected to be short. We shouldn't use
921 * conn->errorMessage either, since this might be only a notice.
922 */
923 initPQExpBuffer(&workBuf);
924
925 /*
926 * Make a PGresult to hold the accumulated fields. We temporarily lie
927 * about the result status, so that PQmakeEmptyPGresult doesn't uselessly
928 * copy conn->errorMessage.
929 *
930 * NB: This allocation can fail, if you run out of memory. The rest of the
931 * function handles that gracefully, and we still try to set the error
932 * message as the connection's error message.
933 */
935 if (res)
937
938 /*
939 * Read the fields and save into res.
940 *
941 * While at it, save the SQLSTATE in conn->last_sqlstate, and note whether
942 * we saw a PG_DIAG_STATEMENT_POSITION field.
943 */
944 for (;;)
945 {
946 if (pqGetc(&id, conn))
947 goto fail;
948 if (id == '\0')
949 break; /* terminator found */
950 if (pqGets(&workBuf, conn))
951 goto fail;
952 pqSaveMessageField(res, id, workBuf.data);
953 if (id == PG_DIAG_SQLSTATE)
954 strlcpy(conn->last_sqlstate, workBuf.data,
955 sizeof(conn->last_sqlstate));
956 else if (id == PG_DIAG_STATEMENT_POSITION)
957 have_position = true;
958 }
959
960 /*
961 * Save the active query text, if any, into res as well; but only if we
962 * might need it for an error cursor display, which is only true if there
963 * is a PG_DIAG_STATEMENT_POSITION field.
964 */
965 if (have_position && res && conn->cmd_queue_head && conn->cmd_queue_head->query)
967
968 /*
969 * Now build the "overall" error message for PQresultErrorMessage.
970 */
971 resetPQExpBuffer(&workBuf);
973
974 /*
975 * Either save error as current async result, or just emit the notice.
976 */
977 if (isError)
978 {
979 pqClearAsyncResult(conn); /* redundant, but be safe */
980 if (res)
981 {
982 pqSetResultError(res, &workBuf, 0);
983 conn->result = res;
984 }
985 else
986 {
987 /* Fall back to using the internal-error processing paths */
988 conn->error_result = true;
989 }
990
991 if (PQExpBufferDataBroken(workBuf))
992 libpq_append_conn_error(conn, "out of memory");
993 else
995 }
996 else
997 {
998 /* if we couldn't allocate the result set, just discard the NOTICE */
999 if (res)
1000 {
1001 /*
1002 * We can cheat a little here and not copy the message. But if we
1003 * were unlucky enough to run out of memory while filling workBuf,
1004 * insert "out of memory", as in pqSetResultError.
1005 */
1006 if (PQExpBufferDataBroken(workBuf))
1007 res->errMsg = libpq_gettext("out of memory\n");
1008 else
1009 res->errMsg = workBuf.data;
1010 if (res->noticeHooks.noticeRec != NULL)
1012 PQclear(res);
1013 }
1014 }
1015
1016 termPQExpBuffer(&workBuf);
1017 return 0;
1018
1019fail:
1020 PQclear(res);
1021 termPQExpBuffer(&workBuf);
1022 return EOF;
1023}
void pqSaveMessageField(PGresult *res, char code, const char *value)
Definition: fe-exec.c:1066
void pqSetResultError(PGresult *res, PQExpBuffer errorMessage, int offset)
Definition: fe-exec.c:698
char * pqResultStrdup(PGresult *res, const char *str)
Definition: fe-exec.c:681
int pqGets(PQExpBuffer buf, PGconn *conn)
Definition: fe-misc.c:136
void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
@ PGRES_EMPTY_QUERY
Definition: libpq-fe.h:124
@ PGRES_NONFATAL_ERROR
Definition: libpq-fe.h:135
@ PQ_PIPELINE_ABORTED
Definition: libpq-fe.h:189
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
PQnoticeReceiver noticeRec
Definition: libpq-int.h:149
void * noticeRecArg
Definition: libpq-int.h:150
PGVerbosity verbosity
Definition: libpq-int.h:560
char last_sqlstate[6]
Definition: libpq-int.h:465
PGContextVisibility show_context
Definition: libpq-int.h:561
PGNoticeHooks noticeHooks
Definition: libpq-int.h:183

References appendPQExpBufferStr(), pg_conn::cmd_queue_head, conn, PQExpBufferData::data, pg_result::errMsg, pg_conn::error_result, pg_conn::errorMessage, pg_result::errQuery, initPQExpBuffer(), pg_conn::last_sqlstate, libpq_append_conn_error(), libpq_gettext, pg_result::noticeHooks, PGNoticeHooks::noticeRec, PGNoticeHooks::noticeRecArg, PG_DIAG_SQLSTATE, PG_DIAG_STATEMENT_POSITION, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PGRES_NONFATAL_ERROR, pg_conn::pipelineStatus, PQ_PIPELINE_ABORTED, PQ_PIPELINE_OFF, pqBuildErrorMessage3(), PQclear, pqClearAsyncResult(), PQExpBufferDataBroken, pqGetc(), pqGets(), PQmakeEmptyPGresult(), pqResultStrdup(), pqSaveMessageField(), pqSetResultError(), PGcmdQueueEntry::query, resetPQExpBuffer(), pg_conn::result, pg_result::resultStatus, pg_conn::show_context, strlcpy(), termPQExpBuffer(), and pg_conn::verbosity.

Referenced by getCopyDataMessage(), PQconnectPoll(), pqFunctionCall3(), and pqParseInput3().

◆ pqGetHomeDirectory()

bool pqGetHomeDirectory ( char *  buf,
int  bufsize 
)

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

8233{
8234#ifndef WIN32
8235 const char *home;
8236
8237 home = getenv("HOME");
8238 if (home && home[0])
8239 {
8240 strlcpy(buf, home, bufsize);
8241 return true;
8242 }
8243 else
8244 {
8245 struct passwd pwbuf;
8246 struct passwd *pw;
8247 char tmpbuf[1024];
8248 int rc;
8249
8250 rc = getpwuid_r(geteuid(), &pwbuf, tmpbuf, sizeof tmpbuf, &pw);
8251 if (rc != 0 || !pw)
8252 return false;
8253 strlcpy(buf, pw->pw_dir, bufsize);
8254 return true;
8255 }
8256#else
8257 char tmppath[MAX_PATH];
8258
8259 ZeroMemory(tmppath, sizeof(tmppath));
8260 if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
8261 return false;
8262 snprintf(buf, bufsize, "%s/postgresql", tmppath);
8263 return true;
8264#endif
8265}
#define bufsize
Definition: indent_globs.h:36
static char * buf
Definition: pg_test_fsync.c:72
static StringInfoData tmpbuf
Definition: walsender.c:178

References buf, bufsize, snprintf, strlcpy(), and tmpbuf.

Referenced by initialize_SSL(), parseServiceInfo(), and pqConnectOptions2().

◆ pqGetInt()

int pqGetInt ( int *  result,
size_t  bytes,
PGconn conn 
)

Definition at line 216 of file fe-misc.c.

217{
218 uint16 tmp2;
219 uint32 tmp4;
220
221 switch (bytes)
222 {
223 case 2:
224 if (conn->inCursor + 2 > conn->inEnd)
225 return EOF;
226 memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2);
227 conn->inCursor += 2;
228 *result = (int) pg_ntoh16(tmp2);
229 break;
230 case 4:
231 if (conn->inCursor + 4 > conn->inEnd)
232 return EOF;
233 memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4);
234 conn->inCursor += 4;
235 *result = (int) pg_ntoh32(tmp4);
236 break;
237 default:
239 "integer of size %lu not supported by pqGetInt",
240 (unsigned long) bytes);
241 return EOF;
242 }
243
244 return 0;
245}
uint16_t uint16
Definition: c.h:540
#define pg_ntoh32(x)
Definition: pg_bswap.h:125
#define pg_ntoh16(x)
Definition: pg_bswap.h:124

References conn, pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, pg_conn::noticeHooks, pg_ntoh16, pg_ntoh32, and pqInternalNotice().

Referenced by getAnotherTuple(), getBackendKeyData(), getCopyDataMessage(), getCopyStart(), getNotify(), getParamDescriptions(), getRowDescriptions(), PQconnectPoll(), pqFunctionCall3(), pqGetNegotiateProtocolVersion3(), and pqParseInput3().

◆ pqGetline3()

int pqGetline3 ( PGconn conn,
char *  s,
int  maxlen 
)

Definition at line 1958 of file fe-protocol3.c.

1959{
1960 int status;
1961
1962 if (conn->sock == PGINVALID_SOCKET ||
1966 {
1967 libpq_append_conn_error(conn, "PQgetline: not doing text COPY OUT");
1968 *s = '\0';
1969 return EOF;
1970 }
1971
1972 while ((status = PQgetlineAsync(conn, s, maxlen - 1)) == 0)
1973 {
1974 /* need to load more data */
1975 if (pqWait(true, false, conn) ||
1976 pqReadData(conn) < 0)
1977 {
1978 *s = '\0';
1979 return EOF;
1980 }
1981 }
1982
1983 if (status < 0)
1984 {
1985 /* End of copy detected; gin up old-style terminator */
1986 strcpy(s, "\\.");
1987 return 0;
1988 }
1989
1990 /* Add null terminator, and strip trailing \n if present */
1991 if (s[status - 1] == '\n')
1992 {
1993 s[status - 1] = '\0';
1994 return 0;
1995 }
1996 else
1997 {
1998 s[status] = '\0';
1999 return 1;
2000 }
2001}
int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize)
Definition: fe-exec.c:2918
char copy_is_binary
Definition: libpq-int.h:474

References pg_conn::asyncStatus, conn, pg_conn::copy_is_binary, libpq_append_conn_error(), PGASYNC_COPY_BOTH, PGASYNC_COPY_OUT, PGINVALID_SOCKET, PQgetlineAsync(), pqReadData(), pqWait(), and pg_conn::sock.

Referenced by PQgetline().

◆ pqGetlineAsync3()

int pqGetlineAsync3 ( PGconn conn,
char *  buffer,
int  bufsize 
)

Definition at line 2009 of file fe-protocol3.c.

2010{
2011 int msgLength;
2012 int avail;
2013
2016 return -1; /* we are not doing a copy... */
2017
2018 /*
2019 * Recognize the next input message. To make life simpler for async
2020 * callers, we keep returning 0 until the next message is fully available
2021 * even if it is not Copy Data. This should keep PQendcopy from blocking.
2022 * (Note: unlike pqGetCopyData3, we do not change asyncStatus here.)
2023 */
2024 msgLength = getCopyDataMessage(conn);
2025 if (msgLength < 0)
2026 return -1; /* end-of-copy or error */
2027 if (msgLength == 0)
2028 return 0; /* no data yet */
2029
2030 /*
2031 * Move data from libpq's buffer to the caller's. In the case where a
2032 * prior call found the caller's buffer too small, we use
2033 * conn->copy_already_done to remember how much of the row was already
2034 * returned to the caller.
2035 */
2037 avail = msgLength - 4 - conn->copy_already_done;
2038 if (avail <= bufsize)
2039 {
2040 /* Able to consume the whole message */
2041 memcpy(buffer, &conn->inBuffer[conn->inCursor], avail);
2042 /* Mark message consumed */
2043 conn->inStart = conn->inCursor + avail;
2044 /* Reset state for next time */
2046 return avail;
2047 }
2048 else
2049 {
2050 /* We must return a partial message */
2051 memcpy(buffer, &conn->inBuffer[conn->inCursor], bufsize);
2052 /* The message is NOT consumed from libpq's buffer */
2054 return bufsize;
2055 }
2056}
int copy_already_done
Definition: libpq-int.h:475

References pg_conn::asyncStatus, bufsize, conn, pg_conn::copy_already_done, getCopyDataMessage(), pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inStart, PGASYNC_COPY_BOTH, and PGASYNC_COPY_OUT.

Referenced by PQgetlineAsync().

◆ pqGetnchar()

int pqGetnchar ( void *  s,
size_t  len,
PGconn conn 
)

Definition at line 165 of file fe-misc.c.

166{
167 if (len > (size_t) (conn->inEnd - conn->inCursor))
168 return EOF;
169
170 memcpy(s, conn->inBuffer + conn->inCursor, len);
171 /* no terminating null */
172
173 conn->inCursor += len;
174
175 return 0;
176}

References conn, pg_conn::inBuffer, pg_conn::inCursor, pg_conn::inEnd, and len.

Referenced by getBackendKeyData(), pg_password_sendauth(), pg_SASL_continue(), and pqFunctionCall3().

◆ pqGetNegotiateProtocolVersion3()

int pqGetNegotiateProtocolVersion3 ( PGconn conn)

Definition at line 1443 of file fe-protocol3.c.

1444{
1445 int their_version;
1446 int num;
1447
1448 if (pqGetInt(&their_version, 4, conn) != 0)
1449 goto eof;
1450
1451 if (pqGetInt(&num, 4, conn) != 0)
1452 goto eof;
1453
1454 /* Check the protocol version */
1455 if (their_version > conn->pversion)
1456 {
1457 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested downgrade to a higher-numbered version");
1458 goto failure;
1459 }
1460
1461 if (their_version < PG_PROTOCOL(3, 0))
1462 {
1463 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested downgrade to pre-3.0 protocol version");
1464 goto failure;
1465 }
1466
1467 /* 3.1 never existed, we went straight from 3.0 to 3.2 */
1468 if (their_version == PG_PROTOCOL(3, 1))
1469 {
1470 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested downgrade to non-existent 3.1 protocol version");
1471 goto failure;
1472 }
1473
1474 if (num < 0)
1475 {
1476 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported negative number of unsupported parameters");
1477 goto failure;
1478 }
1479
1480 if (their_version == conn->pversion && num == 0)
1481 {
1482 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server negotiated but asks for no changes");
1483 goto failure;
1484 }
1485
1486 if (their_version < conn->min_pversion)
1487 {
1488 libpq_append_conn_error(conn, "server only supports protocol version %d.%d, but \"%s\" was set to %d.%d",
1489 PG_PROTOCOL_MAJOR(their_version),
1490 PG_PROTOCOL_MINOR(their_version),
1491 "min_protocol_version",
1494
1495 goto failure;
1496 }
1497
1498 /* the version is acceptable */
1499 conn->pversion = their_version;
1500
1501 /*
1502 * We don't currently request any protocol extensions, so we don't expect
1503 * the server to reply with any either.
1504 */
1505 for (int i = 0; i < num; i++)
1506 {
1507 if (pqGets(&conn->workBuffer, conn))
1508 {
1509 goto eof;
1510 }
1511 if (strncmp(conn->workBuffer.data, "_pq_.", 5) != 0)
1512 {
1513 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported unsupported parameter name without a \"%s\" prefix (\"%s\")", "_pq_.", conn->workBuffer.data);
1514 goto failure;
1515 }
1516 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported an unsupported parameter that was not requested (\"%s\")", conn->workBuffer.data);
1517 goto failure;
1518 }
1519
1520 return 0;
1521
1522eof:
1523 libpq_append_conn_error(conn, "received invalid protocol negotiation message: message too short");
1524failure:
1527 return 1;
1528}
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:86
#define PG_PROTOCOL_MINOR(v)
Definition: pqcomm.h:87
ProtocolVersion pversion
Definition: libpq-int.h:503
PQExpBufferData workBuffer
Definition: libpq-int.h:687

References pg_conn::asyncStatus, conn, PQExpBufferData::data, i, libpq_append_conn_error(), pg_conn::min_pversion, PG_PROTOCOL, PG_PROTOCOL_MAJOR, PG_PROTOCOL_MINOR, PGASYNC_READY, pqGetInt(), pqGets(), pqSaveErrorResult(), pg_conn::pversion, and pg_conn::workBuffer.

Referenced by PQconnectPoll().

◆ pqGets()

int pqGets ( PQExpBuffer  buf,
PGconn conn 
)

Definition at line 136 of file fe-misc.c.

137{
138 return pqGets_internal(buf, conn, true);
139}
static int pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
Definition: fe-misc.c:109

References buf, conn, and pqGets_internal().

Referenced by getNotify(), getParameterStatus(), getRowDescriptions(), pg_SASL_init(), pqGetErrorNotice3(), pqGetNegotiateProtocolVersion3(), and pqParseInput3().

◆ pqGets_append()

int pqGets_append ( PQExpBuffer  buf,
PGconn conn 
)

Definition at line 142 of file fe-misc.c.

143{
144 return pqGets_internal(buf, conn, false);
145}

References buf, conn, and pqGets_internal().

Referenced by PQconnectPoll().

◆ pqInternalNotice()

void pqInternalNotice ( const PGNoticeHooks hooks,
const char *  fmt,
  ... 
)

◆ pqMakeEmptyPGconn()

PGconn * pqMakeEmptyPGconn ( void  )

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

4955{
4956 PGconn *conn;
4957
4958#ifdef WIN32
4959
4960 /*
4961 * Make sure socket support is up and running in this process.
4962 *
4963 * Note: the Windows documentation says that we should eventually do a
4964 * matching WSACleanup() call, but experience suggests that that is at
4965 * least as likely to cause problems as fix them. So we don't.
4966 */
4967 static bool wsastartup_done = false;
4968
4969 if (!wsastartup_done)
4970 {
4971 WSADATA wsaData;
4972
4973 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
4974 return NULL;
4975 wsastartup_done = true;
4976 }
4977
4978 /* Forget any earlier error */
4979 WSASetLastError(0);
4980#endif /* WIN32 */
4981
4982 conn = (PGconn *) malloc(sizeof(PGconn));
4983 if (conn == NULL)
4984 return conn;
4985
4986 /* Zero all pointers and booleans */
4987 MemSet(conn, 0, sizeof(PGconn));
4988
4989 /* install default notice hooks */
4992
4997 conn->options_valid = false;
4998 conn->nonblocking = false;
5000 conn->std_strings = false; /* unless server says differently */
5008 conn->Pfdebug = NULL;
5009
5010 /*
5011 * We try to send at least 8K at a time, which is the usual size of pipe
5012 * buffers on Unix systems. That way, when we are sending a large amount
5013 * of data, we avoid incurring extra kernel context swaps for partial
5014 * bufferloads. The output buffer is initially made 16K in size, and we
5015 * try to dump it after accumulating 8K.
5016 *
5017 * With the same goal of minimizing context swaps, the input buffer will
5018 * be enlarged anytime it has less than 8K free, so we initially allocate
5019 * twice that.
5020 */
5021 conn->inBufSize = 16 * 1024;
5022 conn->inBuffer = (char *) malloc(conn->inBufSize);
5023 conn->outBufSize = 16 * 1024;
5024 conn->outBuffer = (char *) malloc(conn->outBufSize);
5025 conn->rowBufLen = 32;
5029
5030 if (conn->inBuffer == NULL ||
5031 conn->outBuffer == NULL ||
5032 conn->rowBuf == NULL ||
5035 {
5036 /* out of memory already :-( */
5038 conn = NULL;
5039 }
5040
5041 return conn;
5042}
#define MemSet(start, val, len)
Definition: c.h:1022
static void defaultNoticeReceiver(void *arg, const PGresult *res)
Definition: fe-connect.c:7908
static void defaultNoticeProcessor(void *arg, const char *message)
Definition: fe-connect.c:7923
static void freePGconn(PGconn *conn)
Definition: fe-connect.c:5054
@ PQERRORS_DEFAULT
Definition: libpq-fe.h:157
@ PG_BOOL_UNKNOWN
Definition: oauth-utils.h:73
@ PG_SQL_ASCII
Definition: pg_wchar.h:226
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
#define SCRAM_SHA_256_DEFAULT_ITERATIONS
Definition: scram-common.h:50
PQnoticeProcessor noticeProc
Definition: libpq-int.h:151
PGdataValue * rowBuf
Definition: libpq-int.h:593
bool std_strings
Definition: libpq-int.h:557
PGTernaryBool in_hot_standby
Definition: libpq-int.h:559
int client_encoding
Definition: libpq-int.h:556
PGTernaryBool default_transaction_read_only
Definition: libpq-int.h:558
int rowBufLen
Definition: libpq-int.h:594
int scram_sha_256_iterations
Definition: libpq-int.h:613

References pg_conn::altsock, pg_conn::asyncStatus, pg_conn::client_encoding, conn, CONNECTION_BAD, pg_conn::default_transaction_read_only, defaultNoticeProcessor(), defaultNoticeReceiver(), pg_conn::errorMessage, freePGconn(), pg_conn::in_hot_standby, pg_conn::inBuffer, pg_conn::inBufSize, initPQExpBuffer(), malloc, MemSet, pg_conn::nonblocking, pg_conn::noticeHooks, PGNoticeHooks::noticeProc, PGNoticeHooks::noticeRec, pg_conn::options_valid, pg_conn::outBuffer, pg_conn::outBufSize, pg_conn::Pfdebug, PG_BOOL_UNKNOWN, PG_SQL_ASCII, PGASYNC_IDLE, PGINVALID_SOCKET, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, PQERRORS_DEFAULT, PQExpBufferBroken, PQSHOW_CONTEXT_ERRORS, PQTRANS_IDLE, pg_conn::rowBuf, pg_conn::rowBufLen, SCRAM_SHA_256_DEFAULT_ITERATIONS, pg_conn::scram_sha_256_iterations, pg_conn::show_context, pg_conn::sock, pg_conn::status, pg_conn::std_strings, pg_conn::verbosity, pg_conn::workBuffer, and pg_conn::xactStatus.

Referenced by PQcancelCreate(), PQconnectStart(), PQconnectStartParams(), and PQsetdbLogin().

◆ pqPacketSend()

int pqPacketSend ( PGconn conn,
char  pack_type,
const void *  buf,
size_t  buf_len 
)

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

5426{
5427 /* Start the message. */
5428 if (pqPutMsgStart(pack_type, conn))
5429 return STATUS_ERROR;
5430
5431 /* Send the message body. */
5432 if (pqPutnchar(buf, buf_len, conn))
5433 return STATUS_ERROR;
5434
5435 /* Finish the message. */
5436 if (pqPutMsgEnd(conn))
5437 return STATUS_ERROR;
5438
5439 /* Flush to ensure backend gets it. */
5440 if (pqFlush(conn))
5441 return STATUS_ERROR;
5442
5443 return STATUS_OK;
5444}
#define STATUS_OK
Definition: c.h:1157
#define STATUS_ERROR
Definition: c.h:1158

References buf, conn, pqFlush(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), STATUS_ERROR, and STATUS_OK.

Referenced by pg_password_sendauth(), pg_SASL_continue(), and PQconnectPoll().

◆ pqParseDone()

void pqParseDone ( PGconn conn,
int  newInStart 
)

Definition at line 443 of file fe-misc.c.

444{
445 /* trace server-to-client message */
446 if (conn->Pfdebug)
448
449 /* Mark message as done */
450 conn->inStart = newInStart;
451}
void pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
Definition: fe-trace.c:624

References conn, pg_conn::inBuffer, pg_conn::inStart, pg_conn::Pfdebug, and pqTraceOutputMessage().

Referenced by getCopyDataMessage(), PQconnectPoll(), pqFunctionCall3(), pqGetCopyData3(), and pqParseInput3().

◆ pqParseInput3()

void pqParseInput3 ( PGconn conn)

Definition at line 70 of file fe-protocol3.c.

71{
72 char id;
73 int msgLength;
74 int avail;
75
76 /*
77 * Loop to parse successive complete messages available in the buffer.
78 */
79 for (;;)
80 {
81 /*
82 * Try to read a message. First get the type code and length. Return
83 * if not enough data.
84 */
86 if (pqGetc(&id, conn))
87 return;
88 if (pqGetInt(&msgLength, 4, conn))
89 return;
90
91 /*
92 * Try to validate message type/length here. A length less than 4 is
93 * definitely broken. Large lengths should only be believed for a few
94 * message types.
95 */
96 if (msgLength < 4)
97 {
98 handleSyncLoss(conn, id, msgLength);
99 return;
100 }
101 if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
102 {
103 handleSyncLoss(conn, id, msgLength);
104 return;
105 }
106
107 /*
108 * Can't process if message body isn't all here yet.
109 */
110 msgLength -= 4;
111 avail = conn->inEnd - conn->inCursor;
112 if (avail < msgLength)
113 {
114 /*
115 * Before returning, enlarge the input buffer if needed to hold
116 * the whole message. This is better than leaving it to
117 * pqReadData because we can avoid multiple cycles of realloc()
118 * when the message is large; also, we can implement a reasonable
119 * recovery strategy if we are unable to make the buffer big
120 * enough.
121 */
122 if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
123 conn))
124 {
125 /*
126 * Abandon the connection. There's not much else we can
127 * safely do; we can't just ignore the message or we could
128 * miss important changes to the connection state.
129 * pqCheckInBufferSpace() already reported the error.
130 */
132 }
133 return;
134 }
135
136 /*
137 * NOTIFY and NOTICE messages can happen in any state; always process
138 * them right away.
139 *
140 * Most other messages should only be processed while in BUSY state.
141 * (In particular, in READY state we hold off further parsing until
142 * the application collects the current PGresult.)
143 *
144 * However, if the state is IDLE then we got trouble; we need to deal
145 * with the unexpected message somehow.
146 *
147 * ParameterStatus ('S') messages are a special case: in IDLE state we
148 * must process 'em (this case could happen if a new value was adopted
149 * from config file due to SIGHUP), but otherwise we hold off until
150 * BUSY state.
151 */
153 {
154 if (getNotify(conn))
155 return;
156 }
157 else if (id == PqMsg_NoticeResponse)
158 {
159 if (pqGetErrorNotice3(conn, false))
160 return;
161 }
162 else if (conn->asyncStatus != PGASYNC_BUSY)
163 {
164 /* If not IDLE state, just wait ... */
166 return;
167
168 /*
169 * Unexpected message in IDLE state; need to recover somehow.
170 * ERROR messages are handled using the notice processor;
171 * ParameterStatus is handled normally; anything else is just
172 * dropped on the floor after displaying a suitable warning
173 * notice. (An ERROR is very possibly the backend telling us why
174 * it is about to close the connection, so we don't want to just
175 * discard it...)
176 */
177 if (id == PqMsg_ErrorResponse)
178 {
179 if (pqGetErrorNotice3(conn, false /* treat as notice */ ))
180 return;
181 }
182 else if (id == PqMsg_ParameterStatus)
183 {
185 return;
186 }
187 else
188 {
189 /* Any other case is unexpected and we summarily skip it */
191 "message type 0x%02x arrived from server while idle",
192 id);
193 /* Discard the unexpected message */
194 conn->inCursor += msgLength;
195 }
196 }
197 else
198 {
199 /*
200 * In BUSY state, we can process everything.
201 */
202 switch (id)
203 {
205 if (pqGets(&conn->workBuffer, conn))
206 return;
208 {
211 if (!conn->result)
212 {
213 libpq_append_conn_error(conn, "out of memory");
215 }
216 }
217 if (conn->result)
221 break;
223 if (pqGetErrorNotice3(conn, true))
224 return;
226 break;
229 return;
231 {
234 if (!conn->result)
235 {
236 libpq_append_conn_error(conn, "out of memory");
238 }
239 else
240 {
243 }
244 }
245 else
246 {
247 /* Advance the command queue and set us idle */
248 pqCommandQueueAdvance(conn, true, false);
250 }
251 break;
254 {
257 if (!conn->result)
258 {
259 libpq_append_conn_error(conn, "out of memory");
261 }
262 }
264 break;
266 /* If we're doing PQprepare, we're done; else ignore */
267 if (conn->cmd_queue_head &&
269 {
271 {
274 if (!conn->result)
275 {
276 libpq_append_conn_error(conn, "out of memory");
278 }
279 }
281 }
282 break;
284 /* Nothing to do for this message type */
285 break;
287 /* If we're doing PQsendClose, we're done; else ignore */
288 if (conn->cmd_queue_head &&
290 {
292 {
295 if (!conn->result)
296 {
297 libpq_append_conn_error(conn, "out of memory");
299 }
300 }
302 }
303 break;
306 return;
307 break;
309
310 /*
311 * This is expected only during backend startup, but it's
312 * just as easy to handle it as part of the main loop.
313 * Save the data and continue processing.
314 */
315 if (getBackendKeyData(conn, msgLength))
316 return;
317 break;
319 if (conn->error_result ||
320 (conn->result != NULL &&
322 {
323 /*
324 * We've already choked for some reason. Just discard
325 * the data till we get to the end of the query.
326 */
327 conn->inCursor += msgLength;
328 }
329 else if (conn->result == NULL ||
332 {
333 /* First 'T' in a query sequence */
334 if (getRowDescriptions(conn, msgLength))
335 return;
336 }
337 else
338 {
339 /*
340 * A new 'T' message is treated as the start of
341 * another PGresult. (It is not clear that this is
342 * really possible with the current backend.) We stop
343 * parsing until the application accepts the current
344 * result.
345 */
347 return;
348 }
349 break;
350 case PqMsg_NoData:
351
352 /*
353 * NoData indicates that we will not be seeing a
354 * RowDescription message because the statement or portal
355 * inquired about doesn't return rows.
356 *
357 * If we're doing a Describe, we have to pass something
358 * back to the client, so set up a COMMAND_OK result,
359 * instead of PGRES_TUPLES_OK. Otherwise we can just
360 * ignore this message.
361 */
362 if (conn->cmd_queue_head &&
364 {
366 {
369 if (!conn->result)
370 {
371 libpq_append_conn_error(conn, "out of memory");
373 }
374 }
376 }
377 break;
379 if (getParamDescriptions(conn, msgLength))
380 return;
381 break;
382 case PqMsg_DataRow:
383 if (conn->result != NULL &&
386 {
387 /* Read another tuple of a normal query response */
388 if (getAnotherTuple(conn, msgLength))
389 return;
390 }
391 else if (conn->error_result ||
392 (conn->result != NULL &&
394 {
395 /*
396 * We've already choked for some reason. Just discard
397 * tuples till we get to the end of the query.
398 */
399 conn->inCursor += msgLength;
400 }
401 else
402 {
403 /* Set up to report error at end of query */
404 libpq_append_conn_error(conn, "server sent data (\"D\" message) without prior row description (\"T\" message)");
406 /* Discard the unexpected message */
407 conn->inCursor += msgLength;
408 }
409 break;
412 return;
414 break;
417 return;
420 break;
423 return;
426 break;
427 case PqMsg_CopyData:
428
429 /*
430 * If we see Copy Data, just silently drop it. This would
431 * only occur if application exits COPY OUT mode too
432 * early.
433 */
434 conn->inCursor += msgLength;
435 break;
436 case PqMsg_CopyDone:
437
438 /*
439 * If we see Copy Done, just silently drop it. This is
440 * the normal case during PQendcopy. We will keep
441 * swallowing data, expecting to see command-complete for
442 * the COPY command.
443 */
444 break;
445 default:
446 libpq_append_conn_error(conn, "unexpected response from server; first received character was \"%c\"", id);
447 /* build an error result holding the error message */
449 /* not sure if we will see more, so go to ready state */
451 /* Discard the unexpected message */
452 conn->inCursor += msgLength;
453 break;
454 } /* switch on protocol character */
455 }
456 /* Successfully consumed this message */
457 if (conn->inCursor == conn->inStart + 5 + msgLength)
458 {
459 /* Normal case: parsing agrees with specified length */
461 }
462 else if (conn->error_result && conn->status == CONNECTION_BAD)
463 {
464 /* The connection was abandoned and we already reported it */
465 return;
466 }
467 else
468 {
469 /* Trouble --- report it */
470 libpq_append_conn_error(conn, "message contents do not agree with length in message type \"%c\"", id);
471 /* build an error result holding the error message */
474 /* trust the specified message length as what to skip */
475 conn->inStart += 5 + msgLength;
476 }
477 }
478}
void pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery, bool gotSync)
Definition: fe-exec.c:3159
static int getAnotherTuple(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:777
static int getRowDescriptions(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:518
static int getCopyStart(PGconn *conn, ExecStatusType copytype)
static int getBackendKeyData(PGconn *conn, int msgLength)
static int getParamDescriptions(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:689
@ PGRES_COPY_IN
Definition: libpq-fe.h:132
@ PGRES_COPY_BOTH
Definition: libpq-fe.h:137
@ PGRES_TUPLES_CHUNK
Definition: libpq-fe.h:142
@ PGRES_COPY_OUT
Definition: libpq-fe.h:131
@ PGRES_PIPELINE_SYNC
Definition: libpq-fe.h:139
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:128
@ PQ_PIPELINE_ON
Definition: libpq-fe.h:188
#define CMDSTATUS_LEN
Definition: libpq-int.h:83
#define PqMsg_CloseComplete
Definition: protocol.h:40
#define PqMsg_BindComplete
Definition: protocol.h:39
#define PqMsg_CopyData
Definition: protocol.h:65
#define PqMsg_ParameterDescription
Definition: protocol.h:58
#define PqMsg_CopyInResponse
Definition: protocol.h:45
#define PqMsg_EmptyQueryResponse
Definition: protocol.h:47
#define PqMsg_RowDescription
Definition: protocol.h:52
#define PqMsg_CopyBothResponse
Definition: protocol.h:54
#define PqMsg_NoData
Definition: protocol.h:56
#define PqMsg_BackendKeyData
Definition: protocol.h:48
#define PqMsg_CommandComplete
Definition: protocol.h:42
#define PqMsg_DataRow
Definition: protocol.h:43
#define PqMsg_CopyOutResponse
Definition: protocol.h:46
#define PqMsg_ParseComplete
Definition: protocol.h:38
char cmdStatus[CMDSTATUS_LEN]
Definition: libpq-int.h:175

References pg_conn::asyncStatus, pg_conn::cmd_queue_head, pg_result::cmdStatus, CMDSTATUS_LEN, conn, CONNECTION_BAD, pg_conn::copy_already_done, PQExpBufferData::data, pg_conn::error_result, getAnotherTuple(), getBackendKeyData(), getCopyStart(), getNotify(), getParamDescriptions(), getParameterStatus(), getReadyForQuery(), getRowDescriptions(), handleFatalError(), handleSyncLoss(), pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, libpq_append_conn_error(), pg_conn::noticeHooks, PGASYNC_BUSY, PGASYNC_COPY_BOTH, PGASYNC_COPY_IN, PGASYNC_COPY_OUT, PGASYNC_IDLE, PGASYNC_READY, pgHavePendingResult, PGQUERY_CLOSE, PGQUERY_DESCRIBE, PGQUERY_PREPARE, PGRES_COMMAND_OK, PGRES_COPY_BOTH, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PGRES_PIPELINE_SYNC, PGRES_TUPLES_CHUNK, PGRES_TUPLES_OK, pg_conn::pipelineStatus, PQ_PIPELINE_OFF, PQ_PIPELINE_ON, pqCheckInBufferSpace(), pqCommandQueueAdvance(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGets(), pqInternalNotice(), PQmakeEmptyPGresult(), PqMsg_BackendKeyData, PqMsg_BindComplete, PqMsg_CloseComplete, PqMsg_CommandComplete, PqMsg_CopyBothResponse, PqMsg_CopyData, PqMsg_CopyDone, PqMsg_CopyInResponse, PqMsg_CopyOutResponse, PqMsg_DataRow, PqMsg_EmptyQueryResponse, PqMsg_ErrorResponse, PqMsg_NoData, PqMsg_NoticeResponse, PqMsg_NotificationResponse, PqMsg_ParameterDescription, PqMsg_ParameterStatus, PqMsg_ParseComplete, PqMsg_ReadyForQuery, PqMsg_RowDescription, pqParseDone(), pqSaveErrorResult(), PGcmdQueueEntry::queryclass, pg_conn::result, pg_result::resultStatus, pg_conn::status, strlcpy(), VALID_LONG_MESSAGE_TYPE, and pg_conn::workBuffer.

Referenced by parseInput().

◆ pqParseIntParam()

bool pqParseIntParam ( const char *  value,
int *  result,
PGconn conn,
const char *  context 
)

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

8275{
8276 char *end;
8277 long numval;
8278
8279 Assert(value != NULL);
8280
8281 *result = 0;
8282
8283 /* strtol(3) skips leading whitespaces */
8284 errno = 0;
8285 numval = strtol(value, &end, 10);
8286
8287 /*
8288 * If no progress was done during the parsing or an error happened, fail.
8289 * This tests properly for overflows of the result.
8290 */
8291 if (value == end || errno != 0 || numval != (int) numval)
8292 goto error;
8293
8294 /*
8295 * Skip any trailing whitespace; if anything but whitespace remains before
8296 * the terminating character, fail
8297 */
8298 while (*end != '\0' && isspace((unsigned char) *end))
8299 end++;
8300
8301 if (*end != '\0')
8302 goto error;
8303
8304 *result = numval;
8305 return true;
8306
8307error:
8308 libpq_append_conn_error(conn, "invalid integer value \"%s\" for connection option \"%s\"",
8309 value, context);
8310 return false;
8311}
static struct @171 value
static void error(void)
Definition: sql-dyntest.c:147

References Assert(), conn, error(), libpq_append_conn_error(), and value.

Referenced by pqConnectDBComplete(), PQconnectPoll(), PQgetCancel(), setKeepalivesCount(), setKeepalivesIdle(), setKeepalivesInterval(), setTCPUserTimeout(), and useKeepalives().

◆ pqPrepareAsyncResult()

PGresult * pqPrepareAsyncResult ( PGconn conn)

Definition at line 857 of file fe-exec.c.

858{
859 PGresult *res;
860
861 res = conn->result;
862 if (res)
863 {
864 /*
865 * If the pre-existing result is an ERROR (presumably something
866 * received from the server), assume that it represents whatever is in
867 * conn->errorMessage, and advance errorReported.
868 */
871 }
872 else
873 {
874 /*
875 * We get here after internal-to-libpq errors. We should probably
876 * always have error_result = true, but if we don't, gin up some error
877 * text.
878 */
879 if (!conn->error_result)
880 libpq_append_conn_error(conn, "no error text available");
881
882 /* Paranoia: be sure errorReported offset is sane */
883 if (conn->errorReported < 0 ||
885 conn->errorReported = 0;
886
887 /*
888 * Make a PGresult struct for the error. We temporarily lie about the
889 * result status, so that PQmakeEmptyPGresult doesn't uselessly copy
890 * all of conn->errorMessage.
891 */
893 if (res)
894 {
895 /*
896 * Report whatever new error text we have, and advance
897 * errorReported.
898 */
902 }
903 else
904 {
905 /*
906 * Ouch, not enough memory for a PGresult. Fortunately, we have a
907 * card up our sleeve: we can use the static OOM_result. Casting
908 * away const here is a bit ugly, but it seems best to declare
909 * OOM_result as const, in hopes it will be allocated in read-only
910 * storage.
911 */
912 res = unconstify(PGresult *, &OOM_result);
913
914 /*
915 * Don't advance errorReported. Perhaps we'll be able to report
916 * the text later.
917 */
918 }
919 }
920
921 /*
922 * Replace conn->result with saved_result, if any. In the normal case
923 * there isn't a saved result and we're just dropping ownership of the
924 * current result. In partial-result mode this restores the situation to
925 * what it was before we created the current partial result.
926 */
928 conn->error_result = false; /* saved_result is never an error */
929 conn->saved_result = NULL;
930
931 return res;
932}
#define unconstify(underlying_type, expr)
Definition: c.h:1233
static const PGresult OOM_result
Definition: fe-exec.c:50
int errorReported
Definition: libpq-int.h:684

References conn, pg_conn::error_result, pg_conn::errorMessage, pg_conn::errorReported, PQExpBufferData::len, libpq_append_conn_error(), OOM_result, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PQmakeEmptyPGresult(), pqSetResultError(), pg_conn::result, pg_result::resultStatus, pg_conn::saved_result, and unconstify.

Referenced by getCopyResult(), pqFunctionCall3(), and PQgetResult().

◆ pqPutc()

int pqPutc ( char  c,
PGconn conn 
)

Definition at line 92 of file fe-misc.c.

93{
94 if (pqPutMsgBytes(&c, 1, conn))
95 return EOF;
96
97 return 0;
98}
static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn)
Definition: fe-misc.c:509
char * c

References conn, and pqPutMsgBytes().

Referenced by PQsendQueryGuts(), and PQsendTypedCommand().

◆ pqPutInt()

int pqPutInt ( int  value,
size_t  bytes,
PGconn conn 
)

Definition at line 253 of file fe-misc.c.

254{
255 uint16 tmp2;
256 uint32 tmp4;
257
258 switch (bytes)
259 {
260 case 2:
261 tmp2 = pg_hton16((uint16) value);
262 if (pqPutMsgBytes((const char *) &tmp2, 2, conn))
263 return EOF;
264 break;
265 case 4:
266 tmp4 = pg_hton32((uint32) value);
267 if (pqPutMsgBytes((const char *) &tmp4, 4, conn))
268 return EOF;
269 break;
270 default:
272 "integer of size %lu not supported by pqPutInt",
273 (unsigned long) bytes);
274 return EOF;
275 }
276
277 return 0;
278}
#define pg_hton32(x)
Definition: pg_bswap.h:121
#define pg_hton16(x)
Definition: pg_bswap.h:120

References conn, pg_conn::noticeHooks, pg_hton16, pg_hton32, pqInternalNotice(), pqPutMsgBytes(), and value.

Referenced by pg_SASL_init(), pqFunctionCall3(), PQsendPrepare(), and PQsendQueryGuts().

◆ pqPutMsgEnd()

int pqPutMsgEnd ( PGconn conn)

Definition at line 532 of file fe-misc.c.

533{
534 /* Fill in length word if needed */
535 if (conn->outMsgStart >= 0)
536 {
537 uint32 msgLen = conn->outMsgEnd - conn->outMsgStart;
538
539 msgLen = pg_hton32(msgLen);
540 memcpy(conn->outBuffer + conn->outMsgStart, &msgLen, 4);
541 }
542
543 /* trace client-to-server message */
544 if (conn->Pfdebug)
545 {
548 else
551 }
552
553 /* Make message eligible to send */
555
556 /* If appropriate, try to push out some data */
557 if (conn->outCount >= 8192)
558 {
559 int toSend = conn->outCount;
560
561 /*
562 * On Unix-pipe connections, it seems profitable to prefer sending
563 * pipe-buffer-sized packets not randomly-sized ones, so retain the
564 * last partial-8K chunk in our buffer for now. On TCP connections,
565 * the advantage of that is far less clear. Moreover, it flat out
566 * isn't safe when using SSL or GSSAPI, because those code paths have
567 * API stipulations that if they fail to send all the data that was
568 * offered in the previous write attempt, we mustn't offer less data
569 * in this write attempt. The previous write attempt might've been
570 * pqFlush attempting to send everything in the buffer, so we mustn't
571 * offer less now. (Presently, we won't try to use SSL or GSSAPI on
572 * Unix connections, so those checks are just Asserts. They'll have
573 * to become part of the regular if-test if we ever change that.)
574 */
575 if (conn->raddr.addr.ss_family == AF_UNIX)
576 {
577#ifdef USE_SSL
579#endif
580#ifdef ENABLE_GSS
581 Assert(!conn->gssenc);
582#endif
583 toSend -= toSend % 8192;
584 }
585
586 if (pqSendSome(conn, toSend) < 0)
587 return EOF;
588 /* in nonblock mode, don't complain if unable to send it all */
589 }
590
591 return 0;
592}
void pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message)
Definition: fe-trace.c:841
struct sockaddr_storage addr
Definition: pqcomm.h:32
int outMsgStart
Definition: libpq-int.h:588
SockAddr raddr
Definition: libpq-int.h:502
int outMsgEnd
Definition: libpq-int.h:590

References SockAddr::addr, Assert(), conn, pg_conn::outBuffer, pg_conn::outCount, pg_conn::outMsgEnd, pg_conn::outMsgStart, pg_conn::Pfdebug, pg_hton32, pqSendSome(), pqTraceOutputMessage(), pqTraceOutputNoTypeByteMessage(), pg_conn::raddr, and pg_conn::ssl_in_use.

Referenced by pg_SASL_init(), pqEndcopy3(), pqFunctionCall3(), pqPacketSend(), pqPipelineSyncInternal(), PQputCopyData(), PQputCopyEnd(), PQsendCancelRequest(), PQsendFlushRequest(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), PQsendTypedCommand(), and sendTerminateConn().

◆ pqPutMsgStart()

int pqPutMsgStart ( char  msg_type,
PGconn conn 
)

Definition at line 473 of file fe-misc.c.

474{
475 int lenPos;
476 int endPos;
477
478 /* allow room for message type byte */
479 if (msg_type)
480 endPos = conn->outCount + 1;
481 else
482 endPos = conn->outCount;
483
484 /* do we want a length word? */
485 lenPos = endPos;
486 /* allow room for message length */
487 endPos += 4;
488
489 /* make sure there is room for message header */
490 if (pqCheckOutBufferSpace(endPos, conn))
491 return EOF;
492 /* okay, save the message type byte if any */
493 if (msg_type)
494 conn->outBuffer[conn->outCount] = msg_type;
495 /* set up the message pointers */
496 conn->outMsgStart = lenPos;
497 conn->outMsgEnd = endPos;
498 /* length word, if needed, will be filled in by pqPutMsgEnd */
499
500 return 0;
501}
int pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:287

References conn, pg_conn::outBuffer, pg_conn::outCount, pg_conn::outMsgEnd, pg_conn::outMsgStart, and pqCheckOutBufferSpace().

Referenced by pg_SASL_init(), pqEndcopy3(), pqFunctionCall3(), pqPacketSend(), pqPipelineSyncInternal(), PQputCopyData(), PQputCopyEnd(), PQsendCancelRequest(), PQsendFlushRequest(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), PQsendTypedCommand(), and sendTerminateConn().

◆ pqPutnchar()

int pqPutnchar ( const void *  s,
size_t  len,
PGconn conn 
)

Definition at line 202 of file fe-misc.c.

203{
204 if (pqPutMsgBytes(s, len, conn))
205 return EOF;
206
207 return 0;
208}

References conn, len, and pqPutMsgBytes().

Referenced by pg_SASL_init(), pqFunctionCall3(), pqPacketSend(), PQputCopyData(), PQsendCancelRequest(), and PQsendQueryGuts().

◆ pqPuts()

int pqPuts ( const char *  s,
PGconn conn 
)

Definition at line 152 of file fe-misc.c.

153{
154 if (pqPutMsgBytes(s, strlen(s) + 1, conn))
155 return EOF;
156
157 return 0;
158}

References conn, and pqPutMsgBytes().

Referenced by pg_SASL_init(), PQputCopyEnd(), PQsendPrepare(), PQsendQueryGuts(), PQsendQueryInternal(), and PQsendTypedCommand().

◆ pqReadData()

int pqReadData ( PGconn conn)

Definition at line 606 of file fe-misc.c.

607{
608 int someread = 0;
609 int nread;
610
611 if (conn->sock == PGINVALID_SOCKET)
612 {
613 libpq_append_conn_error(conn, "connection not open");
614 return -1;
615 }
616
617 /* Left-justify any data in the buffer to make room */
618 if (conn->inStart < conn->inEnd)
619 {
620 if (conn->inStart > 0)
621 {
622 memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
623 conn->inEnd - conn->inStart);
624 conn->inEnd -= conn->inStart;
626 conn->inStart = 0;
627 }
628 }
629 else
630 {
631 /* buffer is logically empty, reset it */
632 conn->inStart = conn->inCursor = conn->inEnd = 0;
633 }
634
635 /*
636 * If the buffer is fairly full, enlarge it. We need to be able to enlarge
637 * the buffer in case a single message exceeds the initial buffer size. We
638 * enlarge before filling the buffer entirely so as to avoid asking the
639 * kernel for a partial packet. The magic constant here should be large
640 * enough for a TCP packet or Unix pipe bufferload. 8K is the usual pipe
641 * buffer size, so...
642 */
643 if (conn->inBufSize - conn->inEnd < 8192)
644 {
645 if (pqCheckInBufferSpace(conn->inEnd + (size_t) 8192, conn))
646 {
647 /*
648 * We don't insist that the enlarge worked, but we need some room
649 */
650 if (conn->inBufSize - conn->inEnd < 100)
651 return -1; /* errorMessage already set */
652 }
653 }
654
655 /* OK, try to read some data */
656retry3:
659 if (nread < 0)
660 {
661 switch (SOCK_ERRNO)
662 {
663 case EINTR:
664 goto retry3;
665
666 /* Some systems return EAGAIN/EWOULDBLOCK for no data */
667#ifdef EAGAIN
668 case EAGAIN:
669 return someread;
670#endif
671#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
672 case EWOULDBLOCK:
673 return someread;
674#endif
675
676 /* We might get ECONNRESET etc here if connection failed */
678 goto definitelyFailed;
679
680 default:
681 /* pqsecure_read set the error message for us */
682 return -1;
683 }
684 }
685 if (nread > 0)
686 {
687 conn->inEnd += nread;
688
689 /*
690 * Hack to deal with the fact that some kernels will only give us back
691 * 1 packet per recv() call, even if we asked for more and there is
692 * more available. If it looks like we are reading a long message,
693 * loop back to recv() again immediately, until we run out of data or
694 * buffer space. Without this, the block-and-restart behavior of
695 * libpq's higher levels leads to O(N^2) performance on long messages.
696 *
697 * Since we left-justified the data above, conn->inEnd gives the
698 * amount of data already read in the current message. We consider
699 * the message "long" once we have acquired 32k ...
700 */
701 if (conn->inEnd > 32768 &&
702 (conn->inBufSize - conn->inEnd) >= 8192)
703 {
704 someread = 1;
705 goto retry3;
706 }
707 return 1;
708 }
709
710 if (someread)
711 return 1; /* got a zero read after successful tries */
712
713 /*
714 * A return value of 0 could mean just that no data is now available, or
715 * it could mean EOF --- that is, the server has closed the connection.
716 * Since we have the socket in nonblock mode, the only way to tell the
717 * difference is to see if select() is saying that the file is ready.
718 * Grumble. Fortunately, we don't expect this path to be taken much,
719 * since in normal practice we should not be trying to read data unless
720 * the file selected for reading already.
721 *
722 * In SSL mode it's even worse: SSL_read() could say WANT_READ and then
723 * data could arrive before we make the pqReadReady() test, but the second
724 * SSL_read() could still say WANT_READ because the data received was not
725 * a complete SSL record. So we must play dumb and assume there is more
726 * data, relying on the SSL layer to detect true EOF.
727 */
728
729#ifdef USE_SSL
730 if (conn->ssl_in_use)
731 return 0;
732#endif
733
734 switch (pqReadReady(conn))
735 {
736 case 0:
737 /* definitely no data available */
738 return 0;
739 case 1:
740 /* ready for read */
741 break;
742 default:
743 /* we override pqReadReady's message with something more useful */
744 goto definitelyEOF;
745 }
746
747 /*
748 * Still not sure that it's EOF, because some data could have just
749 * arrived.
750 */
751retry4:
754 if (nread < 0)
755 {
756 switch (SOCK_ERRNO)
757 {
758 case EINTR:
759 goto retry4;
760
761 /* Some systems return EAGAIN/EWOULDBLOCK for no data */
762#ifdef EAGAIN
763 case EAGAIN:
764 return 0;
765#endif
766#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
767 case EWOULDBLOCK:
768 return 0;
769#endif
770
771 /* We might get ECONNRESET etc here if connection failed */
773 goto definitelyFailed;
774
775 default:
776 /* pqsecure_read set the error message for us */
777 return -1;
778 }
779 }
780 if (nread > 0)
781 {
782 conn->inEnd += nread;
783 return 1;
784 }
785
786 /*
787 * OK, we are getting a zero read even though select() says ready. This
788 * means the connection has been closed. Cope.
789 */
790definitelyEOF:
791 libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
792 "\tThis probably means the server terminated abnormally\n"
793 "\tbefore or while processing the request.");
794
795 /* Come here if lower-level code already set a suitable errorMessage */
796definitelyFailed:
797 /* Do *not* drop any already-read data; caller still wants it */
798 pqDropConnection(conn, false);
799 conn->status = CONNECTION_BAD; /* No more connection to backend */
800 return -1;
801}
int pqReadReady(PGconn *conn)
Definition: fe-misc.c:1058
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1404
ssize_t pqsecure_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:167
#define ALL_CONNECTION_FAILURE_ERRNOS
Definition: port.h:122
#define EINTR
Definition: win32_port.h:364
#define EWOULDBLOCK
Definition: win32_port.h:370
#define EAGAIN
Definition: win32_port.h:362

References ALL_CONNECTION_FAILURE_ERRNOS, conn, CONNECTION_BAD, EAGAIN, EINTR, EWOULDBLOCK, pg_conn::inBuffer, pg_conn::inBufSize, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, libpq_append_conn_error(), PGINVALID_SOCKET, pqCheckInBufferSpace(), pqDropConnection(), pqReadReady(), pqsecure_read(), pg_conn::sock, SOCK_ERRNO, pg_conn::ssl_in_use, and pg_conn::status.

Referenced by PQcancelPoll(), PQconnectPoll(), PQconsumeInput(), pqFunctionCall3(), pqGetCopyData3(), pqGetline3(), PQgetResult(), and pqSendSome().

◆ pqReadReady()

int pqReadReady ( PGconn conn)

Definition at line 1058 of file fe-misc.c.

1059{
1060 return pqSocketCheck(conn, 1, 0, 0);
1061}
static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, pg_usec_time_t end_time)
Definition: fe-misc.c:1083

References conn, and pqSocketCheck().

Referenced by gss_read(), and pqReadData().

◆ pqReleaseConnHosts()

void pqReleaseConnHosts ( PGconn conn)

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

5153{
5154 if (conn->connhost)
5155 {
5156 for (int i = 0; i < conn->nconnhost; ++i)
5157 {
5158 free(conn->connhost[i].host);
5160 free(conn->connhost[i].port);
5161 if (conn->connhost[i].password != NULL)
5162 {
5164 strlen(conn->connhost[i].password));
5166 }
5167 }
5168 free(conn->connhost);
5169 conn->connhost = NULL;
5170 }
5171}
void explicit_bzero(void *buf, size_t len)

References conn, pg_conn::connhost, explicit_bzero(), free, pg_conn_host::host, pg_conn_host::hostaddr, i, pg_conn::nconnhost, pg_conn_host::password, and pg_conn_host::port.

Referenced by freePGconn(), and PQcancelCreate().

◆ pqResultAlloc()

void * pqResultAlloc ( PGresult res,
size_t  nBytes,
bool  isBinary 
)

Definition at line 564 of file fe-exec.c.

565{
566 char *space;
567 PGresult_data *block;
568
569 if (!res)
570 return NULL;
571
572 if (nBytes <= 0)
573 return res->null_field;
574
575 /*
576 * If alignment is needed, round up the current position to an alignment
577 * boundary.
578 */
579 if (isBinary)
580 {
581 int offset = res->curOffset % PGRESULT_ALIGN_BOUNDARY;
582
583 if (offset)
584 {
585 res->curOffset += PGRESULT_ALIGN_BOUNDARY - offset;
586 res->spaceLeft -= PGRESULT_ALIGN_BOUNDARY - offset;
587 }
588 }
589
590 /* If there's enough space in the current block, no problem. */
591 if (nBytes <= (size_t) res->spaceLeft)
592 {
593 space = res->curBlock->space + res->curOffset;
594 res->curOffset += nBytes;
595 res->spaceLeft -= nBytes;
596 return space;
597 }
598
599 /*
600 * If the requested object is very large, give it its own block; this
601 * avoids wasting what might be most of the current block to start a new
602 * block. (We'd have to special-case requests bigger than the block size
603 * anyway.) The object is always given binary alignment in this case.
604 */
605 if (nBytes >= PGRESULT_SEP_ALLOC_THRESHOLD)
606 {
607 size_t alloc_size;
608
609 /* Don't wrap around with overly large requests. */
610 if (nBytes > SIZE_MAX - PGRESULT_BLOCK_OVERHEAD)
611 return NULL;
612
613 alloc_size = nBytes + PGRESULT_BLOCK_OVERHEAD;
614 block = (PGresult_data *) malloc(alloc_size);
615 if (!block)
616 return NULL;
617 res->memorySize += alloc_size;
618 space = block->space + PGRESULT_BLOCK_OVERHEAD;
619 if (res->curBlock)
620 {
621 /*
622 * Tuck special block below the active block, so that we don't
623 * have to waste the free space in the active block.
624 */
625 block->next = res->curBlock->next;
626 res->curBlock->next = block;
627 }
628 else
629 {
630 /* Must set up the new block as the first active block. */
631 block->next = NULL;
632 res->curBlock = block;
633 res->spaceLeft = 0; /* be sure it's marked full */
634 }
635 return space;
636 }
637
638 /* Otherwise, start a new block. */
640 if (!block)
641 return NULL;
643 block->next = res->curBlock;
644 res->curBlock = block;
645 if (isBinary)
646 {
647 /* object needs full alignment */
650 }
651 else
652 {
653 /* we can cram it right after the overhead pointer */
654 res->curOffset = sizeof(PGresult_data);
656 }
657
658 space = block->space + res->curOffset;
659 res->curOffset += nBytes;
660 res->spaceLeft -= nBytes;
661 return space;
662}
#define PGRESULT_DATA_BLOCKSIZE
Definition: fe-exec.c:143
#define PGRESULT_BLOCK_OVERHEAD
Definition: fe-exec.c:145
#define PGRESULT_SEP_ALLOC_THRESHOLD
Definition: fe-exec.c:146
#define PGRESULT_ALIGN_BOUNDARY
Definition: fe-exec.c:144
union pgresult_data PGresult_data
Definition: libpq-int.h:98
size_t memorySize
Definition: libpq-int.h:209
int curOffset
Definition: libpq-int.h:206
char null_field[1]
Definition: libpq-int.h:198
int spaceLeft
Definition: libpq-int.h:207
PGresult_data * curBlock
Definition: libpq-int.h:205
PGresult_data * next
Definition: libpq-int.h:102
char space[1]
Definition: libpq-int.h:103

References pg_result::curBlock, pg_result::curOffset, malloc, pg_result::memorySize, pgresult_data::next, pg_result::null_field, PGRESULT_ALIGN_BOUNDARY, PGRESULT_BLOCK_OVERHEAD, PGRESULT_DATA_BLOCKSIZE, PGRESULT_SEP_ALLOC_THRESHOLD, pgresult_data::space, and pg_result::spaceLeft.

Referenced by getCopyStart(), getParamDescriptions(), getRowDescriptions(), pqInternalNotice(), PQresultAlloc(), pqResultStrdup(), pqRowProcessor(), pqSaveMessageField(), and PQsetvalue().

◆ pqResultStrdup()

char * pqResultStrdup ( PGresult res,
const char *  str 
)

Definition at line 681 of file fe-exec.c.

682{
683 char *space = (char *) pqResultAlloc(res, strlen(str) + 1, false);
684
685 if (space)
686 strcpy(space, str);
687 return space;
688}
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
Definition: fe-exec.c:564
const char * str

References pqResultAlloc(), and str.

Referenced by getRowDescriptions(), pqGetErrorNotice3(), PQsetResultAttrs(), and pqSetResultError().

◆ pqRowProcessor()

int pqRowProcessor ( PGconn conn,
const char **  errmsgp 
)

Definition at line 1223 of file fe-exec.c.

1224{
1225 PGresult *res = conn->result;
1226 int nfields = res->numAttributes;
1227 const PGdataValue *columns = conn->rowBuf;
1228 PGresAttValue *tup;
1229 int i;
1230
1231 /*
1232 * In partial-result mode, if we don't already have a partial PGresult
1233 * then make one by cloning conn->result (which should hold the correct
1234 * result metadata by now). Then the original conn->result is moved over
1235 * to saved_result so that we can re-use it as a reference for future
1236 * partial results. The saved result will become active again after
1237 * pqPrepareAsyncResult() returns the partial result to the application.
1238 */
1239 if (conn->partialResMode && conn->saved_result == NULL)
1240 {
1241 /* Copy everything that should be in the result at this point */
1242 res = PQcopyResult(res,
1245 if (!res)
1246 return 0;
1247 /* Change result status to appropriate special value */
1249 /* And stash it as the active result */
1251 conn->result = res;
1252 }
1253
1254 /*
1255 * Basically we just allocate space in the PGresult for each field and
1256 * copy the data over.
1257 *
1258 * Note: on malloc failure, we return 0 leaving *errmsgp still NULL, which
1259 * caller will take to mean "out of memory". This is preferable to trying
1260 * to set up such a message here, because evidently there's not enough
1261 * memory for gettext() to do anything.
1262 */
1263 tup = (PGresAttValue *)
1264 pqResultAlloc(res, nfields * sizeof(PGresAttValue), true);
1265 if (tup == NULL)
1266 return 0;
1267
1268 for (i = 0; i < nfields; i++)
1269 {
1270 int clen = columns[i].len;
1271
1272 if (clen < 0)
1273 {
1274 /* null field */
1275 tup[i].len = NULL_LEN;
1276 tup[i].value = res->null_field;
1277 }
1278 else
1279 {
1280 bool isbinary = (res->attDescs[i].format != 0);
1281 char *val;
1282
1283 val = (char *) pqResultAlloc(res, (size_t) clen + 1, isbinary);
1284 if (val == NULL)
1285 return 0;
1286
1287 /* copy and zero-terminate the data (even if it's binary) */
1288 memcpy(val, columns[i].value, clen);
1289 val[clen] = '\0';
1290
1291 tup[i].len = clen;
1292 tup[i].value = val;
1293 }
1294 }
1295
1296 /* And add the tuple to the PGresult's tuple array */
1297 if (!pqAddTuple(res, tup, errmsgp))
1298 return 0;
1299
1300 /*
1301 * Success. In partial-result mode, if we have enough rows then make the
1302 * result available to the client immediately.
1303 */
1304 if (conn->partialResMode && res->ntups >= conn->maxChunkSize)
1306
1307 return 1;
1308}
PGresult * PQcopyResult(const PGresult *src, int flags)
Definition: fe-exec.c:319
static bool pqAddTuple(PGresult *res, PGresAttValue *tup, const char **errmsgp)
Definition: fe-exec.c:999
@ PGRES_SINGLE_TUPLE
Definition: libpq-fe.h:138
#define PG_COPYRES_ATTRS
Definition: libpq-fe.h:69
#define PG_COPYRES_EVENTS
Definition: libpq-fe.h:71
#define PG_COPYRES_NOTICEHOOKS
Definition: libpq-fe.h:72
#define NULL_LEN
Definition: libpq-int.h:130
int maxChunkSize
Definition: libpq-int.h:472
bool singleRowMode
Definition: libpq-int.h:471
bool partialResMode
Definition: libpq-int.h:470
int ntups
Definition: libpq-int.h:166
PGresAttDesc * attDescs
Definition: libpq-int.h:168
int numAttributes
Definition: libpq-int.h:167
char * value
Definition: libpq-int.h:135

References pg_conn::asyncStatus, pg_result::attDescs, conn, pgresAttDesc::format, i, pgresAttValue::len, pgDataValue::len, pg_conn::maxChunkSize, pg_result::ntups, pg_result::null_field, NULL_LEN, pg_result::numAttributes, pg_conn::partialResMode, PG_COPYRES_ATTRS, PG_COPYRES_EVENTS, PG_COPYRES_NOTICEHOOKS, PGASYNC_READY_MORE, PGRES_SINGLE_TUPLE, PGRES_TUPLES_CHUNK, pqAddTuple(), PQcopyResult(), pqResultAlloc(), pg_conn::result, pg_result::resultStatus, pg_conn::rowBuf, pg_conn::saved_result, pg_conn::singleRowMode, val, value, and pgresAttValue::value.

Referenced by getAnotherTuple().

◆ pqSaveErrorResult()

void pqSaveErrorResult ( PGconn conn)

Definition at line 809 of file fe-exec.c.

810{
811 /* Drop any pending result ... */
813 /* ... and set flag to remember to make an error result later */
814 conn->error_result = true;
815}

References conn, pg_conn::error_result, and pqClearAsyncResult().

Referenced by getAnotherTuple(), getCopyResult(), getParamDescriptions(), getRowDescriptions(), handleFatalError(), pqFunctionCall3(), pqGetNegotiateProtocolVersion3(), PQgetResult(), pqParseInput3(), pqPipelineProcessQueue(), and pqSaveWriteError().

◆ pqSaveMessageField()

void void pqSaveMessageField ( PGresult res,
char  code,
const char *  value 
)

Definition at line 1066 of file fe-exec.c.

1067{
1068 PGMessageField *pfield;
1069
1070 pfield = (PGMessageField *)
1071 pqResultAlloc(res,
1072 offsetof(PGMessageField, contents) +
1073 strlen(value) + 1,
1074 true);
1075 if (!pfield)
1076 return; /* out of memory? */
1077 pfield->code = code;
1078 strcpy(pfield->contents, value);
1079 pfield->next = res->errFields;
1080 res->errFields = pfield;
1081}
struct pgMessageField * next
Definition: libpq-int.h:141
char contents[FLEXIBLE_ARRAY_MEMBER]
Definition: libpq-int.h:143

References pgMessageField::code, pgMessageField::contents, pg_result::errFields, pgMessageField::next, pqResultAlloc(), and value.

Referenced by pqGetErrorNotice3(), and pqInternalNotice().

◆ pqSaveParameterStatus()

int pqSaveParameterStatus ( PGconn conn,
const char *  name,
const char *  value 
)

Definition at line 1091 of file fe-exec.c.

1092{
1093 pgParameterStatus *pstatus;
1094 pgParameterStatus *prev;
1095
1096 /*
1097 * Forget any old information about the parameter
1098 */
1099 for (pstatus = conn->pstatus, prev = NULL;
1100 pstatus != NULL;
1101 prev = pstatus, pstatus = pstatus->next)
1102 {
1103 if (strcmp(pstatus->name, name) == 0)
1104 {
1105 if (prev)
1106 prev->next = pstatus->next;
1107 else
1108 conn->pstatus = pstatus->next;
1109 free(pstatus); /* frees name and value strings too */
1110 break;
1111 }
1112 }
1113
1114 /*
1115 * Store new info as a single malloc block
1116 */
1117 pstatus = (pgParameterStatus *) malloc(sizeof(pgParameterStatus) +
1118 strlen(name) + strlen(value) + 2);
1119 if (pstatus)
1120 {
1121 char *ptr;
1122
1123 ptr = ((char *) pstatus) + sizeof(pgParameterStatus);
1124 pstatus->name = ptr;
1125 strcpy(ptr, name);
1126 ptr += strlen(name) + 1;
1127 pstatus->value = ptr;
1128 strcpy(ptr, value);
1129 pstatus->next = conn->pstatus;
1130 conn->pstatus = pstatus;
1131 }
1132 else
1133 {
1134 /* out of memory */
1135 return 0;
1136 }
1137
1138 /*
1139 * Save values of settings that are of interest to libpq in fields of the
1140 * PGconn object. We keep client_encoding and standard_conforming_strings
1141 * in static variables as well, so that PQescapeString and PQescapeBytea
1142 * can behave somewhat sanely (at least in single-connection-using
1143 * programs).
1144 */
1145 if (strcmp(name, "client_encoding") == 0)
1146 {
1148 /* if we don't recognize the encoding name, fall back to SQL_ASCII */
1149 if (conn->client_encoding < 0)
1152 }
1153 else if (strcmp(name, "standard_conforming_strings") == 0)
1154 {
1155 conn->std_strings = (strcmp(value, "on") == 0);
1157 }
1158 else if (strcmp(name, "server_version") == 0)
1159 {
1160 /* We convert the server version to numeric form. */
1161 int cnt;
1162 int vmaj,
1163 vmin,
1164 vrev;
1165
1166 cnt = sscanf(value, "%d.%d.%d", &vmaj, &vmin, &vrev);
1167
1168 if (cnt == 3)
1169 {
1170 /* old style, e.g. 9.6.1 */
1171 conn->sversion = (100 * vmaj + vmin) * 100 + vrev;
1172 }
1173 else if (cnt == 2)
1174 {
1175 if (vmaj >= 10)
1176 {
1177 /* new style, e.g. 10.1 */
1178 conn->sversion = 100 * 100 * vmaj + vmin;
1179 }
1180 else
1181 {
1182 /* old style without minor version, e.g. 9.6devel */
1183 conn->sversion = (100 * vmaj + vmin) * 100;
1184 }
1185 }
1186 else if (cnt == 1)
1187 {
1188 /* new style without minor version, e.g. 10devel */
1189 conn->sversion = 100 * 100 * vmaj;
1190 }
1191 else
1192 conn->sversion = 0; /* unknown */
1193 }
1194 else if (strcmp(name, "default_transaction_read_only") == 0)
1195 {
1197 (strcmp(value, "on") == 0) ? PG_BOOL_YES : PG_BOOL_NO;
1198 }
1199 else if (strcmp(name, "in_hot_standby") == 0)
1200 {
1202 (strcmp(value, "on") == 0) ? PG_BOOL_YES : PG_BOOL_NO;
1203 }
1204 else if (strcmp(name, "scram_iterations") == 0)
1205 {
1207 }
1208
1209 return 1;
1210}
static bool static_std_strings
Definition: fe-exec.c:61
static int static_client_encoding
Definition: fe-exec.c:60
struct pgParameterStatus pgParameterStatus
@ PG_BOOL_YES
Definition: oauth-utils.h:74
@ PG_BOOL_NO
Definition: oauth-utils.h:75
#define pg_char_to_encoding
Definition: pg_wchar.h:629
struct pgParameterStatus * next
Definition: libpq-int.h:271
int sversion
Definition: libpq-int.h:504
pgParameterStatus * pstatus
Definition: libpq-int.h:555

References pg_conn::client_encoding, conn, pg_conn::default_transaction_read_only, free, pg_conn::in_hot_standby, malloc, name, pgParameterStatus::name, pgParameterStatus::next, PG_BOOL_NO, PG_BOOL_YES, pg_char_to_encoding, PG_SQL_ASCII, pg_conn::pstatus, pg_conn::scram_sha_256_iterations, static_client_encoding, static_std_strings, pg_conn::std_strings, pg_conn::sversion, value, and pgParameterStatus::value.

Referenced by getParameterStatus().

◆ pqsecure_close()

void pqsecure_close ( PGconn conn)

Definition at line 152 of file fe-secure.c.

153{
154#ifdef USE_SSL
156#endif
157}

References conn, and pgtls_close().

Referenced by pqDropConnection().

◆ pqsecure_open_client()

PostgresPollingStatusType pqsecure_open_client ( PGconn conn)

Definition at line 138 of file fe-secure.c.

139{
140#ifdef USE_SSL
141 return pgtls_open_client(conn);
142#else
143 /* shouldn't get here */
145#endif
146}
PostgresPollingStatusType pgtls_open_client(PGconn *conn)

References conn, PGRES_POLLING_FAILED, and pgtls_open_client().

Referenced by PQconnectPoll().

◆ pqsecure_raw_read()

ssize_t pqsecure_raw_read ( PGconn conn,
void *  ptr,
size_t  len 
)

Definition at line 193 of file fe-secure.c.

194{
195 ssize_t n;
196 int result_errno = 0;
197 char sebuf[PG_STRERROR_R_BUFLEN];
198
200
201 n = recv(conn->sock, ptr, len, 0);
202
203 if (n < 0)
204 {
205 result_errno = SOCK_ERRNO;
206
207 /* Set error message if appropriate */
208 switch (result_errno)
209 {
210#ifdef EAGAIN
211 case EAGAIN:
212#endif
213#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
214 case EWOULDBLOCK:
215#endif
216 case EINTR:
217 /* no error message, caller is expected to retry */
218 break;
219
220 case EPIPE:
221 case ECONNRESET:
222 libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
223 "\tThis probably means the server terminated abnormally\n"
224 "\tbefore or while processing the request.");
225 break;
226
227 case 0:
228 /* If errno didn't get set, treat it as regular EOF */
229 n = 0;
230 break;
231
232 default:
233 libpq_append_conn_error(conn, "could not receive data from server: %s",
234 SOCK_STRERROR(result_errno,
235 sebuf, sizeof(sebuf)));
236 break;
237 }
238 }
239
240 /* ensure we return the intended errno to caller */
241 SOCK_ERRNO_SET(result_errno);
242
243 return n;
244}
#define recv(s, buf, len, flags)
Definition: win32_port.h:504

References conn, EAGAIN, ECONNRESET, EINTR, EWOULDBLOCK, len, libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, recv, pg_conn::sock, SOCK_ERRNO, SOCK_ERRNO_SET, and SOCK_STRERROR.

Referenced by gss_read(), pg_GSS_read(), pgconn_bio_read(), and pqsecure_read().

◆ pqsecure_raw_write()

ssize_t pqsecure_raw_write ( PGconn conn,
const void *  ptr,
size_t  len 
)

Definition at line 316 of file fe-secure.c.

317{
318 ssize_t n;
319 int flags = 0;
320 int result_errno = 0;
321 char msgbuf[1024];
322 char sebuf[PG_STRERROR_R_BUFLEN];
323
324 DECLARE_SIGPIPE_INFO(spinfo);
325
326 /*
327 * If we already had a write failure, we will never again try to send data
328 * on that connection. Even if the kernel would let us, we've probably
329 * lost message boundary sync with the server. conn->write_failed
330 * therefore persists until the connection is reset, and we just discard
331 * all data presented to be written.
332 */
333 if (conn->write_failed)
334 return len;
335
336#ifdef MSG_NOSIGNAL
337 if (conn->sigpipe_flag)
338 flags |= MSG_NOSIGNAL;
339
340retry_masked:
341#endif /* MSG_NOSIGNAL */
342
343 DISABLE_SIGPIPE(conn, spinfo, return -1);
344
345 n = send(conn->sock, ptr, len, flags);
346
347 if (n < 0)
348 {
349 result_errno = SOCK_ERRNO;
350
351 /*
352 * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available
353 * on this machine. So, clear sigpipe_flag so we don't try the flag
354 * again, and retry the send().
355 */
356#ifdef MSG_NOSIGNAL
357 if (flags != 0 && result_errno == EINVAL)
358 {
359 conn->sigpipe_flag = false;
360 flags = 0;
361 goto retry_masked;
362 }
363#endif /* MSG_NOSIGNAL */
364
365 /* Set error message if appropriate */
366 switch (result_errno)
367 {
368#ifdef EAGAIN
369 case EAGAIN:
370#endif
371#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
372 case EWOULDBLOCK:
373#endif
374 case EINTR:
375 /* no error message, caller is expected to retry */
376 break;
377
378 case EPIPE:
379 /* Set flag for EPIPE */
380 REMEMBER_EPIPE(spinfo, true);
381
382 /* FALL THRU */
383
384 case ECONNRESET:
385 conn->write_failed = true;
386 /* Store error message in conn->write_err_msg, if possible */
387 /* (strdup failure is OK, we'll cope later) */
388 snprintf(msgbuf, sizeof(msgbuf),
389 libpq_gettext("server closed the connection unexpectedly\n"
390 "\tThis probably means the server terminated abnormally\n"
391 "\tbefore or while processing the request."));
392 /* keep newline out of translated string */
393 strlcat(msgbuf, "\n", sizeof(msgbuf));
394 conn->write_err_msg = strdup(msgbuf);
395 /* Now claim the write succeeded */
396 n = len;
397 break;
398
399 default:
400 conn->write_failed = true;
401 /* Store error message in conn->write_err_msg, if possible */
402 /* (strdup failure is OK, we'll cope later) */
403 snprintf(msgbuf, sizeof(msgbuf),
404 libpq_gettext("could not send data to server: %s"),
405 SOCK_STRERROR(result_errno,
406 sebuf, sizeof(sebuf)));
407 /* keep newline out of translated string */
408 strlcat(msgbuf, "\n", sizeof(msgbuf));
409 conn->write_err_msg = strdup(msgbuf);
410 /* Now claim the write succeeded */
411 n = len;
412 break;
413 }
414 }
415
416 RESTORE_SIGPIPE(conn, spinfo);
417
418 /* ensure we return the intended errno to caller */
419 SOCK_ERRNO_SET(result_errno);
420
421 return n;
422}
#define REMEMBER_EPIPE(spinfo, cond)
Definition: fe-secure.c:77
#define DISABLE_SIGPIPE(conn, spinfo, failaction)
Definition: fe-secure.c:66
#define DECLARE_SIGPIPE_INFO(spinfo)
Definition: fe-secure.c:64
#define RESTORE_SIGPIPE(conn, spinfo)
Definition: fe-secure.c:83
size_t strlcat(char *dst, const char *src, size_t siz)
Definition: strlcat.c:33
char * write_err_msg
Definition: libpq-int.h:513
bool sigpipe_flag
Definition: libpq-int.h:511
bool write_failed
Definition: libpq-int.h:512
#define send(s, buf, len, flags)
Definition: win32_port.h:505

References conn, DECLARE_SIGPIPE_INFO, DISABLE_SIGPIPE, EAGAIN, ECONNRESET, EINTR, EWOULDBLOCK, len, libpq_gettext, PG_STRERROR_R_BUFLEN, REMEMBER_EPIPE, RESTORE_SIGPIPE, send, pg_conn::sigpipe_flag, snprintf, pg_conn::sock, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, strlcat(), pg_conn::write_err_msg, and pg_conn::write_failed.

Referenced by pg_GSS_write(), pgconn_bio_write(), pqsecure_open_gss(), and pqsecure_write().

◆ pqsecure_read()

ssize_t pqsecure_read ( PGconn conn,
void *  ptr,
size_t  len 
)

Definition at line 167 of file fe-secure.c.

168{
169 ssize_t n;
170
171#ifdef USE_SSL
172 if (conn->ssl_in_use)
173 {
174 n = pgtls_read(conn, ptr, len);
175 }
176 else
177#endif
178#ifdef ENABLE_GSS
179 if (conn->gssenc)
180 {
181 n = pg_GSS_read(conn, ptr, len);
182 }
183 else
184#endif
185 {
186 n = pqsecure_raw_read(conn, ptr, len);
187 }
188
189 return n;
190}
ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len)
ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len)
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:193

References conn, len, pg_GSS_read(), pgtls_read(), pqsecure_raw_read(), and pg_conn::ssl_in_use.

Referenced by pqReadData().

◆ pqsecure_write()

ssize_t pqsecure_write ( PGconn conn,
const void *  ptr,
size_t  len 
)

Definition at line 267 of file fe-secure.c.

268{
269 ssize_t n;
270
271#ifdef USE_SSL
272 if (conn->ssl_in_use)
273 {
274 n = pgtls_write(conn, ptr, len);
275 }
276 else
277#endif
278#ifdef ENABLE_GSS
279 if (conn->gssenc)
280 {
281 n = pg_GSS_write(conn, ptr, len);
282 }
283 else
284#endif
285 {
286 n = pqsecure_raw_write(conn, ptr, len);
287 }
288
289 return n;
290}
ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len)
ssize_t pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
Definition: fe-secure.c:316

References conn, len, pg_GSS_write(), pgtls_write(), pqsecure_raw_write(), and pg_conn::ssl_in_use.

Referenced by pqSendSome().

◆ PQsendCancelRequest()

int PQsendCancelRequest ( PGconn cancelConn)

Definition at line 472 of file fe-cancel.c.

473{
475
476 /* Start the message. */
478 return STATUS_ERROR;
479
480 /* Send the message body. */
481 memset(&req, 0, offsetof(CancelRequestPacket, cancelAuthCode));
484 if (pqPutnchar(&req, offsetof(CancelRequestPacket, cancelAuthCode), cancelConn))
485 return STATUS_ERROR;
486 if (pqPutnchar(cancelConn->be_cancel_key, cancelConn->be_cancel_key_len, cancelConn))
487 return STATUS_ERROR;
488
489 /* Finish the message. */
491 return STATUS_ERROR;
492
493 /* Flush to ensure backend gets it. */
494 if (pqFlush(cancelConn))
495 return STATUS_ERROR;
496
497 return STATUS_OK;
498}
static PGcancel *volatile cancelConn
Definition: cancel.c:43
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:106
ProtocolVersion MsgType
Definition: pqcomm.h:117
MsgType cancelRequestCode
Definition: pqcomm.h:149
uint32 backendPID
Definition: pqcomm.h:150
int be_pid
Definition: fe-cancel.c:43

References CancelRequestPacket::backendPID, pg_cancel::be_pid, CANCEL_REQUEST_CODE, cancelConn, CancelRequestPacket::cancelRequestCode, pg_hton32, pqFlush(), pqPutMsgEnd(), pqPutMsgStart(), pqPutnchar(), STATUS_ERROR, and STATUS_OK.

Referenced by PQconnectPoll().

◆ PQsendQueryContinue()

int PQsendQueryContinue ( PGconn conn,
const char *  query 
)

Definition at line 1439 of file fe-exec.c.

1440{
1441 return PQsendQueryInternal(conn, query, false);
1442}
static int PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery)
Definition: fe-exec.c:1445

References conn, and PQsendQueryInternal().

Referenced by PQconnectPoll().

◆ pqSetResultError()

void pqSetResultError ( PGresult res,
PQExpBuffer  errorMessage,
int  offset 
)

Definition at line 698 of file fe-exec.c.

699{
700 char *msg;
701
702 if (!res)
703 return;
704
705 /*
706 * We handle two OOM scenarios here. The errorMessage buffer might be
707 * marked "broken" due to having previously failed to allocate enough
708 * memory for the message, or it might be fine but pqResultStrdup fails
709 * and returns NULL. In either case, just make res->errMsg point directly
710 * at a constant "out of memory" string.
711 */
712 if (!PQExpBufferBroken(errorMessage))
713 msg = pqResultStrdup(res, errorMessage->data + offset);
714 else
715 msg = NULL;
716 if (msg)
717 res->errMsg = msg;
718 else
719 res->errMsg = libpq_gettext("out of memory\n");
720}

References PQExpBufferData::data, pg_result::errMsg, libpq_gettext, PQExpBufferBroken, and pqResultStrdup().

Referenced by pqGetErrorNotice3(), PQmakeEmptyPGresult(), and pqPrepareAsyncResult().

◆ pqSkipnchar()

int pqSkipnchar ( size_t  len,
PGconn conn 
)

Definition at line 187 of file fe-misc.c.

188{
189 if (len > (size_t) (conn->inEnd - conn->inCursor))
190 return EOF;
191
192 conn->inCursor += len;
193
194 return 0;
195}

References conn, pg_conn::inCursor, pg_conn::inEnd, and len.

Referenced by getAnotherTuple().

◆ pqTraceOutputCharResponse()

void pqTraceOutputCharResponse ( PGconn conn,
const char *  responseType,
char  response 
)

Definition at line 915 of file fe-trace.c.

917{
919 {
920 char timestr[128];
921
922 pqTraceFormatTimestamp(timestr, sizeof(timestr));
923 fprintf(conn->Pfdebug, "%s\t", timestr);
924 }
925
926 fprintf(conn->Pfdebug, "B\t1\t%s\t %c\n", responseType, response);
927}
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
static void pqTraceFormatTimestamp(char *timestr, size_t ts_len)
Definition: fe-trace.c:80
#define PQTRACE_SUPPRESS_TIMESTAMPS
Definition: libpq-fe.h:478
int traceFlags
Definition: libpq-int.h:451

References conn, fprintf, pg_conn::Pfdebug, PQTRACE_SUPPRESS_TIMESTAMPS, pqTraceFormatTimestamp(), and pg_conn::traceFlags.

Referenced by PQconnectPoll().

◆ pqTraceOutputMessage()

void pqTraceOutputMessage ( PGconn conn,
const char *  message,
bool  toServer 
)

Definition at line 624 of file fe-trace.c.

625{
626 char id;
627 int length;
628 char *prefix = toServer ? "F" : "B";
629 int logCursor = 0;
630 bool regress;
631
633 {
634 char timestr[128];
635
636 pqTraceFormatTimestamp(timestr, sizeof(timestr));
637 fprintf(conn->Pfdebug, "%s\t", timestr);
638 }
639 regress = (conn->traceFlags & PQTRACE_REGRESS_MODE) != 0;
640
641 id = message[logCursor++];
642
643 memcpy(&length, message + logCursor, 4);
644 length = (int) pg_ntoh32(length);
645 logCursor += 4;
646
647 /*
648 * In regress mode, suppress the length of ErrorResponse and
649 * NoticeResponse. The F (file name), L (line number) and R (routine
650 * name) fields can change as server code is modified, and if their
651 * lengths differ from the originals, that would break tests.
652 */
653 if (regress && !toServer && (id == PqMsg_ErrorResponse || id == PqMsg_NoticeResponse))
654 fprintf(conn->Pfdebug, "%s\tNN\t", prefix);
655 else
656 fprintf(conn->Pfdebug, "%s\t%d\t", prefix, length);
657
658 switch (id)
659 {
661 fprintf(conn->Pfdebug, "ParseComplete");
662 /* No message content */
663 break;
665 fprintf(conn->Pfdebug, "BindComplete");
666 /* No message content */
667 break;
669 fprintf(conn->Pfdebug, "CloseComplete");
670 /* No message content */
671 break;
673 pqTraceOutput_NotificationResponse(conn->Pfdebug, message, &logCursor, regress);
674 break;
675 case PqMsg_Bind:
676 pqTraceOutput_Bind(conn->Pfdebug, message, &logCursor);
677 break;
678 case PqMsg_CopyDone:
679 fprintf(conn->Pfdebug, "CopyDone");
680 /* No message content */
681 break;
683 /* Close(F) and CommandComplete(B) use the same identifier. */
685 if (toServer)
686 pqTraceOutput_Close(conn->Pfdebug, message, &logCursor);
687 else
688 pqTraceOutput_CommandComplete(conn->Pfdebug, message, &logCursor);
689 break;
690 case PqMsg_CopyData:
691 pqTraceOutput_CopyData(conn->Pfdebug, message, &logCursor,
692 length, regress);
693 break;
694 case PqMsg_Describe:
695 /* Describe(F) and DataRow(B) use the same identifier. */
697 if (toServer)
698 pqTraceOutput_Describe(conn->Pfdebug, message, &logCursor);
699 else
700 pqTraceOutput_DataRow(conn->Pfdebug, message, &logCursor);
701 break;
702 case PqMsg_Execute:
703 /* Execute(F) and ErrorResponse(B) use the same identifier. */
705 if (toServer)
706 pqTraceOutput_Execute(conn->Pfdebug, message, &logCursor, regress);
707 else
708 pqTraceOutput_ErrorResponse(conn->Pfdebug, message, &logCursor, regress);
709 break;
710 case PqMsg_CopyFail:
711 pqTraceOutput_CopyFail(conn->Pfdebug, message, &logCursor);
712 break;
717
718 /*
719 * These messages share a common type byte, so we discriminate by
720 * having the code store the auth type separately.
721 */
723 {
726 &logCursor, length, regress);
727 break;
730 &logCursor);
731 break;
734 &logCursor, regress);
735 break;
738 &logCursor, length, regress);
739 break;
740 default:
741 fprintf(conn->Pfdebug, "UnknownAuthenticationResponse");
742 break;
743 }
745 break;
747 pqTraceOutput_FunctionCall(conn->Pfdebug, message, &logCursor, regress);
748 break;
750 pqTraceOutput_CopyInResponse(conn->Pfdebug, message, &logCursor);
751 break;
752 case PqMsg_Flush:
753 /* Flush(F) and CopyOutResponse(B) use the same identifier */
755 if (toServer)
756 fprintf(conn->Pfdebug, "Flush"); /* no message content */
757 else
758 pqTraceOutput_CopyOutResponse(conn->Pfdebug, message, &logCursor);
759 break;
761 fprintf(conn->Pfdebug, "EmptyQueryResponse");
762 /* No message content */
763 break;
765 pqTraceOutput_BackendKeyData(conn->Pfdebug, message, &logCursor, regress);
766 break;
767 case PqMsg_NoData:
768 fprintf(conn->Pfdebug, "NoData");
769 /* No message content */
770 break;
772 pqTraceOutput_NoticeResponse(conn->Pfdebug, message, &logCursor, regress);
773 break;
774 case PqMsg_Parse:
775 pqTraceOutput_Parse(conn->Pfdebug, message, &logCursor, regress);
776 break;
777 case PqMsg_Query:
778 pqTraceOutput_Query(conn->Pfdebug, message, &logCursor);
779 break;
781 pqTraceOutput_Authentication(conn->Pfdebug, message, &logCursor,
782 length, regress);
783 break;
785 fprintf(conn->Pfdebug, "PortalSuspended");
786 /* No message content */
787 break;
788 case PqMsg_Sync:
789 /* ParameterStatus(B) and Sync(F) use the same identifier */
791 if (toServer)
792 fprintf(conn->Pfdebug, "Sync"); /* no message content */
793 else
794 pqTraceOutput_ParameterStatus(conn->Pfdebug, message, &logCursor);
795 break;
797 pqTraceOutput_ParameterDescription(conn->Pfdebug, message, &logCursor, regress);
798 break;
800 pqTraceOutput_RowDescription(conn->Pfdebug, message, &logCursor, regress);
801 break;
804 break;
806 pqTraceOutput_FunctionCallResponse(conn->Pfdebug, message, &logCursor);
807 break;
809 pqTraceOutput_CopyBothResponse(conn->Pfdebug, message, &logCursor, length);
810 break;
811 case PqMsg_Terminate:
812 fprintf(conn->Pfdebug, "Terminate");
813 /* No message content */
814 break;
816 pqTraceOutput_ReadyForQuery(conn->Pfdebug, message, &logCursor);
817 break;
818 default:
819 fprintf(conn->Pfdebug, "Unknown message: %02x", id);
820 break;
821 }
822
823 fputc('\n', conn->Pfdebug);
824
825 /*
826 * Verify the printing routine did it right. Note that the one-byte
827 * message identifier is not included in the length, but our cursor does
828 * include it.
829 */
830 if (logCursor - 1 != length)
832 "mismatched message length: consumed %d, expected %d\n",
833 logCursor - 1, length);
834}
static void pqTraceOutput_RowDescription(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:559
static void pqTraceOutput_GSSResponse(FILE *f, const char *message, int *cursor, int length, bool regress)
Definition: fe-trace.c:367
static void pqTraceOutput_FunctionCall(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:403
static void pqTraceOutput_CopyInResponse(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:429
static void pqTraceOutput_BackendKeyData(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:455
static void pqTraceOutput_Authentication(FILE *f, const char *message, int *cursor, int length, bool suppress)
Definition: fe-trace.c:484
static void pqTraceOutput_Parse(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:463
static void pqTraceOutput_NoticeResponse(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:346
static void pqTraceOutput_ParameterDescription(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:547
static void pqTraceOutput_DataRow(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:293
static void pqTraceOutput_SASLResponse(FILE *f, const char *message, int *cursor, int length, bool regress)
Definition: fe-trace.c:395
static void pqTraceOutput_Query(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:477
static void pqTraceOutput_CopyData(FILE *f, const char *message, int *cursor, int length, bool suppress)
Definition: fe-trace.c:285
static void pqTraceOutput_SASLInitialResponse(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:382
static void pqTraceOutput_NegotiateProtocolVersion(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:579
static void pqTraceOutput_CopyBothResponse(FILE *f, const char *message, int *cursor, int length)
Definition: fe-trace.c:604
static void pqTraceOutput_Bind(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:240
static void pqTraceOutput_ErrorResponse(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:340
static void pqTraceOutput_Close(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:270
static void pqTraceOutput_Describe(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:311
static void pqTraceOutput_NotificationResponse(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:231
static void pqTraceOutput_CommandComplete(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:278
static void pqTraceOutput_ParameterStatus(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:539
static void pqTraceOutput_Execute(FILE *f, const char *message, int *cursor, bool regress)
Definition: fe-trace.c:352
static void pqTraceOutput_CopyOutResponse(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:442
static void pqTraceOutput_ReadyForQuery(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:614
static void pqTraceOutput_CopyFail(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:360
static void pqTraceOutput_PasswordMessage(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:375
static void pqTraceOutput_FunctionCallResponse(FILE *f, const char *message, int *cursor)
Definition: fe-trace.c:593
#define PQTRACE_REGRESS_MODE
Definition: libpq-fe.h:480
#define AUTH_RESPONSE_PASSWORD
Definition: libpq-int.h:336
#define AUTH_RESPONSE_SASL
Definition: libpq-int.h:338
#define AUTH_RESPONSE_SASL_INITIAL
Definition: libpq-int.h:337
#define AUTH_RESPONSE_GSS
Definition: libpq-int.h:335
#define PqMsg_GSSResponse
Definition: protocol.h:30
#define PqMsg_SASLResponse
Definition: protocol.h:33
#define PqMsg_Describe
Definition: protocol.h:21
#define PqMsg_SASLInitialResponse
Definition: protocol.h:32
#define PqMsg_AuthenticationRequest
Definition: protocol.h:50
#define PqMsg_NegotiateProtocolVersion
Definition: protocol.h:59
#define PqMsg_PortalSuspended
Definition: protocol.h:57
#define PqMsg_Parse
Definition: protocol.h:25
#define PqMsg_Bind
Definition: protocol.h:19
#define PqMsg_PasswordMessage
Definition: protocol.h:31
#define PqMsg_CopyFail
Definition: protocol.h:29
#define PqMsg_Flush
Definition: protocol.h:24
#define PqMsg_Query
Definition: protocol.h:26
#define PqMsg_Terminate
Definition: protocol.h:28
#define PqMsg_Execute
Definition: protocol.h:22
#define PqMsg_Close
Definition: protocol.h:20
char current_auth_response
Definition: libpq-int.h:523

References Assert(), AUTH_RESPONSE_GSS, AUTH_RESPONSE_PASSWORD, AUTH_RESPONSE_SASL, AUTH_RESPONSE_SASL_INITIAL, conn, pg_conn::current_auth_response, fprintf, pg_conn::Pfdebug, pg_ntoh32, PqMsg_AuthenticationRequest, PqMsg_BackendKeyData, PqMsg_Bind, PqMsg_BindComplete, PqMsg_Close, PqMsg_CloseComplete, PqMsg_CommandComplete, PqMsg_CopyBothResponse, PqMsg_CopyData, PqMsg_CopyDone, PqMsg_CopyFail, PqMsg_CopyInResponse, PqMsg_CopyOutResponse, PqMsg_DataRow, PqMsg_Describe, PqMsg_EmptyQueryResponse, PqMsg_ErrorResponse, PqMsg_Execute, PqMsg_Flush, PqMsg_FunctionCall, PqMsg_FunctionCallResponse, PqMsg_GSSResponse, PqMsg_NegotiateProtocolVersion, PqMsg_NoData, PqMsg_NoticeResponse, PqMsg_NotificationResponse, PqMsg_ParameterDescription, PqMsg_ParameterStatus, PqMsg_Parse, PqMsg_ParseComplete, PqMsg_PasswordMessage, PqMsg_PortalSuspended, PqMsg_Query, PqMsg_ReadyForQuery, PqMsg_RowDescription, PqMsg_SASLInitialResponse, PqMsg_SASLResponse, PqMsg_Sync, PqMsg_Terminate, PQTRACE_REGRESS_MODE, PQTRACE_SUPPRESS_TIMESTAMPS, pqTraceFormatTimestamp(), pqTraceOutput_Authentication(), pqTraceOutput_BackendKeyData(), pqTraceOutput_Bind(), pqTraceOutput_Close(), pqTraceOutput_CommandComplete(), pqTraceOutput_CopyBothResponse(), pqTraceOutput_CopyData(), pqTraceOutput_CopyFail(), pqTraceOutput_CopyInResponse(), pqTraceOutput_CopyOutResponse(), pqTraceOutput_DataRow(), pqTraceOutput_Describe(), pqTraceOutput_ErrorResponse(), pqTraceOutput_Execute(), pqTraceOutput_FunctionCall(), pqTraceOutput_FunctionCallResponse(), pqTraceOutput_GSSResponse(), pqTraceOutput_NegotiateProtocolVersion(), pqTraceOutput_NoticeResponse(), pqTraceOutput_NotificationResponse(), pqTraceOutput_ParameterDescription(), pqTraceOutput_ParameterStatus(), pqTraceOutput_Parse(), pqTraceOutput_PasswordMessage(), pqTraceOutput_Query(), pqTraceOutput_ReadyForQuery(), pqTraceOutput_RowDescription(), pqTraceOutput_SASLInitialResponse(), pqTraceOutput_SASLResponse(), and pg_conn::traceFlags.

Referenced by pg_password_sendauth(), pg_SASL_continue(), pg_SASL_init(), pqParseDone(), and pqPutMsgEnd().

◆ pqTraceOutputNoTypeByteMessage()

void pqTraceOutputNoTypeByteMessage ( PGconn conn,
const char *  message 
)

Definition at line 841 of file fe-trace.c.

842{
843 int length;
844 int version;
845 bool regress;
846 int logCursor = 0;
847
848 regress = (conn->traceFlags & PQTRACE_REGRESS_MODE) != 0;
849
851 {
852 char timestr[128];
853
854 pqTraceFormatTimestamp(timestr, sizeof(timestr));
855 fprintf(conn->Pfdebug, "%s\t", timestr);
856 }
857
858 memcpy(&length, message + logCursor, 4);
859 length = (int) pg_ntoh32(length);
860 logCursor += 4;
861
862 fprintf(conn->Pfdebug, "F\t%d\t", length);
863
864 if (length < 8)
865 {
866 fprintf(conn->Pfdebug, "Unknown message\n");
867 return;
868 }
869
870 memcpy(&version, message + logCursor, 4);
871 version = (int) pg_ntoh32(version);
872
873 if (version == CANCEL_REQUEST_CODE && length >= 16)
874 {
875 fprintf(conn->Pfdebug, "CancelRequest\t");
876 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
877 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
878 pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, regress);
879 pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, regress);
880 }
881 else if (version == NEGOTIATE_SSL_CODE)
882 {
883 fprintf(conn->Pfdebug, "SSLRequest\t");
884 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
885 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
886 }
887 else if (version == NEGOTIATE_GSS_CODE)
888 {
889 fprintf(conn->Pfdebug, "GSSENCRequest\t");
890 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
891 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
892 }
893 else
894 {
895 fprintf(conn->Pfdebug, "StartupMessage\t");
896 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
897 pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
898 while (message[logCursor] != '\0')
899 {
900 /* XXX should we suppress anything in regress mode? */
901 pqTraceOutputString(conn->Pfdebug, message, &logCursor, false);
902 pqTraceOutputString(conn->Pfdebug, message, &logCursor, false);
903 }
904 }
905
906 fputc('\n', conn->Pfdebug);
907}
static void pqTraceOutputString(FILE *pfdebug, const char *data, int *cursor, bool suppress)
Definition: fe-trace.c:166
static int pqTraceOutputInt16(FILE *pfdebug, const char *data, int *cursor)
Definition: fe-trace.c:126
static int pqTraceOutputInt32(FILE *pfdebug, const char *data, int *cursor, bool suppress)
Definition: fe-trace.c:145
#define NEGOTIATE_GSS_CODE
Definition: pqcomm.h:113
#define NEGOTIATE_SSL_CODE
Definition: pqcomm.h:112

References CANCEL_REQUEST_CODE, conn, fprintf, NEGOTIATE_GSS_CODE, NEGOTIATE_SSL_CODE, pg_conn::Pfdebug, pg_ntoh32, PQTRACE_REGRESS_MODE, PQTRACE_SUPPRESS_TIMESTAMPS, pqTraceFormatTimestamp(), pqTraceOutputInt16(), pqTraceOutputInt32(), pqTraceOutputString(), and pg_conn::traceFlags.

Referenced by pqPutMsgEnd().

◆ pqWait()

int pqWait ( int  forRead,
int  forWrite,
PGconn conn 
)

Definition at line 1019 of file fe-misc.c.

1020{
1021 return pqWaitTimed(forRead, forWrite, conn, -1);
1022}

References conn, and pqWaitTimed().

Referenced by pqFunctionCall3(), pqGetCopyData3(), pqGetline3(), PQgetResult(), and pqSendSome().

◆ pqWaitTimed()

int pqWaitTimed ( int  forRead,
int  forWrite,
PGconn conn,
pg_usec_time_t  end_time 
)

Definition at line 1035 of file fe-misc.c.

1036{
1037 int result;
1038
1039 result = pqSocketCheck(conn, forRead, forWrite, end_time);
1040
1041 if (result < 0)
1042 return -1; /* errorMessage is already set */
1043
1044 if (result == 0)
1045 {
1046 libpq_append_conn_error(conn, "timeout expired");
1047 return 1;
1048 }
1049
1050 return 0;
1051}

References conn, end_time, libpq_append_conn_error(), and pqSocketCheck().

Referenced by pqConnectDBComplete(), and pqWait().

◆ pqWriteReady()

int pqWriteReady ( PGconn conn)

Definition at line 1068 of file fe-misc.c.

1069{
1070 return pqSocketCheck(conn, 0, 1, 0);
1071}

References conn, and pqSocketCheck().

Variable Documentation

◆ pg_g_threadlock

pgthreadlock_t pg_g_threadlock
extern

Definition at line 35 of file oauth-utils.c.

Referenced by libpq_oauth_init(), and PQregisterThreadLock().

◆ pgresStatus

char* const pgresStatus[]
extern

Definition at line 33 of file fe-exec.c.

Referenced by PQresStatus().