1/*-------------------------------------------------------------------------
2 *
3 * fe-protocol2.c
4 * functions that are specific to frontend/backend protocol version 2
5 *
6 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/interfaces/libpq/fe-protocol2.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres_fe.h"
16
17#include <ctype.h>
18#include <fcntl.h>
19
20#include "libpq-fe.h"
21#include "libpq-int.h"
22#include "port/pg_bswap.h"
23
24
25#ifdef WIN32
26#include "win32.h"
27#else
28#include <unistd.h>
29#ifdef HAVE_NETINET_TCP_H
30#include <netinet/tcp.h>
31#endif
32#endif
33
34
35static int getRowDescriptions(PGconn *conn);
36static int getAnotherTuple(PGconn *conn, bool binary);
37static int pqGetErrorNotice2(PGconn *conn, bool isError);
38static void checkXactStatus(PGconn *conn, const char *cmdTag);
39static int getNotify(PGconn *conn);
40
41
42/*
43 * pqSetenvPoll
44 *
45 * Polls the process of passing the values of a standard set of environment
46 * variables to the backend.
47 */
48PostgresPollingStatusType
49pqSetenvPoll(PGconn *conn)
50{
51 PGresult *res;
52
53 if (conn == NULL || conn->status == CONNECTION_BAD)
54 return PGRES_POLLING_FAILED;
55
56 /* Check whether there are any data for us */
57 switch (conn->setenv_state)
58 {
59 /* These are reading states */
60 case SETENV_STATE_CLIENT_ENCODING_WAIT:
61 case SETENV_STATE_OPTION_WAIT:
62 case SETENV_STATE_QUERY1_WAIT:
63 case SETENV_STATE_QUERY2_WAIT:
64 {
65 /* Load waiting data */
66 int n = pqReadData(conn);
67
68 if (n < 0)
69 goto error_return;
70 if (n == 0)
71 return PGRES_POLLING_READING;
72
73 break;
74 }
75
76 /* These are writing states, so we just proceed. */
77 case SETENV_STATE_CLIENT_ENCODING_SEND:
78 case SETENV_STATE_OPTION_SEND:
79 case SETENV_STATE_QUERY1_SEND:
80 case SETENV_STATE_QUERY2_SEND:
81 break;
82
83 /* Should we raise an error if called when not active? */
84 case SETENV_STATE_IDLE:
85 return PGRES_POLLING_OK;
86
87 default:
88 printfPQExpBuffer(&conn->errorMessage,
89 libpq_gettext(
90 "invalid setenv state %c, "
91 "probably indicative of memory corruption\n"
92 ),
93 conn->setenv_state);
94 goto error_return;
95 }
96
97 /* We will loop here until there is nothing left to do in this call. */
98 for (;;)
99 {
100 switch (conn->setenv_state)
101 {
102 /*
103 * The _CLIENT_ENCODING_SEND code is slightly different from
104 * _OPTION_SEND below (e.g., no getenv() call), which is why a
105 * different state is used.
106 */
107 case SETENV_STATE_CLIENT_ENCODING_SEND:
108 {
109 char setQuery[100]; /* note length limit in
110 * sprintf below */
111 const char *val = conn->client_encoding_initial;
112
113 if (val)
114 {
115 if (pg_strcasecmp(val, "default") == 0)
116 sprintf(setQuery, "SET client_encoding = DEFAULT");
117 else
118 sprintf(setQuery, "SET client_encoding = '%.60s'",
119 val);
120#ifdef CONNECTDEBUG
121 fprintf(stderr,
122 "Sending client_encoding with %s\n",
123 setQuery);
124#endif
125 if (!PQsendQuery(conn, setQuery))
126 goto error_return;
127
128 conn->setenv_state = SETENV_STATE_CLIENT_ENCODING_WAIT;
129 }
130 else
131 conn->setenv_state = SETENV_STATE_OPTION_SEND;
132 break;
133 }
134
135 case SETENV_STATE_OPTION_SEND:
136 {
137 /*
138 * Send SET commands for stuff directed by Environment
139 * Options. Note: we assume that SET commands won't start
140 * transaction blocks, even in a 7.3 server with
141 * autocommit off.
142 */
143 char setQuery[100]; /* note length limit in
144 * sprintf below */
145
146 if (conn->next_eo->envName)
147 {
148 const char *val;
149
150 if ((val = getenv(conn->next_eo->envName)))
151 {
152 if (pg_strcasecmp(val, "default") == 0)
153 sprintf(setQuery, "SET %s = DEFAULT",
154 conn->next_eo->pgName);
155 else
156 sprintf(setQuery, "SET %s = '%.60s'",
157 conn->next_eo->pgName, val);
158#ifdef CONNECTDEBUG
159 fprintf(stderr,
160 "Use environment variable %s to send %s\n",
161 conn->next_eo->envName, setQuery);
162#endif
163 if (!PQsendQuery(conn, setQuery))
164 goto error_return;
165
166 conn->setenv_state = SETENV_STATE_OPTION_WAIT;
167 }
168 else
169 conn->next_eo++;
170 }
171 else
172 {
173 /* No more options to send, so move on to querying */
174 conn->setenv_state = SETENV_STATE_QUERY1_SEND;
175 }
176 break;
177 }
178
179 case SETENV_STATE_CLIENT_ENCODING_WAIT:
180 {
181 if (PQisBusy(conn))
182 return PGRES_POLLING_READING;
183
184 res = PQgetResult(conn);
185
186 if (res)
187 {
188 if (PQresultStatus(res) != PGRES_COMMAND_OK)
189 {
190 PQclear(res);
191 goto error_return;
192 }
193 PQclear(res);
194 /* Keep reading until PQgetResult returns NULL */
195 }
196 else
197 {
198 /* Query finished, so send the next option */
199 conn->setenv_state = SETENV_STATE_OPTION_SEND;
200 }
201 break;
202 }
203
204 case SETENV_STATE_OPTION_WAIT:
205 {
206 if (PQisBusy(conn))
207 return PGRES_POLLING_READING;
208
209 res = PQgetResult(conn);
210
211 if (res)
212 {
213 if (PQresultStatus(res) != PGRES_COMMAND_OK)
214 {
215 PQclear(res);
216 goto error_return;
217 }
218 PQclear(res);
219 /* Keep reading until PQgetResult returns NULL */
220 }
221 else
222 {
223 /* Query finished, so send the next option */
224 conn->next_eo++;
225 conn->setenv_state = SETENV_STATE_OPTION_SEND;
226 }
227 break;
228 }
229
230 case SETENV_STATE_QUERY1_SEND:
231 {
232 /*
233 * Issue query to get information we need. Here we must
234 * use begin/commit in case autocommit is off by default
235 * in a 7.3 server.
236 *
237 * Note: version() exists in all protocol-2.0-supporting
238 * backends. In 7.3 it would be safer to write
239 * pg_catalog.version(), but we can't do that without
240 * causing problems on older versions.
241 */
242 if (!PQsendQuery(conn, "begin; select version(); end"))
243 goto error_return;
244
245 conn->setenv_state = SETENV_STATE_QUERY1_WAIT;
246 return PGRES_POLLING_READING;
247 }
248
249 case SETENV_STATE_QUERY1_WAIT:
250 {
251 if (PQisBusy(conn))
252 return PGRES_POLLING_READING;
253
254 res = PQgetResult(conn);
255
256 if (res)
257 {
258 char *val;
259
260 if (PQresultStatus(res) == PGRES_COMMAND_OK)
261 {
262 /* ignore begin/commit command results */
263 PQclear(res);
264 continue;
265 }
266
267 if (PQresultStatus(res) != PGRES_TUPLES_OK ||
268 PQntuples(res) != 1)
269 {
270 PQclear(res);
271 goto error_return;
272 }
273
274 /*
275 * Extract server version and save as if
276 * ParameterStatus
277 */
278 val = PQgetvalue(res, 0, 0);
279 if (val && strncmp(val, "PostgreSQL ", 11) == 0)
280 {
281 char *ptr;
282
283 /* strip off PostgreSQL part */
284 val += 11;
285
286 /*
287 * strip off platform part (scribbles on result,
288 * naughty naughty)
289 */
290 ptr = strchr(val, ' ');
291 if (ptr)
292 *ptr = '\0';
293
294 pqSaveParameterStatus(conn, "server_version",
295 val);
296 }
297
298 PQclear(res);
299 /* Keep reading until PQgetResult returns NULL */
300 }
301 else
302 {
303 /* Query finished, move to next */
304 conn->setenv_state = SETENV_STATE_QUERY2_SEND;
305 }
306 break;
307 }
308
309 case SETENV_STATE_QUERY2_SEND:
310 {
311 const char *query;
312
313 /*
314 * pg_client_encoding does not exist in pre-7.2 servers.
315 * So we need to be prepared for an error here. Do *not*
316 * start a transaction block, except in 7.3 servers where
317 * we need to prevent autocommit-off from starting a
318 * transaction anyway.
319 */
320 if (conn->sversion >= 70300 &&
321 conn->sversion < 70400)
322 query = "begin; select pg_catalog.pg_client_encoding(); end";
323 else
324 query = "select pg_client_encoding()";
325 if (!PQsendQuery(conn, query))
326 goto error_return;
327
328 conn->setenv_state = SETENV_STATE_QUERY2_WAIT;
329 return PGRES_POLLING_READING;
330 }
331
332 case SETENV_STATE_QUERY2_WAIT:
333 {
334 if (PQisBusy(conn))
335 return PGRES_POLLING_READING;
336
337 res = PQgetResult(conn);
338
339 if (res)
340 {
341 const char *val;
342
343 if (PQresultStatus(res) == PGRES_COMMAND_OK)
344 {
345 /* ignore begin/commit command results */
346 PQclear(res);
347 continue;
348 }
349
350 if (PQresultStatus(res) == PGRES_TUPLES_OK &&
351 PQntuples(res) == 1)
352 {
353 /* Extract client encoding and save it */
354 val = PQgetvalue(res, 0, 0);
355 if (val && *val) /* null should not happen, but */
356 pqSaveParameterStatus(conn, "client_encoding",
357 val);
358 }
359 else
360 {
361 /*
362 * Error: presumably function not available, so
363 * use PGCLIENTENCODING or SQL_ASCII as the
364 * fallback.
365 */
366 val = getenv("PGCLIENTENCODING");
367 if (val && *val)
368 pqSaveParameterStatus(conn, "client_encoding",
369 val);
370 else
371 pqSaveParameterStatus(conn, "client_encoding",
372 "SQL_ASCII");
373 }
374
375 PQclear(res);
376 /* Keep reading until PQgetResult returns NULL */
377 }
378 else
379 {
380 /* Query finished, so we're done */
381 conn->setenv_state = SETENV_STATE_IDLE;
382 return PGRES_POLLING_OK;
383 }
384 break;
385 }
386
387 default:
388 printfPQExpBuffer(&conn->errorMessage,
389 libpq_gettext("invalid state %c, "
390 "probably indicative of memory corruption\n"),
391 conn->setenv_state);
392 goto error_return;
393 }
394 }
395
396 /* Unreachable */
397
398error_return:
399 conn->setenv_state = SETENV_STATE_IDLE;
400 return PGRES_POLLING_FAILED;
401}
402
403
404/*
405 * parseInput: if appropriate, parse input data from backend
406 * until input is exhausted or a stopping state is reached.
407 * Note that this function will NOT attempt to read more data from the backend.
408 */
409void
410pqParseInput2(PGconn *conn)
411{
412 char id;
413
414 /*
415 * Loop to parse successive complete messages available in the buffer.
416 */
417 for (;;)
418 {
419 /*
420 * Quit if in COPY_OUT state: we expect raw data from the server until
421 * PQendcopy is called. Don't try to parse it according to the normal
422 * protocol. (This is bogus. The data lines ought to be part of the
423 * protocol and have identifying leading characters.)
424 */
425 if (conn->asyncStatus == PGASYNC_COPY_OUT)
426 return;
427
428 /*
429 * OK to try to read a message type code.
430 */
431 conn->inCursor = conn->inStart;
432 if (pqGetc(&id, conn))
433 return;
434
435 /*
436 * NOTIFY and NOTICE messages can happen in any state besides COPY
437 * OUT; always process them right away.
438 *
439 * Most other messages should only be processed while in BUSY state.
440 * (In particular, in READY state we hold off further parsing until
441 * the application collects the current PGresult.)
442 *
443 * However, if the state is IDLE then we got trouble; we need to deal
444 * with the unexpected message somehow.
445 */
446 if (id == 'A')
447 {
448 if (getNotify(conn))
449 return;
450 }
451 else if (id == 'N')
452 {
453 if (pqGetErrorNotice2(conn, false))
454 return;
455 }
456 else if (conn->asyncStatus != PGASYNC_BUSY)
457 {
458 /* If not IDLE state, just wait ... */
459 if (conn->asyncStatus != PGASYNC_IDLE)
460 return;
461
462 /*
463 * Unexpected message in IDLE state; need to recover somehow.
464 * ERROR messages are displayed using the notice processor;
465 * anything else is just dropped on the floor after displaying a
466 * suitable warning notice. (An ERROR is very possibly the
467 * backend telling us why it is about to close the connection, so
468 * we don't want to just discard it...)
469 */
470 if (id == 'E')
471 {
472 if (pqGetErrorNotice2(conn, false /* treat as notice */ ))
473 return;
474 }
475 else
476 {
477 pqInternalNotice(&conn->noticeHooks,
478 "message type 0x%02x arrived from server while idle",
479 id);
480 /* Discard the unexpected message; good idea?? */
481 conn->inStart = conn->inEnd;
482 break;
483 }
484 }
485 else
486 {
487 /*
488 * In BUSY state, we can process everything.
489 */
490 switch (id)
491 {
492 case 'C': /* command complete */
493 if (pqGets(&conn->workBuffer, conn))
494 return;
495 if (conn->result == NULL)
496 {
497 conn->result = PQmakeEmptyPGresult(conn,
498 PGRES_COMMAND_OK);
499 if (!conn->result)
500 {
501 printfPQExpBuffer(&conn->errorMessage,
502 libpq_gettext("out of memory"));
503 pqSaveErrorResult(conn);
504 }
505 }
506 if (conn->result)
507 {
508 strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
509 CMDSTATUS_LEN);
510 }
511 checkXactStatus(conn, conn->workBuffer.data);
512 conn->asyncStatus = PGASYNC_READY;
513 break;
514 case 'E': /* error return */
515 if (pqGetErrorNotice2(conn, true))
516 return;
517 conn->asyncStatus = PGASYNC_READY;
518 break;
519 case 'Z': /* backend is ready for new query */
520 conn->asyncStatus = PGASYNC_IDLE;
521 break;
522 case 'I': /* empty query */
523 /* read and throw away the closing '\0' */
524 if (pqGetc(&id, conn))
525 return;
526 if (id != '\0')
527 pqInternalNotice(&conn->noticeHooks,
528 "unexpected character %c following empty query response (\"I\" message)",
529 id);
530 if (conn->result == NULL)
531 {
532 conn->result = PQmakeEmptyPGresult(conn,
533 PGRES_EMPTY_QUERY);
534 if (!conn->result)
535 {
536 printfPQExpBuffer(&conn->errorMessage,
537 libpq_gettext("out of memory"));
538 pqSaveErrorResult(conn);
539 }
540 }
541 conn->asyncStatus = PGASYNC_READY;
542 break;
543 case 'K': /* secret key data from the backend */
544
545 /*
546 * This is expected only during backend startup, but it's
547 * just as easy to handle it as part of the main loop.
548 * Save the data and continue processing.
549 */
550 if (pqGetInt(&(conn->be_pid), 4, conn))
551 return;
552 if (pqGetInt(&(conn->be_key), 4, conn))
553 return;
554 break;
555 case 'P': /* synchronous (normal) portal */
556 if (pqGets(&conn->workBuffer, conn))
557 return;
558 /* We pretty much ignore this message type... */
559 break;
560 case 'T': /* row descriptions (start of query results) */
561 if (conn->result == NULL)
562 {
563 /* First 'T' in a query sequence */
564 if (getRowDescriptions(conn))
565 return;
566 /* getRowDescriptions() moves inStart itself */
567 continue;
568 }
569 else
570 {
571 /*
572 * A new 'T' message is treated as the start of
573 * another PGresult. (It is not clear that this is
574 * really possible with the current backend.) We stop
575 * parsing until the application accepts the current
576 * result.
577 */
578 conn->asyncStatus = PGASYNC_READY;
579 return;
580 }
581 break;
582 case 'D': /* ASCII data tuple */
583 if (conn->result != NULL)
584 {
585 /* Read another tuple of a normal query response */
586 if (getAnotherTuple(conn, false))
587 return;
588 /* getAnotherTuple() moves inStart itself */
589 continue;
590 }
591 else
592 {
593 pqInternalNotice(&conn->noticeHooks,
594 "server sent data (\"D\" message) without prior row description (\"T\" message)");
595 /* Discard the unexpected message; good idea?? */
596 conn->inStart = conn->inEnd;
597 return;
598 }
599 break;
600 case 'B': /* Binary data tuple */
601 if (conn->result != NULL)
602 {
603 /* Read another tuple of a normal query response */
604 if (getAnotherTuple(conn, true))
605 return;
606 /* getAnotherTuple() moves inStart itself */
607 continue;
608 }
609 else
610 {
611 pqInternalNotice(&conn->noticeHooks,
612 "server sent binary data (\"B\" message) without prior row description (\"T\" message)");
613 /* Discard the unexpected message; good idea?? */
614 conn->inStart = conn->inEnd;
615 return;
616 }
617 break;
618 case 'G': /* Start Copy In */
619 conn->asyncStatus = PGASYNC_COPY_IN;
620 break;
621 case 'H': /* Start Copy Out */
622 conn->asyncStatus = PGASYNC_COPY_OUT;
623 break;
624
625 /*
626 * Don't need to process CopyBothResponse here because it
627 * never arrives from the server during protocol 2.0.
628 */
629 default:
630 printfPQExpBuffer(&conn->errorMessage,
631 libpq_gettext(
632 "unexpected response from server; first received character was \"%c\"\n"),
633 id);
634 /* build an error result holding the error message */
635 pqSaveErrorResult(conn);
636 /* Discard the unexpected message; good idea?? */
637 conn->inStart = conn->inEnd;
638 conn->asyncStatus = PGASYNC_READY;
639 return;
640 } /* switch on protocol character */
641 }
642 /* Successfully consumed this message */
643 conn->inStart = conn->inCursor;
644 }
645}
646
647/*
648 * parseInput subroutine to read a 'T' (row descriptions) message.
649 * We build a PGresult structure containing the attribute data.
650 * Returns: 0 if completed message, EOF if error or not enough data
651 * received yet.
652 *
653 * Note that if we run out of data, we have to suspend and reprocess
654 * the message after more data is received. Otherwise, conn->inStart
655 * must get advanced past the processed data.
656 */
657static int
658getRowDescriptions(PGconn *conn)
659{
660 PGresult *result;
661 int nfields;
662 const char *errmsg;
663 int i;
664
665 result = PQmakeEmptyPGresult(conn, PGRES_TUPLES_OK);
666 if (!result)
667 {
668 errmsg = NULL; /* means "out of memory", see below */
669 goto advance_and_error;
670 }
671
672 /* parseInput already read the 'T' label. */
673 /* the next two bytes are the number of fields */
674 if (pqGetInt(&(result->numAttributes), 2, conn))
675 goto EOFexit;
676 nfields = result->numAttributes;
677
678 /* allocate space for the attribute descriptors */
679 if (nfields > 0)
680 {
681 result->attDescs = (PGresAttDesc *)
682 pqResultAlloc(result, nfields * sizeof(PGresAttDesc), true);
683 if (!result->attDescs)
684 {
685 errmsg = NULL; /* means "out of memory", see below */
686 goto advance_and_error;
687 }
688 MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc));
689 }
690
691 /* get type info */
692 for (i = 0; i < nfields; i++)
693 {
694 int typid;
695 int typlen;
696 int atttypmod;
697
698 if (pqGets(&conn->workBuffer, conn) ||
699 pqGetInt(&typid, 4, conn) ||
700 pqGetInt(&typlen, 2, conn) ||
701 pqGetInt(&atttypmod, 4, conn))
702 goto EOFexit;
703
704 /*
705 * Since pqGetInt treats 2-byte integers as unsigned, we need to
706 * coerce the result to signed form.
707 */
708 typlen = (int) ((int16) typlen);
709
710 result->attDescs[i].name = pqResultStrdup(result,
711 conn->workBuffer.data);
712 if (!result->attDescs[i].name)
713 {
714 errmsg = NULL; /* means "out of memory", see below */
715 goto advance_and_error;
716 }
717 result->attDescs[i].tableid = 0;
718 result->attDescs[i].columnid = 0;
719 result->attDescs[i].format = 0;
720 result->attDescs[i].typid = typid;
721 result->attDescs[i].typlen = typlen;
722 result->attDescs[i].atttypmod = atttypmod;
723 }
724
725 /* Success! */
726 conn->result = result;
727
728 /* Advance inStart to show that the "T" message has been processed. */
729 conn->inStart = conn->inCursor;
730
731 /*
732 * We could perform additional setup for the new result set here, but for
733 * now there's nothing else to do.
734 */
735
736 /* And we're done. */
737 return 0;
738
739advance_and_error:
740
741 /*
742 * Discard the failed message. Unfortunately we don't know for sure where
743 * the end is, so just throw away everything in the input buffer. This is
744 * not very desirable but it's the best we can do in protocol v2.
745 */
746 conn->inStart = conn->inEnd;
747
748 /*
749 * Replace partially constructed result with an error result. First
750 * discard the old result to try to win back some memory.
751 */
752 pqClearAsyncResult(conn);
753
754 /*
755 * If preceding code didn't provide an error message, assume "out of
756 * memory" was meant. The advantage of having this special case is that
757 * freeing the old result first greatly improves the odds that gettext()
758 * will succeed in providing a translation.
759 */
760 if (!errmsg)
761 errmsg = libpq_gettext("out of memory for query result");
762
763 printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
764
765 /*
766 * XXX: if PQmakeEmptyPGresult() fails, there's probably not much we can
767 * do to recover...
768 */
769 conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
770 conn->asyncStatus = PGASYNC_READY;
771
772EOFexit:
773 if (result && result != conn->result)
774 PQclear(result);
775 return EOF;
776}
777
778/*
779 * parseInput subroutine to read a 'B' or 'D' (row data) message.
780 * We fill rowbuf with column pointers and then call the row processor.
781 * Returns: 0 if completed message, EOF if error or not enough data
782 * received yet.
783 *
784 * Note that if we run out of data, we have to suspend and reprocess
785 * the message after more data is received. Otherwise, conn->inStart
786 * must get advanced past the processed data.
787 */
788static int
789getAnotherTuple(PGconn *conn, bool binary)
790{
791 PGresult *result = conn->result;
792 int nfields = result->numAttributes;
793 const char *errmsg;
794 PGdataValue *rowbuf;
795
796 /* the backend sends us a bitmap of which attributes are null */
797 char std_bitmap[64]; /* used unless it doesn't fit */
798 char *bitmap = std_bitmap;
799 int i;
800 size_t nbytes; /* the number of bytes in bitmap */
801 char bmap; /* One byte of the bitmap */
802 int bitmap_index; /* Its index */
803 int bitcnt; /* number of bits examined in current byte */
804 int vlen; /* length of the current field value */
805
806 /* Resize row buffer if needed */
807 rowbuf = conn->rowBuf;
808 if (nfields > conn->rowBufLen)
809 {
810 rowbuf = (PGdataValue *) realloc(rowbuf,
811 nfields * sizeof(PGdataValue));
812 if (!rowbuf)
813 {
814 errmsg = NULL; /* means "out of memory", see below */
815 goto advance_and_error;
816 }
817 conn->rowBuf = rowbuf;
818 conn->rowBufLen = nfields;
819 }
820
821 /* Save format specifier */
822 result->binary = binary;
823
824 /*
825 * If it's binary, fix the column format indicators. We assume the
826 * backend will consistently send either B or D, not a mix.
827 */
828 if (binary)
829 {
830 for (i = 0; i < nfields; i++)
831 result->attDescs[i].format = 1;
832 }
833
834 /* Get the null-value bitmap */
835 nbytes = (nfields + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
836 /* malloc() only for unusually large field counts... */
837 if (nbytes > sizeof(std_bitmap))
838 {
839 bitmap = (char *) malloc(nbytes);
840 if (!bitmap)
841 {
842 errmsg = NULL; /* means "out of memory", see below */
843 goto advance_and_error;
844 }
845 }
846
847 if (pqGetnchar(bitmap, nbytes, conn))
848 goto EOFexit;
849
850 /* Scan the fields */
851 bitmap_index = 0;
852 bmap = bitmap[bitmap_index];
853 bitcnt = 0;
854
855 for (i = 0; i < nfields; i++)
856 {
857 /* get the value length */
858 if (!(bmap & 0200))
859 vlen = NULL_LEN;
860 else if (pqGetInt(&vlen, 4, conn))
861 goto EOFexit;
862 else
863 {
864 if (!binary)
865 vlen = vlen - 4;
866 if (vlen < 0)
867 vlen = 0;
868 }
869 rowbuf[i].len = vlen;
870
871 /*
872 * rowbuf[i].value always points to the next address in the data
873 * buffer even if the value is NULL. This allows row processors to
874 * estimate data sizes more easily.
875 */
876 rowbuf[i].value = conn->inBuffer + conn->inCursor;
877
878 /* Skip over the data value */
879 if (vlen > 0)
880 {
881 if (pqSkipnchar(vlen, conn))
882 goto EOFexit;
883 }
884
885 /* advance the bitmap stuff */
886 bitcnt++;
887 if (bitcnt == BITS_PER_BYTE)
888 {
889 bitmap_index++;
890 bmap = bitmap[bitmap_index];
891 bitcnt = 0;
892 }
893 else
894 bmap <<= 1;
895 }
896
897 /* Release bitmap now if we allocated it */
898 if (bitmap != std_bitmap)
899 free(bitmap);
900 bitmap = NULL;
901
902 /* Advance inStart to show that the "D" message has been processed. */
903 conn->inStart = conn->inCursor;
904
905 /* Process the collected row */
906 errmsg = NULL;
907 if (pqRowProcessor(conn, &errmsg))
908 return 0; /* normal, successful exit */
909
910 goto set_error_result; /* pqRowProcessor failed, report it */
911
912advance_and_error:
913
914 /*
915 * Discard the failed message. Unfortunately we don't know for sure where
916 * the end is, so just throw away everything in the input buffer. This is
917 * not very desirable but it's the best we can do in protocol v2.
918 */
919 conn->inStart = conn->inEnd;
920
921set_error_result:
922
923 /*
924 * Replace partially constructed result with an error result. First
925 * discard the old result to try to win back some memory.
926 */
927 pqClearAsyncResult(conn);
928
929 /*
930 * If preceding code didn't provide an error message, assume "out of
931 * memory" was meant. The advantage of having this special case is that
932 * freeing the old result first greatly improves the odds that gettext()
933 * will succeed in providing a translation.
934 */
935 if (!errmsg)
936 errmsg = libpq_gettext("out of memory for query result");
937
938 printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
939
940 /*
941 * XXX: if PQmakeEmptyPGresult() fails, there's probably not much we can
942 * do to recover...
943 */
944 conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
945 conn->asyncStatus = PGASYNC_READY;
946
947EOFexit:
948 if (bitmap != NULL && bitmap != std_bitmap)
949 free(bitmap);
950 return EOF;
951}
952
953
954/*
955 * Attempt to read an Error or Notice response message.
956 * This is possible in several places, so we break it out as a subroutine.
957 * Entry: 'E' or 'N' message type has already been consumed.
958 * Exit: returns 0 if successfully consumed message.
959 * returns EOF if not enough data.
960 */
961static int
962pqGetErrorNotice2(PGconn *conn, bool isError)
963{
964 PGresult *res = NULL;
965 PQExpBufferData workBuf;
966 char *startp;
967 char *splitp;
968
969 /*
970 * If this is an error message, pre-emptively clear any incomplete query
971 * result we may have. We'd just throw it away below anyway, and
972 * releasing it before collecting the error might avoid out-of-memory.
973 */
974 if (isError)
975 pqClearAsyncResult(conn);
976
977 /*
978 * Since the message might be pretty long, we create a temporary
979 * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended
980 * for stuff that is expected to be short.
981 */
982 initPQExpBuffer(&workBuf);
983 if (pqGets(&workBuf, conn))
984 goto failure;
985
986 /*
987 * Make a PGresult to hold the message. We temporarily lie about the
988 * result status, so that PQmakeEmptyPGresult doesn't uselessly copy
989 * conn->errorMessage.
990 *
991 * NB: This allocation can fail, if you run out of memory. The rest of the
992 * function handles that gracefully, and we still try to set the error
993 * message as the connection's error message.
994 */
995 res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
996 if (res)
997 {
998 res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
999 res->errMsg = pqResultStrdup(res, workBuf.data);
1000 }
1001
1002 /*
1003 * Break the message into fields. We can't do very much here, but we can
1004 * split the severity code off, and remove trailing newlines. Also, we use
1005 * the heuristic that the primary message extends only to the first
1006 * newline --- anything after that is detail message. (In some cases it'd
1007 * be better classed as hint, but we can hardly be expected to guess that
1008 * here.)
1009 */
1010 while (workBuf.len > 0 && workBuf.data[workBuf.len - 1] == '\n')
1011 workBuf.data[--workBuf.len] = '\0';
1012 splitp = strstr(workBuf.data, ": ");
1013 if (splitp)
1014 {
1015 /* what comes before the colon is severity */
1016 *splitp = '\0';
1017 pqSaveMessageField(res, PG_DIAG_SEVERITY, workBuf.data);
1018 startp = splitp + 3;
1019 }
1020 else
1021 {
1022 /* can't find a colon? oh well... */
1023 startp = workBuf.data;
1024 }
1025 splitp = strchr(startp, '\n');
1026 if (splitp)
1027 {
1028 /* what comes before the newline is primary message */
1029 *splitp++ = '\0';
1030 pqSaveMessageField(res, PG_DIAG_MESSAGE_PRIMARY, startp);
1031 /* the rest is detail; strip any leading whitespace */
1032 while (*splitp && isspace((unsigned char) *splitp))
1033 splitp++;
1034 pqSaveMessageField(res, PG_DIAG_MESSAGE_DETAIL, splitp);
1035 }
1036 else
1037 {
1038 /* single-line message, so all primary */
1039 pqSaveMessageField(res, PG_DIAG_MESSAGE_PRIMARY, startp);
1040 }
1041
1042 /*
1043 * Either save error as current async result, or just emit the notice.
1044 * Also, if it's an error and we were in a transaction block, assume the
1045 * server has now gone to error-in-transaction state.
1046 */
1047 if (isError)
1048 {
1049 pqClearAsyncResult(conn); /* redundant, but be safe */
1050 conn->result = res;
1051 resetPQExpBuffer(&conn->errorMessage);
1052 if (res && !PQExpBufferDataBroken(workBuf) && res->errMsg)
1053 appendPQExpBufferStr(&conn->errorMessage, res->errMsg);
1054 else
1055 printfPQExpBuffer(&conn->errorMessage,
1056 libpq_gettext("out of memory"));
1057 if (conn->xactStatus == PQTRANS_INTRANS)
1058 conn->xactStatus = PQTRANS_INERROR;
1059 }
1060 else
1061 {
1062 if (res)
1063 {
1064 if (res->noticeHooks.noticeRec != NULL)
1065 res->noticeHooks.noticeRec(res->noticeHooks.noticeRecArg, res);
1066 PQclear(res);
1067 }
1068 }
1069
1070 termPQExpBuffer(&workBuf);
1071 return 0;
1072
1073failure:
1074 if (res)
1075 PQclear(res);
1076 termPQExpBuffer(&workBuf);
1077 return EOF;
1078}
1079
1080/*
1081 * checkXactStatus - attempt to track transaction-block status of server
1082 *
1083 * This is called each time we receive a command-complete message. By
1084 * watching for messages from BEGIN/COMMIT/ROLLBACK commands, we can do
1085 * a passable job of tracking the server's xact status. BUT: this does
1086 * not work at all on 7.3 servers with AUTOCOMMIT OFF. (Man, was that
1087 * feature ever a mistake.) Caveat user.
1088 *
1089 * The tags known here are all those used as far back as 7.0; is it worth
1090 * adding those from even-older servers?
1091 */
1092static void
1093checkXactStatus(PGconn *conn, const char *cmdTag)
1094{
1095 if (strcmp(cmdTag, "BEGIN") == 0)
1096 conn->xactStatus = PQTRANS_INTRANS;
1097 else if (strcmp(cmdTag, "COMMIT") == 0)
1098 conn->xactStatus = PQTRANS_IDLE;
1099 else if (strcmp(cmdTag, "ROLLBACK") == 0)
1100 conn->xactStatus = PQTRANS_IDLE;
1101 else if (strcmp(cmdTag, "START TRANSACTION") == 0) /* 7.3 only */
1102 conn->xactStatus = PQTRANS_INTRANS;
1103
1104 /*
1105 * Normally we get into INERROR state by detecting an Error message.
1106 * However, if we see one of these tags then we know for sure the server
1107 * is in abort state ...
1108 */
1109 else if (strcmp(cmdTag, "*ABORT STATE*") == 0) /* pre-7.3 only */
1110 conn->xactStatus = PQTRANS_INERROR;
1111}
1112
1113/*
1114 * Attempt to read a Notify response message.
1115 * This is possible in several places, so we break it out as a subroutine.
1116 * Entry: 'A' message type and length have already been consumed.
1117 * Exit: returns 0 if successfully consumed Notify message.
1118 * returns EOF if not enough data.
1119 */
1120static int
1121getNotify(PGconn *conn)
1122{
1123 int be_pid;
1124 int nmlen;
1125 PGnotify *newNotify;
1126
1127 if (pqGetInt(&be_pid, 4, conn))
1128 return EOF;
1129 if (pqGets(&conn->workBuffer, conn))
1130 return EOF;
1131
1132 /*
1133 * Store the relation name right after the PQnotify structure so it can
1134 * all be freed at once. We don't use NAMEDATALEN because we don't want
1135 * to tie this interface to a specific server name length.
1136 */
1137 nmlen = strlen(conn->workBuffer.data);
1138 newNotify = (PGnotify *) malloc(sizeof(PGnotify) + nmlen + 1);
1139 if (newNotify)
1140 {
1141 newNotify->relname = (char *) newNotify + sizeof(PGnotify);
1142 strcpy(newNotify->relname, conn->workBuffer.data);
1143 /* fake up an empty-string extra field */
1144 newNotify->extra = newNotify->relname + nmlen;
1145 newNotify->be_pid = be_pid;
1146 newNotify->next = NULL;
1147 if (conn->notifyTail)
1148 conn->notifyTail->next = newNotify;
1149 else
1150 conn->notifyHead = newNotify;
1151 conn->notifyTail = newNotify;
1152 }
1153
1154 return 0;
1155}
1156
1157
1158/*
1159 * PQgetCopyData - read a row of data from the backend during COPY OUT
1160 *
1161 * If successful, sets *buffer to point to a malloc'd row of data, and
1162 * returns row length (always > 0) as result.
1163 * Returns 0 if no row available yet (only possible if async is true),
1164 * -1 if end of copy (consult PQgetResult), or -2 if error (consult
1165 * PQerrorMessage).
1166 */
1167int
1168pqGetCopyData2(PGconn *conn, char **buffer, int async)
1169{
1170 bool found;
1171 int msgLength;
1172
1173 for (;;)
1174 {
1175 /*
1176 * Do we have a complete line of data?
1177 */
1178 conn->inCursor = conn->inStart;
1179 found = false;
1180 while (conn->inCursor < conn->inEnd)
1181 {
1182 char c = conn->inBuffer[conn->inCursor++];
1183
1184 if (c == '\n')
1185 {
1186 found = true;
1187 break;
1188 }
1189 }
1190 if (!found)
1191 goto nodata;
1192 msgLength = conn->inCursor - conn->inStart;
1193
1194 /*
1195 * If it's the end-of-data marker, consume it, exit COPY_OUT mode, and
1196 * let caller read status with PQgetResult().
1197 */
1198 if (msgLength == 3 &&
1199 strncmp(&conn->inBuffer[conn->inStart], "\\.\n", 3) == 0)
1200 {
1201 conn->inStart = conn->inCursor;
1202 conn->asyncStatus = PGASYNC_BUSY;
1203 return -1;
1204 }
1205
1206 /*
1207 * Pass the line back to the caller.
1208 */
1209 *buffer = (char *) malloc(msgLength + 1);
1210 if (*buffer == NULL)
1211 {
1212 printfPQExpBuffer(&conn->errorMessage,
1213 libpq_gettext("out of memory\n"));
1214 return -2;
1215 }
1216 memcpy(*buffer, &conn->inBuffer[conn->inStart], msgLength);
1217 (*buffer)[msgLength] = '\0'; /* Add terminating null */
1218
1219 /* Mark message consumed */
1220 conn->inStart = conn->inCursor;
1221
1222 return msgLength;
1223
1224nodata:
1225 /* Don't block if async read requested */
1226 if (async)
1227 return 0;
1228 /* Need to load more data */
1229 if (pqWait(true, false, conn) ||
1230 pqReadData(conn) < 0)
1231 return -2;
1232 }
1233}
1234
1235
1236/*
1237 * PQgetline - gets a newline-terminated string from the backend.
1238 *
1239 * See fe-exec.c for documentation.
1240 */
1241int
1242pqGetline2(PGconn *conn, char *s, int maxlen)
1243{
1244 int result = 1; /* return value if buffer overflows */
1245
1246 if (conn->sock == PGINVALID_SOCKET ||
1247 conn->asyncStatus != PGASYNC_COPY_OUT)
1248 {
1249 *s = '\0';
1250 return EOF;
1251 }
1252
1253 /*
1254 * Since this is a purely synchronous routine, we don't bother to maintain
1255 * conn->inCursor; there is no need to back up.
1256 */
1257 while (maxlen > 1)
1258 {
1259 if (conn->inStart < conn->inEnd)
1260 {
1261 char c = conn->inBuffer[conn->inStart++];
1262
1263 if (c == '\n')
1264 {
1265 result = 0; /* success exit */
1266 break;
1267 }
1268 *s++ = c;
1269 maxlen--;
1270 }
1271 else
1272 {
1273 /* need to load more data */
1274 if (pqWait(true, false, conn) ||
1275 pqReadData(conn) < 0)
1276 {
1277 result = EOF;
1278 break;
1279 }
1280 }
1281 }
1282 *s = '\0';
1283
1284 return result;
1285}
1286
1287/*
1288 * PQgetlineAsync - gets a COPY data row without blocking.
1289 *
1290 * See fe-exec.c for documentation.
1291 */
1292int
1293pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize)
1294{
1295 int avail;
1296
1297 if (conn->asyncStatus != PGASYNC_COPY_OUT)
1298 return -1; /* we are not doing a copy... */
1299
1300 /*
1301 * Move data from libpq's buffer to the caller's. We want to accept data
1302 * only in units of whole lines, not partial lines. This ensures that we
1303 * can recognize the terminator line "\\.\n". (Otherwise, if it happened
1304 * to cross a packet/buffer boundary, we might hand the first one or two
1305 * characters off to the caller, which we shouldn't.)
1306 */
1307
1308 conn->inCursor = conn->inStart;
1309
1310 avail = bufsize;
1311 while (avail > 0 && conn->inCursor < conn->inEnd)
1312 {
1313 char c = conn->inBuffer[conn->inCursor++];
1314
1315 *buffer++ = c;
1316 --avail;
1317 if (c == '\n')
1318 {
1319 /* Got a complete line; mark the data removed from libpq */
1320 conn->inStart = conn->inCursor;
1321 /* Is it the endmarker line? */
1322 if (bufsize - avail == 3 && buffer[-3] == '\\' && buffer[-2] == '.')
1323 return -1;
1324 /* No, return the data line to the caller */
1325 return bufsize - avail;
1326 }
1327 }
1328
1329 /*
1330 * We don't have a complete line. We'd prefer to leave it in libpq's
1331 * buffer until the rest arrives, but there is a special case: what if the
1332 * line is longer than the buffer the caller is offering us? In that case
1333 * we'd better hand over a partial line, else we'd get into an infinite
1334 * loop. Do this in a way that ensures we can't misrecognize a terminator
1335 * line later: leave last 3 characters in libpq buffer.
1336 */
1337 if (avail == 0 && bufsize > 3)
1338 {
1339 conn->inStart = conn->inCursor - 3;
1340 return bufsize - 3;
1341 }
1342 return 0;
1343}
1344
1345/*
1346 * PQendcopy
1347 *
1348 * See fe-exec.c for documentation.
1349 */
1350int
1351pqEndcopy2(PGconn *conn)
1352{
1353 PGresult *result;
1354
1355 if (conn->asyncStatus != PGASYNC_COPY_IN &&
1356 conn->asyncStatus != PGASYNC_COPY_OUT)
1357 {
1358 printfPQExpBuffer(&conn->errorMessage,
1359 libpq_gettext("no COPY in progress\n"));
1360 return 1;
1361 }
1362
1363 /*
1364 * make sure no data is waiting to be sent, abort if we are non-blocking
1365 * and the flush fails
1366 */
1367 if (pqFlush(conn) && pqIsnonblocking(conn))
1368 return 1;
1369
1370 /* non blocking connections may have to abort at this point. */
1371 if (pqIsnonblocking(conn) && PQisBusy(conn))
1372 return 1;
1373
1374 /* Return to active duty */
1375 conn->asyncStatus = PGASYNC_BUSY;
1376 resetPQExpBuffer(&conn->errorMessage);
1377
1378 /* Wait for the completion response */
1379 result = PQgetResult(conn);
1380
1381 /* Expecting a successful result */
1382 if (result && result->resultStatus == PGRES_COMMAND_OK)
1383 {
1384 PQclear(result);
1385 return 0;
1386 }
1387
1388 /*
1389 * Trouble. For backwards-compatibility reasons, we issue the error
1390 * message as if it were a notice (would be nice to get rid of this
1391 * silliness, but too many apps probably don't handle errors from
1392 * PQendcopy reasonably). Note that the app can still obtain the error
1393 * status from the PGconn object.
1394 */
1395 if (conn->errorMessage.len > 0)
1396 {
1397 /* We have to strip the trailing newline ... pain in neck... */
1398 char svLast = conn->errorMessage.data[conn->errorMessage.len - 1];
1399
1400 if (svLast == '\n')
1401 conn->errorMessage.data[conn->errorMessage.len - 1] = '\0';
1402 pqInternalNotice(&conn->noticeHooks, "%s", conn->errorMessage.data);
1403 conn->errorMessage.data[conn->errorMessage.len - 1] = svLast;
1404 }
1405
1406 PQclear(result);
1407
1408 /*
1409 * The worst case is that we've lost sync with the backend entirely due to
1410 * application screwup of the copy in/out protocol. To recover, reset the
1411 * connection (talk about using a sledgehammer...)
1412 */
1413 pqInternalNotice(&conn->noticeHooks,
1414 "lost synchronization with server, resetting connection");
1415
1416 /*
1417 * Users doing non-blocking connections need to handle the reset
1418 * themselves, they'll need to check the connection status if we return an
1419 * error.
1420 */
1421 if (pqIsnonblocking(conn))
1422 PQresetStart(conn);
1423 else
1424 PQreset(conn);
1425
1426 return 1;
1427}
1428
1429
1430/*
1431 * PQfn - Send a function call to the POSTGRES backend.
1432 *
1433 * See fe-exec.c for documentation.
1434 */
1435PGresult *
1436pqFunctionCall2(PGconn *conn, Oid fnid,
1437 int *result_buf, int *actual_result_len,
1438 int result_is_int,
1439 const PQArgBlock *args, int nargs)
1440{
1441 bool needInput = false;
1442 ExecStatusType status = PGRES_FATAL_ERROR;
1443 char id;
1444 int i;
1445
1446 /* PQfn already validated connection state */
1447
1448 if (pqPutMsgStart('F', false, conn) < 0 || /* function call msg */
1449 pqPuts(" ", conn) < 0 || /* dummy string */
1450 pqPutInt(fnid, 4, conn) != 0 || /* function id */
1451 pqPutInt(nargs, 4, conn) != 0) /* # of args */
1452 {
1453 /* error message should be set up already */
1454 return NULL;
1455 }
1456
1457 for (i = 0; i < nargs; ++i)
1458 { /* len.int4 + contents */
1459 if (pqPutInt(args[i].len, 4, conn))
1460 return NULL;
1461
1462 if (args[i].isint)
1463 {
1464 if (pqPutInt(args[i].u.integer, 4, conn))
1465 return NULL;
1466 }
1467 else
1468 {
1469 if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))
1470 return NULL;
1471 }
1472 }
1473
1474 if (pqPutMsgEnd(conn) < 0 ||
1475 pqFlush(conn))
1476 return NULL;
1477
1478 for (;;)
1479 {
1480 if (needInput)
1481 {
1482 /* Wait for some data to arrive (or for the channel to close) */
1483 if (pqWait(true, false, conn) ||
1484 pqReadData(conn) < 0)
1485 break;
1486 }
1487
1488 /*
1489 * Scan the message. If we run out of data, loop around to try again.
1490 */
1491 conn->inCursor = conn->inStart;
1492 needInput = true;
1493
1494 if (pqGetc(&id, conn))
1495 continue;
1496
1497 /*
1498 * We should see V or E response to the command, but might get N
1499 * and/or A notices first. We also need to swallow the final Z before
1500 * returning.
1501 */
1502 switch (id)
1503 {
1504 case 'V': /* function result */
1505 if (pqGetc(&id, conn))
1506 continue;
1507 if (id == 'G')
1508 {
1509 /* function returned nonempty value */
1510 if (pqGetInt(actual_result_len, 4, conn))
1511 continue;
1512 if (result_is_int)
1513 {
1514 if (pqGetInt(result_buf, 4, conn))
1515 continue;
1516 }
1517 else
1518 {
1519 if (pqGetnchar((char *) result_buf,
1520 *actual_result_len,
1521 conn))
1522 continue;
1523 }
1524 if (pqGetc(&id, conn)) /* get the last '0' */
1525 continue;
1526 }
1527 if (id == '0')
1528 {
1529 /* correctly finished function result message */
1530 status = PGRES_COMMAND_OK;
1531 }
1532 else
1533 {
1534 /* The backend violates the protocol. */
1535 printfPQExpBuffer(&conn->errorMessage,
1536 libpq_gettext("protocol error: id=0x%x\n"),
1537 id);
1538 pqSaveErrorResult(conn);
1539 conn->inStart = conn->inCursor;
1540 return pqPrepareAsyncResult(conn);
1541 }
1542 break;
1543 case 'E': /* error return */
1544 if (pqGetErrorNotice2(conn, true))
1545 continue;
1546 status = PGRES_FATAL_ERROR;
1547 break;
1548 case 'A': /* notify message */
1549 /* handle notify and go back to processing return values */
1550 if (getNotify(conn))
1551 continue;
1552 break;
1553 case 'N': /* notice */
1554 /* handle notice and go back to processing return values */
1555 if (pqGetErrorNotice2(conn, false))
1556 continue;
1557 break;
1558 case 'Z': /* backend is ready for new query */
1559 /* consume the message and exit */
1560 conn->inStart = conn->inCursor;
1561 /* if we saved a result object (probably an error), use it */
1562 if (conn->result)
1563 return pqPrepareAsyncResult(conn);
1564 return PQmakeEmptyPGresult(conn, status);
1565 default:
1566 /* The backend violates the protocol. */
1567 printfPQExpBuffer(&conn->errorMessage,
1568 libpq_gettext("protocol error: id=0x%x\n"),
1569 id);
1570 pqSaveErrorResult(conn);
1571 conn->inStart = conn->inCursor;
1572 return pqPrepareAsyncResult(conn);
1573 }
1574 /* Completed this message, keep going */
1575 conn->inStart = conn->inCursor;
1576 needInput = false;
1577 }
1578
1579 /*
1580 * We fall out of the loop only upon failing to read data.
1581 * conn->errorMessage has been set by pqWait or pqReadData. We want to
1582 * append it to any already-received error message.
1583 */
1584 pqSaveErrorResult(conn);
1585 return pqPrepareAsyncResult(conn);
1586}
1587
1588
1589/*
1590 * Construct startup packet
1591 *
1592 * Returns a malloc'd packet buffer, or NULL if out of memory
1593 */
1594char *
1595pqBuildStartupPacket2(PGconn *conn, int *packetlen,
1596 const PQEnvironmentOption *options)
1597{
1598 StartupPacket *startpacket;
1599
1600 *packetlen = sizeof(StartupPacket);
1601 startpacket = (StartupPacket *) malloc(sizeof(StartupPacket));
1602 if (!startpacket)
1603 return NULL;
1604
1605 MemSet(startpacket, 0, sizeof(StartupPacket));
1606
1607 startpacket->protoVersion = pg_hton32(conn->pversion);
1608
1609 /* strncpy is safe here: postmaster will handle full fields correctly */
1610 strncpy(startpacket->user, conn->pguser, SM_USER);
1611 strncpy(startpacket->database, conn->dbName, SM_DATABASE);
1612 strncpy(startpacket->tty, conn->pgtty, SM_TTY);
1613
1614 if (conn->pgoptions)
1615 strncpy(startpacket->options, conn->pgoptions, SM_OPTIONS);
1616
1617 return (char *) startpacket;
1618}
1619