PostgreSQL Source Code  git master
libpq-fe.h File Reference
#include <stdio.h>
#include "postgres_ext.h"
Include dependency graph for libpq-fe.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  pgNotify
 
struct  _PQprintOpt
 
struct  _PQconninfoOption
 
struct  PQArgBlock
 
struct  pgresAttDesc
 

Macros

#define PG_COPYRES_ATTRS   0x01
 
#define PG_COPYRES_TUPLES   0x02 /* Implies PG_COPYRES_ATTRS */
 
#define PG_COPYRES_EVENTS   0x04
 
#define PG_COPYRES_NOTICEHOOKS   0x08
 
#define PQsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME)   PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL)
 
#define PQfreeNotify(ptr)   PQfreemem(ptr)
 
#define PQnoPasswordSupplied   "fe_sendauth: no password supplied\n"
 

Typedefs

typedef struct pg_conn PGconn
 
typedef struct pg_result PGresult
 
typedef struct pg_cancel PGcancel
 
typedef struct pgNotify PGnotify
 
typedef void(* PQnoticeReceiver) (void *arg, const PGresult *res)
 
typedef void(* PQnoticeProcessor) (void *arg, const char *message)
 
typedef char pqbool
 
typedef struct _PQprintOpt PQprintOpt
 
typedef struct _PQconninfoOption PQconninfoOption
 
typedef struct pgresAttDesc PGresAttDesc
 
typedef void(* pgthreadlock_t) (int acquire)
 
typedef int(* PQsslKeyPassHook_OpenSSL_type) (char *buf, int size, PGconn *conn)
 

Enumerations

enum  ConnStatusType {
  CONNECTION_OK, CONNECTION_BAD, CONNECTION_STARTED, CONNECTION_MADE,
  CONNECTION_AWAITING_RESPONSE, CONNECTION_AUTH_OK, CONNECTION_SETENV, CONNECTION_SSL_STARTUP,
  CONNECTION_NEEDED, CONNECTION_CHECK_WRITABLE, CONNECTION_CONSUME, CONNECTION_GSS_STARTUP,
  CONNECTION_CHECK_TARGET
}
 
enum  PostgresPollingStatusType {
  PGRES_POLLING_FAILED = 0, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PGRES_POLLING_OK,
  PGRES_POLLING_ACTIVE
}
 
enum  ExecStatusType {
  PGRES_EMPTY_QUERY = 0, PGRES_COMMAND_OK, PGRES_TUPLES_OK, PGRES_COPY_OUT,
  PGRES_COPY_IN, PGRES_BAD_RESPONSE, PGRES_NONFATAL_ERROR, PGRES_FATAL_ERROR,
  PGRES_COPY_BOTH, PGRES_SINGLE_TUPLE
}
 
enum  PGTransactionStatusType {
  PQTRANS_IDLE, PQTRANS_ACTIVE, PQTRANS_INTRANS, PQTRANS_INERROR,
  PQTRANS_UNKNOWN
}
 
enum  PGVerbosity { PQERRORS_TERSE, PQERRORS_DEFAULT, PQERRORS_VERBOSE, PQERRORS_SQLSTATE }
 
enum  PGContextVisibility { PQSHOW_CONTEXT_NEVER, PQSHOW_CONTEXT_ERRORS, PQSHOW_CONTEXT_ALWAYS }
 
enum  PGPing { PQPING_OK, PQPING_REJECT, PQPING_NO_RESPONSE, PQPING_NO_ATTEMPT }
 

Functions

PGconnPQconnectStart (const char *conninfo)
 
PGconnPQconnectStartParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PostgresPollingStatusType PQconnectPoll (PGconn *conn)
 
PGconnPQconnectdb (const char *conninfo)
 
PGconnPQconnectdbParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
PGconnPQsetdbLogin (const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd)
 
void PQfinish (PGconn *conn)
 
PQconninfoOptionPQconndefaults (void)
 
PQconninfoOptionPQconninfoParse (const char *conninfo, char **errmsg)
 
PQconninfoOptionPQconninfo (PGconn *conn)
 
void PQconninfoFree (PQconninfoOption *connOptions)
 
int PQresetStart (PGconn *conn)
 
PostgresPollingStatusType PQresetPoll (PGconn *conn)
 
void PQreset (PGconn *conn)
 
PGcancelPQgetCancel (PGconn *conn)
 
void PQfreeCancel (PGcancel *cancel)
 
int PQcancel (PGcancel *cancel, char *errbuf, int errbufsize)
 
int PQrequestCancel (PGconn *conn)
 
char * PQdb (const PGconn *conn)
 
char * PQuser (const PGconn *conn)
 
char * PQpass (const PGconn *conn)
 
char * PQhost (const PGconn *conn)
 
char * PQhostaddr (const PGconn *conn)
 
char * PQport (const PGconn *conn)
 
char * PQtty (const PGconn *conn)
 
char * PQoptions (const PGconn *conn)
 
ConnStatusType PQstatus (const PGconn *conn)
 
PGTransactionStatusType PQtransactionStatus (const PGconn *conn)
 
const char * PQparameterStatus (const PGconn *conn, const char *paramName)
 
int PQprotocolVersion (const PGconn *conn)
 
int PQserverVersion (const PGconn *conn)
 
char * PQerrorMessage (const PGconn *conn)
 
int PQsocket (const PGconn *conn)
 
int PQbackendPID (const PGconn *conn)
 
int PQconnectionNeedsPassword (const PGconn *conn)
 
int PQconnectionUsedPassword (const PGconn *conn)
 
int PQclientEncoding (const PGconn *conn)
 
int PQsetClientEncoding (PGconn *conn, const char *encoding)
 
int PQsslInUse (PGconn *conn)
 
void * PQsslStruct (PGconn *conn, const char *struct_name)
 
const char * PQsslAttribute (PGconn *conn, const char *attribute_name)
 
const char *const * PQsslAttributeNames (PGconn *conn)
 
void * PQgetssl (PGconn *conn)
 
void PQinitSSL (int do_init)
 
void PQinitOpenSSL (int do_ssl, int do_crypto)
 
int PQgssEncInUse (PGconn *conn)
 
void * PQgetgssctx (PGconn *conn)
 
PGVerbosity PQsetErrorVerbosity (PGconn *conn, PGVerbosity verbosity)
 
PGContextVisibility PQsetErrorContextVisibility (PGconn *conn, PGContextVisibility show_context)
 
void PQtrace (PGconn *conn, FILE *debug_port)
 
void PQuntrace (PGconn *conn)
 
PQnoticeReceiver PQsetNoticeReceiver (PGconn *conn, PQnoticeReceiver proc, void *arg)
 
PQnoticeProcessor PQsetNoticeProcessor (PGconn *conn, PQnoticeProcessor proc, void *arg)
 
pgthreadlock_t PQregisterThreadLock (pgthreadlock_t newhandler)
 
PGresultPQexec (PGconn *conn, const char *query)
 
