PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 }
 
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)
 
void 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 (char *s, size_t len, PGconn *conn)
 
int pqSkipnchar (size_t len, PGconn *conn)
 
int pqPutnchar (const char *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 938 of file libpq-int.h.

◆ libpq_ngettext

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

Definition at line 939 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 932 of file libpq-int.h.

◆ pgHavePendingResult

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

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

◆ pglock_thread

#define pglock_thread ( )    pg_g_threadlock(true)

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

◆ pgunlock_thread

#define pgunlock_thread ( )    pg_g_threadlock(false)

Definition at line 733 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 911 of file libpq-int.h.

◆ pqIsnonblocking

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

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

◆ SOCK_ERRNO

#define SOCK_ERRNO   errno

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

◆ SOCK_ERRNO_SET

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

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

◆ SOCK_STRERROR

#define SOCK_STRERROR   strerror_r

Definition at line 960 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 

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 1498 of file fe-secure-openssl.c.

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

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}
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1381
#define malloc(a)
Definition: header.h:50
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:960
#define SOCK_ERRNO
Definition: libpq-int.h:959
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:961
#define PG_STRERROR_R_BUFLEN
Definition: port.h:257
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
PQExpBufferData errorMessage
Definition: libpq-int.h:671
#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:478
pg_conn_host * connhost
Definition: libpq-int.h:479
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 504 of file fe-secure.c.

505{
506 sigset_t sigpipe_sigset;
507 sigset_t sigset;
508
509 sigemptyset(&sigpipe_sigset);
510 sigaddset(&sigpipe_sigset, SIGPIPE);
511
512 /* Block SIGPIPE and save previous mask for later reset */
513 SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
514 if (SOCK_ERRNO)
515 return -1;
516
517 /* We can have a pending SIGPIPE only if it was blocked before */
518 if (sigismember(osigset, SIGPIPE))
519 {
520 /* Is there a pending SIGPIPE? */
521 if (sigpending(&sigset) != 0)
522 return -1;
523
524 if (sigismember(&sigset, SIGPIPE))
525 *sigpipe_pending = true;
526 else
527 *sigpipe_pending = false;
528 }
529 else
530 *sigpipe_pending = false;
531
532 return 0;
533}
#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 554 of file fe-secure.c.

555{
556 int save_errno = SOCK_ERRNO;
557 int signo;
558 sigset_t sigset;
559
560 /* Clear SIGPIPE only if none was pending */
561 if (got_epipe && !sigpipe_pending)
562 {
563 if (sigpending(&sigset) == 0 &&
564 sigismember(&sigset, SIGPIPE))
565 {
566 sigset_t sigpipe_sigset;
567
568 sigemptyset(&sigpipe_sigset);
569 sigaddset(&sigpipe_sigset, SIGPIPE);
570
571 sigwait(&sigpipe_sigset, &signo);
572 }
573 }
574
575 /* Restore saved block mask */
576 pthread_sigmask(SIG_SETMASK, osigset, NULL);
577
578 SOCK_ERRNO_SET(save_errno);
579}

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 1010 of file fe-protocol3.c.

1012{
1013 const char *val;
1014 const char *querytext = NULL;
1015 int querypos = 0;
1016
1017 /* If we couldn't allocate a PGresult, just say "out of memory" */
1018 if (res == NULL)
1019 {
1020 appendPQExpBufferStr(msg, libpq_gettext("out of memory\n"));
1021 return;
1022 }
1023
1024 /*
1025 * If we don't have any broken-down fields, just return the base message.
1026 * This mainly applies if we're given a libpq-generated error result.
1027 */
1028 if (res->errFields == NULL)
1029 {
1030 if (res->errMsg && res->errMsg[0])
1031 appendPQExpBufferStr(msg, res->errMsg);
1032 else
1033 appendPQExpBufferStr(msg, libpq_gettext("no error message available\n"));
1034 return;
1035 }
1036
1037 /* Else build error message from relevant fields */
1039 if (val)
1040 appendPQExpBuffer(msg, "%s: ", val);
1041
1042 if (verbosity == PQERRORS_SQLSTATE)
1043 {
1044 /*
1045 * If we have a SQLSTATE, print that and nothing else. If not (which
1046 * shouldn't happen for server-generated errors, but might possibly
1047 * happen for libpq-generated ones), fall back to TERSE format, as
1048 * that seems better than printing nothing at all.
1049 */
1051 if (val)
1052 {
1053 appendPQExpBuffer(msg, "%s\n", val);
1054 return;
1055 }
1056 verbosity = PQERRORS_TERSE;
1057 }
1058
1059 if (verbosity == PQERRORS_VERBOSE)
1060 {
1062 if (val)
1063 appendPQExpBuffer(msg, "%s: ", val);
1064 }
1066 if (val)
1069 if (val)
1070 {
1071 if (verbosity != PQERRORS_TERSE && res->errQuery != NULL)
1072 {
1073 /* emit position as a syntax cursor display */
1074 querytext = res->errQuery;
1075 querypos = atoi(val);
1076 }
1077 else
1078 {
1079 /* emit position as text addition to primary message */
1080 /* translator: %s represents a digit string */
1081 appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1082 val);
1083 }
1084 }
1085 else
1086 {
1088 if (val)
1089 {
1091 if (verbosity != PQERRORS_TERSE && querytext != NULL)
1092 {
1093 /* emit position as a syntax cursor display */
1094 querypos = atoi(val);
1095 }
1096 else
1097 {
1098 /* emit position as text addition to primary message */
1099 /* translator: %s represents a digit string */
1100 appendPQExpBuffer(msg, libpq_gettext(" at character %s"),
1101 val);
1102 }
1103 }
1104 }
1105 appendPQExpBufferChar(msg, '\n');
1106 if (verbosity != PQERRORS_TERSE)
1107 {
1108 if (querytext && querypos > 0)
1109 reportErrorPosition(msg, querytext, querypos,
1110 res->client_encoding);
1112 if (val)
1113 appendPQExpBuffer(msg, libpq_gettext("DETAIL: %s\n"), val);
1115 if (val)
1116 appendPQExpBuffer(msg, libpq_gettext("HINT: %s\n"), val);
1118 if (val)
1119 appendPQExpBuffer(msg, libpq_gettext("QUERY: %s\n"), val);
1120 if (show_context == PQSHOW_CONTEXT_ALWAYS ||
1121 (show_context == PQSHOW_CONTEXT_ERRORS &&
1123 {
1125 if (val)
1126 appendPQExpBuffer(msg, libpq_gettext("CONTEXT: %s\n"),
1127 val);
1128 }
1129 }
1130 if (verbosity == PQERRORS_VERBOSE)
1131 {
1133 if (val)
1135 libpq_gettext("SCHEMA NAME: %s\n"), val);
1137 if (val)
1139 libpq_gettext("TABLE NAME: %s\n"), val);
1141 if (val)
1143 libpq_gettext("COLUMN NAME: %s\n"), val);
1145 if (val)
1147 libpq_gettext("DATATYPE NAME: %s\n"), val);
1149 if (val)
1151 libpq_gettext("CONSTRAINT NAME: %s\n"), val);
1152 }
1153 if (verbosity == PQERRORS_VERBOSE)
1154 {
1155 const char *valf;
1156 const char *vall;
1157
1161 if (val || valf || vall)
1162 {
1163 appendPQExpBufferStr(msg, libpq_gettext("LOCATION: "));
1164 if (val)
1165 appendPQExpBuffer(msg, libpq_gettext("%s, "), val);
1166 if (valf && vall) /* unlikely we'd have just one */
1167 appendPQExpBuffer(msg, libpq_gettext("%s:%s"),
1168 valf, vall);
1169 appendPQExpBufferChar(msg, '\n');
1170 }
1171 }
1172}
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3466
static void reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding)
long val
Definition: informix.c:689
@ 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: libpq-int.h:938
#define PG_DIAG_INTERNAL_QUERY
Definition: postgres_ext.h:58
#define PG_DIAG_SCHEMA_NAME
Definition: postgres_ext.h:60
#define PG_DIAG_CONSTRAINT_NAME
Definition: postgres_ext.h:64
#define PG_DIAG_DATATYPE_NAME
Definition: postgres_ext.h:63
#define PG_DIAG_SOURCE_LINE
Definition: postgres_ext.h:66
#define PG_DIAG_STATEMENT_POSITION
Definition: postgres_ext.h:56
#define PG_DIAG_SOURCE_FILE
Definition: postgres_ext.h:65
#define PG_DIAG_MESSAGE_HINT
Definition: postgres_ext.h:55
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:52
#define PG_DIAG_TABLE_NAME
Definition: postgres_ext.h:61
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:53
#define PG_DIAG_COLUMN_NAME
Definition: postgres_ext.h:62
#define PG_DIAG_MESSAGE_DETAIL
Definition: postgres_ext.h:54
#define PG_DIAG_CONTEXT
Definition: postgres_ext.h:59
#define PG_DIAG_SEVERITY
Definition: postgres_ext.h:50
#define PG_DIAG_SOURCE_FUNCTION
Definition: postgres_ext.h:67
#define PG_DIAG_INTERNAL_POSITION
Definition: postgres_ext.h:57
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 2313 of file fe-protocol3.c.

