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-2018, 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  */
66 typedef 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  */
101 typedef union pgresult_data PGresult_data;
102 
103 union 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 */
110 typedef 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 
135 typedef 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 */
142 typedef 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 */
150 typedef struct
151 {
152 	PQnoticeReceiver noticeRec; /* notice message receiver */
153 	void	   *noticeRecArg;
154 	PQnoticeProcessor noticeProc;	/* notice message processor */
155 	void	   *noticeProcArg;
156 } PGNoticeHooks;
157 
158 typedef 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 
167 struct 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 
213 /* PGAsyncStatusType defines the state of the query-execution state machine */
214 typedef enum
215 {
216 	PGASYNC_IDLE,				/* nothing's happening, dude */
217 	PGASYNC_BUSY,				/* query in progress */
218 	PGASYNC_READY,				/* result ready for PQgetResult */
219 	PGASYNC_COPY_IN,			/* Copy In data transfer in progress */
220 	PGASYNC_COPY_OUT,			/* Copy Out data transfer in progress */
221 	PGASYNC_COPY_BOTH			/* Copy In/Out data transfer in progress */
222 } PGAsyncStatusType;
223 
224 /* PGQueryClass tracks which query protocol we are now executing */
225 typedef enum
226 {
227 	PGQUERY_SIMPLE,				/* simple Query protocol (PQexec) */
228 	PGQUERY_EXTENDED,			/* full Extended protocol (PQexecParams) */
229 	PGQUERY_PREPARE,			/* Parse only (PQprepare) */
230 	PGQUERY_DESCRIBE			/* Describe Statement or Portal */
231 } PGQueryClass;
232 
233 /* PGSetenvStatusType defines the state of the PQSetenv state machine */
234 /* (this is used only for 2.0-protocol connections) */
235 typedef enum
236 {
237 	SETENV_STATE_CLIENT_ENCODING_SEND,	/* About to send an Environment Option */
238 	SETENV_STATE_CLIENT_ENCODING_WAIT,	/* Waiting for above send to complete */
239 	SETENV_STATE_OPTION_SEND,	/* About to send an Environment Option */
240 	SETENV_STATE_OPTION_WAIT,	/* Waiting for above send to complete */
241 	SETENV_STATE_QUERY1_SEND,	/* About to send a status query */
242 	SETENV_STATE_QUERY1_WAIT,	/* Waiting for query to complete */
243 	SETENV_STATE_QUERY2_SEND,	/* About to send a status query */
244 	SETENV_STATE_QUERY2_WAIT,	/* Waiting for query to complete */
245 	SETENV_STATE_IDLE
246 } PGSetenvStatusType;
247 
248 /* Typedef for the EnvironmentOptions[] array */
249 typedef struct PQEnvironmentOption
250 {
251 	const char *envName,		/* name of an environment variable */
252 			   *pgName;			/* name of corresponding SET variable */
253 } PQEnvironmentOption;
254 
255 /* Typedef for parameter-status list entries */
256 typedef struct pgParameterStatus
257 {
258 	struct pgParameterStatus *next; /* list link */
259 	char	   *name;			/* parameter name */
260 	char	   *value;			/* parameter value */
261 	/* Note: name and value are stored in same malloc block as struct is */
262 } pgParameterStatus;
263 
264 /* large-object-access data ... allocated only if large-object code is used. */
265 typedef struct pgLobjfuncs
266 {
267 	Oid			fn_lo_open;		/* OID of backend function lo_open		*/
268 	Oid			fn_lo_close;	/* OID of backend function lo_close		*/
269 	Oid			fn_lo_creat;	/* OID of backend function lo_creat		*/
270 	Oid			fn_lo_create;	/* OID of backend function lo_create	*/
271 	Oid			fn_lo_unlink;	/* OID of backend function lo_unlink	*/
272 	Oid			fn_lo_lseek;	/* OID of backend function lo_lseek		*/
273 	Oid			fn_lo_lseek64;	/* OID of backend function lo_lseek64	*/
274 	Oid			fn_lo_tell;		/* OID of backend function lo_tell		*/
275 	Oid			fn_lo_tell64;	/* OID of backend function lo_tell64	*/
276 	Oid			fn_lo_truncate; /* OID of backend function lo_truncate	*/
277 	Oid			fn_lo_truncate64;	/* OID of function lo_truncate64 */
278 	Oid			fn_lo_read;		/* OID of backend function LOread		*/
279 	Oid			fn_lo_write;	/* OID of backend function LOwrite		*/
280 } PGlobjfuncs;
281 
282 /* PGdataValue represents a data field value being passed to a row processor.
283  * It could be either text or binary data; text data is not zero-terminated.
284  * A SQL NULL is represented by len < 0; then value is still valid but there
285  * are no data bytes there.
286  */
287 typedef struct pgDataValue
288 {
289 	int			len;			/* data length in bytes, or <0 if NULL */
290 	const char *value;			/* data value, without zero-termination */
291 } PGdataValue;
292 
293 /* Host address type enum for struct pg_conn_host */
294 typedef enum pg_conn_host_type
295 {
296 	CHT_HOST_NAME,
297 	CHT_HOST_ADDRESS,
298 	CHT_UNIX_SOCKET
299 } pg_conn_host_type;
300 
301 /*
302  * pg_conn_host stores all information about each of possibly several hosts
303  * mentioned in the connection string.  Most fields are derived by splitting
304  * the relevant connection parameter (e.g., pghost) at commas.
305  */
306 typedef struct pg_conn_host
307 {
308 	pg_conn_host_type type;		/* type of host address */
309 	char	   *host;			/* host name or socket path */
310 	char	   *hostaddr;		/* host numeric IP address */
311 	char	   *port;			/* port number (always provided) */
312 	char	   *password;		/* password for this host, read from the
313 								 * password file; NULL if not sought or not
314 								 * found in password file. */
315 	struct addrinfo *was_addrlist;	/* dummy for ABI compatibility */
316 } pg_conn_host;
317 
318 /*
319  * PGconn stores all the state data associated with a single connection
320  * to a backend.
321  */
322 struct pg_conn
323 {
324 	/* Saved values of connection options */
325 	char	   *pghost;			/* the machine on which the server is running,
326 								 * or a path to a UNIX-domain socket, or a
327 								 * comma-separated list of machines and/or
328 								 * paths; if NULL, use DEFAULT_PGSOCKET_DIR */
329 	char	   *pghostaddr;		/* the numeric IP address of the machine on
330 								 * which the server is running, or a
331 								 * comma-separated list of same.  Takes
332 								 * precedence over pghost. */
333 	char	   *pgport;			/* the server's communication port number, or
334 								 * a comma-separated list of ports */
335 	char	   *pgtty;			/* tty on which the backend messages is
336 								 * displayed (OBSOLETE, NOT USED) */
337 	char	   *connect_timeout;	/* connection timeout (numeric string) */
338 	char	   *client_encoding_initial;	/* encoding to use */
339 	char	   *pgoptions;		/* options to start the backend with */
340 	char	   *appname;		/* application name */
341 	char	   *fbappname;		/* fallback application name */
342 	char	   *dbName;			/* database name */
343 	char	   *replication;	/* connect as the replication standby? */
344 	char	   *pguser;			/* Postgres username and password, if any */
345 	char	   *pgpass;
346 	char	   *pgpassfile;		/* path to a file containing password(s) */
347 	char	   *keepalives;		/* use TCP keepalives? */
348 	char	   *keepalives_idle;	/* time between TCP keepalives */
349 	char	   *keepalives_interval;	/* time between TCP keepalive
350 										 * retransmits */
351 	char	   *keepalives_count;	/* maximum number of TCP keepalive
352 									 * retransmits */
353 	char	   *sslmode;		/* SSL mode (require,prefer,allow,disable) */
354 	char	   *sslcompression; /* SSL compression (0 or 1) */
355 	char	   *sslkey;			/* client key filename */
356 	char	   *sslcert;		/* client certificate filename */
357 	char	   *sslrootcert;	/* root certificate filename */
358 	char	   *sslcrl;			/* certificate revocation list filename */
359 	char	   *requirepeer;	/* required peer credentials for local sockets */
360 	char	   *krbsrvname;		/* Kerberos service name */
361 	char	   *gsslib;			/* What GSS library to use ("gssapi" or
362 								 * "sspi") */
363 
364 	/* Type of connection to make.  Possible values: any, read-write. */
365 	char	   *target_session_attrs;
366 
367 	/* Optional file to write trace info to */
368 	FILE	   *Pfdebug;
369 
370 	/* Callback procedures for notice message processing */
371 	PGNoticeHooks noticeHooks;
372 
373 	/* Event procs registered via PQregisterEventProc */
374 	PGEvent    *events;			/* expandable array of event data */
375 	int			nEvents;		/* number of active events */
376 	int			eventArraySize; /* allocated array size */
377 
378 	/* Status indicators */
379 	ConnStatusType status;
380 	PGAsyncStatusType asyncStatus;
381 	PGTransactionStatusType xactStatus; /* never changes to ACTIVE */
382 	PGQueryClass queryclass;
383 	char	   *last_query;		/* last SQL command, or NULL if unknown */
384 	char		last_sqlstate[6];	/* last reported SQLSTATE */
385 	bool		options_valid;	/* true if OK to attempt connection */
386 	bool		nonblocking;	/* whether this connection is using nonblock
387 								 * sending semantics */
388 	bool		singleRowMode;	/* return current query result row-by-row? */
389 	char		copy_is_binary; /* 1 = copy binary, 0 = copy text */
390 	int			copy_already_done;	/* # bytes already returned in COPY OUT */
391 	PGnotify   *notifyHead;		/* oldest unreported Notify msg */
392 	PGnotify   *notifyTail;		/* newest unreported Notify msg */
393 
394 	/* Support for multiple hosts in connection string */
395 	int			nconnhost;		/* # of hosts named in conn string */
396 	int			whichhost;		/* host we're currently trying/connected to */
397 	pg_conn_host *connhost;		/* details about each named host */
398 
399 	/* Connection data */
400 	pgsocket	sock;			/* FD for socket, PGINVALID_SOCKET if
401 								 * unconnected */
402 	SockAddr	laddr;			/* Local address */
403 	SockAddr	raddr;			/* Remote address */
404 	ProtocolVersion pversion;	/* FE/BE protocol version in use */
405 	int			sversion;		/* server version, e.g. 70401 for 7.4.1 */
406 	bool		auth_req_received;	/* true if any type of auth req received */
407 	bool		password_needed;	/* true if server demanded a password */
408 	bool		sigpipe_so;		/* have we masked SIGPIPE via SO_NOSIGPIPE? */
409 	bool		sigpipe_flag;	/* can we mask SIGPIPE via MSG_NOSIGNAL? */
410 
411 	/* Transient state needed while establishing connection */
412 	bool		try_next_addr;	/* time to advance to next address/host? */
413 	bool		try_next_host;	/* time to advance to next connhost[]? */
414 	struct addrinfo *addr_cur;	/* backend address currently being tried */
415 	PGSetenvStatusType setenv_state;	/* for 2.0 protocol only */
416 	const PQEnvironmentOption *next_eo;
417 	bool		send_appname;	/* okay to send application_name? */
418 
419 	/* Miscellaneous stuff */
420 	int			be_pid;			/* PID of backend --- needed for cancels */
421 	int			be_key;			/* key of backend --- needed for cancels */
422 	pgParameterStatus *pstatus; /* ParameterStatus data */
423 	int			client_encoding;	/* encoding id */
424 	bool		std_strings;	/* standard_conforming_strings */
425 	PGVerbosity verbosity;		/* error/notice message verbosity */
426 	PGContextVisibility show_context;	/* whether to show CONTEXT field */
427 	PGlobjfuncs *lobjfuncs;		/* private state for large-object access fns */
428 
429 	/* Buffer for data received from backend and not yet processed */
430 	char	   *inBuffer;		/* currently allocated buffer */
431 	int			inBufSize;		/* allocated size of buffer */
432 	int			inStart;		/* offset to first unconsumed data in buffer */
433 	int			inCursor;		/* next byte to tentatively consume */
434 	int			inEnd;			/* offset to first position after avail data */
435 
436 	/* Buffer for data not yet sent to backend */
437 	char	   *outBuffer;		/* currently allocated buffer */
438 	int			outBufSize;		/* allocated size of buffer */
439 	int			outCount;		/* number of chars waiting in buffer */
440 
441 	/* State for constructing messages in outBuffer */
442 	int			outMsgStart;	/* offset to msg start (length word); if -1,
443 								 * msg has no length word */
444 	int			outMsgEnd;		/* offset to msg end (so far) */
445 
446 	/* Row processor interface workspace */
447 	PGdataValue *rowBuf;		/* array for passing values to rowProcessor */
448 	int			rowBufLen;		/* number of entries allocated in rowBuf */
449 
450 	/* Status for asynchronous result construction */
451 	PGresult   *result;			/* result being constructed */
452 	PGresult   *next_result;	/* next result (used in single-row mode) */
453 
454 	/* Assorted state for SASL, SSL, GSS, etc */
455 	void	   *sasl_state;
456 
457 	/* SSL structures */
458 	bool		ssl_in_use;
459 
460 #ifdef USE_SSL
461 	bool		allow_ssl_try;	/* Allowed to try SSL negotiation */
462 	bool		wait_ssl_try;	/* Delay SSL negotiation until after
463 								 * attempting normal connection */
464 #ifdef USE_OPENSSL
465 	SSL		   *ssl;			/* SSL status, if have SSL connection */
466 	X509	   *peer;			/* X509 cert of server */
467 #ifdef USE_SSL_ENGINE
468 	ENGINE	   *engine;			/* SSL engine, if any */
469 #else
470 	void	   *engine;			/* dummy field to keep struct the same if
471 								 * OpenSSL version changes */
472 #endif
473 #endif							/* USE_OPENSSL */
474 #endif							/* USE_SSL */
475 
476 #ifdef ENABLE_GSS
477 	gss_ctx_id_t gctx;			/* GSS context */
478 	gss_name_t	gtarg_nam;		/* GSS target name */
479 #endif
480 
481 #ifdef ENABLE_SSPI
482 	CredHandle *sspicred;		/* SSPI credentials handle */
483 	CtxtHandle *sspictx;		/* SSPI context */
484 	char	   *sspitarget;		/* SSPI target name */
485 	int			usesspi;		/* Indicate if SSPI is in use on the
486 								 * connection */
487 #endif
488 
489 	/* Buffer for current error message */
490 	PQExpBufferData errorMessage;	/* expansible string */
491 
492 	/* Buffer for receiving various parts of messages */
493 	PQExpBufferData workBuffer; /* expansible string */
494 
495 	/* Placed at the end, in this branch, to minimize ABI breakage */
496 	struct addrinfo *addrlist;	/* list of addresses for current connhost */
497 	int			addrlist_family;	/* needed to know how to free addrlist */
498 };
499 
500 /* PGcancel stores all data necessary to cancel a connection. A copy of this
501  * data is required to safely cancel a connection running on a different
502  * thread.
503  */
504 struct pg_cancel
505 {
506 	SockAddr	raddr;			/* Remote address */
507 	int			be_pid;			/* PID of backend --- needed for cancels */
508 	int			be_key;			/* key of backend --- needed for cancels */
509 };
510 
511 
512 /* String descriptions of the ExecStatusTypes.
513  * direct use of this array is deprecated; call PQresStatus() instead.
514  */
515 extern char *const pgresStatus[];
516 
517 
518 #ifdef USE_SSL
519 
520 #ifndef WIN32
521 #define USER_CERT_FILE		".postgresql/postgresql.crt"
522 #define USER_KEY_FILE		".postgresql/postgresql.key"
523 #define ROOT_CERT_FILE		".postgresql/root.crt"
524 #define ROOT_CRL_FILE		".postgresql/root.crl"
525 #else
526 /* On Windows, the "home" directory is already PostgreSQL-specific */
527 #define USER_CERT_FILE		"postgresql.crt"
528 #define USER_KEY_FILE		"postgresql.key"
529 #define ROOT_CERT_FILE		"root.crt"
530 #define ROOT_CRL_FILE		"root.crl"
531 #endif
532 
533 #endif							/* USE_SSL */
534 
535 /* ----------------
536  * Internal functions of libpq
537  * Functions declared here need to be visible across files of libpq,
538  * but are not intended to be called by applications.  We use the
539  * convention "pqXXX" for internal functions, vs. the "PQxxx" names
540  * used for application-visible routines.
541  * ----------------
542  */
543 
544 /* === in fe-connect.c === */
545 
546 extern void pqDropConnection(PGconn *conn, bool flushInput);
547 extern int pqPacketSend(PGconn *conn, char pack_type,
548 			 const void *buf, size_t buf_len);
549 extern bool pqGetHomeDirectory(char *buf, int bufsize);
550 
551 #ifdef ENABLE_THREAD_SAFETY
552 extern pgthreadlock_t pg_g_threadlock;
553 
554 #define PGTHREAD_ERROR(msg) \
555 	do { \
556 		fprintf(stderr, "%s\n", msg); \
557 		abort(); \
558 	} while (0)
559 
560 
561 #define pglock_thread()		pg_g_threadlock(true)
562 #define pgunlock_thread()	pg_g_threadlock(false)
563 #else
564 #define pglock_thread()		((void) 0)
565 #define pgunlock_thread()	((void) 0)
566 #endif
567 
568 /* === in fe-exec.c === */
569 
570 extern void pqSetResultError(PGresult *res, const char *msg);
571 extern void pqCatenateResultError(PGresult *res, const char *msg);
572 extern void *pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary);
573 extern char *pqResultStrdup(PGresult *res, const char *str);
574 extern void pqClearAsyncResult(PGconn *conn);
575 extern void pqSaveErrorResult(PGconn *conn);
576 extern PGresult *pqPrepareAsyncResult(PGconn *conn);
577 extern void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...) pg_attribute_printf(2, 3);
578 extern void pqSaveMessageField(PGresult *res, char code,
579 				   const char *value);
580 extern void pqSaveParameterStatus(PGconn *conn, const char *name,
581 					  const char *value);
582 extern int	pqRowProcessor(PGconn *conn, const char **errmsgp);
583 extern void pqHandleSendFailure(PGconn *conn);
584 
585 /* === in fe-protocol2.c === */
586 
587 extern PostgresPollingStatusType pqSetenvPoll(PGconn *conn);
588 
589 extern char *pqBuildStartupPacket2(PGconn *conn, int *packetlen,
590 					  const PQEnvironmentOption *options);
591 extern void pqParseInput2(PGconn *conn);
592 extern int	pqGetCopyData2(PGconn *conn, char **buffer, int async);
593 extern int	pqGetline2(PGconn *conn, char *s, int maxlen);
594 extern int	pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize);
595 extern int	pqEndcopy2(PGconn *conn);
596 extern PGresult *pqFunctionCall2(PGconn *conn, Oid fnid,
597 				int *result_buf, int *actual_result_len,
598 				int result_is_int,
599 				const PQArgBlock *args, int nargs);
600 
601 /* === in fe-protocol3.c === */
602 
603 extern char *pqBuildStartupPacket3(PGconn *conn, int *packetlen,
604 					  const PQEnvironmentOption *options);
605 extern void pqParseInput3(PGconn *conn);
606 extern int	pqGetErrorNotice3(PGconn *conn, bool isError);
607 extern void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res,
608 					 PGVerbosity verbosity, PGContextVisibility show_context);
609 extern int	pqGetCopyData3(PGconn *conn, char **buffer, int async);
610 extern int	pqGetline3(PGconn *conn, char *s, int maxlen);
611 extern int	pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize);
612 extern int	pqEndcopy3(PGconn *conn);
613 extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid,
614 				int *result_buf, int *actual_result_len,
615 				int result_is_int,
616 				const PQArgBlock *args, int nargs);
617 
618 /* === in fe-misc.c === */
619 
620  /*
621   * "Get" and "Put" routines return 0 if successful, EOF if not. Note that for
622   * Get, EOF merely means the buffer is exhausted, not that there is
623   * necessarily any error.
624   */
625 extern int	pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn);
626 extern int	pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn);
627 extern int	pqGetc(char *result, PGconn *conn);
628 extern int	pqPutc(char c, PGconn *conn);
629 extern int	pqGets(PQExpBuffer buf, PGconn *conn);
630 extern int	pqGets_append(PQExpBuffer buf, PGconn *conn);
631 extern int	pqPuts(const char *s, PGconn *conn);
632 extern int	pqGetnchar(char *s, size_t len, PGconn *conn);
633 extern int	pqSkipnchar(size_t len, PGconn *conn);
634 extern int	pqPutnchar(const char *s, size_t len, PGconn *conn);
635 extern int	pqGetInt(int *result, size_t bytes, PGconn *conn);
636 extern int	pqPutInt(int value, size_t bytes, PGconn *conn);
637 extern int	pqPutMsgStart(char msg_type, bool force_len, PGconn *conn);
638 extern int	pqPutMsgEnd(PGconn *conn);
639 extern int	pqReadData(PGconn *conn);
640 extern int	pqFlush(PGconn *conn);
641 extern int	pqWait(int forRead, int forWrite, PGconn *conn);
642 extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn,
643 			time_t finish_time);
644 extern int	pqReadReady(PGconn *conn);
645 extern int	pqWriteReady(PGconn *conn);
646 
647 /* === in fe-secure.c === */
648 
649 extern int	pqsecure_initialize(PGconn *);
650 extern void pqsecure_destroy(void);
651 extern PostgresPollingStatusType pqsecure_open_client(PGconn *);
652 extern void pqsecure_close(PGconn *);
653 extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len);
654 extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len);
655 extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len);
656 extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len);
657 
658 #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
659 extern int	pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending);
660 extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending,
661 				 bool got_epipe);
662 #endif
663 
664 /* === SSL === */
665 
666 /*
667  * The SSL implementation provides these functions.
668  */
669 
670 /*
671  *	Implementation of PQinitSSL().
672  */
673 extern void pgtls_init_library(bool do_ssl, int do_crypto);
674 
675 /*
676  * Initialize SSL library.
677  *
678  * The conn parameter is only used to be able to pass back an error
679  * message - no connection-local setup is made here.
680  *
681  * Returns 0 if OK, -1 on failure (with a message in conn->errorMessage).
682  */
683 extern int	pgtls_init(PGconn *conn);
684 
685 /*
686  *	Begin or continue negotiating a secure session.
687  */
688 extern PostgresPollingStatusType pgtls_open_client(PGconn *conn);
689 
690 /*
691  *	Close SSL connection.
692  */
693 extern void pgtls_close(PGconn *conn);
694 
695 /*
696  *	Read data from a secure connection.
697  *
698  * On failure, this function is responsible for putting a suitable message
699  * into conn->errorMessage.  The caller must still inspect errno, but only
700  * to determine whether to continue/retry after error.
701  */
702 extern ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len);
703 
704 /*
705  *	Is there unread data waiting in the SSL read buffer?
706  */
707 extern bool pgtls_read_pending(PGconn *conn);
708 
709 /*
710  *	Write data to a secure connection.
711  *
712  * On failure, this function is responsible for putting a suitable message
713  * into conn->errorMessage.  The caller must still inspect errno, but only
714  * to determine whether to continue/retry after error.
715  */
716 extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len);
717 
718 /*
719  * Get the hash of the server certificate, for SCRAM channel binding type
720  * tls-server-end-point.
721  *
722  * NULL is sent back to the caller in the event of an error, with an
723  * error message for the caller to consume.
724  *
725  * This is not supported with old versions of OpenSSL that don't have
726  * the X509_get_signature_nid() function.
727  */
728 #if defined(USE_OPENSSL) && defined(HAVE_X509_GET_SIGNATURE_NID)
729 #define HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
730 extern char *pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len);
731 #endif
732 
733 /*
734  * Verify that the server certificate matches the host name we connected to.
735  *
736  * The certificate's Common Name and Subject Alternative Names are considered.
737  *
738  * Returns 1 if the name matches, and 0 if it does not. On error, returns
739  * -1, and sets the libpq error message.
740  *
741  */
742 extern int pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
743 												int *names_examined,
744 												char **first_name);
745 
746 /* === miscellaneous macros === */
747 
748 /*
749  * this is so that we can check if a connection is non-blocking internally
750  * without the overhead of a function call
751  */
752 #define pqIsnonblocking(conn)	((conn)->nonblocking)
753 
754 #ifdef ENABLE_NLS
755 extern char *libpq_gettext(const char *msgid) pg_attribute_format_arg(1);
756 extern char *libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n) pg_attribute_format_arg(1) pg_attribute_format_arg(2);
757 #else
758 #define libpq_gettext(x) (x)
759 #define libpq_ngettext(s, p, n) ((n) == 1 ? (s) : (p))
760 #endif
761 
762 /*
763  * These macros are needed to let error-handling code be portable between
764  * Unix and Windows.  (ugh)
765  */
766 #ifdef WIN32
767 #define SOCK_ERRNO (WSAGetLastError())
768 #define SOCK_STRERROR winsock_strerror
769 #define SOCK_ERRNO_SET(e) WSASetLastError(e)
770 #else
771 #define SOCK_ERRNO errno
772 #define SOCK_STRERROR pqStrerror
773 #define SOCK_ERRNO_SET(e) (errno = (e))
774 #endif
775 
776 #endif							/* LIBPQ_INT_H */
777