PGresultPQexecParams (PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
 
PGresultPQprepare (PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
 
PGresultPQexecPrepared (PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
 
int PQsendQuery (PGconn *conn, const char *query)
 
int PQsendQueryParams (PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
 
int PQsendPrepare (PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
 
int PQsendQueryPrepared (PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
 
int PQsetSingleRowMode (PGconn *conn)
 
PGresultPQgetResult (PGconn *conn)
 
int PQisBusy (PGconn *conn)
 
int PQconsumeInput (PGconn *conn)
 
PGnotifyPQnotifies (PGconn *conn)
 
int PQputCopyData (PGconn *conn, const char *buffer, int nbytes)
 
int PQputCopyEnd (PGconn *conn, const char *errormsg)
 
int PQgetCopyData (PGconn *conn, char **buffer, int async)
 
int PQgetline (PGconn *conn, char *string, int length)
 
int PQputline (PGconn *conn, const char *string)
 
int PQgetlineAsync (PGconn *conn, char *buffer, int bufsize)
 
int PQputnbytes (PGconn *conn, const char *buffer, int nbytes)
 
int PQendcopy (PGconn *conn)
 
int PQsetnonblocking (PGconn *conn, int arg)
 
int PQisnonblocking (const PGconn *conn)
 
int PQisthreadsafe (void)
 
PGPing PQping (const char *conninfo)
 
PGPing PQpingParams (const char *const *keywords, const char *const *values, int expand_dbname)
 
int PQflush (PGconn *conn)
 
PGresultPQfn (PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
 
ExecStatusType PQresultStatus (const PGresult *res)
 
char * PQresStatus (ExecStatusType status)
 
char * PQresultErrorMessage (const PGresult *res)
 
char * PQresultVerboseErrorMessage (const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
 
char * PQresultErrorField (const PGresult *res, int fieldcode)
 
int PQntuples (const PGresult *res)
 
int PQnfields (const PGresult *res)
 
int PQbinaryTuples (const PGresult *res)
 
char * PQfname (const PGresult *res, int field_num)
 
int PQfnumber (const PGresult *res, const char *field_name)
 
Oid PQftable (const PGresult *res, int field_num)
 
int PQftablecol (const PGresult *res, int field_num)
 
int PQfformat (const PGresult *res, int field_num)
 
Oid PQftype (const PGresult *res, int field_num)
 
int PQfsize (const PGresult *res, int field_num)
 
int PQfmod (const PGresult *res, int field_num)
 
char * PQcmdStatus (PGresult *res)
 
char * PQoidStatus (const PGresult *res)
 
Oid PQoidValue (const PGresult *res)
 
char * PQcmdTuples (PGresult *res)
 
char * PQgetvalue (const PGresult *res, int tup_num, int field_num)
 
int PQgetlength (const PGresult *res, int tup_num, int field_num)
 
int PQgetisnull (const PGresult *res, int tup_num, int field_num)
 
int PQnparams (const PGresult *res)
 
Oid PQparamtype (const PGresult *res, int param_num)
 
PGresultPQdescribePrepared (PGconn *conn, const char *stmt)
 
PGresultPQdescribePortal (PGconn *conn, const char *portal)
 
int PQsendDescribePrepared (PGconn *conn, const char *stmt)
 
int PQsendDescribePortal (PGconn *conn, const char *portal)
 
void PQclear (PGresult *res)
 
void PQfreemem (void *ptr)
 
PGresultPQmakeEmptyPGresult (PGconn *conn, ExecStatusType status)
 
PGresultPQcopyResult (const PGresult *src, int flags)
 
int PQsetResultAttrs (PGresult *res, int numAttributes, PGresAttDesc *attDescs)
 
void * PQresultAlloc (PGresult *res, size_t nBytes)
 
size_t PQresultMemorySize (const PGresult *res)
 
int PQsetvalue (PGresult *res, int tup_num, int field_num, char *value, int len)
 
size_t PQescapeStringConn (PGconn *conn, char *to, const char *from, size_t length, int *error)
 
char * PQescapeLiteral (PGconn *conn, const char *str, size_t len)
 
char * PQescapeIdentifier (PGconn *conn, const char *str, size_t len)
 
unsigned char * PQescapeByteaConn (PGconn *conn, const unsigned char *from, size_t from_length, size_t *to_length)
 
unsigned char * PQunescapeBytea (const unsigned char *strtext, size_t *retbuflen)
 
size_t PQescapeString (char *to, const char *from, size_t length)
 
unsigned char * PQescapeBytea (const unsigned char *from, size_t from_length, size_t *to_length)
 
void PQprint (FILE *fout, const PGresult *res, const PQprintOpt *ps)
 
void PQdisplayTuples (const PGresult *res, FILE *fp, int fillAlign, const char *fieldSep, int printHeader, int quiet)
 
void PQprintTuples (const PGresult *res, FILE *fout, int PrintAttNames, int TerseOutput, int colWidth)
 
int lo_open (PGconn *conn, Oid lobjId, int mode)
 
int lo_close (PGconn *conn, int fd)
 
int lo_read (PGconn *conn, int fd, char *buf, size_t len)
 
int lo_write (PGconn *conn, int fd, const char *buf, size_t len)
 
int lo_lseek (PGconn *conn, int fd, int offset, int whence)
 
pg_int64 lo_lseek64 (PGconn *conn, int fd, pg_int64 offset, int whence)
 
Oid lo_creat (PGconn *conn, int mode)
 
Oid lo_create (PGconn *conn, Oid lobjId)
 
int lo_tell (PGconn *conn, int fd)
 
pg_int64 lo_tell64 (PGconn *conn, int fd)
 
int lo_truncate (PGconn *conn, int fd, size_t len)
 
int lo_truncate64 (PGconn *conn, int fd, pg_int64 len)
 
int lo_unlink (PGconn *conn, Oid lobjId)
 
Oid lo_import (PGconn *conn, const char *filename)
 
Oid lo_import_with_oid (PGconn *conn, const char *filename, Oid lobjId)
 
int lo_export (PGconn *conn, Oid lobjId, const char *filename)
 
int PQlibVersion (void)
 
int PQmblen (const char *s, int encoding)
 
int PQdsplen (const char *s, int encoding)
 
int PQenv2encoding (void)
 
char * PQencryptPassword (const char *passwd, const char *user)
 
char * PQencryptPasswordConn (PGconn *conn, const char *passwd, const char *user, const char *algorithm)
 
int pg_char_to_encoding (const char *name)
 
const char * pg_encoding_to_char (int encoding)
 
int pg_valid_server_encoding_id (int encoding)
 
PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL (void)
 
void PQsetSSLKeyPassHook_OpenSSL (PQsslKeyPassHook_OpenSSL_type hook)
 
int PQdefaultSSLKeyPassHook_OpenSSL (char *buf, int size, PGconn *conn)
 

Macro Definition Documentation

◆ PG_COPYRES_ATTRS

#define PG_COPYRES_ATTRS   0x01

Definition at line 34 of file libpq-fe.h.

Referenced by PQcopyResult(), and pqRowProcessor().

◆ PG_COPYRES_EVENTS

#define PG_COPYRES_EVENTS   0x04

Definition at line 36 of file libpq-fe.h.

Referenced by PQcopyResult(), and pqRowProcessor().

◆ PG_COPYRES_NOTICEHOOKS

#define PG_COPYRES_NOTICEHOOKS   0x08

Definition at line 37 of file libpq-fe.h.

Referenced by PQcopyResult(), and pqRowProcessor().

◆ PG_COPYRES_TUPLES

#define PG_COPYRES_TUPLES   0x02 /* Implies PG_COPYRES_ATTRS */

Definition at line 35 of file libpq-fe.h.

Referenced by PQcopyResult().

◆ PQfreeNotify

#define PQfreeNotify (   ptr)    PQfreemem(ptr)

Definition at line 518 of file libpq-fe.h.

◆ PQnoPasswordSupplied

#define PQnoPasswordSupplied   "fe_sendauth: no password supplied\n"

Definition at line 522 of file libpq-fe.h.

Referenced by pg_fe_sendauth(), and pg_SASL_init().

◆ PQsetdb

#define PQsetdb (   M_PGHOST,
  M_PGPORT,
  M_PGOPT,
  M_PGTTY,
  M_DBNAME 
)    PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL)

Definition at line 272 of file libpq-fe.h.

Referenced by main().

Typedef Documentation

◆ PGcancel

typedef struct pg_cancel PGcancel

Definition at line 156 of file libpq-fe.h.

◆ PGconn

typedef struct pg_conn PGconn

Definition at line 143 of file libpq-fe.h.

◆ PGnotify

typedef struct pgNotify PGnotify

◆ PGresAttDesc

typedef struct pgresAttDesc PGresAttDesc

◆ PGresult

typedef struct pg_result PGresult

Definition at line 150 of file libpq-fe.h.

◆ pgthreadlock_t

typedef void(* pgthreadlock_t) (int acquire)

Definition at line 384 of file libpq-fe.h.

◆ pqbool

typedef char pqbool

Definition at line 178 of file libpq-fe.h.

◆ PQconninfoOption

◆ PQnoticeProcessor

typedef void(* PQnoticeProcessor) (void *arg, const char *message)

Definition at line 175 of file libpq-fe.h.

◆ PQnoticeReceiver

typedef void(* PQnoticeReceiver) (void *arg, const PGresult *res)

Definition at line 174 of file libpq-fe.h.

◆ PQprintOpt

typedef struct _PQprintOpt PQprintOpt

◆ PQsslKeyPassHook_OpenSSL_type

typedef int(* PQsslKeyPassHook_OpenSSL_type) (char *buf, int size, PGconn *conn)

Definition at line 623 of file libpq-fe.h.

Enumeration Type Documentation

◆ ConnStatusType

Enumerator
CONNECTION_OK 
CONNECTION_BAD 
CONNECTION_STARTED 
CONNECTION_MADE 
CONNECTION_AWAITING_RESPONSE 
CONNECTION_AUTH_OK 
CONNECTION_SETENV 
CONNECTION_SSL_STARTUP 
CONNECTION_NEEDED 
CONNECTION_CHECK_WRITABLE 
CONNECTION_CONSUME 
CONNECTION_GSS_STARTUP 
CONNECTION_CHECK_TARGET 

Definition at line 47 of file libpq-fe.h.

48 {
51  /* Non-blocking mode only below here */
52 
53  /*
54  * The existence of these should never be relied upon - they should only
55  * be used for user feedback or similar purposes.
56  */
57  CONNECTION_STARTED, /* Waiting for connection to be made. */
58  CONNECTION_MADE, /* Connection OK; waiting to send. */
59  CONNECTION_AWAITING_RESPONSE, /* Waiting for a response from the
60  * postmaster. */
61  CONNECTION_AUTH_OK, /* Received authentication; waiting for
62  * backend startup. */
63  CONNECTION_SETENV, /* Negotiating environment. */
64  CONNECTION_SSL_STARTUP, /* Negotiating SSL. */
65  CONNECTION_NEEDED, /* Internal state: connect() needed */
66  CONNECTION_CHECK_WRITABLE, /* Check if we could make a writable
67  * connection. */
68  CONNECTION_CONSUME, /* Wait for any pending message and consume
69  * them. */
70  CONNECTION_GSS_STARTUP, /* Negotiating GSSAPI. */
71  CONNECTION_CHECK_TARGET /* Check if we have a proper target connection */
ConnStatusType
Definition: libpq-fe.h:47

◆ ExecStatusType

Enumerator
PGRES_EMPTY_QUERY 
PGRES_COMMAND_OK 
PGRES_TUPLES_OK 
PGRES_COPY_OUT 
PGRES_COPY_IN 
PGRES_BAD_RESPONSE 
PGRES_NONFATAL_ERROR 
PGRES_FATAL_ERROR 
PGRES_COPY_BOTH 
PGRES_SINGLE_TUPLE 

Definition at line 84 of file libpq-fe.h.

85 {
86  PGRES_EMPTY_QUERY = 0, /* empty query string was executed */
87  PGRES_COMMAND_OK, /* a query command that doesn't return
88  * anything was executed properly by the
89  * backend */
90  PGRES_TUPLES_OK, /* a query command that returns tuples was
91  * executed properly by the backend, PGresult
92  * contains the result tuples */
93  PGRES_COPY_OUT, /* Copy Out data transfer in progress */
94  PGRES_COPY_IN, /* Copy In data transfer in progress */
95  PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the
96  * backend */
97  PGRES_NONFATAL_ERROR, /* notice or warning message */
98  PGRES_FATAL_ERROR, /* query failed */
99  PGRES_COPY_BOTH, /* Copy In/Out data transfer in progress */
100  PGRES_SINGLE_TUPLE /* single tuple from larger resultset */
ExecStatusType
Definition: libpq-fe.h:84

◆ PGContextVisibility

Enumerator
PQSHOW_CONTEXT_NEVER 
PQSHOW_CONTEXT_ERRORS 
PQSHOW_CONTEXT_ALWAYS 

Definition at line 120 of file libpq-fe.h.

121 {
122  PQSHOW_CONTEXT_NEVER, /* never show CONTEXT field */
123  PQSHOW_CONTEXT_ERRORS, /* show CONTEXT for errors only (default) */
124  PQSHOW_CONTEXT_ALWAYS /* always show CONTEXT field */
PGContextVisibility
Definition: libpq-fe.h:120

◆ PGPing

enum PGPing
Enumerator
PQPING_OK 
PQPING_REJECT 
PQPING_NO_RESPONSE 
PQPING_NO_ATTEMPT 

Definition at line 132 of file libpq-fe.h.

133 {
134  PQPING_OK, /* server is accepting connections */
135  PQPING_REJECT, /* server is alive but rejecting connections */
136  PQPING_NO_RESPONSE, /* could not establish connection */
137  PQPING_NO_ATTEMPT /* connection not attempted (bad params) */
138 } PGPing;
PGPing
Definition: libpq-fe.h:132

◆ PGTransactionStatusType

Enumerator
PQTRANS_IDLE 
PQTRANS_ACTIVE 
PQTRANS_INTRANS 
PQTRANS_INERROR 
PQTRANS_UNKNOWN 

Definition at line 103 of file libpq-fe.h.

104 {
105  PQTRANS_IDLE, /* connection idle */
106  PQTRANS_ACTIVE, /* command in progress */
107  PQTRANS_INTRANS, /* idle, within transaction block */
108  PQTRANS_INERROR, /* idle, within failed transaction */
109  PQTRANS_UNKNOWN /* cannot determine status */
PGTransactionStatusType
Definition: libpq-fe.h:103

◆ PGVerbosity

Enumerator
PQERRORS_TERSE 
PQERRORS_DEFAULT 
PQERRORS_VERBOSE 
PQERRORS_SQLSTATE 

Definition at line 112 of file libpq-fe.h.

113 {
114  PQERRORS_TERSE, /* single-line error messages */
115  PQERRORS_DEFAULT, /* recommended style */
116  PQERRORS_VERBOSE, /* all the facts, ma'am */
117  PQERRORS_SQLSTATE /* only error severity and SQLSTATE code */
118 } PGVerbosity;
PGVerbosity
Definition: libpq-fe.h:112

◆ PostgresPollingStatusType

Enumerator
PGRES_POLLING_FAILED 
PGRES_POLLING_READING 
PGRES_POLLING_WRITING 
PGRES_POLLING_OK 
PGRES_POLLING_ACTIVE 

Definition at line 74 of file libpq-fe.h.

75 {
77  PGRES_POLLING_READING, /* These two indicate that one may */
78  PGRES_POLLING_WRITING, /* use select before polling again. */
80  PGRES_POLLING_ACTIVE /* unused; keep for awhile for backwards
81  * compatibility */
PostgresPollingStatusType
Definition: libpq-fe.h:74

Function Documentation

◆ lo_close()

int lo_close ( PGconn conn,
int  fd 
)

Definition at line 99 of file fe-lobj.c.

References fd(), pgLobjfuncs::fn_lo_close, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

Referenced by dumpBlobs(), EndRestoreBlob(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), and pickout().

100 {
101  PQArgBlock argv[1];
102  PGresult *res;
103  int retval;
104  int result_len;
105 
106  if (conn == NULL || conn->lobjfuncs == NULL)
107  {
108  if (lo_initialize(conn) < 0)
109  return -1;
110  }
111 
112  argv[0].isint = 1;
113  argv[0].len = 4;
114  argv[0].u.integer = fd;
115  res = PQfn(conn, conn->lobjfuncs->fn_lo_close,
116  &retval, &result_len, 1, argv, 1);
117  if (PQresultStatus(res) == PGRES_COMMAND_OK)
118  {
119  PQclear(res);
120  return retval;
121  }
122  else
123  {
124  PQclear(res);
125  return -1;
126  }
127 }
union PQArgBlock::@161 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void PQclear(PGresult *res)
Definition: fe-exec.c:694
Oid fn_lo_close
Definition: libpq-int.h:271
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
int integer
Definition: libpq-fe.h:230
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_creat()

Oid lo_creat ( PGconn conn,
int  mode 
)

Definition at line 465 of file fe-lobj.c.

References pgLobjfuncs::fn_lo_creat, PQArgBlock::integer, InvalidOid, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, mode, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

Referenced by importFile(), and lo_import_internal().

466 {
467  PQArgBlock argv[1];
468  PGresult *res;
469  int retval;
470  int result_len;
471 
472  if (conn == NULL || conn->lobjfuncs == NULL)
473  {
474  if (lo_initialize(conn) < 0)
475  return InvalidOid;
476  }
477 
478  argv[0].isint = 1;
479  argv[0].len = 4;
480  argv[0].u.integer = mode;
481  res = PQfn(conn, conn->lobjfuncs->fn_lo_creat,
482  &retval, &result_len, 1, argv, 1);
483  if (PQresultStatus(res) == PGRES_COMMAND_OK)
484  {
485  PQclear(res);
486  return (Oid) retval;
487  }
488  else
489  {
490  PQclear(res);
491  return InvalidOid;
492  }
493 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
union PQArgBlock::@161 u
unsigned int Oid
Definition: postgres_ext.h:31
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
#define InvalidOid
Definition: postgres_ext.h:36
void PQclear(PGresult *res)
Definition: fe-exec.c:694
Oid fn_lo_creat
Definition: libpq-int.h:272
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
int integer
Definition: libpq-fe.h:230
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_create()

Oid lo_create ( PGconn conn,
Oid  lobjId 
)

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

References pg_conn::errorMessage, pgLobjfuncs::fn_lo_create, PQArgBlock::integer, InvalidOid, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

Referenced by lo_import_internal(), and StartRestoreBlob().

505 {
506  PQArgBlock argv[1];
507  PGresult *res;
508  int retval;
509  int result_len;
510 
511  if (conn == NULL || conn->lobjfuncs == NULL)
512  {
513  if (lo_initialize(conn) < 0)
514  return InvalidOid;
515  }
516 
517  /* Must check this on-the-fly because it's not there pre-8.1 */
518  if (conn->lobjfuncs->fn_lo_create == 0)
519  {
521  libpq_gettext("cannot determine OID of function lo_create\n"));
522  return InvalidOid;
523  }
524 
525  argv[0].isint = 1;
526  argv[0].len = 4;
527  argv[0].u.integer = lobjId;
528  res = PQfn(conn, conn->lobjfuncs->fn_lo_create,
529  &retval, &result_len, 1, argv, 1);
530  if (PQresultStatus(res) == PGRES_COMMAND_OK)
531  {
532  PQclear(res);
533  return (Oid) retval;
534  }
535  else
536  {
537  PQclear(res);
538  return InvalidOid;
539  }
540 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
union PQArgBlock::@161 u
Oid fn_lo_create
Definition: libpq-int.h:273
unsigned int Oid
Definition: postgres_ext.h:31
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
PQExpBufferData errorMessage
Definition: libpq-int.h:526
#define InvalidOid
Definition: postgres_ext.h:36
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
#define libpq_gettext(x)
Definition: libpq-int.h:805
int integer
Definition: libpq-fe.h:230
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_export()

int lo_export ( PGconn conn,
Oid  lobjId,
const char *  filename 
)

Definition at line 784 of file fe-lobj.c.

References buf, close, pg_conn::errorMessage, fd(), INV_READ, libpq_gettext, LO_BUFSIZE, lo_close(), lo_open(), lo_read(), PG_BINARY, PG_STRERROR_R_BUFLEN, printfPQExpBuffer(), strerror_r, and write.

Referenced by do_lo_export(), and main().

785 {
786  int result = 1;
787  int fd;
788  int nbytes,
789  tmp;
790  char buf[LO_BUFSIZE];
791  int lobj;
792  char sebuf[PG_STRERROR_R_BUFLEN];
793 
794  /*
795  * open the large object.
796  */
797  lobj = lo_open(conn, lobjId, INV_READ);
798  if (lobj == -1)
799  {
800  /* we assume lo_open() already set a suitable error message */
801  return -1;
802  }
803 
804  /*
805  * create the file to be written to
806  */
807  fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
808  if (fd < 0)
809  {
810  /* We must do lo_close before setting the errorMessage */
811  int save_errno = errno;
812 
813  (void) lo_close(conn, lobj);
815  libpq_gettext("could not open file \"%s\": %s\n"),
816  filename,
817  strerror_r(save_errno, sebuf, sizeof(sebuf)));
818  return -1;
819  }
820 
821  /*
822  * read in from the large object and write to the file
823  */
824  while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0)
825  {
826  tmp = write(fd, buf, nbytes);
827  if (tmp != nbytes)
828  {
829  /* We must do lo_close before setting the errorMessage */
830  int save_errno = errno;
831 
832  (void) lo_close(conn, lobj);
833  (void) close(fd);
835  libpq_gettext("could not write to file \"%s\": %s\n"),
836  filename,
837  strerror_r(save_errno, sebuf, sizeof(sebuf)));
838  return -1;
839  }
840  }
841 
842  /*
843  * If lo_read() failed, we are now in an aborted transaction so there's no
844  * need for lo_close(); furthermore, if we tried it we'd overwrite the
845  * useful error result with a useless one. So skip lo_close() if we got a
846  * failure result.
847  */
848  if (nbytes < 0 ||
849  lo_close(conn, lobj) != 0)
850  {
851  /* assume lo_read() or lo_close() left a suitable error message */
852  result = -1;
853  }
854 
855  /* if we already failed, don't overwrite that msg with a close error */
856  if (close(fd) != 0 && result >= 0)
857  {
859  libpq_gettext("could not write to file \"%s\": %s\n"),
860  filename, strerror_r(errno, sebuf, sizeof(sebuf)));
861  result = -1;
862  }
863 
864  return result;
865 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
#define write(a, b, c)
Definition: win32.h:14
#define PG_STRERROR_R_BUFLEN
Definition: port.h:233
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1213
#define INV_READ
Definition: libpq-fs.h:22
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:99
static char * buf
Definition: pg_test_fsync.c:68
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
PQExpBufferData errorMessage
Definition: libpq-int.h:526
#define LO_BUFSIZE
Definition: fe-lobj.c:42
#define strerror_r
Definition: port.h:232
static char * filename
Definition: pg_dumpall.c:91
int lo_read(PGconn *conn, int fd, char *buf, size_t len)
Definition: fe-lobj.c:258
#define close(a)
Definition: win32.h:12
#define libpq_gettext(x)
Definition: libpq-int.h:805

◆ lo_import()

Oid lo_import ( PGconn conn,
const char *  filename 
)

Definition at line 668 of file fe-lobj.c.

References InvalidOid, and lo_import_internal().

Referenced by do_lo_import(), and main().

669 {
670  return lo_import_internal(conn, filename, InvalidOid);
671 }
static Oid lo_import_internal(PGconn *conn, const char *filename, Oid oid)
Definition: fe-lobj.c:689
#define InvalidOid
Definition: postgres_ext.h:36
static char * filename
Definition: pg_dumpall.c:91

◆ lo_import_with_oid()

Oid lo_import_with_oid ( PGconn conn,
const char *  filename,
Oid  lobjId 
)

Definition at line 683 of file fe-lobj.c.

References lo_import_internal().

684 {
685  return lo_import_internal(conn, filename, lobjId);
686 }
static Oid lo_import_internal(PGconn *conn, const char *filename, Oid oid)
Definition: fe-lobj.c:689
static char * filename
Definition: pg_dumpall.c:91

◆ lo_lseek()

int lo_lseek ( PGconn conn,
int  fd,
int  offset,
int  whence 
)

Definition at line 365 of file fe-lobj.c.

References fd(), pgLobjfuncs::fn_lo_lseek, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

Referenced by overwrite(), and pickout().

366 {
367  PQArgBlock argv[3];
368  PGresult *res;
369  int retval;
370  int result_len;
371 
372  if (conn == NULL || conn->lobjfuncs == NULL)
373  {
374  if (lo_initialize(conn) < 0)
375  return -1;
376  }
377 
378  argv[0].isint = 1;
379  argv[0].len = 4;
380  argv[0].u.integer = fd;
381 
382  argv[1].isint = 1;
383  argv[1].len = 4;
384  argv[1].u.integer = offset;
385 
386  argv[2].isint = 1;
387  argv[2].len = 4;
388  argv[2].u.integer = whence;
389 
390  res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek,
391  &retval, &result_len, 1, argv, 3);
392  if (PQresultStatus(res) == PGRES_COMMAND_OK)
393  {
394  PQclear(res);
395  return retval;
396  }
397  else
398  {
399  PQclear(res);
400  return -1;
401  }
402 }
union PQArgBlock::@161 u
Oid fn_lo_lseek
Definition: libpq-int.h:275
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
int integer
Definition: libpq-fe.h:230
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_lseek64()

pg_int64 lo_lseek64 ( PGconn conn,
int  fd,
pg_int64  offset,
int  whence 
)

Definition at line 409 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_lseek64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_hton64(), lo_initialize(), lo_ntoh64(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), PQArgBlock::ptr, and PQArgBlock::u.

Referenced by overwrite(), and pickout().

410 {
411  PQArgBlock argv[3];
412  PGresult *res;
413  pg_int64 retval;
414  int result_len;
415 
416  if (conn == NULL || conn->lobjfuncs == NULL)
417  {
418  if (lo_initialize(conn) < 0)
419  return -1;
420  }
421 
422  if (conn->lobjfuncs->fn_lo_lseek64 == 0)
423  {
425  libpq_gettext("cannot determine OID of function lo_lseek64\n"));
426  return -1;
427  }
428 
429  argv[0].isint = 1;
430  argv[0].len = 4;
431  argv[0].u.integer = fd;
432 
433  offset = lo_hton64(offset);
434  argv[1].isint = 0;
435  argv[1].len = 8;
436  argv[1].u.ptr = (int *) &offset;
437 
438  argv[2].isint = 1;
439  argv[2].len = 4;
440  argv[2].u.integer = whence;
441 
442  res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek64,
443  (void *) &retval, &result_len, 0, argv, 3);
444  if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
445  {
446  PQclear(res);
447  return lo_ntoh64(retval);
448  }
449  else
450  {
451  PQclear(res);
452  return -1;
453  }
454 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
union PQArgBlock::@161 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
PG_INT64_TYPE pg_int64
Definition: postgres_ext.h:47
static pg_int64 lo_hton64(pg_int64 host64)
Definition: fe-lobj.c:1061
PQExpBufferData errorMessage
Definition: libpq-int.h:526
void PQclear(PGresult *res)
Definition: fe-exec.c:694
Oid fn_lo_lseek64
Definition: libpq-int.h:276
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
int * ptr
Definition: libpq-fe.h:229
#define libpq_gettext(x)
Definition: libpq-int.h:805
int integer
Definition: libpq-fe.h:230
static pg_int64 lo_ntoh64(pg_int64 net64)
Definition: fe-lobj.c:1086
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_open()

int lo_open ( PGconn conn,
Oid  lobjId,
int  mode 
)

Definition at line 57 of file fe-lobj.c.

References fd(), pgLobjfuncs::fn_lo_open, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, mode, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

Referenced by dumpBlobs(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), pickout(), and StartRestoreBlob().

58 {
59  int fd;
60  int result_len;
61  PQArgBlock argv[2];
62  PGresult *res;
63 
64  if (conn == NULL || conn->lobjfuncs == NULL)
65  {
66  if (lo_initialize(conn) < 0)
67  return -1;
68  }
69 
70  argv[0].isint = 1;
71  argv[0].len = 4;
72  argv[0].u.integer = lobjId;
73 
74  argv[1].isint = 1;
75  argv[1].len = 4;
76  argv[1].u.integer = mode;
77 
78  res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, argv, 2);
79  if (PQresultStatus(res) == PGRES_COMMAND_OK)
80  {
81  PQclear(res);
82  return fd;
83  }
84  else
85  {
86  PQclear(res);
87  return -1;
88  }
89 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
union PQArgBlock::@161 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
Oid fn_lo_open
Definition: libpq-int.h:270
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
int integer
Definition: libpq-fe.h:230
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_read()

int lo_read ( PGconn conn,
int  fd,
char *  buf,
size_t  len 
)

Definition at line 258 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_read, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

Referenced by lo_export().

259 {
260  PQArgBlock argv[2];
261  PGresult *res;
262  int result_len;
263 
264  if (conn == NULL || conn->lobjfuncs == NULL)
265  {
266  if (lo_initialize(conn) < 0)
267  return -1;
268  }
269 
270  /*
271  * Long ago, somebody thought it'd be a good idea to declare this function
272  * as taking size_t ... but the underlying backend function only accepts a
273  * signed int32 length. So throw error if the given value overflows
274  * int32.
275  */
276  if (len > (size_t) INT_MAX)
277  {
279  libpq_gettext("argument of lo_read exceeds integer range\n"));
280  return -1;
281  }
282 
283  argv[0].isint = 1;
284  argv[0].len = 4;
285  argv[0].u.integer = fd;
286 
287  argv[1].isint = 1;
288  argv[1].len = 4;
289  argv[1].u.integer = (int) len;
290 
291  res = PQfn(conn, conn->lobjfuncs->fn_lo_read,
292  (void *) buf, &result_len, 0, argv, 2);
293  if (PQresultStatus(res) == PGRES_COMMAND_OK)
294  {
295  PQclear(res);
296  return result_len;
297  }
298  else
299  {
300  PQclear(res);
301  return -1;
302  }
303 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
union PQArgBlock::@161 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
Oid fn_lo_read
Definition: libpq-int.h:281
static char * buf
Definition: pg_test_fsync.c:68
PQExpBufferData errorMessage
Definition: libpq-int.h:526
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
#define libpq_gettext(x)
Definition: libpq-int.h:805
int integer
Definition: libpq-fe.h:230
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_tell()

int lo_tell ( PGconn conn,
int  fd 
)

Definition at line 548 of file fe-lobj.c.

References fd(), pgLobjfuncs::fn_lo_tell, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

549 {
550  int retval;
551  PQArgBlock argv[1];
552  PGresult *res;
553  int result_len;
554 
555  if (conn == NULL || conn->lobjfuncs == NULL)
556  {
557  if (lo_initialize(conn) < 0)
558  return -1;
559  }
560 
561  argv[0].isint = 1;
562  argv[0].len = 4;
563  argv[0].u.integer = fd;
564 
565  res = PQfn(conn, conn->lobjfuncs->fn_lo_tell,
566  &retval, &result_len, 1, argv, 1);
567  if (PQresultStatus(res) == PGRES_COMMAND_OK)
568  {
569  PQclear(res);
570  return retval;
571  }
572  else
573  {
574  PQclear(res);
575  return -1;
576  }
577 }
union PQArgBlock::@161 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
Oid fn_lo_tell
Definition: libpq-int.h:277
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
int integer
Definition: libpq-fe.h:230
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_tell64()

pg_int64 lo_tell64 ( PGconn conn,
int  fd 
)

Definition at line 584 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_tell64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), lo_ntoh64(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

Referenced by pickout().

585 {
586  pg_int64 retval;
587  PQArgBlock argv[1];
588  PGresult *res;
589  int result_len;
590 
591  if (conn == NULL || conn->lobjfuncs == NULL)
592  {
593  if (lo_initialize(conn) < 0)
594  return -1;
595  }
596 
597  if (conn->lobjfuncs->fn_lo_tell64 == 0)
598  {
600  libpq_gettext("cannot determine OID of function lo_tell64\n"));
601  return -1;
602  }
603 
604  argv[0].isint = 1;
605  argv[0].len = 4;
606  argv[0].u.integer = fd;
607 
608  res = PQfn(conn, conn->lobjfuncs->fn_lo_tell64,
609  (void *) &retval, &result_len, 0, argv, 1);
610  if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
611  {
612  PQclear(res);
613  return lo_ntoh64(retval);
614  }
615  else
616  {
617  PQclear(res);
618  return -1;
619  }
620 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
union PQArgBlock::@161 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
PG_INT64_TYPE pg_int64
Definition: postgres_ext.h:47
Oid fn_lo_tell64
Definition: libpq-int.h:278
PQExpBufferData errorMessage
Definition: libpq-int.h:526
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
#define libpq_gettext(x)
Definition: libpq-int.h:805
int integer
Definition: libpq-fe.h:230
static pg_int64 lo_ntoh64(pg_int64 net64)
Definition: fe-lobj.c:1086
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_truncate()

int lo_truncate ( PGconn conn,
int  fd,
size_t  len 
)

Definition at line 137 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_truncate, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

138 {
139  PQArgBlock argv[2];
140  PGresult *res;
141  int retval;
142  int result_len;
143 
144  if (conn == NULL || conn->lobjfuncs == NULL)
145  {
146  if (lo_initialize(conn) < 0)
147  return -1;
148  }
149 
150  /* Must check this on-the-fly because it's not there pre-8.3 */
151  if (conn->lobjfuncs->fn_lo_truncate == 0)
152  {
154  libpq_gettext("cannot determine OID of function lo_truncate\n"));
155  return -1;
156  }
157 
158  /*
159  * Long ago, somebody thought it'd be a good idea to declare this function
160  * as taking size_t ... but the underlying backend function only accepts a
161  * signed int32 length. So throw error if the given value overflows
162  * int32. (A possible alternative is to automatically redirect the call
163  * to lo_truncate64; but if the caller wanted to rely on that backend
164  * function being available, he could have called lo_truncate64 for
165  * himself.)
166  */
167  if (len > (size_t) INT_MAX)
168  {
170  libpq_gettext("argument of lo_truncate exceeds integer range\n"));
171  return -1;
172  }
173 
174  argv[0].isint = 1;
175  argv[0].len = 4;
176  argv[0].u.integer = fd;
177 
178  argv[1].isint = 1;
179  argv[1].len = 4;
180  argv[1].u.integer = (int) len;
181 
182  res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate,
183  &retval, &result_len, 1, argv, 2);
184 
185  if (PQresultStatus(res) == PGRES_COMMAND_OK)
186  {
187  PQclear(res);
188  return retval;
189  }
190  else
191  {
192  PQclear(res);
193  return -1;
194  }
195 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
union PQArgBlock::@161 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
Oid fn_lo_truncate
Definition: libpq-int.h:279
PQExpBufferData errorMessage
Definition: libpq-int.h:526
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
#define libpq_gettext(x)
Definition: libpq-int.h:805
int integer
Definition: libpq-fe.h:230
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_truncate64()

int lo_truncate64 ( PGconn conn,
int  fd,
pg_int64  len 
)

Definition at line 205 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_truncate64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_hton64(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), PQArgBlock::ptr, and PQArgBlock::u.

Referenced by my_truncate().

206 {
207  PQArgBlock argv[2];
208  PGresult *res;
209  int retval;
210  int result_len;
211 
212  if (conn == NULL || conn->lobjfuncs == NULL)
213  {
214  if (lo_initialize(conn) < 0)
215  return -1;
216  }
217 
218  if (conn->lobjfuncs->fn_lo_truncate64 == 0)
219  {
221  libpq_gettext("cannot determine OID of function lo_truncate64\n"));
222  return -1;
223  }
224 
225  argv[0].isint = 1;
226  argv[0].len = 4;
227  argv[0].u.integer = fd;
228 
229  len = lo_hton64(len);
230  argv[1].isint = 0;
231  argv[1].len = 8;
232  argv[1].u.ptr = (int *) &len;
233 
234  res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate64,
235  &retval, &result_len, 1, argv, 2);
236 
237  if (PQresultStatus(res) == PGRES_COMMAND_OK)
238  {
239  PQclear(res);
240  return retval;
241  }
242  else
243  {
244  PQclear(res);
245  return -1;
246  }
247 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
union PQArgBlock::@161 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
static pg_int64 lo_hton64(pg_int64 host64)
Definition: fe-lobj.c:1061
Oid fn_lo_truncate64
Definition: libpq-int.h:280
PQExpBufferData errorMessage
Definition: libpq-int.h:526
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
int * ptr
Definition: libpq-fe.h:229
#define libpq_gettext(x)
Definition: libpq-int.h:805
int integer
Definition: libpq-fe.h:230
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_unlink()

int lo_unlink ( PGconn conn,
Oid  lobjId 
)

Definition at line 628 of file fe-lobj.c.

References pgLobjfuncs::fn_lo_unlink, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

Referenced by do_lo_unlink(), and vacuumlo().

629 {
630  PQArgBlock argv[1];
631  PGresult *res;
632  int result_len;
633  int retval;
634 
635  if (conn == NULL || conn->lobjfuncs == NULL)
636  {
637  if (lo_initialize(conn) < 0)
638  return -1;
639  }
640 
641  argv[0].isint = 1;
642  argv[0].len = 4;
643  argv[0].u.integer = lobjId;
644 
645  res = PQfn(conn, conn->lobjfuncs->fn_lo_unlink,
646  &retval, &result_len, 1, argv, 1);
647  if (PQresultStatus(res) == PGRES_COMMAND_OK)
648  {
649  PQclear(res);
650  return retval;
651  }
652  else
653  {
654  PQclear(res);
655  return -1;
656  }
657 }
union PQArgBlock::@161 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void PQclear(PGresult *res)
Definition: fe-exec.c:694
Oid fn_lo_unlink
Definition: libpq-int.h:274
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
int integer
Definition: libpq-fe.h:230
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_write()

int lo_write ( PGconn conn,
int  fd,
const char *  buf,
size_t  len 
)

Definition at line 312 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_write, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), PQArgBlock::ptr, PQArgBlock::u, and unconstify.

Referenced by lo_import_internal().

313 {
314  PQArgBlock argv[2];
315  PGresult *res;
316  int result_len;
317  int retval;
318 
319  if (conn == NULL || conn->lobjfuncs == NULL)
320  {
321  if (lo_initialize(conn) < 0)
322  return -1;
323  }
324 
325  /*
326  * Long ago, somebody thought it'd be a good idea to declare this function
327  * as taking size_t ... but the underlying backend function only accepts a
328  * signed int32 length. So throw error if the given value overflows
329  * int32.
330  */
331  if (len > (size_t) INT_MAX)
332  {
334  libpq_gettext("argument of lo_write exceeds integer range\n"));
335  return -1;
336  }
337 
338  argv[0].isint = 1;
339  argv[0].len = 4;
340  argv[0].u.integer = fd;
341 
342  argv[1].isint = 0;
343  argv[1].len = (int) len;
344  argv[1].u.ptr = (int *) unconstify(char *, buf);
345 
346  res = PQfn(conn, conn->lobjfuncs->fn_lo_write,
347  &retval, &result_len, 1, argv, 2);
348  if (PQresultStatus(res) == PGRES_COMMAND_OK)
349  {
350  PQclear(res);
351  return retval;
352  }
353  else
354  {
355  PQclear(res);
356  return -1;
357  }
358 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
union PQArgBlock::@161 u
Oid fn_lo_write
Definition: libpq-int.h:282
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2652
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
static char * buf
Definition: pg_test_fsync.c:68
#define unconstify(underlying_type, expr)
Definition: c.h:1185
PQExpBufferData errorMessage
Definition: libpq-int.h:526
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int isint
Definition: libpq-fe.h:226
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:441
int * ptr
Definition: libpq-fe.h:229
#define libpq_gettext(x)
Definition: libpq-int.h:805
int integer
Definition: libpq-fe.h:230
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ pg_char_to_encoding()

int pg_char_to_encoding ( const char *  name)

Definition at line 550 of file encnames.c.

References clean_encoding_name(), sort-test::key, lengthof, NAMEDATALEN, and pg_encname_tbl.

Referenced by CreateConversionCommand(), length_in_encoding(), main(), PG_char_to_encoding(), pg_convert(), pg_get_utf8_id(), pg_valid_client_encoding(), pg_valid_server_encoding(), PQenv2encoding(), pqSaveParameterStatus(), ProcessCopyOptions(), processEncodingEntry(), and to_ascii_encname().

551 {
552  unsigned int nel = lengthof(pg_encname_tbl);
553  const pg_encname *base = pg_encname_tbl,
554  *last = base + nel - 1,
555  *position;
556  int result;
557  char buff[NAMEDATALEN],
558  *key;
559 
560  if (name == NULL || *name == '\0')
561  return -1;
562 
563  if (strlen(name) >= NAMEDATALEN)
564  return -1; /* it's certainly not in the table */
565 
566  key = clean_encoding_name(name, buff);
567 
568  while (last >= base)
569  {
570  position = base + ((last - base) >> 1);
571  result = key[0] - position->name[0];
572 
573  if (result == 0)
574  {
575  result = strcmp(key, position->name);
576  if (result == 0)
577  return position->encoding;
578  }
579  if (result < 0)
580  last = position - 1;
581  else
582  base = position + 1;
583  }
584  return -1;
585 }
#define lengthof(array)
Definition: c.h:676
#define NAMEDATALEN
static const pg_encname pg_encname_tbl[]
Definition: encnames.c:39
const char * name
Definition: encode.c:561
static char * clean_encoding_name(const char *key, char *newkey)
Definition: encnames.c:525

◆ pg_encoding_to_char()

◆ pg_valid_server_encoding_id()

int pg_valid_server_encoding_id ( int  encoding)

Definition at line 514 of file encnames.c.

References PG_VALID_BE_ENCODING.

Referenced by setup_locale_encoding().

515 {
517 }
#define PG_VALID_BE_ENCODING(_enc)
Definition: pg_wchar.h:295
int32 encoding
Definition: pg_database.h:41

◆ PQbackendPID()

int PQbackendPID ( const PGconn conn)

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

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

Referenced by get_prompt(), libpqrcv_get_backend_pid(), main(), and StartLogStreamer().

6696 {
6697  if (!conn || conn->status != CONNECTION_OK)
6698  return 0;
6699  return conn->be_pid;
6700 }
ConnStatusType status
Definition: libpq-int.h:388
int be_pid
Definition: libpq-int.h:434

◆ PQbinaryTuples()

int PQbinaryTuples ( const PGresult res)

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

References pg_result::binary.

Referenced by ProcessResult().

2786 {
2787  if (!res)
2788  return 0;
2789  return res->binary;
2790 }
int binary
Definition: libpq-int.h:179

◆ PQcancel()

int PQcancel ( PGcancel cancel,
char *  errbuf,
int  errbufsize 
)

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

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

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

4451 {
4452  if (!cancel)
4453  {
4454  strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
4455  return false;
4456  }
4457 
4458  return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
4459  errbuf, errbufsize);
4460 }
static int internal_cancel(SockAddr *raddr, int be_pid, int be_key, char *errbuf, int errbufsize)
Definition: fe-connect.c:4346
int be_pid
Definition: libpq-int.h:539
int be_key
Definition: libpq-int.h:540
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
SockAddr raddr
Definition: libpq-int.h:538

◆ PQclear()

void PQclear ( PGresult res)

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

References pg_result::attDescs, pg_result::curBlock, pg_result::errFields, pg_result::events, free, i, PGEvent::name, pg_result::nEvents, pgresult_data::next, pg_result::paramDescs, PGEvent::passThrough, PGEVT_RESULTDESTROY, PGEvent::proc, PGEventResultDestroy::result, PGEvent::resultInitialized, and pg_result::tuples.

Referenced by _check_database_version(), _doSetSessionAuth(), _selectOutputSchema(), _selectTableAccessMethod(), _selectTablespace(), add_tablespace_footer(), append_depends_on_extension(), appendQualifiedRelation(), BaseBackup(), binary_upgrade_set_pg_class_oids(), binary_upgrade_set_type_oids_by_rel_oid(), binary_upgrade_set_type_oids_by_type_oid(), buildMatViewRefreshDependencies(), buildShSecLabels(), check_for_data_type_usage(), check_for_isn_and_int8_passing_mismatch(), check_for_jsonb_9_4_usage(), check_for_pg_role_prefix(), check_for_prepared_transactions(), check_for_reg_data_type_usage(), check_for_tables_with_oids(), check_for_user_defined_postfix_ops(), check_is_install_user(), check_loadable_libraries(), check_prepare_conn(), check_proper_datallowconn(), ClearOrSaveResult(), close_cursor(), cluster_all_databases(), connectDatabase(), ConnectDatabase(), connectToServer(), convertTSFunction(), create_cursor(), CreateReplicationSlot(), createViewAsClause(), dblink_close(), dblink_exec(), dblink_fetch(), dblink_open(), dblink_res_error(), deallocate_one(), describeAccessMethods(), describeAggregates(), describeFunctions(), describeOneTableDetails(), describeOneTSConfig(), describeOneTSParser(), describeOperators(), describePublications(), DescribeQuery(), describeRoles(), describeSubscriptions(), describeTableDetails(), describeTablespaces(), describeTypes(), descriptor_free(), do_lo_import(), do_lo_list(), do_sql_command(), dropDBs(), DropReplicationSlot(), dropRoles(), dropTablespaces(), dumpAgg(), dumpBaseType(), dumpBlobs(), dumpCollation(), dumpCompositeType(), dumpCompositeTypeColComments(), dumpConversion(), dumpDatabase(), dumpDatabaseConfig(), dumpDatabases(), dumpDomain(), dumpEnumType(), dumpFunc(), dumpGroups(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpRangeType(), dumpRoleMembership(), dumpRoles(), dumpRule(), dumpSearchPath(), dumpSequence(), dumpSequenceData(), dumpStatisticsExt(), dumpTable(), dumpTableData_copy(), dumpTableData_insert(), dumpTableSchema(), dumpTablespaces(), dumpTSConfig(), dumpTSDictionary(), dumpUserConfig(), dumpUserMappings(), ecpg_autostart_transaction(), ecpg_check_PQresult(), ecpg_is_type_an_array(), ecpg_process_output(), ECPGdescribe(), ECPGsetcommit(), ECPGtrans(), EndDBCopyMode(), exec_command_password(), ExecQueryUsingCursor(), execute_foreign_modify(), executeCommand(), executeMaintenanceCommand(), executeQueryOrDie(), ExecuteSqlCommand(), ExecuteSqlStatement(), executeStatement(), expand_dbname_patterns(), expand_foreign_server_name_patterns(), expand_schema_name_patterns(), expand_table_name_patterns(), fail_lo_xact(), fetch_more_data(), findLastBuiltinOid_V71(), finish_foreign_modify(), finish_lo_xact(), get_create_object_cmd(), get_db_infos(), get_language_name(), get_loadable_libraries(), get_parallel_object_list(), get_rel_infos(), get_remote_estimate(), get_returning_data(), get_synchronized_snapshot(), get_tablespace_paths(), getAccessMethods(), getAggregates(), getBlobs(), getCasts(), getCollations(), GetConnection(), getConstraints(), getConversions(), getCopyStart(), getDefaultACLs(), getDependencies(), getDomainConstraints(), getEventTriggers(), getExtendedStatistics(), getExtensionMembership(), getExtensions(), getForeignDataWrappers(), getForeignServers(), getFormattedTypeName(), getFuncs(), getIndexes(), getInherits(), getNamespaces(), getOpclasses(), getOperators(), getOpfamilies(), getParamDescriptions(), getPolicies(), getProcLangs(), getPublications(), getPublicationTables(), getRowDescriptions(), getRules(), getSubscriptions(), getTableAttrs(), GetTableInfo(), getTables(), getTransforms(), getTriggers(), getTSConfigurations(), getTSDictionaries(), getTSParsers(), getTSTemplates(), getTypes(), handleCopyIn(), HandleEndOfCopyStream(), initGenerateDataClientSide(), libpq_executeFileMap(), libpqConnect(), libpqGetFile(), libpqProcessFileList(), libpqrcv_connect(), libpqrcv_create_slot(), libpqrcv_endstreaming(), libpqrcv_exec(), libpqrcv_identify_system(), libpqrcv_PQexec(), libpqrcv_readtimelinehistoryfile(), libpqrcv_receive(), libpqrcv_startstreaming(), listAllDbs(), listCasts(), listCollations(), listConversions(), listDbRoleSettings(), listDefaultACLs(), listDomains(), listEventTriggers(), listExtensionContents(), listExtensions(), listForeignDataWrappers(), listForeignServers(), listForeignTables(), listLanguages(), listOneExtensionContents(), listOperatorClasses(), listOperatorFamilies(), listOpFamilyFunctions(), listOpFamilyOperators(), listPartitionedTables(), listPublications(), listSchemas(), listTables(), listTSConfigs(), listTSConfigsVerbose(), listTSDictionaries(), listTSParsers(), listTSParsersVerbose(), listTSTemplates(), listUserMappings(), lo_close(), lo_creat(), lo_create(), lo_initialize(), lo_lseek(), lo_lseek64(), lo_open(), lo_read(), lo_tell(), lo_tell64(), lo_truncate(), lo_truncate64(), lo_unlink(), lo_write(), lockTableForWorker(), lookup_object_oid(), main(), materializeResult(), new_9_0_populate_pg_largeobject_metadata(), objectDescription(), old_9_6_invalidate_hash_indexes(), permissionsList(), pg_attribute_noreturn(), pgfdw_cancel_query(), pgfdw_exec_cleanup_query(), pgfdw_get_cleanup_result(), pgfdw_get_result(), pgfdw_report_error(), pgfdw_xact_callback(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresEndDirectModify(), postgresImportForeignSchema(), postgresReScanForeignScan(), pqClearAsyncResult(), PQconnectPoll(), PQcopyResult(), PQencryptPasswordConn(), pqEndcopy2(), pqEndcopy3(), PQexecFinish(), PQexecStart(), pqGetErrorNotice2(), pqGetErrorNotice3(), pqInternalNotice(), PQmakeEmptyPGresult(), pqRowProcessor(), PQsetClientEncoding(), pqSetenvPoll(), prepare_common(), prepare_foreign_modify(), processExtensionTables(), processQueryResult(), ProcessResult(), PSQLexecWatch(), readCommandResponse(), ReceiveCopyData(), receiveFileChunks(), ReceiveXlogStream(), reindex_all_databases(), RetrieveDataDirCreatePerm(), RetrieveWalSegSize(), run_permutation(), run_simple_command(), run_simple_query(), RunIdentifySystem(), sendCommand(), SendQuery(), set_frozenxids(), setup_connection(), sql_conn(), sql_exec(), start_lo_xact(), store_returning_result(), storeQueryResult(), StreamLogicalLog(), try_complete_step(), tryExecuteStatement(), vacuum_all_databases(), vacuum_one_database(), and vacuumlo().

695 {
696  PGresult_data *block;
697  int i;
698 
699  if (!res)
700  return;
701 
702  for (i = 0; i < res->nEvents; i++)
703  {
704  /* only send DESTROY to successfully-initialized event procs */
705  if (res->events[i].resultInitialized)
706  {
708 
709  evt.result = res;
710  (void) res->events[i].proc(PGEVT_RESULTDESTROY, &evt,
711  res->events[i].passThrough);
712  }
713  free(res->events[i].name);
714  }
715 
716  if (res->events)
717  free(res->events);
718 
719  /* Free all the subsidiary blocks */
720  while ((block = res->curBlock) != NULL)
721  {
722  res->curBlock = block->next;
723  free(block);
724  }
725 
726  /* Free the top-level tuple pointer array */
727  if (res->tuples)
728  free(res->tuples);
729 
730  /* zero out the pointer fields to catch programming errors */
731  res->attDescs = NULL;
732  res->tuples = NULL;
733  res->paramDescs = NULL;
734  res->errFields = NULL;
735  res->events = NULL;
736  res->nEvents = 0;
737  /* res->curBlock was zeroed out earlier */
738 
739  /* Free the PGresult structure itself */
740  free(res);
741 }
PGMessageField * errFields
Definition: libpq-int.h:197
bool resultInitialized
Definition: libpq-int.h:164
PGresult_data * next
Definition: libpq-int.h:105
int nEvents
Definition: libpq-int.h:188
PGresAttDesc * attDescs
Definition: libpq-int.h:171
PGresAttValue ** tuples
Definition: libpq-int.h:172
PGresult_data * curBlock
Definition: libpq-int.h:208
#define free(a)
Definition: header.h:65
PGresParamDesc * paramDescs
Definition: libpq-int.h:176
PGEventProc proc
Definition: libpq-int.h:160
int i
void * passThrough
Definition: libpq-int.h:162
PGEvent * events
Definition: libpq-int.h:187
char * name
Definition: libpq-int.h:161

◆ PQclientEncoding()

int PQclientEncoding ( const PGconn conn)

◆ PQcmdStatus()

char* PQcmdStatus ( PGresult res)

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

References pg_result::cmdStatus.

Referenced by dblink_exec(), ecpg_process_output(), materializeResult(), PrintQueryResults(), PrintQueryStatus(), PSQLexecWatch(), and SendQuery().

3041 {
3042  if (!res)
3043  return NULL;
3044  return res->cmdStatus;
3045 }
char cmdStatus[CMDSTATUS_LEN]
Definition: libpq-int.h:178

◆ PQcmdTuples()

char* PQcmdTuples ( PGresult res)

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

References pg_result::cmdStatus, pg_result::noticeHooks, and pqInternalNotice().

Referenced by ecpg_process_output(), execute_dml_stmt(), execute_foreign_modify(), and SetResultVariables().

3111 {
3112  char *p,
3113  *c;
3114 
3115  if (!res)
3116  return "";
3117 
3118  if (strncmp(res->cmdStatus, "INSERT ", 7) == 0)
3119  {
3120  p = res->cmdStatus + 7;
3121  /* INSERT: skip oid and space */
3122  while (*p && *p != ' ')
3123  p++;
3124  if (*p == 0)
3125  goto interpret_error; /* no space? */
3126  p++;
3127  }
3128  else if (strncmp(res->cmdStatus, "SELECT ", 7) == 0 ||
3129  strncmp(res->cmdStatus, "DELETE ", 7) == 0 ||
3130  strncmp(res->cmdStatus, "UPDATE ", 7) == 0)
3131  p = res->cmdStatus + 7;
3132  else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0)
3133  p = res->cmdStatus + 6;
3134  else if (strncmp(res->cmdStatus, "MOVE ", 5) == 0 ||
3135  strncmp(res->cmdStatus, "COPY ", 5) == 0)
3136  p = res->cmdStatus + 5;
3137  else
3138  return "";
3139 
3140  /* check that we have an integer (at least one digit, nothing else) */
3141  for (c = p; *c; c++)
3142  {
3143  if (!isdigit((unsigned char) *c))
3144  goto interpret_error;
3145  }
3146  if (c == p)
3147  goto interpret_error;
3148 
3149  return p;
3150 
3151 interpret_error:
3153  "could not interpret result from server: %s",
3154  res->cmdStatus);
3155  return "";
3156 }
PGNoticeHooks noticeHooks
Definition: libpq-int.h:186
char * c
void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...)
Definition: fe-exec.c:871
char cmdStatus[CMDSTATUS_LEN]
Definition: libpq-int.h:178

◆ PQconndefaults()

PQconninfoOption* PQconndefaults ( void  )

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

References conninfo_add_defaults(), conninfo_init(), initPQExpBuffer(), PQconninfoFree(), PQExpBufferDataBroken, and termPQExpBuffer().

Referenced by check_pghost_envvar(), dblink_fdw_validator(), do_connect(), get_connect_string(), InitPgFdwOptions(), and main().

1446 {
1447  PQExpBufferData errorBuf;
1448  PQconninfoOption *connOptions;
1449 
1450  /* We don't actually report any errors here, but callees want a buffer */
1451  initPQExpBuffer(&errorBuf);
1452  if (PQExpBufferDataBroken(errorBuf))
1453  return NULL; /* out of memory already :-( */
1454 
1455  connOptions = conninfo_init(&errorBuf);
1456  if (connOptions != NULL)
1457  {
1458  /* pass NULL errorBuf to ignore errors */
1459  if (!conninfo_add_defaults(connOptions, NULL))
1460  {
1461  PQconninfoFree(connOptions);
1462  connOptions = NULL;
1463  }
1464  }
1465 
1466  termPQExpBuffer(&errorBuf);
1467  return connOptions;
1468 }
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:5293
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:6501
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
static bool conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
Definition: fe-connect.c:5729
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ PQconnectdb()

PGconn* PQconnectdb ( const char *  conninfo)

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

References conn, connectDBComplete(), CONNECTION_BAD, PQconnectStart(), and pg_conn::status.

Referenced by dblink_connect(), dblink_get_conn(), get_db_conn(), libpqConnect(), and main().

704 {
705  PGconn *conn = PQconnectStart(conninfo);
706 
707  if (conn && conn->status != CONNECTION_BAD)
708  (void) connectDBComplete(conn);
709 
710  return conn;
711 }
PGconn * conn
Definition: streamutil.c:54
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:2078
PGconn * PQconnectStart(const char *conninfo)
Definition: fe-connect.c:829
ConnStatusType status
Definition: libpq-int.h:388

◆ PQconnectdbParams()

PGconn* PQconnectdbParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)

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

