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