2315{
2316 char *startpacket;
2317
2318 *packetlen = build_startup_packet(conn, NULL, options);
2319 startpacket = (char *) malloc(*packetlen);
2320 if (!startpacket)
2321 return NULL;
2322 *packetlen = build_startup_packet(conn, startpacket, options);
2323 return startpacket;
2324}
static int build_startup_packet(const PGconn *conn, char *packet, const PQEnvironmentOption *options)

References build_startup_packet(), conn, 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:564
int inCursor
Definition: libpq-int.h:567
int inEnd
Definition: libpq-int.h:568
int inBufSize
Definition: libpq-int.h:565
int inStart
Definition: libpq-int.h:566

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:572
char * outBuffer
Definition: libpq-int.h:571

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 779 of file fe-exec.c.

780{
782 conn->result = NULL;
783 conn->error_result = false;
785 conn->saved_result = NULL;
786}
void PQclear(PGresult *res)
Definition: fe-exec.c:721
PGresult * result
Definition: libpq-int.h:594
PGresult * saved_result
Definition: libpq-int.h:596
bool error_result
Definition: libpq-int.h:595

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 5243 of file fe-connect.c.

5244{
5245 /*
5246 * If possible, send Terminate message to close the connection politely.
5247 */
5249
5250 /*
5251 * Must reset the blocking status so a possible reconnect will work.
5252 *
5253 * Don't call PQsetnonblocking() because it will fail if it's unable to
5254 * flush the connection.
5255 */
5256 conn->nonblocking = false;
5257
5258 /*
5259 * Close the connection, reset all transient state, flush I/O buffers.
5260 * Note that this includes clearing conn's error state; we're no longer
5261 * interested in any failures associated with the old connection, and we
5262 * want a clean slate for any new connection attempt.
5263 */
5264 pqDropConnection(conn, true);
5265 conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just absent */
5270 pqClearAsyncResult(conn); /* deallocate result */
5272
5273 /*
5274 * Release addrinfo, but since cancel requests never change their addrinfo
5275 * we don't do that. Otherwise we would have to rebuild it during a
5276 * PQcancelReset.
5277 */
5278 if (!conn->cancelRequest)
5280
5281 /* Reset all state obtained from server, too */
5283}
void pqClearOAuthToken(PGconn *conn)
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:520
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:5209
static void release_conn_addrinfo(PGconn *conn)
Definition: fe-connect.c:5195
static void pqDropServerData(PGconn *conn)
Definition: fe-connect.c:646
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:779
@ 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:911
PGTransactionStatusType xactStatus
Definition: libpq-int.h:461
bool cancelRequest
Definition: libpq-int.h:431
bool nonblocking
Definition: libpq-int.h:464
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:460
PGpipelineStatus pipelineStatus
Definition: libpq-int.h:466
ConnStatusType status
Definition: libpq-int.h:459

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 3142 of file fe-exec.c.

3143{
3144 PGcmdQueueEntry *prevquery;
3145
3146 if (conn->cmd_queue_head == NULL)
3147 return;
3148
3149 /*
3150 * If processing a query of simple query protocol, we only advance the
3151 * queue when we receive the ReadyForQuery message for it.
3152 */
3153 if (conn->cmd_queue_head->queryclass == PGQUERY_SIMPLE && !isReadyForQuery)
3154 return;
3155
3156 /*
3157 * If we're waiting for a SYNC, don't advance the queue until we get one.
3158 */
3159 if (conn->cmd_queue_head->queryclass == PGQUERY_SYNC && !gotSync)
3160 return;
3161
3162 /* delink element from queue */
3163 prevquery = conn->cmd_queue_head;
3165
3166 /* If the queue is now empty, reset the tail too */
3167 if (conn->cmd_queue_head == NULL)
3168 conn->cmd_queue_tail = NULL;
3169
3170 /* and make the queue element recyclable */
3171 prevquery->next = NULL;
3172 pqRecycleCmdQueueEntry(conn, prevquery);
3173}
static void pqRecycleCmdQueueEntry(PGconn *conn, PGcmdQueueEntry *entry)
Definition: fe-exec.c:1386
PGQueryClass queryclass
Definition: libpq-int.h:345
struct PGcmdQueueEntry * next
Definition: libpq-int.h:347
PGcmdQueueEntry * cmd_queue_tail
Definition: libpq-int.h:487
PGcmdQueueEntry * cmd_queue_head
Definition: libpq-int.h:486

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 2779 of file fe-connect.c.

2780{
2783 int timeout = 0;
2784 int last_whichhost = -2; /* certainly different from whichhost */
2785 int last_whichaddr = -2; /* certainly different from whichaddr */
2786
2787 if (conn == NULL || conn->status == CONNECTION_BAD)
2788 return 0;
2789
2790 /*
2791 * Set up a time limit, if connect_timeout is greater than zero.
2792 */
2793 if (conn->connect_timeout != NULL)
2794 {
2795 if (!pqParseIntParam(conn->connect_timeout, &timeout, conn,
2796 "connect_timeout"))
2797 {
2798 /* mark the connection as bad to report the parsing failure */
2800 return 0;
2801 }
2802 }
2803
2804 for (;;)
2805 {
2806 int ret = 0;
2807
2808 /*
2809 * (Re)start the connect_timeout timer if it's active and we are
2810 * considering a different host than we were last time through. If
2811 * we've already succeeded, though, needn't recalculate.
2812 */
2813 if (flag != PGRES_POLLING_OK &&
2814 timeout > 0 &&
2815 (conn->whichhost != last_whichhost ||
2816 conn->whichaddr != last_whichaddr))
2817 {
2818 end_time = PQgetCurrentTimeUSec() + (pg_usec_time_t) timeout * 1000000;
2819 last_whichhost = conn->whichhost;
2820 last_whichaddr = conn->whichaddr;
2821 }
2822
2823 /*
2824 * Wait, if necessary. Note that the initial state (just after
2825 * PQconnectStart) is to wait for the socket to select for writing.
2826 */
2827 switch (flag)
2828 {
2829 case PGRES_POLLING_OK:
2830 return 1; /* success! */
2831
2833 ret = pqWaitTimed(1, 0, conn, end_time);
2834 if (ret == -1)
2835 {
2836 /* hard failure, eg select() problem, aborts everything */
2838 return 0;
2839 }
2840 break;
2841
2843 ret = pqWaitTimed(0, 1, conn, end_time);
2844 if (ret == -1)
2845 {
2846 /* hard failure, eg select() problem, aborts everything */
2848 return 0;
2849 }
2850 break;
2851
2852 default:
2853 /* Just in case we failed to set it in PQconnectPoll */
2855 return 0;
2856 }
2857
2858 if (ret == 1) /* connect_timeout elapsed */
2859 {
2860 /*
2861 * Give up on current server/address, try the next one.
2862 */
2863 conn->try_next_addr = true;
2865 }
2866
2867 /*
2868 * Now try to advance the state machine.
2869 */
2870 if (conn->cancelRequest)
2872 else
2874 }
2875}
PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn)
Definition: fe-cancel.c:225
PostgresPollingStatusType PQconnectPoll(PGconn *conn)
Definition: fe-connect.c:2905
bool pqParseIntParam(const char *value, int *result, PGconn *conn, const char *context)
Definition: fe-connect.c:8177
pg_usec_time_t PQgetCurrentTimeUSec(void)
Definition: fe-misc.c:1209
int pqWaitTimed(int forRead, int forWrite, PGconn *conn, pg_usec_time_t end_time)
Definition: fe-misc.c:1009
@ CONNECTION_NEEDED
Definition: libpq-fe.h:100
int64_t pg_usec_time_t
Definition: libpq-fe.h:241
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:537
char * connect_timeout
Definition: libpq-int.h:383
bool try_next_addr
Definition: libpq-int.h:534
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 2701 of file fe-connect.c.

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

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 1240 of file fe-connect.c.

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

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 1025 of file fe-connect.c.