References conn, connectDBComplete(), CONNECTION_BAD, PQconnectStartParams(), and pg_conn::status.

Referenced by connect_pg_server(), connectDatabase(), ConnectDatabase(), do_connect(), doConnect(), ECPGconnect(), GetConnection(), main(), sql_conn(), and vacuumlo().

650 {
651  PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
652 
653  if (conn && conn->status != CONNECTION_BAD)
654  (void) connectDBComplete(conn);
655 
656  return conn;
657 
658 }
PGconn * conn
Definition: streamutil.c:54
static int connectDBComplete(PGconn *conn)
Definition: fe-connect.c:2078
ConnStatusType status
Definition: libpq-int.h:388
static Datum values[MAXATTR]
Definition: bootstrap.c:165
PGconn * PQconnectStartParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:750

◆ PQconnectionNeedsPassword()

int PQconnectionNeedsPassword ( const PGconn conn)

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

References password, pg_conn::password_needed, and PQpass().

Referenced by connectDatabase(), ConnectDatabase(), do_connect(), doConnect(), GetConnection(), main(), sql_conn(), and vacuumlo().

6704 {
6705  char *password;
6706 
6707  if (!conn)
6708  return false;
6709  password = PQpass(conn);
6710  if (conn->password_needed &&
6711  (password == NULL || password[0] == '\0'))
6712  return true;
6713  else
6714  return false;
6715 }
bool password_needed
Definition: libpq-int.h:417
char * PQpass(const PGconn *conn)
Definition: fe-connect.c:6535
static char * password
Definition: streamutil.c:53

