1/*-------------------------------------------------------------------------
2 *
3 * libpq-int.h
4 * This file contains internal definitions meant to be used only by
5 * the frontend libpq library, not by applications that call it.
6 *
7 * An application can include this file if it wants to bypass the
8 * official API defined by libpq-fe.h, but code that does so is much
9 * more likely to break across PostgreSQL releases than code that uses
10 * only the official API.
11 *
12 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
13 * Portions Copyright (c) 1994, Regents of the University of California
14 *
15 * src/interfaces/libpq/libpq-int.h
16 *
17 *-------------------------------------------------------------------------
18 */
19
20#ifndef LIBPQ_INT_H
21#define LIBPQ_INT_H
22
23/* We assume libpq-fe.h has already been included. */
24#include "libpq-events.h"
25
26#include <time.h>
27#ifndef WIN32
28#include <sys/time.h>
29#endif
30
31#ifdef ENABLE_THREAD_SAFETY
32#ifdef WIN32
33#include "pthread-win32.h"
34#else
35#include <pthread.h>
36#endif
37#include <signal.h>
38#endif
39
40/* include stuff common to fe and be */
41#include "getaddrinfo.h"
42#include "libpq/pqcomm.h"
43/* include stuff found in fe only */
44#include "pqexpbuffer.h"
45
46#ifdef ENABLE_GSS
47#if defined(HAVE_GSSAPI_H)
48#include <gssapi.h>
49#else
50#include <gssapi/gssapi.h>
51#endif
52#endif
53
54#ifdef ENABLE_SSPI
55#define SECURITY_WIN32
56#if defined(WIN32) && !defined(_MSC_VER)
57#include <ntsecapi.h>
58#endif
59#include <security.h>
60#undef SECURITY_WIN32
61
62#ifndef ENABLE_GSS
63/*
64 * Define a fake structure compatible with GSSAPI on Unix.
65 */
66typedef struct
67{
68 void *value;
69 int length;
70} gss_buffer_desc;
71#endif
72#endif /* ENABLE_SSPI */
73
74#ifdef USE_OPENSSL
75#include <openssl/ssl.h>
76#include <openssl/err.h>
77
78#ifndef OPENSSL_NO_ENGINE
79#define USE_SSL_ENGINE
80#endif
81#endif /* USE_OPENSSL */
82
83/*
84 * POSTGRES backend dependent Constants.
85 */
86#define CMDSTATUS_LEN 64 /* should match COMPLETION_TAG_BUFSIZE */
87
88/*
89 * PGresult and the subsidiary types PGresAttDesc, PGresAttValue
90 * represent the result of a query (or more precisely, of a single SQL
91 * command --- a query string given to PQexec can contain multiple commands).
92 * Note we assume that a single command can return at most one tuple group,
93 * hence there is no need for multiple descriptor sets.
94 */
95
96/* Subsidiary-storage management structure for PGresult.
97 * See space management routines in fe-exec.c for details.
98 * Note that space[k] refers to the k'th byte starting from the physical
99 * head of the block --- it's a union, not a struct!
100 */
101typedef union pgresult_data PGresult_data;
102
103union pgresult_data
104{
105 PGresult_data *next; /* link to next block, or NULL */
106 char space[1]; /* dummy for accessing block as bytes */
107};
108
109/* Data about a single parameter of a prepared statement */
110typedef struct pgresParamDesc
111{
112 Oid typid; /* type id */
113} PGresParamDesc;
114
115/*
116 * Data for a single attribute of a single tuple
117 *
118 * We use char* for Attribute values.
119 *
120 * The value pointer always points to a null-terminated area; we add a
121 * null (zero) byte after whatever the backend sends us. This is only
122 * particularly useful for text values ... with a binary value, the
123 * value might have embedded nulls, so the application can't use C string
124 * operators on it. But we add a null anyway for consistency.
125 * Note that the value itself does not contain a length word.
126 *
127 * A NULL attribute is a special case in two ways: its len field is NULL_LEN
128 * and its value field points to null_field in the owning PGresult. All the
129 * NULL attributes in a query result point to the same place (there's no need
130 * to store a null string separately for each one).
131 */
132
133#define NULL_LEN (-1) /* pg_result len for NULL value */
134
135typedef struct pgresAttValue
136{
137 int len; /* length in bytes of the value */
138 char *value; /* actual value, plus terminating zero byte */
139} PGresAttValue;
140
141/* Typedef for message-field list entries */
142typedef struct pgMessageField
143{
144 struct pgMessageField *next; /* list link */
145 char code; /* field code */
146 char contents[FLEXIBLE_ARRAY_MEMBER]; /* value, nul-terminated */
147} PGMessageField;
148
149/* Fields needed for notice handling */
150typedef struct
151{
152 PQnoticeReceiver noticeRec; /* notice message receiver */
153 void *noticeRecArg;
154 PQnoticeProcessor noticeProc; /* notice message processor */
155 void *noticeProcArg;
156} PGNoticeHooks;
157
158typedef struct PGEvent
159{
160 PGEventProc proc; /* the function to call on events */
161 char *name; /* used only for error messages */
162 void *passThrough; /* pointer supplied at registration time */
163 void *data; /* optional state (instance) data */
164 bool resultInitialized; /* T if RESULTCREATE/COPY succeeded */
165} PGEvent;
166
167struct pg_result
168{
169 int ntups;
170 int numAttributes;
171 PGresAttDesc *attDescs;
172 PGresAttValue **tuples; /* each PGresTuple is an array of
173 * PGresAttValue's */
174 int tupArrSize; /* allocated size of tuples array */
175 int numParameters;
176 PGresParamDesc *paramDescs;
177 ExecStatusType resultStatus;
178 char cmdStatus[CMDSTATUS_LEN]; /* cmd status from the query */
179 int binary; /* binary tuple values if binary == 1,
180 * otherwise text */
181
182 /*
183 * These fields are copied from the originating PGconn, so that operations
184 * on the PGresult don't have to reference the PGconn.
185 */
186 PGNoticeHooks noticeHooks;
187 PGEvent *events;
188 int nEvents;
189 int client_encoding; /* encoding id */
190
191 /*
192 * Error information (all NULL if not an error result). errMsg is the
193 * "overall" error message returned by PQresultErrorMessage. If we have
194 * per-field info then it is stored in a linked list.
195 */
196 char *errMsg; /* error message, or NULL if no error */
197 PGMessageField *errFields; /* message broken into fields */
198 char *errQuery; /* text of triggering query, if available */
199
200 /* All NULL attributes in the query result point to this null string */
201 char null_field[1];
202
203 /*
204 * Space management information. Note that attDescs and error stuff, if
205 * not null, point into allocated blocks. But tuples points to a
206 * separately malloc'd block, so that we can realloc it.
207 */
208 PGresult_data *curBlock; /* most recently allocated block */
209 int curOffset; /* start offset of free space in block */
210 int spaceLeft; /* number of free bytes remaining in block */
211
212 size_t memorySize; /* total space allocated for this PGresult */
213};
214
215/* PGAsyncStatusType defines the state of the query-execution state machine */
216typedef enum
217{
218 PGASYNC_IDLE, /* nothing's happening, dude */
219 PGASYNC_BUSY, /* query in progress */
220 PGASYNC_READY, /* result ready for PQgetResult */
221 PGASYNC_COPY_IN, /* Copy In data transfer in progress */
222 PGASYNC_COPY_OUT, /* Copy Out data transfer in progress */
223 PGASYNC_COPY_BOTH /* Copy In/Out data transfer in progress */
224} PGAsyncStatusType;
225
226/* PGQueryClass tracks which query protocol we are now executing */
227typedef enum
228{
229 PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */
230 PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */
231 PGQUERY_PREPARE, /* Parse only (PQprepare) */
232 PGQUERY_DESCRIBE /* Describe Statement or Portal */
233} PGQueryClass;
234
235/* PGSetenvStatusType defines the state of the PQSetenv state machine */
236/* (this is used only for 2.0-protocol connections) */
237typedef enum
238{
239 SETENV_STATE_CLIENT_ENCODING_SEND, /* About to send an Environment Option */
240 SETENV_STATE_CLIENT_ENCODING_WAIT, /* Waiting for above send to complete */
241 SETENV_STATE_OPTION_SEND, /* About to send an Environment Option */
242 SETENV_STATE_OPTION_WAIT, /* Waiting for above send to complete */
243 SETENV_STATE_QUERY1_SEND, /* About to send a status query */
244 SETENV_STATE_QUERY1_WAIT, /* Waiting for query to complete */
245 SETENV_STATE_QUERY2_SEND, /* About to send a status query */
246 SETENV_STATE_QUERY2_WAIT, /* Waiting for query to complete */
247 SETENV_STATE_IDLE
248} PGSetenvStatusType;
249
250/* Typedef for the EnvironmentOptions[] array */
251typedef struct PQEnvironmentOption
252{
253 const char *envName, /* name of an environment variable */
254 *pgName; /* name of corresponding SET variable */
255} PQEnvironmentOption;
256
257/* Typedef for parameter-status list entries */
258typedef struct pgParameterStatus
259{
260 struct pgParameterStatus *next; /* list link */
261 char *name; /* parameter name */
262 char *value; /* parameter value */
263 /* Note: name and value are stored in same malloc block as struct is */
264} pgParameterStatus;
265
266/* large-object-access data ... allocated only if large-object code is used. */
267typedef struct pgLobjfuncs
268{
269 Oid fn_lo_open; /* OID of backend function lo_open */
270 Oid fn_lo_close; /* OID of backend function lo_close */
271 Oid fn_lo_creat; /* OID of backend function lo_creat */
272 Oid fn_lo_create; /* OID of backend function lo_create */
273 Oid fn_lo_unlink; /* OID of backend function lo_unlink */
274 Oid fn_lo_lseek; /* OID of backend function lo_lseek */
275 Oid fn_lo_lseek64; /* OID of backend function lo_lseek64 */
276 Oid fn_lo_tell; /* OID of backend function lo_tell */
277 Oid fn_lo_tell64; /* OID of backend function lo_tell64 */
278 Oid fn_lo_truncate; /* OID of backend function lo_truncate */
279 Oid fn_lo_truncate64; /* OID of function lo_truncate64 */
280 Oid fn_lo_read; /* OID of backend function LOread */
281 Oid fn_lo_write; /* OID of backend function LOwrite */
282} PGlobjfuncs;
283
284/* PGdataValue represents a data field value being passed to a row processor.
285 * It could be either text or binary data; text data is not zero-terminated.
286 * A SQL NULL is represented by len < 0; then value is still valid but there
287 * are no data bytes there.
288 */
289typedef struct pgDataValue
290{
291 int len; /* data length in bytes, or <0 if NULL */
292 const char *value; /* data value, without zero-termination */
293} PGdataValue;
294
295/* Host address type enum for struct pg_conn_host */
296typedef enum pg_conn_host_type
297{
298 CHT_HOST_NAME,
299 CHT_HOST_ADDRESS,
300 CHT_UNIX_SOCKET
301} pg_conn_host_type;
302
303/*
304 * pg_conn_host stores all information about each of possibly several hosts
305 * mentioned in the connection string. Most fields are derived by splitting
306 * the relevant connection parameter (e.g., pghost) at commas.
307 */
308typedef struct pg_conn_host
309{
310 pg_conn_host_type type; /* type of host address */
311 char *host; /* host name or socket path */
312 char *hostaddr; /* host numeric IP address */
313 char *port; /* port number (always provided) */
314 char *password; /* password for this host, read from the
315 * password file; NULL if not sought or not
316 * found in password file. */
317} pg_conn_host;
318
319/*
320 * PGconn stores all the state data associated with a single connection
321 * to a backend.
322 */
323struct pg_conn
324{
325 /* Saved values of connection options */
326 char *pghost; /* the machine on which the server is running,
327 * or a path to a UNIX-domain socket, or a
328 * comma-separated list of machines and/or
329 * paths; if NULL, use DEFAULT_PGSOCKET_DIR */
330 char *pghostaddr; /* the numeric IP address of the machine on
331 * which the server is running, or a
332 * comma-separated list of same. Takes
333 * precedence over pghost. */
334 char *pgport; /* the server's communication port number, or
335 * a comma-separated list of ports */
336 char *pgtty; /* tty on which the backend messages is
337 * displayed (OBSOLETE, NOT USED) */
338 char *connect_timeout; /* connection timeout (numeric string) */
339 char *pgtcp_user_timeout; /* tcp user timeout (numeric string) */
340 char *client_encoding_initial; /* encoding to use */
341 char *pgoptions; /* options to start the backend with */
342 char *appname; /* application name */
343 char *fbappname; /* fallback application name */
344 char *dbName; /* database name */
345 char *replication; /* connect as the replication standby? */
346 char *pguser; /* Postgres username and password, if any */
347 char *pgpass;
348 char *pgpassfile; /* path to a file containing password(s) */
349 char *keepalives; /* use TCP keepalives? */
350 char *keepalives_idle; /* time between TCP keepalives */
351 char *keepalives_interval; /* time between TCP keepalive
352 * retransmits */
353 char *keepalives_count; /* maximum number of TCP keepalive
354 * retransmits */
355 char *sslmode; /* SSL mode (require,prefer,allow,disable) */
356 char *sslcompression; /* SSL compression (0 or 1) */
357 char *sslkey; /* client key filename */
358 char *sslcert; /* client certificate filename */
359 char *sslrootcert; /* root certificate filename */
360 char *sslcrl; /* certificate revocation list filename */
361 char *requirepeer; /* required peer credentials for local sockets */
362
363#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
364 char *krbsrvname; /* Kerberos service name */
365#endif
366
367 /* Type of connection to make. Possible values: any, read-write. */
368 char *target_session_attrs;
369
370 /* Optional file to write trace info to */
371 FILE *Pfdebug;
372
373 /* Callback procedures for notice message processing */
374 PGNoticeHooks noticeHooks;
375
376 /* Event procs registered via PQregisterEventProc */
377 PGEvent *events; /* expandable array of event data */
378 int nEvents; /* number of active events */
379 int eventArraySize; /* allocated array size */
380
381 /* Status indicators */
382 ConnStatusType status;
383 PGAsyncStatusType asyncStatus;
384 PGTransactionStatusType xactStatus; /* never changes to ACTIVE */
385 PGQueryClass queryclass;
386 char *last_query; /* last SQL command, or NULL if unknown */
387 char last_sqlstate[6]; /* last reported SQLSTATE */
388 bool options_valid; /* true if OK to attempt connection */
389 bool nonblocking; /* whether this connection is using nonblock
390 * sending semantics */
391 bool singleRowMode; /* return current query result row-by-row? */
392 char copy_is_binary; /* 1 = copy binary, 0 = copy text */
393 int copy_already_done; /* # bytes already returned in COPY OUT */
394 PGnotify *notifyHead; /* oldest unreported Notify msg */
395 PGnotify *notifyTail; /* newest unreported Notify msg */
396
397 /* Support for multiple hosts in connection string */
398 int nconnhost; /* # of hosts named in conn string */
399 int whichhost; /* host we're currently trying/connected to */
400 pg_conn_host *connhost; /* details about each named host */
401 char *connip; /* IP address for current network connection */
402
403 /* Connection data */
404 pgsocket sock; /* FD for socket, PGINVALID_SOCKET if
405 * unconnected */
406 SockAddr laddr; /* Local address */
407 SockAddr raddr; /* Remote address */
408 ProtocolVersion pversion; /* FE/BE protocol version in use */
409 int sversion; /* server version, e.g. 70401 for 7.4.1 */
410 bool auth_req_received; /* true if any type of auth req received */
411 bool password_needed; /* true if server demanded a password */
412 bool sigpipe_so; /* have we masked SIGPIPE via SO_NOSIGPIPE? */
413 bool sigpipe_flag; /* can we mask SIGPIPE via MSG_NOSIGNAL? */
414 bool write_failed; /* have we had a write failure on sock? */
415 char *write_err_msg; /* write error message, or NULL if OOM */
416
417 /* Transient state needed while establishing connection */
418 bool try_next_addr; /* time to advance to next address/host? */
419 bool try_next_host; /* time to advance to next connhost[]? */
420 struct addrinfo *addrlist; /* list of addresses for current connhost */
421 struct addrinfo *addr_cur; /* the one currently being tried */
422 int addrlist_family; /* needed to know how to free addrlist */
423 PGSetenvStatusType setenv_state; /* for 2.0 protocol only */
424 const PQEnvironmentOption *next_eo;
425 bool send_appname; /* okay to send application_name? */
426
427 /* Miscellaneous stuff */
428 int be_pid; /* PID of backend --- needed for cancels */
429 int be_key; /* key of backend --- needed for cancels */
430 pgParameterStatus *pstatus; /* ParameterStatus data */
431 int client_encoding; /* encoding id */
432 bool std_strings; /* standard_conforming_strings */
433 PGVerbosity verbosity; /* error/notice message verbosity */
434 PGContextVisibility show_context; /* whether to show CONTEXT field */
435 PGlobjfuncs *lobjfuncs; /* private state for large-object access fns */
436
437 /* Buffer for data received from backend and not yet processed */
438 char *inBuffer; /* currently allocated buffer */
439 int inBufSize; /* allocated size of buffer */
440 int inStart; /* offset to first unconsumed data in buffer */
441 int inCursor; /* next byte to tentatively consume */
442 int inEnd; /* offset to first position after avail data */
443
444 /* Buffer for data not yet sent to backend */
445 char *outBuffer; /* currently allocated buffer */
446 int outBufSize; /* allocated size of buffer */
447 int outCount; /* number of chars waiting in buffer */
448
449 /* State for constructing messages in outBuffer */
450 int outMsgStart; /* offset to msg start (length word); if -1,
451 * msg has no length word */
452 int outMsgEnd; /* offset to msg end (so far) */
453
454 /* Row processor interface workspace */
455 PGdataValue *rowBuf; /* array for passing values to rowProcessor */
456 int rowBufLen; /* number of entries allocated in rowBuf */
457
458 /* Status for asynchronous result construction */
459 PGresult *result; /* result being constructed */
460 PGresult *next_result; /* next result (used in single-row mode) */
461
462 /* Assorted state for SASL, SSL, GSS, etc */
463 void *sasl_state;
464
465 /* SSL structures */
466 bool ssl_in_use;
467
468#ifdef USE_SSL
469 bool allow_ssl_try; /* Allowed to try SSL negotiation */
470 bool wait_ssl_try; /* Delay SSL negotiation until after
471 * attempting normal connection */
472#ifdef USE_OPENSSL
473 SSL *ssl; /* SSL status, if have SSL connection */
474 X509 *peer; /* X509 cert of server */
475#ifdef USE_SSL_ENGINE
476 ENGINE *engine; /* SSL engine, if any */
477#else
478 void *engine; /* dummy field to keep struct the same if
479 * OpenSSL version changes */
480#endif
481#endif /* USE_OPENSSL */
482#endif /* USE_SSL */
483
484 char *gssencmode; /* GSS mode (require,prefer,disable) */
485#ifdef ENABLE_GSS
486 gss_ctx_id_t gctx; /* GSS context */
487 gss_name_t gtarg_nam; /* GSS target name */
488
489 /* The following are encryption-only */
490 bool try_gss; /* GSS attempting permitted */
491 bool gssenc; /* GSS encryption is usable */
492 gss_cred_id_t gcred; /* GSS credential temp storage. */
493#endif
494
495#ifdef ENABLE_SSPI
496#ifdef ENABLE_GSS
497 char *gsslib; /* What GSS library to use ("gssapi" or
498 * "sspi") */
499#endif
500 CredHandle *sspicred; /* SSPI credentials handle */
501 CtxtHandle *sspictx; /* SSPI context */
502 char *sspitarget; /* SSPI target name */
503 int usesspi; /* Indicate if SSPI is in use on the
504 * connection */
505#endif
506
507 /* Buffer for current error message */
508 PQExpBufferData errorMessage; /* expansible string */
509
510 /* Buffer for receiving various parts of messages */
511 PQExpBufferData workBuffer; /* expansible string */
512};
513
514/* PGcancel stores all data necessary to cancel a connection. A copy of this
515 * data is required to safely cancel a connection running on a different
516 * thread.
517 */
518struct pg_cancel
519{
520 SockAddr raddr; /* Remote address */
521 int be_pid; /* PID of backend --- needed for cancels */
522 int be_key; /* key of backend --- needed for cancels */
523};
524
525
526/* String descriptions of the ExecStatusTypes.
527 * direct use of this array is deprecated; call PQresStatus() instead.
528 */
529extern char *const pgresStatus[];
530
531
532#ifdef USE_SSL
533
534#ifndef WIN32
535#define USER_CERT_FILE ".postgresql/postgresql.crt"
536#define USER_KEY_FILE ".postgresql/postgresql.key"
537#define ROOT_CERT_FILE ".postgresql/root.crt"
538#define ROOT_CRL_FILE ".postgresql/root.crl"
539#else
540/* On Windows, the "home" directory is already PostgreSQL-specific */
541#define USER_CERT_FILE "postgresql.crt"
542#define USER_KEY_FILE "postgresql.key"
543#define ROOT_CERT_FILE "root.crt"
544#define ROOT_CRL_FILE "root.crl"
545#endif
546
547#endif /* USE_SSL */
548
549/* ----------------
550 * Internal functions of libpq
551 * Functions declared here need to be visible across files of libpq,
552 * but are not intended to be called by applications. We use the
553 * convention "pqXXX" for internal functions, vs. the "PQxxx" names
554 * used for application-visible routines.
555 * ----------------
556 */
557
558/* === in fe-connect.c === */
559
560extern void pqDropConnection(PGconn *conn, bool flushInput);
561extern int pqPacketSend(PGconn *conn, char pack_type,
562 const void *buf, size_t buf_len);
563extern bool pqGetHomeDirectory(char *buf, int bufsize);
564
565#ifdef ENABLE_THREAD_SAFETY
566extern pgthreadlock_t pg_g_threadlock;
567
568#define PGTHREAD_ERROR(msg) \
569 do { \
570 fprintf(stderr, "%s\n", msg); \
571 abort(); \
572 } while (0)
573
574
575#define pglock_thread() pg_g_threadlock(true)
576#define pgunlock_thread() pg_g_threadlock(false)
577#else
578#define pglock_thread() ((void) 0)
579#define pgunlock_thread() ((void) 0)
580#endif
581
582/* === in fe-exec.c === */
583
584extern void pqSetResultError(PGresult *res, const char *msg);
585extern void pqCatenateResultError(PGresult *res, const char *msg);
586extern void *pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary);
587extern char *pqResultStrdup(PGresult *res, const char *str);
588extern void pqClearAsyncResult(PGconn *conn);
589extern void pqSaveErrorResult(PGconn *conn);
590extern PGresult *pqPrepareAsyncResult(PGconn *conn);
591extern void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...) pg_attribute_printf(2, 3);
592extern void pqSaveMessageField(PGresult *res, char code,
593 const char *value);
594extern void pqSaveParameterStatus(PGconn *conn, const char *name,
595 const char *value);
596extern int pqRowProcessor(PGconn *conn, const char **errmsgp);
597
598/* === in fe-protocol2.c === */
599
600extern PostgresPollingStatusType pqSetenvPoll(PGconn *conn);
601
602extern char *pqBuildStartupPacket2(PGconn *conn, int *packetlen,
603 const PQEnvironmentOption *options);
604extern void pqParseInput2(PGconn *conn);
605extern int pqGetCopyData2(PGconn *conn, char **buffer, int async);
606extern int pqGetline2(PGconn *conn, char *s, int maxlen);
607extern int pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize);
608extern int pqEndcopy2(PGconn *conn);
609extern PGresult *pqFunctionCall2(PGconn *conn, Oid fnid,
610 int *result_buf, int *actual_result_len,
611 int result_is_int,
612 const PQArgBlock *args, int nargs);
613
614/* === in fe-protocol3.c === */
615
616extern char *pqBuildStartupPacket3(PGconn *conn, int *packetlen,
617 const PQEnvironmentOption *options);
618extern void pqParseInput3(PGconn *conn);
619extern int pqGetErrorNotice3(PGconn *conn, bool isError);
620extern void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res,
621 PGVerbosity verbosity, PGContextVisibility show_context);
622extern int pqGetCopyData3(PGconn *conn, char **buffer, int async);
623extern int pqGetline3(PGconn *conn, char *s, int maxlen);
624extern int pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize);
625extern int pqEndcopy3(PGconn *conn);
626extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid,
627 int *result_buf, int *actual_result_len,
628 int result_is_int,
629 const PQArgBlock *args, int nargs);
630
631/* === in fe-misc.c === */
632
633 /*
634 * "Get" and "Put" routines return 0 if successful, EOF if not. Note that for
635 * Get, EOF merely means the buffer is exhausted, not that there is
636 * necessarily any error.
637 */
638extern int pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn);
639extern int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn);
640extern int pqGetc(char *result, PGconn *conn);
641extern int pqPutc(char c, PGconn *conn);
642extern int pqGets(PQExpBuffer buf, PGconn *conn);
643extern int pqGets_append(PQExpBuffer buf, PGconn *conn);
644extern int pqPuts(const char *s, PGconn *conn);
645extern int pqGetnchar(char *s, size_t len, PGconn *conn);
646extern int pqSkipnchar(size_t len, PGconn *conn);
647extern int pqPutnchar(const char *s, size_t len, PGconn *conn);
648extern int pqGetInt(int *result, size_t bytes, PGconn *conn);
649extern int pqPutInt(int value, size_t bytes, PGconn *conn);
650extern int pqPutMsgStart(char msg_type, bool force_len, PGconn *conn);
651extern int pqPutMsgEnd(PGconn *conn);
652extern int pqReadData(PGconn *conn);
653extern int pqFlush(PGconn *conn);
654extern int pqWait(int forRead, int forWrite, PGconn *conn);
655extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn,
656 time_t finish_time);
657extern int pqReadReady(PGconn *conn);
658extern int pqWriteReady(PGconn *conn);
659
660/* === in fe-secure.c === */
661
662extern int pqsecure_initialize(PGconn *);
663extern void pqsecure_destroy(void);
664extern PostgresPollingStatusType pqsecure_open_client(PGconn *);
665extern void pqsecure_close(PGconn *);
666extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len);
667extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len);
668extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len);
669extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len);
670
671#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
672extern int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending);
673extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending,
674 bool got_epipe);
675#endif
676
677/* === SSL === */
678
679/*
680 * The SSL implementation provides these functions.
681 */
682
683/*
684 * Implementation of PQinitSSL().
685 */
686extern void pgtls_init_library(bool do_ssl, int do_crypto);
687
688/*
689 * Initialize SSL library.
690 *
691 * The conn parameter is only used to be able to pass back an error
692 * message - no connection-local setup is made here.
693 *
694 * Returns 0 if OK, -1 on failure (with a message in conn->errorMessage).
695 */
696extern int pgtls_init(PGconn *conn);
697
698/*
699 * Begin or continue negotiating a secure session.
700 */
701extern PostgresPollingStatusType pgtls_open_client(PGconn *conn);
702
703/*
704 * Close SSL connection.
705 */
706extern void pgtls_close(PGconn *conn);
707
708/*
709 * Read data from a secure connection.
710 *
711 * On failure, this function is responsible for putting a suitable message
712 * into conn->errorMessage. The caller must still inspect errno, but only
713 * to determine whether to continue/retry after error.
714 */
715extern ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len);
716
717/*
718 * Is there unread data waiting in the SSL read buffer?
719 */
720extern bool pgtls_read_pending(PGconn *conn);
721
722/*
723 * Write data to a secure connection.
724 *
725 * On failure, this function is responsible for putting a suitable message
726 * into conn->errorMessage. The caller must still inspect errno, but only
727 * to determine whether to continue/retry after error.
728 */
729extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len);
730
731/*
732 * Get the hash of the server certificate, for SCRAM channel binding type
733 * tls-server-end-point.
734 *
735 * NULL is sent back to the caller in the event of an error, with an
736 * error message for the caller to consume.
737 *
738 * This is not supported with old versions of OpenSSL that don't have
739 * the X509_get_signature_nid() function.
740 */
741#if defined(USE_OPENSSL) && defined(HAVE_X509_GET_SIGNATURE_NID)
742#define HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
743extern char *pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len);
744#endif
745
746/*
747 * Verify that the server certificate matches the host name we connected to.
748 *
749 * The certificate's Common Name and Subject Alternative Names are considered.
750 *
751 * Returns 1 if the name matches, and 0 if it does not. On error, returns
752 * -1, and sets the libpq error message.
753 *
754 */
755extern int pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
756 int *names_examined,
757 char **first_name);
758
759/* === GSSAPI === */
760
761#ifdef ENABLE_GSS
762
763/*
764 * Establish a GSSAPI-encrypted connection.
765 */
766extern PostgresPollingStatusType pqsecure_open_gss(PGconn *conn);
767
768/*
769 * Read and write functions for GSSAPI-encrypted connections, with internal
770 * buffering to handle nonblocking sockets.
771 */
772extern ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len);
773extern ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len);
774#endif
775
776/* === miscellaneous macros === */
777
778/*
779 * this is so that we can check if a connection is non-blocking internally
780 * without the overhead of a function call
781 */
782#define pqIsnonblocking(conn) ((conn)->nonblocking)
783
784#ifdef ENABLE_NLS
785extern char *libpq_gettext(const char *msgid) pg_attribute_format_arg(1);
786extern char *libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n) pg_attribute_format_arg(1) pg_attribute_format_arg(2);
787#else
788#define libpq_gettext(x) (x)
789#define libpq_ngettext(s, p, n) ((n) == 1 ? (s) : (p))
790#endif
791
792/*
793 * These macros are needed to let error-handling code be portable between
794 * Unix and Windows. (ugh)
795 */
796#ifdef WIN32
797#define SOCK_ERRNO (WSAGetLastError())
798#define SOCK_STRERROR winsock_strerror
799#define SOCK_ERRNO_SET(e) WSASetLastError(e)
800#else
801#define SOCK_ERRNO errno
802#define SOCK_STRERROR strerror_r
803#define SOCK_ERRNO_SET(e) (errno = (e))
804#endif
805
806#endif /* LIBPQ_INT_H */
807