1026{
1028
1029 /* copy over connection options */
1030 for (option = PQconninfoOptions; option->keyword; option++)
1031 {
1032 if (option->connofs >= 0)
1033 {
1034 const char **tmp = (const char **) ((char *) srcConn + option->connofs);
1035
1036 if (*tmp)
1037 {
1038 char **dstConnmember = (char **) ((char *) dstConn + option->connofs);
1039
1040 if (*dstConnmember)
1041 free(*dstConnmember);
1042 *dstConnmember = strdup(*tmp);
1043 if (*dstConnmember == NULL)
1044 {
1045 libpq_append_conn_error(dstConn, "out of memory");
1046 return false;
1047 }
1048 }
1049 }
1050 }
1051 return true;
1052}
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:193

References free, libpq_append_conn_error(), and PQconninfoOptions.

Referenced by PQcancelCreate().

◆ pqDropConnection()

void pqDropConnection ( PGconn conn,
bool  flushInput 
)

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

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

◆ pqEndcopy3()

int pqEndcopy3 ( PGconn conn)

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

1991{
1992 PGresult *result;
1993
1997 {
1998 libpq_append_conn_error(conn, "no COPY in progress");
1999 return 1;
2000 }
2001
2002 /* Send the CopyDone message if needed */
2005 {
2006 if (pqPutMsgStart(PqMsg_CopyDone, conn) < 0 ||
2007 pqPutMsgEnd(conn) < 0)
2008 return 1;
2009
2010 /*
2011 * If we sent the COPY command in extended-query mode, we must issue a
2012 * Sync as well.
2013 */
2014 if (conn->cmd_queue_head &&
2016 {
2017 if (pqPutMsgStart(PqMsg_Sync, conn) < 0 ||
2018 pqPutMsgEnd(conn) < 0)
2019 return 1;
2020 }
2021 }
2022
2023 /*
2024 * make sure no data is waiting to be sent, abort if we are non-blocking
2025 * and the flush fails
2026 */
2028 return 1;
2029
2030 /* Return to active duty */
2032
2033 /*
2034 * Non blocking connections may have to abort at this point. If everyone
2035 * played the game there should be no problem, but in error scenarios the
2036 * expected messages may not have arrived yet. (We are assuming that the
2037 * backend's packetizing will ensure that CommandComplete arrives along
2038 * with the CopyDone; are there corner cases where that doesn't happen?)
2039 */
2041 return 1;
2042
2043 /* Wait for the completion response */
2044 result = PQgetResult(conn);
2045
2046 /* Expecting a successful result */
2047 if (result && result->resultStatus == PGRES_COMMAND_OK)
2048 {
2049 PQclear(result);
2050 return 0;
2051 }
2052
2053 /*
2054 * Trouble. For backwards-compatibility reasons, we issue the error
2055 * message as if it were a notice (would be nice to get rid of this
2056 * silliness, but too many apps probably don't handle errors from
2057 * PQendcopy reasonably). Note that the app can still obtain the error
2058 * status from the PGconn object.
2059 */
2060 if (conn->errorMessage.len > 0)
2061 {
2062 /* We have to strip the trailing newline ... pain in neck... */
2063 char svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
2064
2065 if (svLast == '\n')
2066 conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
2068 conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
2069 }
2070
2071 PQclear(result);
2072
2073 return 1;
2074}
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:2062
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:938
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:2031
int pqFlush(PGconn *conn)
Definition: fe-misc.c:968
int pqPutMsgStart(char msg_type, PGconn *conn)
Definition: fe-misc.c:473
int pqPutMsgEnd(PGconn *conn)
Definition: fe-misc.c:532
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:125
#define pqIsnonblocking(conn)
Definition: libpq-int.h:927
#define PqMsg_CopyDone
Definition: protocol.h:64
#define PqMsg_Sync
Definition: protocol.h:27
PGNoticeHooks noticeHooks
Definition: libpq-int.h:451

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)

◆ 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 2083 of file fe-protocol3.c.