◆ PQconnectionUsedPassword()

int PQconnectionUsedPassword ( const PGconn conn)

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

References pg_conn::password_needed.

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

6719 {
6720  if (!conn)
6721  return false;
6722  if (conn->password_needed)
6723  return true;
6724  else
6725  return false;
6726 }
bool password_needed
Definition: libpq-int.h:417

◆ PQconnectPoll()

PostgresPollingStatusType PQconnectPoll ( PGconn conn)

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

References SockAddr::addr, pg_conn::addr_cur, pg_conn::addrlist, pg_conn::addrlist_family, addrinfo::ai_addr, addrinfo::ai_addrlen, addrinfo::ai_family, addrinfo::ai_flags, addrinfo::ai_next, AI_NUMERICHOST, addrinfo::ai_socktype, appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), pg_conn::appname, Assert, pg_conn::asyncStatus, AUTH_REQ_MD5, AUTH_REQ_OK, pg_conn::auth_req_received, CHT_HOST_ADDRESS, CHT_HOST_NAME, CHT_UNIX_SOCKET, connect, connectFailureMessage(), CONNECTION_AUTH_OK, CONNECTION_AWAITING_RESPONSE, CONNECTION_BAD, CONNECTION_CHECK_TARGET, CONNECTION_CHECK_WRITABLE, CONNECTION_CONSUME, CONNECTION_GSS_STARTUP, CONNECTION_MADE, CONNECTION_NEEDED, CONNECTION_OK, CONNECTION_SETENV, CONNECTION_SSL_STARTUP, CONNECTION_STARTED, connectNoDelay(), pg_conn::connhost, pg_conn::connip, PQExpBufferData::data, EINPROGRESS, EINTR, EnvironmentOptions, ERRCODE_APPNAME_UNKNOWN, pg_conn::errorMessage, EWOULDBLOCK, pg_conn::fbappname, free, gai_strerror, getHostaddr(), getpeereid(), pg_conn::gssencmode, pg_conn_host::host, pg_conn_host::hostaddr, pg_conn::inCursor, pg_conn::inEnd, pg_conn::inStart, IS_AF_UNIX, pg_conn::laddr, PQExpBufferData::len, libpq_gettext, MAXPGPATH, MemSet, pg_conn::nconnhost, NEGOTIATE_GSS_CODE, NEGOTIATE_SSL_CODE, pg_conn::next_eo, NI_MAXHOST, parse_int_param(), PG_DIAG_SQLSTATE, pg_fe_sendauth(), pg_getaddrinfo_all(), pg_GSS_have_cred_cache(), pg_hton32, PG_PROTOCOL, PG_PROTOCOL_MAJOR, pg_set_noblock(), PG_STRERROR_R_BUFLEN, PGASYNC_BUSY, PGASYNC_IDLE, PGINVALID_SOCKET, pgpassfileWarning(), PGRES_FATAL_ERROR, PGRES_POLLING_FAILED, PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, PGRES_TUPLES_OK, pg_conn_host::port, pqBuildStartupPacket2(), pqBuildStartupPacket3(), pqCheckInBufferSpace(), PQclear(), pqClearAsyncResult(), PQconsumeInput(), pqDropConnection(), pqDropServerData(), pqFlush(), pqGetc(), pqGetErrorNotice3(), pqGetInt(), pqGetpwuid(), PQgetResult(), pqGets_append(), PQgetvalue(), PQisBusy(), PQntuples(), pqPacketSend(), pqReadData(), PQresultErrorField(), PQresultStatus(), pqsecure_initialize(), pqsecure_open_client(), pqsecure_open_gss(), PQsendQuery(), pqSetenvPoll(), PQTRANS_IDLE, printfPQExpBuffer(), pg_conn::pversion, pg_conn::raddr, release_conn_addrinfo(), pg_conn::requirepeer, restoreErrorMessage(), pg_result::resultStatus, SockAddr::salen, saveErrorMessage(), pg_conn::send_appname, sendTerminateConn(), pg_conn::setenv_state, SETENV_STATE_CLIENT_ENCODING_SEND, setKeepalivesCount(), setKeepalivesIdle(), setKeepalivesInterval(), setTCPUserTimeout(), pg_conn::sigpipe_flag, pg_conn::sigpipe_so, snprintf, pg_conn::sock, SOCK_ERRNO, SOCK_STRERROR, socket, pg_conn::ssl_in_use, pg_conn::sslmode, pg_conn::status, STATUS_OK, strerror_r, pg_conn::sversion, pg_conn::target_session_attrs, termPQExpBuffer(), pg_conn::try_next_addr, pg_conn::try_next_host, pg_conn_host::type, UNIXSOCK_PATH, UNIXSOCK_PATH_BUFLEN, useKeepalives(), _internalPQconninfoOption::val, pg_conn::whichhost, and pg_conn::xactStatus.

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

2261 {
2262  bool reset_connection_state_machine = false;
2263  bool need_new_connection = false;
2264  PGresult *res;
2265  char sebuf[PG_STRERROR_R_BUFLEN];
2266  int optval;
2267  PQExpBufferData savedMessage;
2268 
2269  if (conn == NULL)
2270  return PGRES_POLLING_FAILED;
2271 
2272  /* Get the new data */
2273  switch (conn->status)
2274  {
2275  /*
2276  * We really shouldn't have been polled in these two cases, but we
2277  * can handle it.
2278  */
2279  case CONNECTION_BAD:
2280  return PGRES_POLLING_FAILED;
2281  case CONNECTION_OK:
2282  return PGRES_POLLING_OK;
2283 
2284  /* These are reading states */
2286  case CONNECTION_AUTH_OK:
2287  {
2288  /* Load waiting data */
2289  int n = pqReadData(conn);
2290 
2291  if (n < 0)
2292  goto error_return;
2293  if (n == 0)
2294  return PGRES_POLLING_READING;
2295 
2296  break;
2297  }
2298 
2299  /* These are writing states, so we just proceed. */
2300  case CONNECTION_STARTED:
2301  case CONNECTION_MADE:
2302  break;
2303 
2304  /* We allow pqSetenvPoll to decide whether to proceed. */
2305  case CONNECTION_SETENV:
2306  break;
2307 
2308  /* Special cases: proceed without waiting. */
2310  case CONNECTION_NEEDED:
2312  case CONNECTION_CONSUME:
2314  break;
2315 
2316  default:
2318  libpq_gettext("invalid connection state, probably indicative of memory corruption\n"));
2319  goto error_return;
2320  }
2321 
2322 
2323 keep_going: /* We will come back to here until there is
2324  * nothing left to do. */
2325 
2326  /* Time to advance to next address, or next host if no more addresses? */
2327  if (conn->try_next_addr)
2328  {
2329  if (conn->addr_cur && conn->addr_cur->ai_next)
2330  {
2331  conn->addr_cur = conn->addr_cur->ai_next;
2332  reset_connection_state_machine = true;
2333  }
2334  else
2335  conn->try_next_host = true;
2336  conn->try_next_addr = false;
2337  }
2338 
2339  /* Time to advance to next connhost[] entry? */
2340  if (conn->try_next_host)
2341  {
2342  pg_conn_host *ch;
2343  struct addrinfo hint;
2344  int thisport;
2345  int ret;
2346  char portstr[MAXPGPATH];
2347 
2348  if (conn->whichhost + 1 >= conn->nconnhost)
2349  {
2350  /*
2351  * Oops, no more hosts. An appropriate error message is already
2352  * set up, so just set the right status.
2353  */
2354  goto error_return;
2355  }
2356  conn->whichhost++;
2357 
2358  /* Drop any address info for previous host */
2359  release_conn_addrinfo(conn);
2360 
2361  /*
2362  * Look up info for the new host. On failure, log the problem in
2363  * conn->errorMessage, then loop around to try the next host. (Note
2364  * we don't clear try_next_host until we've succeeded.)
2365  */
2366  ch = &conn->connhost[conn->whichhost];
2367 
2368  /* Initialize hint structure */
2369  MemSet(&hint, 0, sizeof(hint));
2370  hint.ai_socktype = SOCK_STREAM;
2371  conn->addrlist_family = hint.ai_family = AF_UNSPEC;
2372 
2373  /* Figure out the port number we're going to use. */
2374  if (ch->port == NULL || ch->port[0] == '\0')
2375  thisport = DEF_PGPORT;
2376  else
2377  {
2378  if (!parse_int_param(ch->port, &thisport, conn, "port"))
2379  goto error_return;
2380 
2381  if (thisport < 1 || thisport > 65535)
2382  {
2384  libpq_gettext("invalid port number: \"%s\"\n"),
2385  ch->port);
2386  goto keep_going;
2387  }
2388  }
2389  snprintf(portstr, sizeof(portstr), "%d", thisport);
2390 
2391  /* Use pg_getaddrinfo_all() to resolve the address */
2392  switch (ch->type)
2393  {
2394  case CHT_HOST_NAME:
2395  ret = pg_getaddrinfo_all(ch->host, portstr, &hint,
2396  &conn->addrlist);
2397  if (ret || !conn->addrlist)
2398  {
2400  libpq_gettext("could not translate host name \"%s\" to address: %s\n"),
2401  ch->host, gai_strerror(ret));
2402  goto keep_going;
2403  }
2404  break;
2405 
2406  case CHT_HOST_ADDRESS:
2407  hint.ai_flags = AI_NUMERICHOST;
2408  ret = pg_getaddrinfo_all(ch->hostaddr, portstr, &hint,
2409  &conn->addrlist);
2410  if (ret || !conn->addrlist)
2411  {
2413  libpq_gettext("could not parse network address \"%s\": %s\n"),
2414  ch->hostaddr, gai_strerror(ret));
2415  goto keep_going;
2416  }
2417  break;
2418 
2419  case CHT_UNIX_SOCKET:
2420 #ifdef HAVE_UNIX_SOCKETS
2421  conn->addrlist_family = hint.ai_family = AF_UNIX;
2422  UNIXSOCK_PATH(portstr, thisport, ch->host);
2423  if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
2424  {
2426  libpq_gettext("Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n"),
2427  portstr,
2428  (int) (UNIXSOCK_PATH_BUFLEN - 1));
2429  goto keep_going;
2430  }
2431 
2432  /*
2433  * NULL hostname tells pg_getaddrinfo_all to parse the service
2434  * name as a Unix-domain socket path.
2435  */
2436  ret = pg_getaddrinfo_all(NULL, portstr, &hint,
2437  &conn->addrlist);
2438  if (ret || !conn->addrlist)
2439  {
2441  libpq_gettext("could not translate Unix-domain socket path \"%s\" to address: %s\n"),
2442  portstr, gai_strerror(ret));
2443  goto keep_going;
2444  }
2445 #else
2446  Assert(false);
2447 #endif
2448  break;
2449  }
2450 
2451  /* OK, scan this addrlist for a working server address */
2452  conn->addr_cur = conn->addrlist;
2453  reset_connection_state_machine = true;
2454  conn->try_next_host = false;
2455  }
2456 
2457  /* Reset connection state machine? */
2458  if (reset_connection_state_machine)
2459  {
2460  /*
2461  * (Re) initialize our connection control variables for a set of
2462  * connection attempts to a single server address. These variables
2463  * must persist across individual connection attempts, but we must
2464  * reset them when we start to consider a new server.
2465  */
2466  conn->pversion = PG_PROTOCOL(3, 0);
2467  conn->send_appname = true;
2468 #ifdef USE_SSL
2469  /* initialize these values based on SSL mode */
2470  conn->allow_ssl_try = (conn->sslmode[0] != 'd'); /* "disable" */
2471  conn->wait_ssl_try = (conn->sslmode[0] == 'a'); /* "allow" */
2472 #endif
2473 #ifdef ENABLE_GSS
2474  conn->try_gss = (conn->gssencmode[0] != 'd'); /* "disable" */
2475 #endif
2476 
2477  reset_connection_state_machine = false;
2478  need_new_connection = true;
2479  }
2480 
2481  /* Force a new connection (perhaps to the same server as before)? */
2482  if (need_new_connection)
2483  {
2484  /* Drop any existing connection */
2485  pqDropConnection(conn, true);
2486 
2487  /* Reset all state obtained from old server */
2488  pqDropServerData(conn);
2489 
2490  /* Drop any PGresult we might have, too */
2491  conn->asyncStatus = PGASYNC_IDLE;
2492  conn->xactStatus = PQTRANS_IDLE;
2493  pqClearAsyncResult(conn);
2494 
2495  /* Reset conn->status to put the state machine in the right state */
2496  conn->status = CONNECTION_NEEDED;
2497 
2498  need_new_connection = false;
2499  }
2500 
2501  /* Now try to advance the state machine for this connection */
2502  switch (conn->status)
2503  {
2504  case CONNECTION_NEEDED:
2505  {
2506  /*
2507  * Try to initiate a connection to one of the addresses
2508  * returned by pg_getaddrinfo_all(). conn->addr_cur is the
2509  * next one to try.
2510  *
2511  * The extra level of braces here is historical. It's not
2512  * worth reindenting this whole switch case to remove 'em.
2513  */
2514  {
2515  struct addrinfo *addr_cur = conn->addr_cur;
2516  char host_addr[NI_MAXHOST];
2517 
2518  /*
2519  * Advance to next possible host, if we've tried all of
2520  * the addresses for the current host.
2521  */
2522  if (addr_cur == NULL)
2523  {
2524  conn->try_next_host = true;
2525  goto keep_going;
2526  }
2527 
2528  /* Remember current address for possible error msg */
2529  memcpy(&conn->raddr.addr, addr_cur->ai_addr,
2530  addr_cur->ai_addrlen);
2531  conn->raddr.salen = addr_cur->ai_addrlen;
2532 
2533  /* set connip */
2534  if (conn->connip != NULL)
2535  {
2536  free(conn->connip);
2537  conn->connip = NULL;
2538  }
2539 
2540  getHostaddr(conn, host_addr, NI_MAXHOST);
2541  if (strlen(host_addr) > 0)
2542  conn->connip = strdup(host_addr);
2543 
2544  /*
2545  * purposely ignore strdup failure; not a big problem if
2546  * it fails anyway.
2547  */
2548 
2549  conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
2550  if (conn->sock == PGINVALID_SOCKET)
2551  {
2552  /*
2553  * Silently ignore socket() failure if we have more
2554  * addresses to try; this reduces useless chatter in
2555  * cases where the address list includes both IPv4 and
2556  * IPv6 but kernel only accepts one family.
2557  */
2558  if (addr_cur->ai_next != NULL ||
2559  conn->whichhost + 1 < conn->nconnhost)
2560  {
2561  conn->try_next_addr = true;
2562  goto keep_going;
2563  }
2565  libpq_gettext("could not create socket: %s\n"),
2566  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2567  goto error_return;
2568  }
2569 
2570  /*
2571  * Select socket options: no delay of outgoing data for
2572  * TCP sockets, nonblock mode, close-on-exec. Try the
2573  * next address if any of this fails.
2574  */
2575  if (!IS_AF_UNIX(addr_cur->ai_family))
2576  {
2577  if (!connectNoDelay(conn))
2578  {
2579  /* error message already created */
2580  conn->try_next_addr = true;
2581  goto keep_going;
2582  }
2583  }
2584  if (!pg_set_noblock(conn->sock))
2585  {
2587  libpq_gettext("could not set socket to nonblocking mode: %s\n"),
2588  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2589  conn->try_next_addr = true;
2590  goto keep_going;
2591  }
2592 
2593 #ifdef F_SETFD
2594  if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
2595  {
2597  libpq_gettext("could not set socket to close-on-exec mode: %s\n"),
2598  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2599  conn->try_next_addr = true;
2600  goto keep_going;
2601  }
2602 #endif /* F_SETFD */
2603 
2604  if (!IS_AF_UNIX(addr_cur->ai_family))
2605  {
2606 #ifndef WIN32
2607  int on = 1;
2608 #endif
2609  int usekeepalives = useKeepalives(conn);
2610  int err = 0;
2611 
2612  if (usekeepalives < 0)
2613  {
2615  libpq_gettext("keepalives parameter must be an integer\n"));
2616  err = 1;
2617  }
2618  else if (usekeepalives == 0)
2619  {
2620  /* Do nothing */
2621  }
2622 #ifndef WIN32
2623  else if (setsockopt(conn->sock,
2624  SOL_SOCKET, SO_KEEPALIVE,
2625  (char *) &on, sizeof(on)) < 0)
2626  {
2628  libpq_gettext("setsockopt(%s) failed: %s\n"),
2629  "SO_KEEPALIVE",
2630  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2631  err = 1;
2632  }
2633  else if (!setKeepalivesIdle(conn)
2634  || !setKeepalivesInterval(conn)
2635  || !setKeepalivesCount(conn))
2636  err = 1;
2637 #else /* WIN32 */
2638 #ifdef SIO_KEEPALIVE_VALS
2639  else if (!setKeepalivesWin32(conn))
2640  err = 1;
2641 #endif /* SIO_KEEPALIVE_VALS */
2642 #endif /* WIN32 */
2643  else if (!setTCPUserTimeout(conn))
2644  err = 1;
2645 
2646  if (err)
2647  {
2648  conn->try_next_addr = true;
2649  goto keep_going;
2650  }
2651  }
2652 
2653  /*----------
2654  * We have three methods of blocking SIGPIPE during
2655  * send() calls to this socket:
2656  *
2657  * - setsockopt(sock, SO_NOSIGPIPE)
2658  * - send(sock, ..., MSG_NOSIGNAL)
2659  * - setting the signal mask to SIG_IGN during send()
2660  *
2661  * The third method requires three syscalls per send,
2662  * so we prefer either of the first two, but they are
2663  * less portable. The state is tracked in the following
2664  * members of PGconn:
2665  *
2666  * conn->sigpipe_so - we have set up SO_NOSIGPIPE
2667  * conn->sigpipe_flag - we're specifying MSG_NOSIGNAL
2668  *
2669  * If we can use SO_NOSIGPIPE, then set sigpipe_so here
2670  * and we're done. Otherwise, set sigpipe_flag so that
2671  * we will try MSG_NOSIGNAL on sends. If we get an error
2672  * with MSG_NOSIGNAL, we'll clear that flag and revert to
2673  * signal masking.
2674  *----------
2675  */
2676  conn->sigpipe_so = false;
2677 #ifdef MSG_NOSIGNAL
2678  conn->sigpipe_flag = true;
2679 #else
2680  conn->sigpipe_flag = false;
2681 #endif /* MSG_NOSIGNAL */
2682 
2683 #ifdef SO_NOSIGPIPE
2684  optval = 1;
2685  if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE,
2686  (char *) &optval, sizeof(optval)) == 0)
2687  {
2688  conn->sigpipe_so = true;
2689  conn->sigpipe_flag = false;
2690  }
2691 #endif /* SO_NOSIGPIPE */
2692 
2693  /*
2694  * Start/make connection. This should not block, since we
2695  * are in nonblock mode. If it does, well, too bad.
2696  */
2697  if (connect(conn->sock, addr_cur->ai_addr,
2698  addr_cur->ai_addrlen) < 0)
2699  {
2700  if (SOCK_ERRNO == EINPROGRESS ||
2701 #ifdef WIN32
2702  SOCK_ERRNO == EWOULDBLOCK ||
2703 #endif
2704  SOCK_ERRNO == EINTR)
2705  {
2706  /*
2707  * This is fine - we're in non-blocking mode, and
2708  * the connection is in progress. Tell caller to
2709  * wait for write-ready on socket.
2710  */
2711  conn->status = CONNECTION_STARTED;
2712  return PGRES_POLLING_WRITING;
2713  }
2714  /* otherwise, trouble */
2715  }
2716  else
2717  {
2718  /*
2719  * Hm, we're connected already --- seems the "nonblock
2720  * connection" wasn't. Advance the state machine and
2721  * go do the next stuff.
2722  */
2723  conn->status = CONNECTION_STARTED;
2724  goto keep_going;
2725  }
2726 
2727  /*
2728  * This connection failed. Add the error report to
2729  * conn->errorMessage, then try the next address if any.
2730  */
2732  conn->try_next_addr = true;
2733  goto keep_going;
2734  }
2735  }
2736 
2737  case CONNECTION_STARTED:
2738  {
2739  ACCEPT_TYPE_ARG3 optlen = sizeof(optval);
2740 
2741  /*
2742  * Write ready, since we've made it here, so the connection
2743  * has been made ... or has failed.
2744  */
2745 
2746  /*
2747  * Now check (using getsockopt) that there is not an error
2748  * state waiting for us on the socket.
2749  */
2750 
2751  if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
2752  (char *) &optval, &optlen) == -1)
2753  {
2755  libpq_gettext("could not get socket error status: %s\n"),
2756  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2757  goto error_return;
2758  }
2759  else if (optval != 0)
2760  {
2761  /*
2762  * When using a nonblocking connect, we will typically see
2763  * connect failures at this point, so provide a friendly
2764  * error message.
2765  */
2766  connectFailureMessage(conn, optval);
2767 
2768  /*
2769  * Try the next address if any, just as in the case where
2770  * connect() returned failure immediately.
2771  */
2772  conn->try_next_addr = true;
2773  goto keep_going;
2774  }
2775 
2776  /* Fill in the client address */
2777  conn->laddr.salen = sizeof(conn->laddr.addr);
2778  if (getsockname(conn->sock,
2779  (struct sockaddr *) &conn->laddr.addr,
2780  &conn->laddr.salen) < 0)
2781  {
2783  libpq_gettext("could not get client address from socket: %s\n"),
2784  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2785  goto error_return;
2786  }
2787 
2788  /*
2789  * Make sure we can write before advancing to next step.
2790  */
2791  conn->status = CONNECTION_MADE;
2792  return PGRES_POLLING_WRITING;
2793  }
2794 
2795  case CONNECTION_MADE:
2796  {
2797  char *startpacket;
2798  int packetlen;
2799 
2800  /*
2801  * Implement requirepeer check, if requested and it's a
2802  * Unix-domain socket.
2803  */
2804  if (conn->requirepeer && conn->requirepeer[0] &&
2805  IS_AF_UNIX(conn->raddr.addr.ss_family))
2806  {
2807 #ifndef WIN32
2808  char pwdbuf[BUFSIZ];
2809  struct passwd pass_buf;
2810  struct passwd *pass;
2811  int passerr;
2812 #endif
2813  uid_t uid;
2814  gid_t gid;
2815 
2816  errno = 0;
2817  if (getpeereid(conn->sock, &uid, &gid) != 0)
2818  {
2819  /*
2820  * Provide special error message if getpeereid is a
2821  * stub
2822  */
2823  if (errno == ENOSYS)
2825  libpq_gettext("requirepeer parameter is not supported on this platform\n"));
2826  else
2828  libpq_gettext("could not get peer credentials: %s\n"),
2829  strerror_r(errno, sebuf, sizeof(sebuf)));
2830  goto error_return;
2831  }
2832 
2833 #ifndef WIN32
2834  passerr = pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
2835  if (pass == NULL)
2836  {
2837  if (passerr != 0)
2839  libpq_gettext("could not look up local user ID %d: %s\n"),
2840  (int) uid,
2841  strerror_r(passerr, sebuf, sizeof(sebuf)));
2842  else
2844  libpq_gettext("local user with ID %d does not exist\n"),
2845  (int) uid);
2846  goto error_return;
2847  }
2848 
2849  if (strcmp(pass->pw_name, conn->requirepeer) != 0)
2850  {
2852  libpq_gettext("requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n"),
2853  conn->requirepeer, pass->pw_name);
2854  goto error_return;
2855  }
2856 #else /* WIN32 */
2857  /* should have failed with ENOSYS above */
2858  Assert(false);
2859 #endif /* WIN32 */
2860  }
2861 
2862  if (IS_AF_UNIX(conn->raddr.addr.ss_family))
2863  {
2864  /* Don't request SSL or GSSAPI over Unix sockets */
2865 #ifdef USE_SSL
2866  conn->allow_ssl_try = false;
2867 #endif
2868 #ifdef ENABLE_GSS
2869  conn->try_gss = false;
2870 #endif
2871  }
2872 
2873 #ifdef ENABLE_GSS
2874 
2875  /*
2876  * If GSSAPI encryption is enabled, then call
2877  * pg_GSS_have_cred_cache() which will return true if we can
2878  * acquire credentials (and give us a handle to use in
2879  * conn->gcred), and then send a packet to the server asking
2880  * for GSSAPI Encryption (and skip past SSL negotiation and
2881  * regular startup below).
2882  */
2883  if (conn->try_gss && !conn->gctx)
2884  conn->try_gss = pg_GSS_have_cred_cache(&conn->gcred);
2885  if (conn->try_gss && !conn->gctx)
2886  {
2888 
2889  if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
2890  {
2892  libpq_gettext("could not send GSSAPI negotiation packet: %s\n"),
2893  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2894  goto error_return;
2895  }
2896 
2897  /* Ok, wait for response */
2899  return PGRES_POLLING_READING;
2900  }
2901  else if (!conn->gctx && conn->gssencmode[0] == 'r')
2902  {
2904  libpq_gettext("GSSAPI encryption required but was impossible (possibly no credential cache, no server support, or using a local socket)\n"));
2905  goto error_return;
2906  }
2907 #endif
2908 
2909 #ifdef USE_SSL
2910 
2911  /*
2912  * If SSL is enabled and we haven't already got it running,
2913  * request it instead of sending the startup message.
2914  */
2915  if (conn->allow_ssl_try && !conn->wait_ssl_try &&
2916  !conn->ssl_in_use)
2917  {
2918  ProtocolVersion pv;
2919 
2920  /*
2921  * Send the SSL request packet.
2922  *
2923  * Theoretically, this could block, but it really
2924  * shouldn't since we only got here if the socket is
2925  * write-ready.
2926  */
2928  if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
2929  {
2931  libpq_gettext("could not send SSL negotiation packet: %s\n"),
2932  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2933  goto error_return;
2934  }
2935  /* Ok, wait for response */
2937  return PGRES_POLLING_READING;
2938  }
2939 #endif /* USE_SSL */
2940 
2941  /*
2942  * Build the startup packet.
2943  */
2944  if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2945  startpacket = pqBuildStartupPacket3(conn, &packetlen,
2947  else
2948  startpacket = pqBuildStartupPacket2(conn, &packetlen,
2950  if (!startpacket)
2951  {
2952  /*
2953  * will not appendbuffer here, since it's likely to also
2954  * run out of memory
2955  */
2957  libpq_gettext("out of memory\n"));
2958  goto error_return;
2959  }
2960 
2961  /*
2962  * Send the startup packet.
2963  *
2964  * Theoretically, this could block, but it really shouldn't
2965  * since we only got here if the socket is write-ready.
2966  */
2967  if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
2968  {
2970  libpq_gettext("could not send startup packet: %s\n"),
2971  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2972  free(startpacket);
2973  goto error_return;
2974  }
2975 
2976  free(startpacket);
2977 
2979  return PGRES_POLLING_READING;
2980  }
2981 
2982  /*
2983  * Handle SSL negotiation: wait for postmaster messages and
2984  * respond as necessary.
2985  */
2987  {
2988 #ifdef USE_SSL
2989  PostgresPollingStatusType pollres;
2990 
2991  /*
2992  * On first time through, get the postmaster's response to our
2993  * SSL negotiation packet.
2994  */
2995  if (!conn->ssl_in_use)
2996  {
2997  /*
2998  * We use pqReadData here since it has the logic to
2999  * distinguish no-data-yet from connection closure. Since
3000  * conn->ssl isn't set, a plain recv() will occur.
3001  */
3002  char SSLok;
3003  int rdresult;
3004 
3005  rdresult = pqReadData(conn);
3006  if (rdresult < 0)
3007  {
3008  /* errorMessage is already filled in */
3009  goto error_return;
3010  }
3011  if (rdresult == 0)
3012  {
3013  /* caller failed to wait for data */
3014  return PGRES_POLLING_READING;
3015  }
3016  if (pqGetc(&SSLok, conn) < 0)
3017  {
3018  /* should not happen really */
3019  return PGRES_POLLING_READING;
3020  }
3021  if (SSLok == 'S')
3022  {
3023  /* mark byte consumed */
3024  conn->inStart = conn->inCursor;
3025  /* Set up global SSL state if required */
3026  if (pqsecure_initialize(conn) != 0)
3027  goto error_return;
3028  }
3029  else if (SSLok == 'N')
3030  {
3031  /* mark byte consumed */
3032  conn->inStart = conn->inCursor;
3033  /* OK to do without SSL? */
3034  if (conn->sslmode[0] == 'r' || /* "require" */
3035  conn->sslmode[0] == 'v') /* "verify-ca" or
3036  * "verify-full" */
3037  {
3038  /* Require SSL, but server does not want it */
3040  libpq_gettext("server does not support SSL, but SSL was required\n"));
3041  goto error_return;
3042  }
3043  /* Otherwise, proceed with normal startup */
3044  conn->allow_ssl_try = false;
3045  conn->status = CONNECTION_MADE;
3046  return PGRES_POLLING_WRITING;
3047  }
3048  else if (SSLok == 'E')
3049  {
3050  /*
3051  * Server failure of some sort, such as failure to
3052  * fork a backend process. We need to process and
3053  * report the error message, which might be formatted
3054  * according to either protocol 2 or protocol 3.
3055  * Rather than duplicate the code for that, we flip
3056  * into AWAITING_RESPONSE state and let the code there
3057  * deal with it. Note we have *not* consumed the "E"
3058  * byte here.
3059  */
3061  goto keep_going;
3062  }
3063  else
3064  {
3066  libpq_gettext("received invalid response to SSL negotiation: %c\n"),
3067  SSLok);
3068  goto error_return;
3069  }
3070  }
3071 
3072  /*
3073  * Begin or continue the SSL negotiation process.
3074  */
3075  pollres = pqsecure_open_client(conn);
3076  if (pollres == PGRES_POLLING_OK)
3077  {
3078  /* SSL handshake done, ready to send startup packet */
3079  conn->status = CONNECTION_MADE;
3080  return PGRES_POLLING_WRITING;
3081  }
3082  if (pollres == PGRES_POLLING_FAILED)
3083  {
3084  /*
3085  * Failed ... if sslmode is "prefer" then do a non-SSL
3086  * retry
3087  */
3088  if (conn->sslmode[0] == 'p' /* "prefer" */
3089  && conn->allow_ssl_try /* redundant? */
3090  && !conn->wait_ssl_try) /* redundant? */
3091  {
3092  /* only retry once */
3093  conn->allow_ssl_try = false;
3094  need_new_connection = true;
3095  goto keep_going;
3096  }
3097  /* Else it's a hard failure */
3098  goto error_return;
3099  }
3100  /* Else, return POLLING_READING or POLLING_WRITING status */
3101  return pollres;
3102 #else /* !USE_SSL */
3103  /* can't get here */
3104  goto error_return;
3105 #endif /* USE_SSL */
3106  }
3107 
3109  {
3110 #ifdef ENABLE_GSS
3111  PostgresPollingStatusType pollres;
3112 
3113  /*
3114  * If we haven't yet, get the postmaster's response to our
3115  * negotiation packet
3116  */
3117  if (conn->try_gss && !conn->gctx)
3118  {
3119  char gss_ok;
3120  int rdresult = pqReadData(conn);
3121 
3122  if (rdresult < 0)
3123  /* pqReadData fills in error message */
3124  goto error_return;
3125  else if (rdresult == 0)
3126  /* caller failed to wait for data */
3127  return PGRES_POLLING_READING;
3128  if (pqGetc(&gss_ok, conn) < 0)
3129  /* shouldn't happen... */
3130  return PGRES_POLLING_READING;
3131 
3132  if (gss_ok == 'E')
3133  {
3134  /*
3135  * Server failure of some sort. Assume it's a
3136  * protocol version support failure, and let's see if
3137  * we can't recover (if it's not, we'll get a better
3138  * error message on retry). Server gets fussy if we
3139  * don't hang up the socket, though.
3140  */
3141  conn->try_gss = false;
3142  pqDropConnection(conn, true);
3143  conn->status = CONNECTION_NEEDED;
3144  goto keep_going;
3145  }
3146 
3147  /* mark byte consumed */
3148  conn->inStart = conn->inCursor;
3149 
3150  if (gss_ok == 'N')
3151  {
3152  /* Server doesn't want GSSAPI; fall back if we can */
3153  if (conn->gssencmode[0] == 'r')
3154  {
3156  libpq_gettext("server doesn't support GSSAPI encryption, but it was required\n"));
3157  goto error_return;
3158  }
3159 
3160  conn->try_gss = false;
3161  conn->status = CONNECTION_MADE;
3162  return PGRES_POLLING_WRITING;
3163  }
3164  else if (gss_ok != 'G')
3165  {
3167  libpq_gettext("received invalid response to GSSAPI negotiation: %c\n"),
3168  gss_ok);
3169  goto error_return;
3170  }
3171  }
3172 
3173  /* Begin or continue GSSAPI negotiation */
3174  pollres = pqsecure_open_gss(conn);
3175  if (pollres == PGRES_POLLING_OK)
3176  {
3177  /* All set for startup packet */
3178  conn->status = CONNECTION_MADE;
3179  return PGRES_POLLING_WRITING;
3180  }
3181  else if (pollres == PGRES_POLLING_FAILED &&
3182  conn->gssencmode[0] == 'p')
3183  {
3184  /*
3185  * We failed, but we can retry on "prefer". Have to drop
3186  * the current connection to do so, though.
3187  */
3188  conn->try_gss = false;
3189  pqDropConnection(conn, true);
3190  conn->status = CONNECTION_NEEDED;
3191  goto keep_going;
3192  }
3193  return pollres;
3194 #else /* !ENABLE_GSS */
3195  /* unreachable */
3196  goto error_return;
3197 #endif /* ENABLE_GSS */
3198  }
3199 
3200  /*
3201  * Handle authentication exchange: wait for postmaster messages
3202  * and respond as necessary.
3203  */
3205  {
3206  char beresp;
3207  int msgLength;
3208  int avail;
3209  AuthRequest areq;
3210  int res;
3211 
3212  /*
3213  * Scan the message from current point (note that if we find
3214  * the message is incomplete, we will return without advancing
3215  * inStart, and resume here next time).
3216  */
3217  conn->inCursor = conn->inStart;
3218 
3219  /* Read type byte */
3220  if (pqGetc(&beresp, conn))
3221  {
3222  /* We'll come back when there is more data */
3223  return PGRES_POLLING_READING;
3224  }
3225 
3226  /*
3227  * Validate message type: we expect only an authentication
3228  * request or an error here. Anything else probably means
3229  * it's not Postgres on the other end at all.
3230  */
3231  if (!(beresp == 'R' || beresp == 'E'))
3232  {
3234  libpq_gettext("expected authentication request from server, but received %c\n"),
3235  beresp);
3236  goto error_return;
3237  }
3238 
3239  if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
3240  {
3241  /* Read message length word */
3242  if (pqGetInt(&msgLength, 4, conn))
3243  {
3244  /* We'll come back when there is more data */
3245  return PGRES_POLLING_READING;
3246  }
3247  }
3248  else
3249  {
3250  /* Set phony message length to disable checks below */
3251  msgLength = 8;
3252  }
3253 
3254  /*
3255  * Try to validate message length before using it.
3256  * Authentication requests can't be very large, although GSS
3257  * auth requests may not be that small. Errors can be a
3258  * little larger, but not huge. If we see a large apparent
3259  * length in an error, it means we're really talking to a
3260  * pre-3.0-protocol server; cope.
3261  */
3262  if (beresp == 'R' && (msgLength < 8 || msgLength > 2000))
3263  {
3265  libpq_gettext("expected authentication request from server, but received %c\n"),
3266  beresp);
3267  goto error_return;
3268  }
3269 
3270  if (beresp == 'E' && (msgLength < 8 || msgLength > 30000))
3271  {
3272  /* Handle error from a pre-3.0 server */
3273  conn->inCursor = conn->inStart + 1; /* reread data */
3274  if (pqGets_append(&conn->errorMessage, conn))
3275  {
3276  /* We'll come back when there is more data */
3277  return PGRES_POLLING_READING;
3278  }
3279  /* OK, we read the message; mark data consumed */
3280  conn->inStart = conn->inCursor;
3281 
3282  /*
3283  * The postmaster typically won't end its message with a
3284  * newline, so add one to conform to libpq conventions.
3285  */
3286  appendPQExpBufferChar(&conn->errorMessage, '\n');
3287 
3288  /*
3289  * If we tried to open the connection in 3.0 protocol,
3290  * fall back to 2.0 protocol.
3291  */
3292  if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
3293  {
3294  conn->pversion = PG_PROTOCOL(2, 0);
3295  need_new_connection = true;
3296  goto keep_going;
3297  }
3298 
3299  goto error_return;
3300  }
3301 
3302  /*
3303  * Can't process if message body isn't all here yet.
3304  *
3305  * (In protocol 2.0 case, we are assuming messages carry at
3306  * least 4 bytes of data.)
3307  */
3308  msgLength -= 4;
3309  avail = conn->inEnd - conn->inCursor;
3310  if (avail < msgLength)
3311  {
3312  /*
3313  * Before returning, try to enlarge the input buffer if
3314  * needed to hold the whole message; see notes in
3315  * pqParseInput3.
3316  */
3317  if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
3318  conn))
3319  goto error_return;
3320  /* We'll come back when there is more data */
3321  return PGRES_POLLING_READING;
3322  }
3323 
3324  /* Handle errors. */
3325  if (beresp == 'E')
3326  {
3327  if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
3328  {
3329  if (pqGetErrorNotice3(conn, true))
3330  {
3331  /* We'll come back when there is more data */
3332  return PGRES_POLLING_READING;
3333  }
3334  }
3335  else
3336  {
3337  if (pqGets_append(&conn->errorMessage, conn))
3338  {
3339  /* We'll come back when there is more data */
3340  return PGRES_POLLING_READING;
3341  }
3342  }
3343  /* OK, we read the message; mark data consumed */
3344  conn->inStart = conn->inCursor;
3345 
3346  /* Check to see if we should mention pgpassfile */
3347  pgpassfileWarning(conn);
3348 
3349 #ifdef ENABLE_GSS
3350 
3351  /*
3352  * If gssencmode is "prefer" and we're using GSSAPI, retry
3353  * without it.
3354  */
3355  if (conn->gssenc && conn->gssencmode[0] == 'p')
3356  {
3357  /* postmaster expects us to drop the connection */
3358  conn->try_gss = false;
3359  pqDropConnection(conn, true);
3360  conn->status = CONNECTION_NEEDED;
3361  goto keep_going;
3362  }
3363 #endif
3364 
3365 #ifdef USE_SSL
3366 
3367  /*
3368  * if sslmode is "allow" and we haven't tried an SSL
3369  * connection already, then retry with an SSL connection
3370  */
3371  if (conn->sslmode[0] == 'a' /* "allow" */
3372  && !conn->ssl_in_use
3373  && conn->allow_ssl_try
3374  && conn->wait_ssl_try)
3375  {
3376  /* only retry once */
3377  conn->wait_ssl_try = false;
3378  need_new_connection = true;
3379  goto keep_going;
3380  }
3381 
3382  /*
3383  * if sslmode is "prefer" and we're in an SSL connection,
3384  * then do a non-SSL retry
3385  */
3386  if (conn->sslmode[0] == 'p' /* "prefer" */
3387  && conn->ssl_in_use
3388  && conn->allow_ssl_try /* redundant? */
3389  && !conn->wait_ssl_try) /* redundant? */
3390  {
3391  /* only retry once */
3392  conn->allow_ssl_try = false;
3393  need_new_connection = true;
3394  goto keep_going;
3395  }
3396 #endif
3397 
3398  goto error_return;
3399  }
3400 
3401  /* It is an authentication request. */
3402  conn->auth_req_received = true;
3403 
3404  /* Get the type of request. */
3405  if (pqGetInt((int *) &areq, 4, conn))
3406  {
3407  /* We'll come back when there are more data */
3408  return PGRES_POLLING_READING;
3409  }
3410  msgLength -= 4;
3411 
3412  /*
3413  * Ensure the password salt is in the input buffer, if it's an
3414  * MD5 request. All the other authentication methods that
3415  * contain extra data in the authentication request are only
3416  * supported in protocol version 3, in which case we already
3417  * read the whole message above.
3418  */
3419  if (areq == AUTH_REQ_MD5 && PG_PROTOCOL_MAJOR(conn->pversion) < 3)
3420  {
3421  msgLength += 4;
3422 
3423  avail = conn->inEnd - conn->inCursor;
3424  if (avail < 4)
3425  {
3426  /*
3427  * Before returning, try to enlarge the input buffer
3428  * if needed to hold the whole message; see notes in
3429  * pqParseInput3.
3430  */
3431  if (pqCheckInBufferSpace(conn->inCursor + (size_t) 4,
3432  conn))
3433  goto error_return;
3434  /* We'll come back when there is more data */
3435  return PGRES_POLLING_READING;
3436  }
3437  }
3438 
3439  /*
3440  * Process the rest of the authentication request message, and
3441  * respond to it if necessary.
3442  *
3443  * Note that conn->pghost must be non-NULL if we are going to
3444  * avoid the Kerberos code doing a hostname look-up.
3445  */
3446  res = pg_fe_sendauth(areq, msgLength, conn);
3447  conn->errorMessage.len = strlen(conn->errorMessage.data);
3448 
3449  /* OK, we have processed the message; mark data consumed */
3450  conn->inStart = conn->inCursor;
3451 
3452  if (res != STATUS_OK)
3453  goto error_return;
3454 
3455  /*
3456  * Just make sure that any data sent by pg_fe_sendauth is
3457  * flushed out. Although this theoretically could block, it
3458  * really shouldn't since we don't send large auth responses.
3459  */
3460  if (pqFlush(conn))
3461  goto error_return;
3462 
3463  if (areq == AUTH_REQ_OK)
3464  {
3465  /* We are done with authentication exchange */
3466  conn->status = CONNECTION_AUTH_OK;
3467 
3468  /*
3469  * Set asyncStatus so that PQgetResult will think that
3470  * what comes back next is the result of a query. See
3471  * below.
3472  */
3473  conn->asyncStatus = PGASYNC_BUSY;
3474  }
3475 
3476  /* Look to see if we have more data yet. */
3477  goto keep_going;
3478  }
3479 
3480  case CONNECTION_AUTH_OK:
3481  {
3482  /*
3483  * Now we expect to hear from the backend. A ReadyForQuery
3484  * message indicates that startup is successful, but we might
3485  * also get an Error message indicating failure. (Notice
3486  * messages indicating nonfatal warnings are also allowed by
3487  * the protocol, as are ParameterStatus and BackendKeyData
3488  * messages.) Easiest way to handle this is to let
3489  * PQgetResult() read the messages. We just have to fake it
3490  * out about the state of the connection, by setting
3491  * asyncStatus = PGASYNC_BUSY (done above).
3492  */
3493 
3494  if (PQisBusy(conn))
3495  return PGRES_POLLING_READING;
3496 
3497  res = PQgetResult(conn);
3498 
3499  /*
3500  * NULL return indicating we have gone to IDLE state is
3501  * expected
3502  */
3503  if (res)
3504  {
3505  if (res->resultStatus != PGRES_FATAL_ERROR)
3507  libpq_gettext("unexpected message from server during startup\n"));
3508  else if (conn->send_appname &&
3509  (conn->appname || conn->fbappname))
3510  {
3511  /*
3512  * If we tried to send application_name, check to see
3513  * if the error is about that --- pre-9.0 servers will
3514  * reject it at this stage of the process. If so,
3515  * close the connection and retry without sending
3516  * application_name. We could possibly get a false
3517  * SQLSTATE match here and retry uselessly, but there
3518  * seems no great harm in that; we'll just get the
3519  * same error again if it's unrelated.
3520  */
3521  const char *sqlstate;
3522 
3523  sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
3524  if (sqlstate &&
3525  strcmp(sqlstate, ERRCODE_APPNAME_UNKNOWN) == 0)
3526  {
3527  PQclear(res);
3528  conn->send_appname = false;
3529  need_new_connection = true;
3530  goto keep_going;
3531  }
3532  }
3533 
3534  /*
3535  * if the resultStatus is FATAL, then conn->errorMessage
3536  * already has a copy of the error; needn't copy it back.
3537  * But add a newline if it's not there already, since
3538  * postmaster error messages may not have one.
3539  */
3540  if (conn->errorMessage.len <= 0 ||
3541  conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
3542  appendPQExpBufferChar(&conn->errorMessage, '\n');
3543  PQclear(res);
3544  goto error_return;
3545  }
3546 
3547  /* Fire up post-connection housekeeping if needed */
3548  if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
3549  {
3550  conn->status = CONNECTION_SETENV;
3552  conn->next_eo = EnvironmentOptions;
3553  return PGRES_POLLING_WRITING;
3554  }
3555 
3556  /* Almost there now ... */
3558  goto keep_going;
3559  }
3560 
3562  {
3563  /*
3564  * If a read-write connection is required, see if we have one.
3565  *
3566  * Servers before 7.4 lack the transaction_read_only GUC, but
3567  * by the same token they don't have any read-only mode, so we
3568  * may just skip the test in that case.
3569  */
3570  if (conn->sversion >= 70400 &&
3571  conn->target_session_attrs != NULL &&
3572  strcmp(conn->target_session_attrs, "read-write") == 0)
3573  {
3574  /*
3575  * Save existing error messages across the PQsendQuery
3576  * attempt. This is necessary because PQsendQuery is
3577  * going to reset conn->errorMessage, so we would lose
3578  * error messages related to previous hosts we have tried
3579  * and failed to connect to.
3580  */
3581  if (!saveErrorMessage(conn, &savedMessage))
3582  goto error_return;
3583 
3584  conn->status = CONNECTION_OK;
3585  if (!PQsendQuery(conn,
3586  "SHOW transaction_read_only"))
3587  {
3588  restoreErrorMessage(conn, &savedMessage);
3589  goto error_return;
3590  }
3592  restoreErrorMessage(conn, &savedMessage);
3593  return PGRES_POLLING_READING;
3594  }
3595 
3596  /* We can release the address list now. */
3597  release_conn_addrinfo(conn);
3598 
3599  /* We are open for business! */
3600  conn->status = CONNECTION_OK;
3601  return PGRES_POLLING_OK;
3602  }
3603 
3604  case CONNECTION_SETENV:
3605  {
3606  /*
3607  * Do post-connection housekeeping (only needed in protocol
3608  * 2.0).
3609  *
3610  * We pretend that the connection is OK for the duration of
3611  * these queries.
3612  */
3613  conn->status = CONNECTION_OK;
3614 
3615  switch (pqSetenvPoll(conn))
3616  {
3617  case PGRES_POLLING_OK: /* Success */
3618  break;
3619 
3620  case PGRES_POLLING_READING: /* Still going */
3621  conn->status = CONNECTION_SETENV;
3622  return PGRES_POLLING_READING;
3623 
3624  case PGRES_POLLING_WRITING: /* Still going */
3625  conn->status = CONNECTION_SETENV;
3626  return PGRES_POLLING_WRITING;
3627 
3628  default:
3629  goto error_return;
3630  }
3631 
3632  /* Almost there now ... */
3634  goto keep_going;
3635  }
3636 
3637  case CONNECTION_CONSUME:
3638  {
3639  conn->status = CONNECTION_OK;
3640  if (!PQconsumeInput(conn))
3641  goto error_return;
3642 
3643  if (PQisBusy(conn))
3644  {
3645  conn->status = CONNECTION_CONSUME;
3646  return PGRES_POLLING_READING;
3647  }
3648 
3649  /*
3650  * Call PQgetResult() again to consume NULL result.
3651  */
3652  res = PQgetResult(conn);
3653  if (res != NULL)
3654  {
3655  PQclear(res);
3656  conn->status = CONNECTION_CONSUME;
3657  goto keep_going;
3658  }
3659 
3660  /* We can release the address list now. */
3661  release_conn_addrinfo(conn);
3662 
3663  /* We are open for business! */
3664  conn->status = CONNECTION_OK;
3665  return PGRES_POLLING_OK;
3666  }
3668  {
3669  const char *displayed_host;
3670  const char *displayed_port;
3671 
3672  if (!saveErrorMessage(conn, &savedMessage))
3673  goto error_return;
3674 
3675  conn->status = CONNECTION_OK;
3676  if (!PQconsumeInput(conn))
3677  {
3678  restoreErrorMessage(conn, &savedMessage);
3679  goto error_return;
3680  }
3681 
3682  if (PQisBusy(conn))
3683  {
3685  restoreErrorMessage(conn, &savedMessage);
3686  return PGRES_POLLING_READING;
3687  }
3688 
3689  res = PQgetResult(conn);
3690  if (res && (PQresultStatus(res) == PGRES_TUPLES_OK) &&
3691  PQntuples(res) == 1)
3692  {
3693  char *val;
3694 
3695  val = PQgetvalue(res, 0, 0);
3696  if (strncmp(val, "on", 2) == 0)
3697  {
3698  /* Not writable; fail this connection. */
3699  PQclear(res);
3700  restoreErrorMessage(conn, &savedMessage);
3701 
3702  /* Append error report to conn->errorMessage. */
3703  if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
3704  displayed_host = conn->connhost[conn->whichhost].hostaddr;
3705  else
3706  displayed_host = conn->connhost[conn->whichhost].host;
3707  displayed_port = conn->connhost[conn->whichhost].port;
3708  if (displayed_port == NULL || displayed_port[0] == '\0')
3709  displayed_port = DEF_PGPORT_STR;
3710 
3712  libpq_gettext("could not make a writable "
3713  "connection to server "
3714  "\"%s:%s\"\n"),
3715  displayed_host, displayed_port);
3716 
3717  /* Close connection politely. */
3718  conn->status = CONNECTION_OK;
3719  sendTerminateConn(conn);
3720 
3721  /*
3722  * Try next host if any, but we don't want to consider
3723  * additional addresses for this host.
3724  */
3725  conn->try_next_host = true;
3726  goto keep_going;
3727  }
3728 
3729  /* Session is read-write, so we're good. */
3730  PQclear(res);
3731  termPQExpBuffer(&savedMessage);
3732 
3733  /*
3734  * Finish reading any remaining messages before being
3735  * considered as ready.
3736  */
3737  conn->status = CONNECTION_CONSUME;
3738  goto keep_going;
3739  }
3740 
3741  /*
3742  * Something went wrong with "SHOW transaction_read_only". We
3743  * should try next addresses.
3744  */
3745  if (res)
3746  PQclear(res);
3747  restoreErrorMessage(conn, &savedMessage);
3748 
3749  /* Append error report to conn->errorMessage. */
3750  if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
3751  displayed_host = conn->connhost[conn->whichhost].hostaddr;
3752  else
3753  displayed_host = conn->connhost[conn->whichhost].host;
3754  displayed_port = conn->connhost[conn->whichhost].port;
3755  if (displayed_port == NULL || displayed_port[0] == '\0')
3756  displayed_port = DEF_PGPORT_STR;
3758  libpq_gettext("test \"SHOW transaction_read_only\" failed "
3759  "on server \"%s:%s\"\n"),
3760  displayed_host, displayed_port);
3761 
3762  /* Close connection politely. */
3763  conn->status = CONNECTION_OK;
3764  sendTerminateConn(conn);
3765 
3766  /* Try next address */
3767  conn->try_next_addr = true;
3768  goto keep_going;
3769  }
3770 
3771  default:
3773  libpq_gettext("invalid connection state %d, "
3774  "probably indicative of memory corruption\n"),
3775  conn->status);
3776  goto error_return;
3777  }
3778 
3779  /* Unreachable */
3780 
3781 error_return:
3782 
3783  /*
3784  * We used to close the socket at this point, but that makes it awkward
3785  * for those above us if they wish to remove this socket from their own
3786  * records (an fd_set for example). We'll just have this socket closed
3787  * when PQfinish is called (which is compulsory even after an error, since
3788  * the connection structure must be freed).
3789  */
3790  conn->status = CONNECTION_BAD;
3791  return PGRES_POLLING_FAILED;
3792 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:1012
bool sigpipe_flag
Definition: libpq-int.h:419
char * gssencmode
Definition: libpq-int.h:366
#define NEGOTIATE_GSS_CODE
Definition: pqcomm.h:206
int inEnd
Definition: libpq-int.h:448
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
#define UNIXSOCK_PATH(path, port, sockdir)
Definition: pqcomm.h:70
int inStart
Definition: libpq-int.h:446
static void release_conn_addrinfo(PGconn *conn)
Definition: fe-connect.c:4097
struct addrinfo * addr_cur
Definition: libpq-int.h:427
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
static int connectNoDelay(PGconn *conn)
Definition: fe-connect.c:1612
int pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
Definition: fe-auth.c:863
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
int getpeereid(int sock, uid_t *uid, gid_t *gid)
Definition: getpeereid.c:35
#define UNIXSOCK_PATH_BUFLEN
Definition: pqcomm.h:86
bool sigpipe_so
Definition: libpq-int.h:418
char * pqBuildStartupPacket2(PGconn *conn, int *packetlen, const PQEnvironmentOption *options)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
#define AUTH_REQ_OK
Definition: pqcomm.h:165
int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
Definition: fe-misc.c:394
#define PG_STRERROR_R_BUFLEN
Definition: port.h:233
static void pgpassfileWarning(PGconn *conn)
Definition: fe-connect.c:7072
char * requirepeer
Definition: libpq-int.h:365
char * host
Definition: libpq-int.h:312
struct sockaddr_storage addr
Definition: pqcomm.h:64
static int setKeepalivesIdle(PGconn *conn)
Definition: fe-connect.c:1810
#define MemSet(start, val, len)
Definition: c.h:950
int pqGetInt(int *result, size_t bytes, PGconn *conn)
Definition: fe-misc.c:253
static bool saveErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
Definition: fe-connect.c:2197
#define connect(s, name, namelen)
Definition: win32_port.h:463
static void sendTerminateConn(PGconn *conn)
Definition: fe-connect.c:4112
void pqDropConnection(PGconn *conn, bool flushInput)
Definition: fe-connect.c:459
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:104
#define AI_NUMERICHOST
Definition: getaddrinfo.h:73
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
uint32 AuthRequest
Definition: pqcomm.h:179
struct addrinfo * addrlist
Definition: libpq-int.h:426
#define AUTH_REQ_MD5
Definition: pqcomm.h:170
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
pg_conn_host_type type
Definition: libpq-int.h:311
PostgresPollingStatusType pqSetenvPoll(PGconn *conn)
Definition: fe-protocol2.c:47
static void getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
Definition: fe-connect.c:1639
#define gai_strerror
Definition: getaddrinfo.h:146
int pg_getaddrinfo_all(const char *hostname, const char *servname, const struct addrinfo *hintp, struct addrinfo **result)
Definition: ip.c:57
static bool parse_int_param(const char *value, int *result, PGconn *conn, const char *context)
Definition: fe-connect.c:1764
int sversion
Definition: libpq-int.h:415
#define SOCK_STRERROR
Definition: libpq-int.h:819
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1234
PGAsyncStatusType asyncStatus
Definition: libpq-int.h:389
#define NI_MAXHOST
Definition: getaddrinfo.h:88
PGSetenvStatusType setenv_state
Definition: libpq-int.h:429
static int setTCPUserTimeout(PGconn *conn)
Definition: fe-connect.c:1965
static int useKeepalives(PGconn *conn)
Definition: fe-connect.c:1745
#define pg_hton32(x)
Definition: pg_bswap.h:121
#define IS_AF_UNIX(fam)
Definition: ip.h:24
#define SOCK_ERRNO
Definition: libpq-int.h:818
int pqGetErrorNotice3(PGconn *conn, bool isError)
Definition: fe-protocol3.c:871
#define MAXPGPATH
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
bool try_next_host
Definition: libpq-int.h:425
#define ERRCODE_APPNAME_UNKNOWN
Definition: fe-connect.c:92
char * hostaddr
Definition: libpq-int.h:313
pg_conn_host * connhost
Definition: libpq-int.h:406
int pqReadData(PGconn *conn)
Definition: fe-misc.c:615
bool ssl_in_use
Definition: libpq-int.h:472
const PQEnvironmentOption * next_eo
Definition: libpq-int.h:430
static void restoreErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
Definition: fe-connect.c:2219
char * appname
Definition: libpq-int.h:343
PostgresPollingStatusType pqsecure_open_client(PGconn *conn)
Definition: fe-secure.c:183
ACCEPT_TYPE_ARG3 salen
Definition: pqcomm.h:65
char * target_session_attrs
Definition: libpq-int.h:374
static void pqDropServerData(PGconn *conn)
Definition: fe-connect.c:554
#define STATUS_OK
Definition: c.h:1112
pgsocket sock
Definition: libpq-int.h:410
uint32 ProtocolVersion
Definition: pqcomm.h:113
int pqGetc(char *result, PGconn *conn)
Definition: fe-misc.c:80
static void connectFailureMessage(PGconn *conn, int errorno)
Definition: fe-connect.c:1671
#define socket(af, type, protocol)
Definition: win32_port.h:459
SockAddr raddr
Definition: libpq-int.h:413
#define PGINVALID_SOCKET
Definition: port.h:33
int addrlist_family
Definition: libpq-int.h:428
int pqsecure_initialize(PGconn *conn)
Definition: fe-secure.c:168
int PQconsumeInput(PGconn *conn)
Definition: fe-exec.c:1704
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
char * sslmode
Definition: libpq-int.h:358
PQExpBufferData errorMessage
Definition: libpq-int.h:526
bool try_next_addr
Definition: libpq-int.h:424
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define free(a)
Definition: header.h:65
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2754
#define Assert(condition)
Definition: c.h:746
bool pg_set_noblock(pgsocket sock)
Definition: noblock.c:25
char * connip
Definition: libpq-int.h:407
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:1754
char * pqBuildStartupPacket3(PGconn *conn, int *packetlen, const PQEnvironmentOption *options)
#define strerror_r
Definition: port.h:232
ProtocolVersion pversion
Definition: libpq-int.h:414
ConnStatusType status
Definition: libpq-int.h:388
bool auth_req_received
Definition: libpq-int.h:416
int uid_t
Definition: win32_port.h:236
static int setKeepalivesInterval(PGconn *conn)
Definition: fe-connect.c:1844
SockAddr laddr
Definition: libpq-int.h:412
PostgresPollingStatusType
Definition: libpq-fe.h:74
struct addrinfo * ai_next
Definition: getaddrinfo.h:107
int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer, size_t buflen, struct passwd **result)
Definition: thread.c:65
bool pg_GSS_have_cred_cache(gss_cred_id_t *cred_out)
int pqPacketSend(PGconn *conn, char pack_type, const void *buf, size_t buf_len)
Definition: fe-connect.c:4519
int gid_t
Definition: win32_port.h:237
#define EINPROGRESS
Definition: win32_port.h:355
char * fbappname
Definition: libpq-int.h:344
#define EWOULDBLOCK
Definition: win32_port.h:349
size_t ai_addrlen
Definition: getaddrinfo.h:104
PostgresPollingStatusType pqsecure_open_gss(PGconn *conn)
void pqClearAsyncResult(PGconn *conn)
Definition: fe-exec.c:749
int inCursor
Definition: libpq-int.h:447
#define EINTR
Definition: win32_port.h:343
char * port
Definition: libpq-int.h:314
#define NEGOTIATE_SSL_CODE
Definition: pqcomm.h:205
int nconnhost
Definition: libpq-int.h:404
#define snprintf
Definition: port.h:215
#define PG_PROTOCOL(m, n)
Definition: pqcomm.h:106
int pqGets_append(PQExpBuffer buf, PGconn *conn)
Definition: fe-misc.c:155
long val
Definition: informix.c:664
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1778
struct sockaddr * ai_addr
Definition: getaddrinfo.h:105
static int setKeepalivesCount(PGconn *conn)
Definition: fe-connect.c:1879
int whichhost
Definition: libpq-int.h:405
#define libpq_gettext(x)
Definition: libpq-int.h:805
bool send_appname
Definition: libpq-int.h:431
PGTransactionStatusType xactStatus
Definition: libpq-int.h:390
static const PQEnvironmentOption EnvironmentOptions[]
Definition: fe-connect.c:363
int ai_family
Definition: getaddrinfo.h:101