2087{
2088 bool needInput = false;
2090 char id;
2091 int msgLength;
2092 int avail;
2093 int i;
2094
2095 /* already validated by PQfn */
2097
2098 /* PQfn already validated connection state */
2099
2101 pqPutInt(fnid, 4, conn) < 0 || /* function id */
2102 pqPutInt(1, 2, conn) < 0 || /* # of format codes */
2103 pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */
2104 pqPutInt(nargs, 2, conn) < 0) /* # of args */
2105 {
2106 /* error message should be set up already */
2107 return NULL;
2108 }
2109
2110 for (i = 0; i < nargs; ++i)
2111 { /* len.int4 + contents */
2112 if (pqPutInt(args[i].len, 4, conn))
2113 return NULL;
2114 if (args[i].len == -1)
2115 continue; /* it's NULL */
2116
2117 if (args[i].isint)
2118 {
2119 if (pqPutInt(args[i].u.integer, args[i].len, conn))
2120 return NULL;
2121 }
2122 else
2123 {
2124 if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))
2125 return NULL;
2126 }
2127 }
2128
2129 if (pqPutInt(1, 2, conn) < 0) /* result format code: BINARY */
2130 return NULL;
2131
2132 if (pqPutMsgEnd(conn) < 0 ||
2133 pqFlush(conn))
2134 return NULL;
2135
2136 for (;;)
2137 {
2138 if (needInput)
2139 {
2140 /* Wait for some data to arrive (or for the channel to close) */
2141 if (pqWait(true, false, conn) ||
2142 pqReadData(conn) < 0)
2143 break;
2144 }
2145
2146 /*
2147 * Scan the message. If we run out of data, loop around to try again.
2148 */
2149 needInput = true;
2150
2152 if (pqGetc(&id, conn))
2153 continue;
2154 if (pqGetInt(&msgLength, 4, conn))
2155 continue;
2156
2157 /*
2158 * Try to validate message type/length here. A length less than 4 is
2159 * definitely broken. Large lengths should only be believed for a few
2160 * message types.
2161 */
2162 if (msgLength < 4)
2163 {
2164 handleSyncLoss(conn, id, msgLength);
2165 break;
2166 }
2167 if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
2168 {
2169 handleSyncLoss(conn, id, msgLength);
2170 break;
2171 }
2172
2173 /*
2174 * Can't process if message body isn't all here yet.
2175 */
2176 msgLength -= 4;
2177 avail = conn->inEnd - conn->inCursor;
2178 if (avail < msgLength)
2179 {
2180 /*
2181 * Before looping, enlarge the input buffer if needed to hold the
2182 * whole message. See notes in parseInput.
2183 */
2184 if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
2185 conn))
2186 {
2187 /*
2188 * XXX add some better recovery code... plan is to skip over
2189 * the message using its length, then report an error. For the
2190 * moment, just treat this like loss of sync (which indeed it
2191 * might be!)
2192 */
2193 handleSyncLoss(conn, id, msgLength);
2194 break;
2195 }
2196 continue;
2197 }
2198
2199 /*
2200 * We should see V or E response to the command, but might get N
2201 * and/or A notices first. We also need to swallow the final Z before
2202 * returning.
2203 */
2204 switch (id)
2205 {
2206 case 'V': /* function result */
2207 if (pqGetInt(actual_result_len, 4, conn))
2208 continue;
2209 if (*actual_result_len != -1)
2210 {
2211 if (result_is_int)
2212 {
2213 if (pqGetInt(result_buf, *actual_result_len, conn))
2214 continue;
2215 }
2216 else
2217 {
2218 if (pqGetnchar((char *) result_buf,
2219 *actual_result_len,
2220 conn))
2221 continue;
2222 }
2223 }
2224 /* correctly finished function result message */
2225 status = PGRES_COMMAND_OK;
2226 break;
2227 case 'E': /* error return */
2228 if (pqGetErrorNotice3(conn, true))
2229 continue;
2230 status = PGRES_FATAL_ERROR;
2231 break;
2232 case 'A': /* notify message */
2233 /* handle notify and go back to processing return values */
2234 if (getNotify(conn))
2235 continue;
2236 break;
2237 case 'N': /* notice */
2238 /* handle notice and go back to processing return values */
2239 if (pqGetErrorNotice3(conn, false))
2240 continue;
2241 break;
2242 case 'Z': /* backend is ready for new query */
2244 continue;
2245
2246 /* consume the message */
2247 pqParseDone(conn, conn->inStart + 5 + msgLength);
2248
2249 /*
2250 * If we already have a result object (probably an error), use
2251 * that. Otherwise, if we saw a function result message,
2252 * report COMMAND_OK. Otherwise, the backend violated the
2253 * protocol, so complain.
2254 */
2256 {
2257 if (status == PGRES_COMMAND_OK)
2258 {
2259 conn->result = PQmakeEmptyPGresult(conn, status);
2260 if (!conn->result)
2261 {
2262 libpq_append_conn_error(conn, "out of memory");
2264 }
2265 }
2266 else
2267 {
2268 libpq_append_conn_error(conn, "protocol error: no function result");
2270 }
2271 }
2272 /* and we're out */
2273 return pqPrepareAsyncResult(conn);
2274 case 'S': /* parameter status */
2276 continue;
2277 break;
2278 default:
2279 /* The backend violates the protocol. */
2280 libpq_append_conn_error(conn, "protocol error: id=0x%x", id);
2282
2283 /*
2284 * We can't call parsing done due to the protocol violation
2285 * (so message tracing wouldn't work), but trust the specified
2286 * message length as what to skip.
2287 */
2288 conn->inStart += 5 + msgLength;
2289 return pqPrepareAsyncResult(conn);
2290 }
2291
2292 /* Completed parsing this message, keep going */
2293 pqParseDone(conn, conn->inStart + 5 + msgLength);
2294 needInput = false;
2295 }
2296
2297 /*
2298 * We fall out of the loop only upon failing to read data.
2299 * conn->errorMessage has been set by pqWait or pqReadData. We want to
2300 * append it to any already-received error message.
2301 */
2303 return pqPrepareAsyncResult(conn);
2304}
PGresult * pqPrepareAsyncResult(PGconn *conn)
Definition: fe-exec.c:851
void pqSaveErrorResult(PGconn *conn)
Definition: fe-exec.c:803
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:159
int pqReadData(PGconn *conn)
Definition: fe-misc.c:580
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 pqGetnchar(char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:165
int pqWait(int forRead, int forWrite, PGconn *conn)
Definition: fe-misc.c:993
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:351
int pqPutnchar(const char *s, size_t len, PGconn *conn)
Definition: fe-misc.c:202
static int getNotify(PGconn *conn)
static int getParameterStatus(PGconn *conn)
#define VALID_LONG_MESSAGE_TYPE(id)
Definition: fe-protocol3.c:36
static void handleSyncLoss(PGconn *conn, char id, int msgLength)
Definition: fe-protocol3.c:478
static int getReadyForQuery(PGconn *conn)
int pqGetErrorNotice3(PGconn *conn, bool isError)
Definition: fe-protocol3.c:878
ExecStatusType
Definition: libpq-fe.h:123
#define pgHavePendingResult(conn)
Definition: libpq-int.h:920
#define PqMsg_FunctionCall
Definition: protocol.h:23

References generate_unaccent_rules::args, Assert(), conn, getNotify(), getParameterStatus(), getReadyForQuery(), 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_FunctionCall, 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 1825 of file fe-protocol3.c.

1826{
1827 int msgLength;
1828
1829 for (;;)
1830 {
1831 /*
1832 * Collect the next input message. To make life simpler for async
1833 * callers, we keep returning 0 until the next message is fully
1834 * available, even if it is not Copy Data.
1835 */
1836 msgLength = getCopyDataMessage(conn);
1837 if (msgLength < 0)
1838 return msgLength; /* end-of-copy or error */
1839 if (msgLength == 0)
1840 {
1841 /* Don't block if async read requested */
1842 if (async)
1843 return 0;
1844 /* Need to load more data */
1845 if (pqWait(true, false, conn) ||
1846 pqReadData(conn) < 0)
1847 return -2;
1848 continue;
1849 }
1850
1851 /*
1852 * Drop zero-length messages (shouldn't happen anyway). Otherwise
1853 * pass the data back to the caller.
1854 */
1855 msgLength -= 4;
1856 if (msgLength > 0)
1857 {
1858 *buffer = (char *) malloc(msgLength + 1);
1859 if (*buffer == NULL)
1860 {
1861 libpq_append_conn_error(conn, "out of memory");
1862 return -2;
1863 }
1864 memcpy(*buffer, &conn->inBuffer[conn->inCursor], msgLength);
1865 (*buffer)[msgLength] = '\0'; /* Add terminating null */
1866
1867 /* Mark message consumed */
1868 pqParseDone(conn, conn->inCursor + msgLength);
1869
1870 return msgLength;
1871 }
1872
1873 /* Empty, so drop it and loop around for another */
1875 }
1876}
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 878 of file fe-protocol3.c.

879{
880 PGresult *res = NULL;
881 bool have_position = false;
882 PQExpBufferData workBuf;
883 char id;
884
885 /* If in pipeline mode, set error indicator for it */
886 if (isError && conn->pipelineStatus != PQ_PIPELINE_OFF)
888
889 /*
890 * If this is an error message, pre-emptively clear any incomplete query
891 * result we may have. We'd just throw it away below anyway, and
892 * releasing it before collecting the error might avoid out-of-memory.
893 */
894 if (isError)
896
897 /*
898 * Since the fields might be pretty long, we create a temporary
899 * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended
900 * for stuff that is expected to be short. We shouldn't use
901 * conn->errorMessage either, since this might be only a notice.
902 */
903 initPQExpBuffer(&workBuf);
904
905 /*
906 * Make a PGresult to hold the accumulated fields. We temporarily lie
907 * about the result status, so that PQmakeEmptyPGresult doesn't uselessly
908 * copy conn->errorMessage.
909 *
910 * NB: This allocation can fail, if you run out of memory. The rest of the
911 * function handles that gracefully, and we still try to set the error
912 * message as the connection's error message.
913 */
915 if (res)
917
918 /*
919 * Read the fields and save into res.
920 *
921 * While at it, save the SQLSTATE in conn->last_sqlstate, and note whether
922 * we saw a PG_DIAG_STATEMENT_POSITION field.
923 */
924 for (;;)
925 {
926 if (pqGetc(&id, conn))
927 goto fail;
928 if (id == '\0')
929 break; /* terminator found */
930 if (pqGets(&workBuf, conn))
931 goto fail;
932 pqSaveMessageField(res, id, workBuf.data);
933 if (id == PG_DIAG_SQLSTATE)
934 strlcpy(conn->last_sqlstate, workBuf.data,
935 sizeof(conn->last_sqlstate));
936 else if (id == PG_DIAG_STATEMENT_POSITION)
937 have_position = true;
938 }
939
940 /*
941 * Save the active query text, if any, into res as well; but only if we
942 * might need it for an error cursor display, which is only true if there
943 * is a PG_DIAG_STATEMENT_POSITION field.
944 */
945 if (have_position && res && conn->cmd_queue_head && conn->cmd_queue_head->query)
947
948 /*
949 * Now build the "overall" error message for PQresultErrorMessage.
950 */
951 resetPQExpBuffer(&workBuf);
953
954 /*
955 * Either save error as current async result, or just emit the notice.
956 */
957 if (isError)
958 {
959 pqClearAsyncResult(conn); /* redundant, but be safe */
960 if (res)
961 {
962 pqSetResultError(res, &workBuf, 0);
963 conn->result = res;
964 }
965 else
966 {
967 /* Fall back to using the internal-error processing paths */
968 conn->error_result = true;
969 }
970
971 if (PQExpBufferDataBroken(workBuf))
972 libpq_append_conn_error(conn, "out of memory");
973 else
975 }
976 else
977 {
978 /* if we couldn't allocate the result set, just discard the NOTICE */
979 if (res)
980 {
981 /*
982 * We can cheat a little here and not copy the message. But if we
983 * were unlucky enough to run out of memory while filling workBuf,
984 * insert "out of memory", as in pqSetResultError.
985 */
986 if (PQExpBufferDataBroken(workBuf))
987 res->errMsg = libpq_gettext("out of memory\n");
988 else
989 res->errMsg = workBuf.data;
990 if (res->noticeHooks.noticeRec != NULL)
992 PQclear(res);
993 }
994 }
995
996 termPQExpBuffer(&workBuf);
997 return 0;
998
999fail:
1000 PQclear(res);
1001 termPQExpBuffer(&workBuf);
1002 return EOF;
1003}
void pqSaveMessageField(PGresult *res, char code, const char *value)
Definition: fe-exec.c:1060
void pqSetResultError(PGresult *res, PQExpBuffer errorMessage, int offset)
Definition: fe-exec.c:692
char * pqResultStrdup(PGresult *res, const char *str)
Definition: fe-exec.c:675
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:557
char last_sqlstate[6]
Definition: libpq-int.h:462
PGContextVisibility show_context
Definition: libpq-int.h:558
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 8136 of file fe-connect.c.

8137{
8138#ifndef WIN32
8139 const char *home;
8140
8141 home = getenv("HOME");
8142 if (home && home[0])
8143 {
8144 strlcpy(buf, home, bufsize);
8145 return true;
8146 }
8147 else
8148 {
8149 struct passwd pwbuf;
8150 struct passwd *pw;
8151 char tmpbuf[1024];
8152 int rc;
8153
8154 rc = getpwuid_r(geteuid(), &pwbuf, tmpbuf, sizeof tmpbuf, &pw);
8155 if (rc != 0 || !pw)
8156 return false;
8157 strlcpy(buf, pw->pw_dir, bufsize);
8158 return true;
8159 }
8160#else
8161 char tmppath[MAX_PATH];
8162
8163 ZeroMemory(tmppath, sizeof(tmppath));
8164 if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
8165 return false;
8166 snprintf(buf, bufsize, "%s/postgresql", tmppath);
8167 return true;
8168#endif
8169}
#define bufsize
Definition: indent_globs.h:36
static char * buf
Definition: pg_test_fsync.c:72
static StringInfoData tmpbuf
Definition: walsender.c:175

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:501
#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 1884 of file fe-protocol3.c.

1885{
1886 int status;
1887
1888 if (conn->sock == PGINVALID_SOCKET ||
1892 {
1893 libpq_append_conn_error(conn, "PQgetline: not doing text COPY OUT");
1894 *s = '\0';
1895 return EOF;
1896 }
1897
1898 while ((status = PQgetlineAsync(conn, s, maxlen - 1)) == 0)
1899 {
1900 /* need to load more data */
1901 if (pqWait(true, false, conn) ||
1902 pqReadData(conn) < 0)
1903 {
1904 *s = '\0';
1905 return EOF;
1906 }
1907 }
1908
1909 if (status < 0)
1910 {
1911 /* End of copy detected; gin up old-style terminator */
1912 strcpy(s, "\\.");
1913 return 0;
1914 }
1915
1916 /* Add null terminator, and strip trailing \n if present */
1917 if (s[status - 1] == '\n')
1918 {
1919 s[status - 1] = '\0';
1920 return 0;
1921 }
1922 else
1923 {
1924 s[status] = '\0';
1925 return 1;
1926 }
1927}
int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize)
Definition: fe-exec.c:2901
char copy_is_binary
Definition: libpq-int.h:471

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 1935 of file fe-protocol3.c.

1936{
1937 int msgLength;
1938 int avail;
1939
1942 return -1; /* we are not doing a copy... */
1943
1944 /*
1945 * Recognize the next input message. To make life simpler for async
1946 * callers, we keep returning 0 until the next message is fully available
1947 * even if it is not Copy Data. This should keep PQendcopy from blocking.
1948 * (Note: unlike pqGetCopyData3, we do not change asyncStatus here.)
1949 */
1950 msgLength = getCopyDataMessage(conn);
1951 if (msgLength < 0)
1952 return -1; /* end-of-copy or error */
1953 if (msgLength == 0)
1954 return 0; /* no data yet */
1955
1956 /*
1957 * Move data from libpq's buffer to the caller's. In the case where a
1958 * prior call found the caller's buffer too small, we use
1959 * conn->copy_already_done to remember how much of the row was already
1960 * returned to the caller.
1961 */
1963 avail = msgLength - 4 - conn->copy_already_done;
1964 if (avail <= bufsize)
1965 {
1966 /* Able to consume the whole message */
1967 memcpy(buffer, &conn->inBuffer[conn->inCursor], avail);
1968 /* Mark message consumed */
1969 conn->inStart = conn->inCursor + avail;
1970 /* Reset state for next time */
1972 return avail;
1973 }
1974 else
1975 {
1976 /* We must return a partial message */
1977 memcpy(buffer, &conn->inBuffer[conn->inCursor], bufsize);
1978 /* The message is NOT consumed from libpq's buffer */
1980 return bufsize;
1981 }
1982}
int copy_already_done
Definition: libpq-int.h:472

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 ( char *  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 1410 of file fe-protocol3.c.

1411{
1412 int their_version;
1413 int num;
1414
1415 if (pqGetInt(&their_version, 4, conn) != 0)
1416 goto eof;
1417
1418 if (pqGetInt(&num, 4, conn) != 0)
1419 goto eof;
1420
1421 /* Check the protocol version */
1422 if (their_version > conn->pversion)
1423 {
1424 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested downgrade to a higher-numbered version");
1425 goto failure;
1426 }
1427
1428 if (their_version < PG_PROTOCOL(3, 0))
1429 {
1430 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested downgrade to pre-3.0 protocol version");
1431 goto failure;
1432 }
1433
1434 /* 3.1 never existed, we went straight from 3.0 to 3.2 */
1435 if (their_version == PG_PROTOCOL(3, 1))
1436 {
1437 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requests downgrade to non-existent 3.1 protocol version");
1438 goto failure;
1439 }
1440
1441 if (num < 0)
1442 {
1443 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported negative number of unsupported parameters");
1444 goto failure;
1445 }
1446
1447 if (their_version == conn->pversion && num == 0)
1448 {
1449 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server negotiated but asks for no changes");
1450 goto failure;
1451 }
1452
1453 if (their_version < conn->min_pversion)
1454 {
1455 libpq_append_conn_error(conn, "server only supports protocol version %d.%d, but min_protocol_version was set to %d.%d",
1456 PG_PROTOCOL_MAJOR(their_version),
1457 PG_PROTOCOL_MINOR(their_version),
1460
1461 goto failure;
1462 }
1463
1464 /* the version is acceptable */
1465 conn->pversion = their_version;
1466
1467 /*
1468 * We don't currently request any protocol extensions, so we don't expect
1469 * the server to reply with any either.
1470 */
1471 for (int i = 0; i < num; i++)
1472 {
1473 if (pqGets(&conn->workBuffer, conn))
1474 {
1475 goto eof;
1476 }
1477 if (strncmp(conn->workBuffer.data, "_pq_.", 5) != 0)
1478 {
1479 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported unsupported parameter name without a _pq_. prefix (\"%s\")", conn->workBuffer.data);
1480 goto failure;
1481 }
1482 libpq_append_conn_error(conn, "received invalid protocol negotiation message: server reported an unsupported parameter that was not requested (\"%s\")", conn->workBuffer.data);
1483 goto failure;
1484 }
1485
1486 return 0;
1487
1488eof:
1489 libpq_append_conn_error(conn, "received invalid protocol negotation message: message too short");
1490failure:
1493 return 1;
1494}
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:87
#define PG_PROTOCOL_MINOR(v)
Definition: pqcomm.h:88
ProtocolVersion pversion
Definition: libpq-int.h:500
PQExpBufferData workBuffer
Definition: libpq-int.h:675

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 4937 of file fe-connect.c.

4938{
4939 PGconn *conn;
4940
4941#ifdef WIN32
4942
4943 /*
4944 * Make sure socket support is up and running in this process.
4945 *
4946 * Note: the Windows documentation says that we should eventually do a
4947 * matching WSACleanup() call, but experience suggests that that is at
4948 * least as likely to cause problems as fix them. So we don't.
4949 */
4950 static bool wsastartup_done = false;
4951
4952 if (!wsastartup_done)
4953 {
4954 WSADATA wsaData;
4955
4956 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
4957 return NULL;
4958 wsastartup_done = true;
4959 }
4960
4961 /* Forget any earlier error */
4962 WSASetLastError(0);
4963#endif /* WIN32 */
4964
4965 conn = (PGconn *) malloc(sizeof(PGconn));
4966 if (conn == NULL)
4967 return conn;
4968
4969 /* Zero all pointers and booleans */
4970 MemSet(conn, 0, sizeof(PGconn));
4971
4972 /* install default notice hooks */
4975
4980 conn->options_valid = false;
4981 conn->nonblocking = false;
4983 conn->std_strings = false; /* unless server says differently */
4991 conn->Pfdebug = NULL;
4992
4993 /*
4994 * We try to send at least 8K at a time, which is the usual size of pipe
4995 * buffers on Unix systems. That way, when we are sending a large amount
4996 * of data, we avoid incurring extra kernel context swaps for partial
4997 * bufferloads. The output buffer is initially made 16K in size, and we
4998 * try to dump it after accumulating 8K.
4999 *
5000 * With the same goal of minimizing context swaps, the input buffer will
5001 * be enlarged anytime it has less than 8K free, so we initially allocate
5002 * twice that.
5003 */
5004 conn->inBufSize = 16 * 1024;
5005 conn->inBuffer = (char *) malloc(conn->inBufSize);
5006 conn->outBufSize = 16 * 1024;
5007 conn->outBuffer = (char *) malloc(conn->outBufSize);
5008 conn->rowBufLen = 32;
5012
5013 if (conn->inBuffer == NULL ||
5014 conn->outBuffer == NULL ||
5015 conn->rowBuf == NULL ||
5018 {
5019 /* out of memory already :-( */
5021 conn = NULL;
5022 }
5023
5024 return conn;
5025}
#define MemSet(start, val, len)
Definition: c.h:991
static void defaultNoticeReceiver(void *arg, const PGresult *res)
Definition: fe-connect.c:7823
static void defaultNoticeProcessor(void *arg, const char *message)
Definition: fe-connect.c:7838
static void freePGconn(PGconn *conn)
Definition: fe-connect.c:5037
@ PQERRORS_DEFAULT
Definition: libpq-fe.h:157
@ 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:581
bool std_strings
Definition: libpq-int.h:554
PGTernaryBool in_hot_standby
Definition: libpq-int.h:556
int client_encoding
Definition: libpq-int.h:553
PGTernaryBool default_transaction_read_only
Definition: libpq-int.h:555
int rowBufLen
Definition: libpq-int.h:582
int scram_sha_256_iterations
Definition: libpq-int.h:601

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 5398 of file fe-connect.c.

5400{
5401 /* Start the message. */
5402 if (pqPutMsgStart(pack_type, conn))
5403 return STATUS_ERROR;
5404
5405 /* Send the message body. */
5406 if (pqPutnchar(buf, buf_len, conn))
5407 return STATUS_ERROR;
5408
5409 /* Finish the message. */
5410 if (pqPutMsgEnd(conn))
5411 return STATUS_ERROR;
5412
5413 /* Flush to ensure backend gets it. */
5414 if (pqFlush(conn))
5415 return STATUS_ERROR;
5416
5417 return STATUS_OK;
5418}
#define STATUS_OK
Definition: c.h:1140
#define STATUS_ERROR
Definition: c.h:1141

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 67 of file fe-protocol3.c.

68{
69 char id;
70 int msgLength;
71 int avail;
72
73 /*
74 * Loop to parse successive complete messages available in the buffer.
75 */
76 for (;;)
77 {
78 /*
79 * Try to read a message. First get the type code and length. Return
80 * if not enough data.
81 */
83 if (pqGetc(&id, conn))
84 return;
85 if (pqGetInt(&msgLength, 4, conn))
86 return;
87
88 /*
89 * Try to validate message type/length here. A length less than 4 is
90 * definitely broken. Large lengths should only be believed for a few
91 * message types.
92 */
93 if (msgLength < 4)
94 {
95 handleSyncLoss(conn, id, msgLength);
96 return;
97 }
98 if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id))
99 {
100 handleSyncLoss(conn, id, msgLength);
101 return;
102 }
103
104 /*
105 * Can't process if message body isn't all here yet.
106 */
107 msgLength -= 4;
108 avail = conn->inEnd - conn->inCursor;
109 if (avail < msgLength)
110 {
111 /*
112 * Before returning, enlarge the input buffer if needed to hold
113 * the whole message. This is better than leaving it to
114 * pqReadData because we can avoid multiple cycles of realloc()
115 * when the message is large; also, we can implement a reasonable
116 * recovery strategy if we are unable to make the buffer big
117 * enough.
118 */
119 if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
120 conn))
121 {
122 /*
123 * XXX add some better recovery code... plan is to skip over
124 * the message using its length, then report an error. For the
125 * moment, just treat this like loss of sync (which indeed it
126 * might be!)
127 */
128 handleSyncLoss(conn, id, msgLength);
129 }
130 return;
131 }
132
133 /*
134 * NOTIFY and NOTICE messages can happen in any state; always process
135 * them right away.
136 *
137 * Most other messages should only be processed while in BUSY state.
138 * (In particular, in READY state we hold off further parsing until
139 * the application collects the current PGresult.)
140 *
141 * However, if the state is IDLE then we got trouble; we need to deal
142 * with the unexpected message somehow.
143 *
144 * ParameterStatus ('S') messages are a special case: in IDLE state we
145 * must process 'em (this case could happen if a new value was adopted
146 * from config file due to SIGHUP), but otherwise we hold off until
147 * BUSY state.
148 */
150 {
151 if (getNotify(conn))
152 return;
153 }
154 else if (id == PqMsg_NoticeResponse)
155 {
156 if (pqGetErrorNotice3(conn, false))
157 return;
158 }
159 else if (conn->asyncStatus != PGASYNC_BUSY)
160 {
161 /* If not IDLE state, just wait ... */
163 return;
164
165 /*
166 * Unexpected message in IDLE state; need to recover somehow.
167 * ERROR messages are handled using the notice processor;
168 * ParameterStatus is handled normally; anything else is just
169 * dropped on the floor after displaying a suitable warning
170 * notice. (An ERROR is very possibly the backend telling us why
171 * it is about to close the connection, so we don't want to just
172 * discard it...)
173 */
174 if (id == PqMsg_ErrorResponse)
175 {
176 if (pqGetErrorNotice3(conn, false /* treat as notice */ ))
177 return;
178 }
179 else if (id == PqMsg_ParameterStatus)
180 {
182 return;
183 }
184 else
185 {
186 /* Any other case is unexpected and we summarily skip it */
188 "message type 0x%02x arrived from server while idle",
189 id);
190 /* Discard the unexpected message */
191 conn->inCursor += msgLength;
192 }
193 }
194 else
195 {
196 /*
197 * In BUSY state, we can process everything.
198 */
199 switch (id)
200 {
202 if (pqGets(&conn->workBuffer, conn))
203 return;
205 {
208 if (!conn->result)
209 {
210 libpq_append_conn_error(conn, "out of memory");
212 }
213 }
214 if (conn->result)
218 break;
220 if (pqGetErrorNotice3(conn, true))
221 return;
223 break;
226 return;
228 {
231 if (!conn->result)
232 {
233 libpq_append_conn_error(conn, "out of memory");
235 }
236 else
237 {
240 }
241 }
242 else
243 {
244 /* Advance the command queue and set us idle */
245 pqCommandQueueAdvance(conn, true, false);
247 }
248 break;
251 {
254 if (!conn->result)
255 {
256 libpq_append_conn_error(conn, "out of memory");
258 }
259 }
261 break;
263 /* If we're doing PQprepare, we're done; else ignore */
264 if (conn->cmd_queue_head &&
266 {
268 {
271 if (!conn->result)
272 {
273 libpq_append_conn_error(conn, "out of memory");
275 }
276 }
278 }
279 break;
281 /* Nothing to do for this message type */
282 break;
284 /* If we're doing PQsendClose, we're done; else ignore */
285 if (conn->cmd_queue_head &&
287 {
289 {
292 if (!conn->result)
293 {
294 libpq_append_conn_error(conn, "out of memory");
296 }
297 }
299 }
300 break;
303 return;
304 break;
306
307 /*
308 * This is expected only during backend startup, but it's
309 * just as easy to handle it as part of the main loop.
310 * Save the data and continue processing.
311 */
312 if (getBackendKeyData(conn, msgLength))
313 return;
314 break;
316 if (conn->error_result ||
317 (conn->result != NULL &&
319 {
320 /*
321 * We've already choked for some reason. Just discard
322 * the data till we get to the end of the query.
323 */
324 conn->inCursor += msgLength;
325 }
326 else if (conn->result == NULL ||
329 {
330 /* First 'T' in a query sequence */
331 if (getRowDescriptions(conn, msgLength))
332 return;
333 }
334 else
335 {
336 /*
337 * A new 'T' message is treated as the start of
338 * another PGresult. (It is not clear that this is
339 * really possible with the current backend.) We stop
340 * parsing until the application accepts the current
341 * result.
342 */
344 return;
345 }
346 break;
347 case PqMsg_NoData:
348
349 /*
350 * NoData indicates that we will not be seeing a
351 * RowDescription message because the statement or portal
352 * inquired about doesn't return rows.
353 *
354 * If we're doing a Describe, we have to pass something
355 * back to the client, so set up a COMMAND_OK result,
356 * instead of PGRES_TUPLES_OK. Otherwise we can just
357 * ignore this message.
358 */
359 if (conn->cmd_queue_head &&
361 {
363 {
366 if (!conn->result)
367 {
368 libpq_append_conn_error(conn, "out of memory");
370 }
371 }
373 }
374 break;
376 if (getParamDescriptions(conn, msgLength))
377 return;
378 break;
379 case PqMsg_DataRow:
380 if (conn->result != NULL &&
383 {
384 /* Read another tuple of a normal query response */
385 if (getAnotherTuple(conn, msgLength))
386 return;
387 }
388 else if (conn->error_result ||
389 (conn->result != NULL &&
391 {
392 /*
393 * We've already choked for some reason. Just discard
394 * tuples till we get to the end of the query.
395 */
396 conn->inCursor += msgLength;
397 }
398 else
399 {
400 /* Set up to report error at end of query */
401 libpq_append_conn_error(conn, "server sent data (\"D\" message) without prior row description (\"T\" message)");
403 /* Discard the unexpected message */
404 conn->inCursor += msgLength;
405 }
406 break;
409 return;
411 break;
414 return;
417 break;
420 return;
423 break;
424 case PqMsg_CopyData:
425
426 /*
427 * If we see Copy Data, just silently drop it. This would
428 * only occur if application exits COPY OUT mode too
429 * early.
430 */
431 conn->inCursor += msgLength;
432 break;
433 case PqMsg_CopyDone:
434
435 /*
436 * If we see Copy Done, just silently drop it. This is
437 * the normal case during PQendcopy. We will keep
438 * swallowing data, expecting to see command-complete for
439 * the COPY command.
440 */
441 break;
442 default:
443 libpq_append_conn_error(conn, "unexpected response from server; first received character was \"%c\"", id);
444 /* build an error result holding the error message */
446 /* not sure if we will see more, so go to ready state */
448 /* Discard the unexpected message */
449 conn->inCursor += msgLength;
450 break;
451 } /* switch on protocol character */
452 }
453 /* Successfully consumed this message */
454 if (conn->inCursor == conn->inStart + 5 + msgLength)
455 {
456 /* Normal case: parsing agrees with specified length */
458 }
459 else
460 {
461 /* Trouble --- report it */
462 libpq_append_conn_error(conn, "message contents do not agree with length in message type \"%c\"", id);
463 /* build an error result holding the error message */
466 /* trust the specified message length as what to skip */
467 conn->inStart += 5 + msgLength;
468 }
469 }
470}
void pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery, bool gotSync)
Definition: fe-exec.c:3142
static int getAnotherTuple(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:757
static int getRowDescriptions(PGconn *conn, int msgLength)
Definition: fe-protocol3.c:498
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:669
@ 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_NotificationResponse
Definition: protocol.h:41
#define PqMsg_BindComplete
Definition: protocol.h:39
#define PqMsg_CopyData
Definition: protocol.h:65
#define PqMsg_ParameterDescription
Definition: protocol.h:58
#define PqMsg_ReadyForQuery
Definition: protocol.h:55
#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_ParameterStatus
Definition: protocol.h:51
#define PqMsg_NoData
Definition: protocol.h:56
#define PqMsg_BackendKeyData
Definition: protocol.h:48
#define PqMsg_CommandComplete
Definition: protocol.h:42
#define PqMsg_ErrorResponse
Definition: protocol.h:44
#define PqMsg_DataRow
Definition: protocol.h:43
#define PqMsg_NoticeResponse
Definition: protocol.h:49
#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, pg_conn::copy_already_done, PQExpBufferData::data, pg_conn::error_result, getAnotherTuple(), getBackendKeyData(), getCopyStart(), getNotify(), getParamDescriptions(), getParameterStatus(), getReadyForQuery(), getRowDescriptions(), 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, 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 8177 of file fe-connect.c.

8179{
8180 char *end;
8181 long numval;
8182
8183 Assert(value != NULL);
8184
8185 *result = 0;
8186
8187 /* strtol(3) skips leading whitespaces */
8188 errno = 0;
8189 numval = strtol(value, &end, 10);
8190
8191 /*
8192 * If no progress was done during the parsing or an error happened, fail.
8193 * This tests properly for overflows of the result.
8194 */
8195 if (value == end || errno != 0 || numval != (int) numval)
8196 goto error;
8197
8198 /*
8199 * Skip any trailing whitespace; if anything but whitespace remains before
8200 * the terminating character, fail
8201 */
8202 while (*end != '\0' && isspace((unsigned char) *end))
8203 end++;
8204
8205 if (*end != '\0')
8206 goto error;
8207
8208 *result = numval;
8209 return true;
8210
8211error:
8212 libpq_append_conn_error(conn, "invalid integer value \"%s\" for connection option \"%s\"",
8213 value, context);
8214 return false;
8215}
static struct @165 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 851 of file fe-exec.c.

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

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 (conn->outCount >= 8192)
557 {
558 int toSend = conn->outCount - (conn->outCount % 8192);
559
560 if (pqSendSome(conn, toSend) < 0)
561 return EOF;
562 /* in nonblock mode, don't complain if unable to send it all */
563 }
564
565 return 0;
566}
void pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message)
Definition: fe-trace.c:841
int outMsgStart
Definition: libpq-int.h:576
int outMsgEnd
Definition: libpq-int.h:578

References conn, pg_conn::outBuffer, pg_conn::outCount, pg_conn::outMsgEnd, pg_conn::outMsgStart, pg_conn::Pfdebug, pg_hton32, pqSendSome(), pqTraceOutputMessage(), and pqTraceOutputNoTypeByteMessage().

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 char *  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 580 of file fe-misc.c.

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

1033{
1034 return pqSocketCheck(conn, 1, 0, 0);
1035}
static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, pg_usec_time_t end_time)
Definition: fe-misc.c:1057

References conn, and pqSocketCheck().

Referenced by gss_read(), and pqReadData().

◆ pqReleaseConnHosts()

void pqReleaseConnHosts ( PGconn conn)

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

5128{
5129 if (conn->connhost)
5130 {
5131 for (int i = 0; i < conn->nconnhost; ++i)
5132 {
5133 free(conn->connhost[i].host);
5135 free(conn->connhost[i].port);
5136 if (conn->connhost[i].password != NULL)
5137 {
5139 strlen(conn->connhost[i].password));
5141 }
5142 }
5143 free(conn->connhost);
5144 }
5145}
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 563 of file fe-exec.c.

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

676{
677 char *space = (char *) pqResultAlloc(res, strlen(str) + 1, false);
678
679 if (space)
680 strcpy(space, str);
681 return space;
682}
void * pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
Definition: fe-exec.c:563
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 1206 of file fe-exec.c.

1207{
1208 PGresult *res = conn->result;
1209 int nfields = res->numAttributes;
1210 const PGdataValue *columns = conn->rowBuf;
1211 PGresAttValue *tup;
1212 int i;
1213
1214 /*
1215 * In partial-result mode, if we don't already have a partial PGresult
1216 * then make one by cloning conn->result (which should hold the correct
1217 * result metadata by now). Then the original conn->result is moved over
1218 * to saved_result so that we can re-use it as a reference for future
1219 * partial results. The saved result will become active again after
1220 * pqPrepareAsyncResult() returns the partial result to the application.
1221 */
1222 if (conn->partialResMode && conn->saved_result == NULL)
1223 {
1224 /* Copy everything that should be in the result at this point */
1225 res = PQcopyResult(res,
1228 if (!res)
1229 return 0;
1230 /* Change result status to appropriate special value */
1232 /* And stash it as the active result */
1234 conn->result = res;
1235 }
1236
1237 /*
1238 * Basically we just allocate space in the PGresult for each field and
1239 * copy the data over.
1240 *
1241 * Note: on malloc failure, we return 0 leaving *errmsgp still NULL, which
1242 * caller will take to mean "out of memory". This is preferable to trying
1243 * to set up such a message here, because evidently there's not enough
1244 * memory for gettext() to do anything.
1245 */
1246 tup = (PGresAttValue *)
1247 pqResultAlloc(res, nfields * sizeof(PGresAttValue), true);
1248 if (tup == NULL)
1249 return 0;
1250
1251 for (i = 0; i < nfields; i++)
1252 {
1253 int clen = columns[i].len;
1254
1255 if (clen < 0)
1256 {
1257 /* null field */
1258 tup[i].len = NULL_LEN;
1259 tup[i].value = res->null_field;
1260 }
1261 else
1262 {
1263 bool isbinary = (res->attDescs[i].format != 0);
1264 char *val;
1265
1266 val = (char *) pqResultAlloc(res, clen + 1, isbinary);
1267 if (val == NULL)
1268 return 0;
1269
1270 /* copy and zero-terminate the data (even if it's binary) */
1271 memcpy(val, columns[i].value, clen);
1272 val[clen] = '\0';
1273
1274 tup[i].len = clen;
1275 tup[i].value = val;
1276 }
1277 }
1278
1279 /* And add the tuple to the PGresult's tuple array */
1280 if (!pqAddTuple(res, tup, errmsgp))
1281 return 0;
1282
1283 /*
1284 * Success. In partial-result mode, if we have enough rows then make the
1285 * result available to the client immediately.
1286 */
1287 if (conn->partialResMode && res->ntups >= conn->maxChunkSize)
1289
1290 return 1;
1291}
PGresult * PQcopyResult(const PGresult *src, int flags)
Definition: fe-exec.c:318
static bool pqAddTuple(PGresult *res, PGresAttValue *tup, const char **errmsgp)
Definition: fe-exec.c:993
@ 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:469
bool singleRowMode
Definition: libpq-int.h:468
bool partialResMode
Definition: libpq-int.h:467
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 803 of file fe-exec.c.

804{
805 /* Drop any pending result ... */
807 /* ... and set flag to remember to make an error result later */
808 conn->error_result = true;
809}

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

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

◆ pqSaveMessageField()

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

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

1061{
1062 PGMessageField *pfield;
1063
1064 pfield = (PGMessageField *)
1065 pqResultAlloc(res,
1066 offsetof(PGMessageField, contents) +
1067 strlen(value) + 1,
1068 true);
1069 if (!pfield)
1070 return; /* out of memory? */
1071 pfield->code = code;
1072 strcpy(pfield->contents, value);
1073 pfield->next = res->errFields;
1074 res->errFields = pfield;
1075}
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()

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

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

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

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:510
bool sigpipe_flag
Definition: libpq-int.h:508
bool write_failed
Definition: libpq-int.h:509
#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 454 of file fe-cancel.c.

455{
457
458 /* Start the message. */
460 return STATUS_ERROR;
461
462 /* Send the message body. */
463 memset(&req, 0, offsetof(CancelRequestPacket, cancelAuthCode));
466 if (pqPutnchar((char *) &req, offsetof(CancelRequestPacket, cancelAuthCode), cancelConn))
467 return STATUS_ERROR;
468 if (pqPutnchar(cancelConn->be_cancel_key, cancelConn->be_cancel_key_len, cancelConn))
469 return STATUS_ERROR;
470
471 /* Finish the message. */
473 return STATUS_ERROR;
474
475 /* Flush to ensure backend gets it. */
476 if (pqFlush(cancelConn))
477 return STATUS_ERROR;
478
479 return STATUS_OK;
480}
static PGcancel *volatile cancelConn
Definition: cancel.c:43
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:137
ProtocolVersion MsgType
Definition: pqcomm.h:101
MsgType cancelRequestCode
Definition: pqcomm.h:142
uint32 backendPID
Definition: pqcomm.h:143
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 1422 of file fe-exec.c.

1423{
1424 return PQsendQueryInternal(conn, query, false);
1425}
static int PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery)
Definition: fe-exec.c:1428

References conn, and PQsendQueryInternal().

Referenced by PQconnectPoll().

◆ pqSetResultError()

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

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

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

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:482
int traceFlags
Definition: libpq-int.h:448

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:484
#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_FunctionCallResponse
Definition: protocol.h:53
#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:520

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:173
#define NEGOTIATE_SSL_CODE
Definition: pqcomm.h:172

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 993 of file fe-misc.c.

994{
995 return pqWaitTimed(forRead, forWrite, conn, -1);
996}

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 1009 of file fe-misc.c.

1010{
1011 int result;
1012
1013 result = pqSocketCheck(conn, forRead, forWrite, end_time);
1014
1015 if (result < 0)
1016 return -1; /* errorMessage is already set */
1017
1018 if (result == 0)
1019 {
1020 libpq_append_conn_error(conn, "timeout expired");
1021 return 1;
1022 }
1023
1024 return 0;
1025}

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

Referenced by pqConnectDBComplete(), and pqWait().

◆ pqWriteReady()

int pqWriteReady ( PGconn conn)

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

1043{
1044 return pqSocketCheck(conn, 0, 1, 0);
1045}

References conn, and pqSocketCheck().

Variable Documentation

◆ pg_g_threadlock

pgthreadlock_t pg_g_threadlock
extern

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

Referenced by PQregisterThreadLock().

◆ pgresStatus

char* const pgresStatus[]
extern

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

Referenced by PQresStatus().