◆ PQconnectStart()

PGconn* PQconnectStart ( const char *  conninfo)

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

References conn, connectDBStart(), CONNECTION_BAD, connectOptions1(), connectOptions2(), makeEmptyPGconn(), and pg_conn::status.

Referenced by PQconnectdb(), and PQping().

830 {
831  PGconn *conn;
832 
833  /*
834  * Allocate memory for the conn structure
835  */
836  conn = makeEmptyPGconn();
837  if (conn == NULL)
838  return NULL;
839 
840  /*
841  * Parse the conninfo string
842  */
843  if (!connectOptions1(conn, conninfo))
844  return conn;
845 
846  /*
847  * Compute derived options
848  */
849  if (!connectOptions2(conn))
850  return conn;
851 
852  /*
853  * Connect to the database
854  */
855  if (!connectDBStart(conn))
856  {
857  /* Just in case we failed to set it in connectDBStart */
858  conn->status = CONNECTION_BAD;
859  }
860 
861  return conn;
862 }
static bool connectOptions1(PGconn *conn, const char *conninfo)
Definition: fe-connect.c:915
PGconn * conn
Definition: streamutil.c:54
static int connectDBStart(PGconn *conn)
Definition: fe-connect.c:2004
static PGconn * makeEmptyPGconn(void)
Definition: fe-connect.c:3867
ConnStatusType status
Definition: libpq-int.h:388
static bool connectOptions2(PGconn *conn)
Definition: fe-connect.c:1013

◆ PQconnectStartParams()

PGconn* PQconnectStartParams ( const char *const *  keywords,
const char *const *  values,
int  expand_dbname 
)

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

References conn, connectDBStart(), CONNECTION_BAD, connectOptions2(), conninfo_array_parse(), pg_conn::errorMessage, fillPGconn(), makeEmptyPGconn(), PQconninfoFree(), and pg_conn::status.

Referenced by libpqrcv_connect(), PQconnectdbParams(), and PQpingParams().

753 {
754  PGconn *conn;
755  PQconninfoOption *connOptions;
756 
757  /*
758  * Allocate memory for the conn structure
759  */
760  conn = makeEmptyPGconn();
761  if (conn == NULL)
762  return NULL;
763 
764  /*
765  * Parse the conninfo arrays
766  */
767  connOptions = conninfo_array_parse(keywords, values,
768  &conn->errorMessage,
769  true, expand_dbname);
770  if (connOptions == NULL)
771  {
772  conn->status = CONNECTION_BAD;
773  /* errorMessage is already set */
774  return conn;
775  }
776 
777  /*
778  * Move option values into conn structure
779  */
780  if (!fillPGconn(conn, connOptions))
781  {
782  PQconninfoFree(connOptions);
783  return conn;
784  }
785 
786  /*
787  * Free the option info - all is in conn now
788  */
789  PQconninfoFree(connOptions);
790 
791  /*
792  * Compute derived options
793  */
794  if (!connectOptions2(conn))
795  return conn;
796 
797  /*
798  * Connect to the database
799  */
800  if (!connectDBStart(conn))
801  {
802  /* Just in case we failed to set it in connectDBStart */
803  conn->status = CONNECTION_BAD;
804  }
805 
806  return conn;
807 }
PGconn * conn
Definition: streamutil.c:54
static int connectDBStart(PGconn *conn)
Definition: fe-connect.c:2004
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:6501
static PGconn * makeEmptyPGconn(void)
Definition: fe-connect.c:3867
PQExpBufferData errorMessage
Definition: libpq-int.h:526
static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
Definition: fe-connect.c:873
ConnStatusType status
Definition: libpq-int.h:388
static Datum values[MAXATTR]
Definition: bootstrap.c:165
static bool connectOptions2(PGconn *conn)
Definition: fe-connect.c:1013
static PQconninfoOption * conninfo_array_parse(const char *const *keywords, const char *const *values, PQExpBuffer errorMessage, bool use_defaults, int expand_dbname)
Definition: fe-connect.c:5565

◆ PQconninfo()

PQconninfoOption* PQconninfo ( PGconn conn)

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

References conninfo_init(), conninfo_storeval(), _internalPQconninfoOption::connofs, initPQExpBuffer(), _internalPQconninfoOption::keyword, PQExpBufferDataBroken, and termPQExpBuffer().

Referenced by do_connect(), GenerateRecoveryConfig(), and libpqrcv_get_conninfo().

6461 {
6462  PQExpBufferData errorBuf;
6463  PQconninfoOption *connOptions;
6464 
6465  if (conn == NULL)
6466  return NULL;
6467 
6468  /* We don't actually report any errors here, but callees want a buffer */
6469  initPQExpBuffer(&errorBuf);
6470  if (PQExpBufferDataBroken(errorBuf))
6471  return NULL; /* out of memory already :-( */
6472 
6473  connOptions = conninfo_init(&errorBuf);
6474 
6475  if (connOptions != NULL)
6476  {
6478 
6479  for (option = PQconninfoOptions; option->keyword; option++)
6480  {
6481  char **connmember;
6482 
6483  if (option->connofs < 0)
6484  continue;
6485 
6486  connmember = (char **) ((char *) conn + option->connofs);
6487 
6488  if (*connmember)
6489  conninfo_storeval(connOptions, option->keyword, *connmember,
6490  &errorBuf, true, false);
6491  }
6492  }
6493 
6494  termPQExpBuffer(&errorBuf);
6495 
6496  return connOptions;
6497 }
static PQconninfoOption * conninfo_storeval(PQconninfoOption *connOptions, const char *keyword, const char *value, PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode)
Definition: fe-connect.c:6377
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
static PQconninfoOption * conninfo_init(PQExpBuffer errorMessage)
Definition: fe-connect.c:5293
static const internalPQconninfoOption PQconninfoOptions[]
Definition: fe-connect.c:194
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ PQconninfoFree()

void PQconninfoFree ( PQconninfoOption connOptions)

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

References free, _PQconninfoOption::keyword, and _PQconninfoOption::val.

Referenced by check_pghost_envvar(), connectDatabase(), connectOptions1(), conninfo_array_parse(), conninfo_parse(), conninfo_uri_parse(), dblink_connstr_check(), do_connect(), GenerateRecoveryConfig(), GetConnection(), libpqrcv_check_conninfo(), libpqrcv_get_conninfo(), PQconndefaults(), and PQconnectStartParams().

6502 {
6504 
6505  if (connOptions == NULL)
6506  return;
6507 
6508  for (option = connOptions; option->keyword != NULL; option++)
6509  {
6510  if (option->val != NULL)
6511  free(option->val);
6512  }
6513  free(connOptions);
6514 }
#define free(a)
Definition: header.h:65

◆ PQconninfoParse()

PQconninfoOption* PQconninfoParse ( const char *  conninfo,
char **  errmsg 
)

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

References PQExpBufferData::data, initPQExpBuffer(), parse_connection_string(), PQExpBufferDataBroken, and termPQExpBuffer().

Referenced by connectDatabase(), dblink_connstr_check(), do_connect(), GetConnection(), libpqrcv_check_conninfo(), and main().

5272 {
5273  PQExpBufferData errorBuf;
5274  PQconninfoOption *connOptions;
5275 
5276  if (errmsg)
5277  *errmsg = NULL; /* default */
5278  initPQExpBuffer(&errorBuf);
5279  if (PQExpBufferDataBroken(errorBuf))
5280  return NULL; /* out of memory already :-( */
5281  connOptions = parse_connection_string(conninfo, &errorBuf, false);
5282  if (connOptions == NULL && errmsg)
5283  *errmsg = errorBuf.data;
5284  else
5285  termPQExpBuffer(&errorBuf);
5286  return connOptions;
5287 }
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
static PQconninfoOption * parse_connection_string(const char *conninfo, PQExpBuffer errorMessage, bool use_defaults)
Definition: fe-connect.c:5333
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
int errmsg(const char *fmt,...)
Definition: elog.c:821
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ PQconsumeInput()

int PQconsumeInput ( PGconn conn)

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

References pqFlush(), pqIsnonblocking, and pqReadData().

Referenced by advanceConnectionState(), CopyStreamReceive(), dblink_get_notify(), dblink_is_busy(), ecpg_process_output(), libpqrcv_PQgetResult(), libpqrcv_receive(), main(), ParallelSlotsGetIdle(), pgfdw_get_cleanup_result(), pgfdw_get_result(), PQconnectPoll(), PrintNotifications(), StreamLogicalLog(), and try_complete_step().

1705 {
1706  if (!conn)
1707  return 0;
1708 
1709  /*
1710  * for non-blocking connections try to flush the send-queue, otherwise we
1711  * may never get a response for something that may not have already been
1712  * sent because it's in our write buffer!
1713  */
1714  if (pqIsnonblocking(conn))
1715  {
1716  if (pqFlush(conn) < 0)
1717  return 0;
1718  }
1719 
1720  /*
1721  * Load more data, if available. We do this no matter what state we are
1722  * in, since we are probably getting called because the application wants
1723  * to get rid of a read-select condition. Note that we will NOT block
1724  * waiting for more input.
1725  */
1726  if (pqReadData(conn) < 0)
1727  return 0;
1728 
1729  /* Parsing of the data waits till later. */
1730  return 1;
1731 }
int pqFlush(PGconn *conn)
Definition: fe-misc.c:1012
#define pqIsnonblocking(conn)
Definition: libpq-int.h:799
int pqReadData(PGconn *conn)
Definition: fe-misc.c:615

◆ PQcopyResult()

PGresult* PQcopyResult ( const PGresult src,
int  flags 
)

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

References pg_result::attDescs, pg_result::client_encoding, pg_result::cmdStatus, PGEventResultCopy::dest, generate_unaccent_rules::dest, dupEvents(), pg_result::events, i, pgresAttValue::len, pg_result::memorySize, pg_result::nEvents, pg_result::noticeHooks, pg_result::ntups, pg_result::numAttributes, PGEvent::passThrough, PG_COPYRES_ATTRS, PG_COPYRES_EVENTS, PG_COPYRES_NOTICEHOOKS, PG_COPYRES_TUPLES, PGEVT_RESULTCOPY, PGRES_TUPLES_OK, PQclear(), PQmakeEmptyPGresult(), PQsetResultAttrs(), PQsetvalue(), PGEvent::proc, PGEvent::resultInitialized, PGEventResultCopy::src, pg_result::tuples, and pgresAttValue::value.

Referenced by pqRowProcessor().

295 {
296  PGresult *dest;
297  int i;
298 
299  if (!src)
300  return NULL;
301 
302  dest = PQmakeEmptyPGresult(NULL, PGRES_TUPLES_OK);
303  if (!dest)
304  return NULL;
305 
306  /* Always copy these over. Is cmdStatus really useful here? */
307  dest->client_encoding = src->client_encoding;
308  strcpy(dest->cmdStatus, src->cmdStatus);
309 
310  /* Wants attrs? */
311  if (flags & (PG_COPYRES_ATTRS | PG_COPYRES_TUPLES))
312  {
313  if (!PQsetResultAttrs(dest, src->numAttributes, src->attDescs))
314  {
315  PQclear(dest);
316  return NULL;
317  }
318  }
319 
320  /* Wants to copy tuples? */
321  if (flags & PG_COPYRES_TUPLES)
322  {
323  int tup,
324  field;
325 
326  for (tup = 0; tup < src->ntups; tup++)
327  {
328  for (field = 0; field < src->numAttributes; field++)
329  {
330  if (!PQsetvalue(dest, tup, field,
331  src->tuples[tup][field].value,
332  src->tuples[tup][field].len))
333  {
334  PQclear(dest);
335  return NULL;
336  }
337  }
338  }
339  }
340 
341  /* Wants to copy notice hooks? */
342  if (flags & PG_COPYRES_NOTICEHOOKS)
343  dest->noticeHooks = src->noticeHooks;
344 
345  /* Wants to copy PGEvents? */
346  if ((flags & PG_COPYRES_EVENTS) && src->nEvents > 0)
347  {
348  dest->events = dupEvents(src->events, src->nEvents,
349  &dest->memorySize);
350  if (!dest->events)
351  {
352  PQclear(dest);
353  return NULL;
354  }
355  dest->nEvents = src->nEvents;
356  }
357 
358  /* Okay, trigger PGEVT_RESULTCOPY event */
359  for (i = 0; i < dest->nEvents; i++)
360  {
361  if (src->events[i].resultInitialized)
362  {
363  PGEventResultCopy evt;
364 
365  evt.src = src;
366  evt.dest = dest;
367  if (!dest->events[i].proc(PGEVT_RESULTCOPY, &evt,
368  dest->events[i].passThrough))
369  {
370  PQclear(dest);
371  return NULL;
372  }
373  dest->events[i].resultInitialized = true;
374  }
375  }
376 
377  return dest;
378 }
size_t memorySize
Definition: libpq-int.h:212
const PGresult * src
Definition: libpq-events.h:60
bool resultInitialized
Definition: libpq-int.h:164
int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len)
Definition: fe-exec.c:431
int nEvents
Definition: libpq-int.h:188
PGresAttDesc * attDescs
Definition: libpq-int.h:171
#define PG_COPYRES_TUPLES
Definition: libpq-fe.h:35
PGresAttValue ** tuples
Definition: libpq-int.h:172
#define PG_COPYRES_EVENTS
Definition: libpq-fe.h:36
PGNoticeHooks noticeHooks
Definition: libpq-int.h:186
#define PG_COPYRES_NOTICEHOOKS
Definition: libpq-fe.h:37
int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs)
Definition: fe-exec.c:229
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:141
int numAttributes
Definition: libpq-int.h:170
#define PG_COPYRES_ATTRS
Definition: libpq-fe.h:34
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int ntups
Definition: libpq-int.h:169
PGEventProc proc
Definition: libpq-int.h:160
char cmdStatus[CMDSTATUS_LEN]
Definition: libpq-int.h:178
int i
void * passThrough
Definition: libpq-int.h:162
char * value
Definition: libpq-int.h:138
static PGEvent * dupEvents(PGEvent *events, int count, size_t *memSize)
Definition: fe-exec.c:387
PGEvent * events
Definition: libpq-int.h:187
PGresult * dest
Definition: libpq-events.h:61
int client_encoding
Definition: libpq-int.h:189

◆ PQdb()

char* PQdb ( const PGconn conn)

◆ PQdefaultSSLKeyPassHook_OpenSSL()

int PQdefaultSSLKeyPassHook_OpenSSL ( char *  buf,
int  size,
PGconn conn 
)

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

References fprintf, libpq_gettext, and pg_conn::sslpassword.

Referenced by PQssl_passwd_cb().

1714 {
1715  if (conn->sslpassword)
1716  {
1717  if (strlen(conn->sslpassword) + 1 > size)
1718  fprintf(stderr, libpq_gettext("WARNING: sslpassword truncated\n"));
1719  strncpy(buf, conn->sslpassword, size);
1720  buf[size - 1] = '\0';
1721  return strlen(buf);
1722  }
1723  else
1724  {
1725  buf[0] = '\0';
1726  return 0;
1727  }
1728 }
#define fprintf
Definition: port.h:219
static char * buf
Definition: pg_test_fsync.c:68
char * sslpassword
Definition: libpq-int.h:362
#define libpq_gettext(x)
Definition: libpq-int.h:805

◆ PQdescribePortal()

PGresult* PQdescribePortal ( PGconn conn,
const char *  portal 
)

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

References PQexecFinish(), PQexecStart(), and PQsendDescribe().

2176 {
2177  if (!PQexecStart(conn))
2178  return NULL;
2179  if (!PQsendDescribe(conn, 'P', portal))
2180  return NULL;
2181  return PQexecFinish(conn);
2182 }
static int PQsendDescribe(PGconn *conn, char desc_type, const char *desc_target)
Definition: fe-exec.c:2220
static PGresult * PQexecFinish(PGconn *conn)
Definition: fe-exec.c:2095
static bool PQexecStart(PGconn *conn)
Definition: fe-exec.c:2021

◆ PQdescribePrepared()

PGresult* PQdescribePrepared ( PGconn conn,
const char *  stmt 
)

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

References PQexecFinish(), PQexecStart(), and PQsendDescribe().

Referenced by DescribeQuery(), and ECPGdescribe().

2157 {
2158  if (!PQexecStart(conn))
2159  return NULL;
2160  if (!PQsendDescribe(conn, 'S', stmt))
2161  return NULL;
2162  return PQexecFinish(conn);
2163 }
static int PQsendDescribe(PGconn *conn, char desc_type, const char *desc_target)
Definition: fe-exec.c:2220
static PGresult * PQexecFinish(PGconn *conn)
Definition: fe-exec.c:2095
static bool PQexecStart(PGconn *conn)
Definition: fe-exec.c:2021

◆ PQdisplayTuples()

void PQdisplayTuples ( const PGresult res,
FILE *  fp,
int  fillAlign,
const char *  fieldSep,
int  printHeader,
int  quiet 
)

Definition at line 578 of file fe-print.c.

References DEFAULT_FIELD_SEP, fill(), fprintf, free, i, libpq_gettext, malloc, PQfname(), PQgetlength(), PQgetvalue(), PQnfields(), PQntuples(), and generate_unaccent_rules::stdout.

585 {
586 #define DEFAULT_FIELD_SEP " "
587 
588  int i,
589  j;
590  int nFields;
591  int nTuples;
592  int *fLength = NULL;
593 
594  if (fieldSep == NULL)
595  fieldSep = DEFAULT_FIELD_SEP;
596 
597  /* Get some useful info about the results */
598  nFields = PQnfields(res);
599  nTuples = PQntuples(res);
600 
601  if (fp == NULL)
602  fp = stdout;
603 
604  /* Figure the field lengths to align to */
605  /* will be somewhat time consuming for very large results */
606  if (fillAlign)
607  {
608  fLength = (int *) malloc(nFields * sizeof(int));
609  if (!fLength)
610  {
611  fprintf(stderr, libpq_gettext("out of memory\n"));
612  abort();
613  }
614 
615  for (j = 0; j < nFields; j++)
616  {
617  fLength[j] = strlen(PQfname(res, j));
618  for (i = 0; i < nTuples; i++)
619  {
620  int flen = PQgetlength(res, i, j);
621 
622  if (flen > fLength[j])
623  fLength[j] = flen;
624  }
625  }
626  }
627 
628  if (printHeader)
629  {
630  /* first, print out the attribute names */
631  for (i = 0; i < nFields; i++)
632  {
633  fputs(PQfname(res, i), fp);
634  if (fillAlign)
635  fill(strlen(PQfname(res, i)), fLength[i], ' ', fp);
636  fputs(fieldSep, fp);
637  }
638  fprintf(fp, "\n");
639 
640  /* Underline the attribute names */
641  for (i = 0; i < nFields; i++)
642  {
643  if (fillAlign)
644  fill(0, fLength[i], '-', fp);
645  fputs(fieldSep, fp);
646  }
647  fprintf(fp, "\n");
648  }
649 
650  /* next, print out the instances */
651  for (i = 0; i < nTuples; i++)
652  {
653  for (j = 0; j < nFields; j++)
654  {
655  fprintf(fp, "%s", PQgetvalue(res, i, j));
656  if (fillAlign)
657  fill(strlen(PQgetvalue(res, i, j)), fLength[j], ' ', fp);
658  fputs(fieldSep, fp);
659  }
660  fprintf(fp, "\n");
661  }
662 
663  if (!quiet)
664  fprintf(fp, "\nQuery returned %d row%s.\n", PQntuples(res),
665  (PQntuples(res) == 1) ? "" : "s");
666 
667  fflush(fp);
668 
669  if (fLength)
670  free(fLength);
671 }
static void fill(int length, int max, char filler, FILE *fp)
Definition: fe-print.c:761
int PQgetlength(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3174
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2777
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2855
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
#define fprintf
Definition: port.h:219
#define malloc(a)
Definition: header.h:50
#define free(a)
Definition: header.h:65
#define DEFAULT_FIELD_SEP
int i
#define libpq_gettext(x)
Definition: libpq-int.h:805

◆ PQdsplen()

int PQdsplen ( const char *  s,
int  encoding 
)

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

References pg_encoding_dsplen().

Referenced by get_prompt(), pg_wcsformat(), pg_wcssize(), pg_wcswidth(), and strlen_max_width().

1242 {
1243  return pg_encoding_dsplen(encoding, s);
1244 }
int pg_encoding_dsplen(int encoding, const char *mbstr)
Definition: wchar.c:1565
int32 encoding
Definition: pg_database.h:41

◆ PQencryptPassword()

char* PQencryptPassword ( const char *  passwd,
const char *  user 
)

Definition at line 1147 of file fe-auth.c.

References free, malloc, MD5_PASSWD_LEN, and pg_md5_encrypt().

1148 {
1149  char *crypt_pwd;
1150 
1151  crypt_pwd = malloc(MD5_PASSWD_LEN + 1);
1152  if (!crypt_pwd)
1153  return NULL;
1154 
1155  if (!pg_md5_encrypt(passwd, user, strlen(user), crypt_pwd))
1156  {
1157  free(crypt_pwd);
1158  return NULL;
1159  }
1160 
1161  return crypt_pwd;
1162 }
#define malloc(a)
Definition: header.h:50
bool pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf)
Definition: md5.c:323
#define MD5_PASSWD_LEN
Definition: md5.h:20
#define free(a)
Definition: header.h:65
static char * user
Definition: pg_regress.c:95

◆ PQencryptPasswordConn()

char* PQencryptPasswordConn ( PGconn conn,
const char *  passwd,
const char *  user,
const char *  algorithm 
)

Definition at line 1189 of file fe-auth.c.

References pg_conn::errorMessage, free, libpq_gettext, malloc, MAX_ALGORITHM_NAME_LEN, MD5_PASSWD_LEN, pg_fe_scram_build_secret(), pg_md5_encrypt(), PGRES_TUPLES_OK, PQclear(), PQexec(), PQgetvalue(), PQnfields(), PQntuples(), PQresultStatus(), printfPQExpBuffer(), and val.

Referenced by exec_command_password(), and main().

1191 {
1192 #define MAX_ALGORITHM_NAME_LEN 50
1193  char algobuf[MAX_ALGORITHM_NAME_LEN + 1];
1194  char *crypt_pwd = NULL;
1195 
1196  if (!conn)
1197  return NULL;
1198 
1199  /* If no algorithm was given, ask the server. */
1200  if (algorithm == NULL)
1201  {
1202  PGresult *res;
1203  char *val;
1204 
1205  res = PQexec(conn, "show password_encryption");
1206  if (res == NULL)
1207  {
1208  /* PQexec() should've set conn->errorMessage already */
1209  return NULL;
1210  }
1211  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1212  {
1213  /* PQexec() should've set conn->errorMessage already */
1214  PQclear(res);
1215  return NULL;
1216  }
1217  if (PQntuples(res) != 1 || PQnfields(res) != 1)
1218  {
1219  PQclear(res);
1221  libpq_gettext("unexpected shape of result set returned for SHOW\n"));
1222  return NULL;
1223  }
1224  val = PQgetvalue(res, 0, 0);
1225 
1226  if (strlen(val) > MAX_ALGORITHM_NAME_LEN)
1227  {
1228  PQclear(res);
1230  libpq_gettext("password_encryption value too long\n"));
1231  return NULL;
1232  }
1233  strcpy(algobuf, val);
1234  PQclear(res);
1235 
1236  algorithm = algobuf;
1237  }
1238 
1239  /*
1240  * Also accept "on" and "off" as aliases for "md5", because
1241  * password_encryption was a boolean before PostgreSQL 10. We refuse to
1242  * send the password in plaintext even if it was "off".
1243  */
1244  if (strcmp(algorithm, "on") == 0 ||
1245  strcmp(algorithm, "off") == 0)
1246  algorithm = "md5";
1247 
1248  /*
1249  * Ok, now we know what algorithm to use
1250  */
1251  if (strcmp(algorithm, "scram-sha-256") == 0)
1252  {
1253  crypt_pwd = pg_fe_scram_build_secret(passwd);
1254  }
1255  else if (strcmp(algorithm, "md5") == 0)
1256  {
1257  crypt_pwd = malloc(MD5_PASSWD_LEN + 1);
1258  if (crypt_pwd)
1259  {
1260  if (!pg_md5_encrypt(passwd, user, strlen(user), crypt_pwd))
1261  {
1262  free(crypt_pwd);
1263  crypt_pwd = NULL;
1264  }
1265  }
1266  }
1267  else
1268  {
1270  libpq_gettext("unrecognized password encryption algorithm \"%s\"\n"),
1271  algorithm);
1272  return NULL;
1273  }
1274 
1275  if (!crypt_pwd)
1277  libpq_gettext("out of memory\n"));
1278 
1279  return crypt_pwd;
1280 }
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2777
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
#define malloc(a)
Definition: header.h:50
#define MAX_ALGORITHM_NAME_LEN
bool pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf)
Definition: md5.c:323
char * pg_fe_scram_build_secret(const char *password)
PQExpBufferData errorMessage
Definition: libpq-int.h:526
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define MD5_PASSWD_LEN
Definition: md5.h:20
#define free(a)
Definition: header.h:65
static char * user
Definition: pg_regress.c:95
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
long val
Definition: informix.c:664
#define libpq_gettext(x)
Definition: libpq-int.h:805

◆ PQendcopy()

int PQendcopy ( PGconn conn)

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

References PG_PROTOCOL_MAJOR, pqEndcopy2(), pqEndcopy3(), and pg_conn::pversion.

Referenced by ecpg_check_PQresult(), initGenerateDataClientSide(), and libpqrcv_endstreaming().

2619 {
2620  if (!conn)
2621  return 0;
2622 
2623  if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2624  return pqEndcopy3(conn);
2625  else
2626  return pqEndcopy2(conn);
2627 }
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:104
int pqEndcopy3(PGconn *conn)
ProtocolVersion pversion
Definition: libpq-int.h:414
int pqEndcopy2(PGconn *conn)

◆ PQenv2encoding()

int PQenv2encoding ( void  )

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

References dgettext, dngettext, encoding, libpq_gettext, libpq_ngettext, pg_char_to_encoding(), PG_SQL_ASCII, PG_TEXTDOMAIN, and generate_unaccent_rules::str.

Referenced by main().

1251 {
1252  char *str;
1253  int encoding = PG_SQL_ASCII;
1254 
1255  str = getenv("PGCLIENTENCODING");