1 /*-------------------------------------------------------------------------
4 * functions related to setting up a connection to the backend
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.77 1998/07/26 04:31:36 scrappy Exp $
12 *-------------------------------------------------------------------------
16 #include <sys/types.h>
20 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <netinet/tcp.h>
33 #include <ctype.h> /* for isspace() */
37 #include "fe-connect.h"
48 #include "mb/pg_wchar.h"
51 static ConnStatusType connectDB(PGconn *conn);
52 static PGconn *makeEmptyPGconn(void);
53 static void freePGconn(PGconn *conn);
54 static void closePGconn(PGconn *conn);
55 static int conninfo_parse(const char *conninfo, char *errorMessage);
56 static char *conninfo_getval(char *keyword);
57 static void conninfo_free(void);
58 /* XXX Why is this not static? */
59 void PQsetenv(PGconn *conn);
61 #define NOTIFYLIST_INITIAL_SIZE 10
62 #define NOTIFYLIST_GROWBY 10
66 * Definition of the conninfo parameters and their fallback resources.
67 * If Environment-Var and Compiled-in are specified as NULL, no
68 * fallback is available. If after all no value can be determined
69 * for an option, an error is returned.
71 * The values for dbname and user are treated special in conninfo_parse.
72 * If the Compiled-in resource is specified as a NULL value, the
73 * user is determined by fe_getauthname() and for dbname the user
76 * The Label and Disp-Char entries are provided for applications that
77 * want to use PQconndefaults() to create a generic database connection
78 * dialog. Disp-Char is defined as follows:
79 * "" Normal input field
82 static PQconninfoOption PQconninfoOptions[] = {
83 /* ----------------------------------------------------------------- */
84 /* Option-name Environment-Var Compiled-in Current value */
86 /* ----------------- --------------- --------------- --------------- */
87 /* "authtype" is ignored as it is no longer used. */
88 {"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
89 "Database-Authtype", "", 20},
91 {"user", "PGUSER", NULL, NULL,
92 "Database-User", "", 20},
94 {"password", "PGPASSWORD", DefaultPassword, NULL,
95 "Database-Password", "", 20},
97 {"dbname", "PGDATABASE", NULL, NULL,
98 "Database-Name", "", 20},
100 {"host", "PGHOST", NULL, NULL,
101 "Database-Host", "", 40},
103 {"port", "PGPORT", DEF_PGPORT, NULL,
104 "Database-Port", "", 6},
106 {"tty", "PGTTY", DefaultTty, NULL,
107 "Backend-Debug-TTY", "D", 40},
109 {"options", "PGOPTIONS", DefaultOption, NULL,
110 "Backend-Debug-Options", "D", 40},
111 /* ----------------- --------------- --------------- --------------- */
112 {NULL, NULL, NULL, NULL,
116 struct EnvironmentOptions
120 } EnvironmentOptions[] =
123 /* common user-interface settings */
125 "PGDATESTYLE", "datestyle"
132 "PGCLIENTENCODING", "client_encoding"
135 /* internal performance-related settings */
137 "PGCOSTHEAP", "cost_heap"
140 "PGCOSTINDEX", "cost_index"
143 "PGRPLANS", "r_plans"
156 * establishes a connection to a postgres backend through the postmaster
157 * using connection information in a string.
159 * The conninfo string is a list of
163 * definitions. Value might be a single value containing no whitespaces
164 * or a single quoted string. If a single quote should appear everywhere
165 * in the value, it must be escaped with a backslash like \'
167 * Returns a PGconn* which is needed for all subsequent libpq calls
168 * if the status field of the connection returned is CONNECTION_BAD,
169 * then some fields may be null'ed out instead of having valid values
173 PQconnectdb(const char *conninfo)
179 * Allocate memory for the conn structure
182 conn = makeEmptyPGconn();
186 "FATAL: PQconnectdb() -- unable to allocate memory for a PGconn");
187 return (PGconn *) NULL;
191 * Parse the conninfo string and save settings in conn structure
194 if (conninfo_parse(conninfo, conn->errorMessage) < 0)
196 conn->status = CONNECTION_BAD;
200 tmp = conninfo_getval("host");
201 conn->pghost = tmp ? strdup(tmp) : NULL;
202 tmp = conninfo_getval("port");
203 conn->pgport = tmp ? strdup(tmp) : NULL;
204 tmp = conninfo_getval("tty");
205 conn->pgtty = tmp ? strdup(tmp) : NULL;
206 tmp = conninfo_getval("options");
207 conn->pgoptions = tmp ? strdup(tmp) : NULL;
208 tmp = conninfo_getval("dbname");
209 conn->dbName = tmp ? strdup(tmp) : NULL;
210 tmp = conninfo_getval("user");
211 conn->pguser = tmp ? strdup(tmp) : NULL;
212 tmp = conninfo_getval("password");
213 conn->pgpass = tmp ? strdup(tmp) : NULL;
216 * Free the connection info - all is in conn now
222 * Connect to the database
225 conn->status = connectDB(conn);
233 * Parse an empty string like PQconnectdb() would do and return the
234 * address of the connection options structure. Using this function
235 * an application might determine all possible options and their
236 * current default values.
242 char errorMessage[ERROR_MSG_LENGTH];
244 conninfo_parse("", errorMessage);
245 return PQconninfoOptions;
251 * establishes a connection to a postgres backend through the postmaster
252 * at the specified host and port.
254 * returns a PGconn* which is needed for all subsequent libpq calls
255 * if the status field of the connection returned is CONNECTION_BAD,
256 * then some fields may be null'ed out instead of having valid values
258 * Uses these environment variables:
260 * PGHOST identifies host to which to connect if <pghost> argument
261 * is NULL or a null string.
263 * PGPORT identifies TCP port to which to connect if <pgport> argument
264 * is NULL or a null string.
266 * PGTTY identifies tty to which to send messages if <pgtty> argument
267 * is NULL or a null string.
269 * PGOPTIONS identifies connection options if <pgoptions> argument is
270 * NULL or a null string.
272 * PGUSER Postgres username to associate with the connection.
274 * PGPASSWORD The user's password.
276 * PGDATABASE name of database to which to connect if <pgdatabase>
277 * argument is NULL or a null string
279 * None of the above need be defined. There are defaults for all of them.
281 * To support "delimited identifiers" for database names, only convert
282 * the database name to lower case if it is not surrounded by double quotes.
283 * Otherwise, strip the double quotes but leave the reset of the string intact.
284 * - thomas 1997-11-08
289 PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd)
293 /* An error message from some service we call. */
295 /* We encountered an error that prevents successful completion */
298 conn = makeEmptyPGconn();
302 "FATAL: PQsetdbLogin() -- unable to allocate memory for a PGconn");
303 return (PGconn *) NULL;
306 if ((pghost == NULL) || pghost[0] == '\0')
308 if ((tmp = getenv("PGHOST")) != NULL)
309 conn->pghost = strdup(tmp);
312 conn->pghost = strdup(pghost);
314 if ((pgport == NULL) || pgport[0] == '\0')
316 if ((tmp = getenv("PGPORT")) == NULL)
318 conn->pgport = strdup(tmp);
321 conn->pgport = strdup(pgport);
323 if ((pgtty == NULL) || pgtty[0] == '\0')
325 if ((tmp = getenv("PGTTY")) == NULL)
327 conn->pgtty = strdup(tmp);
330 conn->pgtty = strdup(pgtty);
332 if ((pgoptions == NULL) || pgoptions[0] == '\0')
334 if ((tmp = getenv("PGOPTIONS")) == NULL)
336 conn->pgoptions = strdup(tmp);
339 conn->pgoptions = strdup(pgoptions);
342 conn->pguser = strdup(login);
343 else if ((tmp = getenv("PGUSER")) != NULL)
344 conn->pguser = strdup(tmp);
346 conn->pguser = fe_getauthname(conn->errorMessage);
348 if (conn->pguser == NULL)
351 sprintf(conn->errorMessage,
352 "FATAL: PQsetdbLogin(): Unable to determine a Postgres username!\n");
356 conn->pgpass = strdup(pwd);
357 else if ((tmp = getenv("PGPASSWORD")) != NULL)
358 conn->pgpass = strdup(tmp);
360 conn->pgpass = strdup(DefaultPassword);
362 if ((dbName == NULL) || dbName[0] == '\0')
364 if ((tmp = getenv("PGDATABASE")) != NULL)
365 conn->dbName = strdup(tmp);
366 else if (conn->pguser)
367 conn->dbName = strdup(conn->pguser);
370 conn->dbName = strdup(dbName);
375 * if the database name is surrounded by double-quotes, then
378 if (*conn->dbName == '"')
380 strcpy(conn->dbName, conn->dbName + 1);
381 conn->dbName[strlen(conn->dbName) - 1] = '\0';
384 for (i = 0; conn->dbName[i]; i++)
385 if (isascii((unsigned char)conn->dbName[i]) &&
386 isupper(conn->dbName[i]))
387 conn->dbName[i] = tolower(conn->dbName[i]);
391 conn->status = CONNECTION_BAD;
393 conn->status = connectDB(conn);
401 * get all additional infos out of dbName
405 update_db_info(PGconn *conn)
407 char *tmp, *old = conn->dbName;
409 if (strchr(conn->dbName, '@') != NULL)
411 /* old style: dbname[@server][:port] */
412 tmp = strrchr(conn->dbName, ':');
413 if (tmp != NULL) /* port number given */
415 conn->pgport = strdup(tmp + 1);
419 tmp = strrchr(conn->dbName, '@');
420 if (tmp != NULL) /* host name given */
422 conn->pghost = strdup(tmp + 1);
426 conn->dbName = strdup(old);
434 * only allow protocols tcp and unix
436 if (strncmp(conn->dbName, "tcp:", 4) == 0)
438 else if (strncmp(conn->dbName, "unix:", 5) == 0)
442 if (strncmp(conn->dbName + offset, "postgresql://", strlen("postgresql://")) == 0)
444 /* new style: <tcp|unix>:postgresql://server[:port][/dbname][?options] */
445 offset += strlen("postgresql://");
447 tmp = strrchr(conn->dbName + offset, '?');
448 if (tmp != NULL) /* options given */
450 conn->pgoptions = strdup(tmp + 1);
454 tmp = strrchr(conn->dbName + offset, '/');
455 if (tmp != NULL) /* database name given */
457 conn->dbName = strdup(tmp + 1);
462 if ((tmp = getenv("PGDATABASE")) != NULL)
463 conn->dbName = strdup(tmp);
464 else if (conn->pguser)
465 conn->dbName = strdup(conn->pguser);
468 tmp = strrchr(old + offset, ':');
469 if (tmp != NULL) /* port number given */
471 conn->pgport = strdup(tmp + 1);
475 if (strncmp(old, "unix:", 5) == 0)
478 if (strcmp(old + offset, "localhost") != 0)
480 (void) sprintf(conn->errorMessage,
481 "connectDB() -- non-tcp access only possible on localhost\n");
485 else conn->pghost = strdup(old + offset);
496 * make a connection to the backend so it is ready to receive queries.
497 * return CONNECTION_OK if successful, CONNECTION_BAD if not.
500 static ConnStatusType
501 connectDB(PGconn *conn)
507 int laddrlen = sizeof(SockAddr);
514 * parse dbName to get all additional info in it, if any
516 if (update_db_info(conn) != 0)
517 goto connect_errReturn;
520 * Initialize the startup packet.
523 MemSet((char *) &sp, 0, sizeof(StartupPacket));
525 sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LATEST);
527 strncpy(sp.user, conn->pguser, SM_USER);
528 strncpy(sp.database, conn->dbName, SM_DATABASE);
529 strncpy(sp.tty, conn->pgtty, SM_TTY);
532 strncpy(sp.options, conn->pgoptions, SM_OPTIONS);
535 * Open a connection to postmaster/backend.
538 if (conn->pghost != NULL)
540 hp = gethostbyname(conn->pghost);
541 if ((hp == NULL) || (hp->h_addrtype != AF_INET))
543 (void) sprintf(conn->errorMessage,
544 "connectDB() -- unknown hostname: %s\n",
546 goto connect_errReturn;
555 MemSet((char *) &conn->raddr, 0, sizeof(conn->raddr));
556 conn->raddr.sa.sa_family = family;
558 portno = atoi(conn->pgport);
559 if (family == AF_INET)
561 memmove((char *) &(conn->raddr.in.sin_addr),
564 conn->raddr.in.sin_port = htons((unsigned short) (portno));
565 conn->raddr_len = sizeof(struct sockaddr_in);
569 conn->raddr_len = UNIXSOCK_PATH(conn->raddr.un, portno);
573 /* Connect to the server */
574 if ((conn->sock = socket(family, SOCK_STREAM, 0)) < 0)
576 (void) sprintf(conn->errorMessage,
577 "connectDB() -- socket() failed: errno=%d\n%s\n",
578 errno, strerror(errno));
579 goto connect_errReturn;
581 if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
583 (void) sprintf(conn->errorMessage,
584 "connectDB() failed: Is the postmaster running and accepting%s connections at '%s' on port '%s'?\n",
585 conn->pghost ? " TCP/IP(with -i)" : "",
586 conn->pghost ? conn->pghost : "UNIX Socket",
588 goto connect_errReturn;
592 * Set the right options.
593 * We need nonblocking I/O, and we don't want delay of outgoing data.
597 if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) < 0)
599 if (ioctlsocket(conn->sock,FIONBIO, &on) != 0)
602 (void) sprintf(conn->errorMessage,
603 "connectDB() -- fcntl() failed: errno=%d\n%s\n",
604 errno, strerror(errno));
605 goto connect_errReturn;
608 if (family == AF_INET)
612 pe = getprotobyname("TCP");
615 (void) sprintf(conn->errorMessage,
616 "connectDB(): getprotobyname failed\n");
617 goto connect_errReturn;
619 if (setsockopt(conn->sock, pe->p_proto, TCP_NODELAY,
626 (void) sprintf(conn->errorMessage,
627 "connectDB() -- setsockopt failed: errno=%d\n%s\n",
628 errno, strerror(errno));
630 printf("Winsock error: %i\n",WSAGetLastError());
632 goto connect_errReturn;
636 /* Fill in the client address */
637 if (getsockname(conn->sock, &conn->laddr.sa, &laddrlen) < 0)
639 (void) sprintf(conn->errorMessage,
640 "connectDB() -- getsockname() failed: errno=%d\n%s\n",
641 errno, strerror(errno));
642 goto connect_errReturn;
645 /* Ensure our buffers are empty */
646 conn->inStart = conn->inCursor = conn->inEnd = 0;
649 /* Send the startup packet. */
651 if (packetSend(conn, (char *) &sp, sizeof(StartupPacket)) != STATUS_OK)
653 sprintf(conn->errorMessage,
654 "connectDB() -- couldn't send startup packet: errno=%d\n%s\n",
655 errno, strerror(errno));
656 goto connect_errReturn;
660 * Perform the authentication exchange:
661 * wait for backend messages and respond as necessary.
662 * We fall out of this loop when done talking to the postmaster.
667 /* Wait for some data to arrive (or for the channel to close) */
668 if (pqWait(TRUE, FALSE, conn))
669 goto connect_errReturn;
670 /* Load data, or detect EOF */
671 if (pqReadData(conn) < 0)
672 goto connect_errReturn;
674 * If we run out of data, loop around to try again.
676 conn->inCursor = conn->inStart;
678 if (pqGetc(&beresp, conn))
679 continue; /* no data yet */
684 if (pqGets(conn->errorMessage, sizeof(conn->errorMessage), conn))
686 goto connect_errReturn;
689 /* Otherwise it should be an authentication request. */
692 (void) sprintf(conn->errorMessage,
693 "connectDB() -- expected authentication request\n");
694 goto connect_errReturn;
697 /* Get the type of request. */
698 if (pqGetInt((int *) &areq, 4, conn))
701 /* Get the password salt if there is one. */
702 if (areq == AUTH_REQ_CRYPT)
704 if (pqGetnchar(conn->salt, sizeof(conn->salt), conn))
708 /* OK, we successfully read the message; mark data consumed */
709 conn->inStart = conn->inCursor;
711 /* Respond to the request if necessary. */
712 if (fe_sendauth(areq, conn, conn->pghost, conn->pgpass,
713 conn->errorMessage) != STATUS_OK)
714 goto connect_errReturn;
716 goto connect_errReturn;
719 if (areq == AUTH_REQ_OK)
724 * Now we expect to hear from the backend.
725 * A ReadyForQuery message indicates that startup is successful,
726 * but we might also get an Error message indicating failure.
727 * (Notice messages indicating nonfatal warnings are also allowed
728 * by the protocol, as is a BackendKeyData message.)
729 * Easiest way to handle this is to let PQgetResult() read the messages.
730 * We just have to fake it out about the state of the connection.
733 conn->status = CONNECTION_OK;
734 conn->asyncStatus = PGASYNC_BUSY;
735 res = PQgetResult(conn);
736 /* NULL return indicating we have gone to IDLE state is expected */
738 if (res->resultStatus != PGRES_FATAL_ERROR)
739 sprintf(conn->errorMessage,
740 "connectDB() -- unexpected message during startup\n");
742 goto connect_errReturn;
745 /* Given the new protocol that sends a ReadyForQuery message
746 * after successful backend startup, it should no longer be
747 * necessary to send an empty query to test for startup.
753 * Send a blank query to make sure everything works; in
754 * particular, that the database exists.
756 res = PQexec(conn, " ");
757 if (res == NULL || res->resultStatus != PGRES_EMPTY_QUERY)
759 /* PQexec has put error message in conn->errorMessage */
762 goto connect_errReturn;
768 /* Post-connection housekeeping.
769 * Send environment variables to server
774 return CONNECTION_OK;
780 closesocket(conn->sock);
786 return CONNECTION_BAD;
791 PQsetenv(PGconn *conn)
793 struct EnvironmentOptions *eo;
794 char setQuery[80]; /* mjl: size okay? XXX */
796 char *envname = "PGCLIENTENCODING";
804 /* query server encoding */
805 env = getenv(envname);
807 rtn = PQexec(conn, "select getdatabaseencoding()");
808 if (rtn && PQresultStatus(rtn) == PGRES_TUPLES_OK) {
809 encoding = PQgetvalue(rtn,0,0);
811 /* set client encoding */
812 sprintf(envbuf,"%s=%s",envname,encoding);
817 if (!encoding) { /* this should not happen */
818 sprintf(envbuf,"%s=%s",envname,pg_encoding_to_char(MULTIBYTE));
824 for (eo = EnvironmentOptions; eo->envName; eo++)
828 if ((val = getenv(eo->envName)))
832 if (strcasecmp(val, "default") == 0)
833 sprintf(setQuery, "SET %s = %.60s", eo->pgName, val);
835 sprintf(setQuery, "SET %s = '%.60s'", eo->pgName, val);
837 printf("Use environment variable %s to send %s\n", eo->envName, setQuery);
839 res = PQexec(conn, setQuery);
840 PQclear(res); /* Don't care? */
847 * - create a PGconn data structure with (as yet) no interesting data
850 makeEmptyPGconn(void)
852 PGconn *conn = (PGconn *) malloc(sizeof(PGconn));
856 /* Zero all pointers */
857 MemSet((char *) conn, 0, sizeof(PGconn));
859 conn->status = CONNECTION_BAD;
860 conn->asyncStatus = PGASYNC_IDLE;
861 conn->notifyList = DLNewList();
863 conn->inBufSize = 8192;
864 conn->inBuffer = (char *) malloc(conn->inBufSize);
865 conn->outBufSize = 8192;
866 conn->outBuffer = (char *) malloc(conn->outBufSize);
867 if (conn->inBuffer == NULL || conn->outBuffer == NULL)
877 * - free the PGconn data structure
881 freePGconn(PGconn *conn)
885 PQclearAsyncResult(conn); /* deallocate result and curTuple */
888 closesocket(conn->sock);
899 free(conn->pgoptions);
906 /* Note that conn->Pfdebug is not ours to close or free */
907 if (conn->notifyList)
908 DLFreeList(conn->notifyList);
910 free(conn->lobjfuncs);
912 free(conn->inBuffer);
914 free(conn->outBuffer);
920 - properly close a connection to the backend
923 closePGconn(PGconn *conn)
928 * Try to send close message.
929 * If connection is already gone, that's cool. No reason for kernel
930 * to kill us when we try to write to it. So ignore SIGPIPE signals.
933 #if defined(USE_POSIX_SIGNALS)
934 struct sigaction ignore_action;
935 struct sigaction oldaction;
937 ignore_action.sa_handler = SIG_IGN;
938 sigemptyset(&ignore_action.sa_mask);
939 ignore_action.sa_flags = 0;
940 sigaction(SIGPIPE, (struct sigaction *) & ignore_action, &oldaction);
942 (void) pqPuts("X", conn);
943 (void) pqFlush(conn);
945 sigaction(SIGPIPE, &oldaction, NULL);
947 void (*oldsignal)(int);
949 oldsignal = signal(SIGPIPE, SIG_IGN);
951 (void) pqPuts("X", conn);
952 (void) pqFlush(conn);
954 signal(SIGPIPE, oldsignal);
956 #endif /* Win32 uses no signals at all */
960 * Close the connection, reset all transient state, flush I/O buffers.
964 closesocket(conn->sock);
969 conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just
971 conn->asyncStatus = PGASYNC_IDLE;
972 PQclearAsyncResult(conn); /* deallocate result and curTuple */
974 free(conn->lobjfuncs);
975 conn->lobjfuncs = NULL;
976 conn->inStart = conn->inCursor = conn->inEnd = 0;
983 properly close a connection to the backend
984 also frees the PGconn data structure so it shouldn't be re-used
988 PQfinish(PGconn *conn)
991 fprintf(stderr, "PQfinish() -- pointer to PGconn is null\n");
1000 resets the connection to the backend
1001 closes the existing connection and makes a new one
1004 PQreset(PGconn *conn)
1007 fprintf(stderr, "PQreset() -- pointer to PGconn is null\n");
1011 conn->status = connectDB(conn);
1017 * PQrequestCancel: attempt to request cancellation of the current operation.
1019 * The return value is TRUE if the cancel request was successfully
1020 * dispatched, FALSE if not (in which case errorMessage is set).
1021 * Note: successful dispatch is no guarantee that there will be any effect at
1022 * the backend. The application must read the operation result as usual.
1024 * CAUTION: we want this routine to be safely callable from a signal handler
1025 * (for example, an application might want to call it in a SIGINT handler).
1026 * This means we cannot use any C library routine that might be non-reentrant.
1027 * malloc/free are often non-reentrant, and anything that might call them is
1028 * just as dangerous. We avoid sprintf here for that reason. Building up
1029 * error messages with strcpy/strcat is tedious but should be quite safe.
1033 PQrequestCancel(PGconn *conn)
1038 CancelRequestPacket cp;
1041 /* Check we have an open connection */
1047 strcpy(conn->errorMessage,
1048 "PQrequestCancel() -- connection is not open\n");
1053 * We need to open a temporary connection to the postmaster.
1054 * Use the information saved by connectDB to do this with
1055 * only kernel calls.
1057 if ((tmpsock = socket(conn->raddr.sa.sa_family, SOCK_STREAM, 0)) < 0)
1059 strcpy(conn->errorMessage, "PQrequestCancel() -- socket() failed: ");
1060 goto cancel_errReturn;
1062 if (connect(tmpsock, &conn->raddr.sa, conn->raddr_len) < 0)
1064 strcpy(conn->errorMessage, "PQrequestCancel() -- connect() failed: ");
1065 goto cancel_errReturn;
1068 * We needn't set nonblocking I/O or NODELAY options here.
1071 /* Create and send the cancel request packet. */
1073 crp.packetlen = htonl((uint32) sizeof(crp));
1074 crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE);
1075 crp.cp.backendPID = htonl(conn->be_pid);
1076 crp.cp.cancelAuthCode = htonl(conn->be_key);
1078 if (send(tmpsock, (char*) &crp, sizeof(crp), 0) != (int) sizeof(crp))
1080 strcpy(conn->errorMessage, "PQrequestCancel() -- send() failed: ");
1081 goto cancel_errReturn;
1086 closesocket(tmpsock);
1094 strcat(conn->errorMessage, strerror(errno));
1095 strcat(conn->errorMessage, "\n");
1099 closesocket(tmpsock);
1109 * PacketSend() -- send a single-packet message.
1110 * this is like PacketSend(), defined in backend/libpq/pqpacket.c
1112 * RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
1113 * SIDE_EFFECTS: may block.
1116 packetSend(PGconn *conn, const char *buf, size_t len)
1118 /* Send the total packet size. */
1120 if (pqPutInt(4 + len, 4, conn))
1121 return STATUS_ERROR;
1123 /* Send the packet itself. */
1125 if (pqPutnchar(buf, len, conn))
1126 return STATUS_ERROR;
1129 return STATUS_ERROR;
1136 * Conninfo parser routine
1140 conninfo_parse(const char *conninfo, char *errorMessage)
1148 PQconninfoOption *option;
1149 char errortmp[ERROR_MSG_LENGTH];
1153 if ((buf = strdup(conninfo)) == NULL)
1155 strcpy(errorMessage,
1156 "FATAL: cannot allocate memory for copy of conninfo string\n");
1163 /* Skip blanks before the parameter name */
1170 /* Get the parameter name */
1190 /* Check that there is a following '=' */
1193 sprintf(errorMessage,
1194 "ERROR: PQconnectdb() - Missing '=' after '%s' in conninfo\n",
1201 /* Skip blanks after the '=' */
1240 sprintf(errorMessage,
1241 "ERROR: PQconnectdb() - unterminated quoted string in conninfo\n");
1263 * Now we have the name and the value. Search
1264 * for the param record.
1267 for (option = PQconninfoOptions; option->keyword != NULL; option++)
1269 if (!strcmp(option->keyword, pname))
1272 if (option->keyword == NULL)
1274 sprintf(errorMessage,
1275 "ERROR: PQconnectdb() - unknown option '%s'\n",
1285 option->val = strdup(pval);
1291 * Get the fallback resources for parameters not specified
1292 * in the conninfo string.
1295 for (option = PQconninfoOptions; option->keyword != NULL; option++)
1297 if (option->val != NULL)
1298 continue; /* Value was in conninfo */
1301 * Try to get the environment variable fallback
1304 if (option->environ != NULL)
1306 if ((tmp = getenv(option->environ)) != NULL)
1308 option->val = strdup(tmp);
1314 * No environment variable specified or this one isn't set -
1318 if (option->compiled != NULL)
1320 option->val = strdup(option->compiled);
1325 * Special handling for user
1328 if (!strcmp(option->keyword, "user"))
1330 tmp = fe_getauthname(errortmp);
1332 option->val = strdup(tmp);
1336 * Special handling for dbname
1339 if (!strcmp(option->keyword, "dbname"))
1341 tmp = conninfo_getval("user");
1343 option->val = strdup(tmp);
1352 conninfo_getval(char *keyword)
1354 PQconninfoOption *option;
1356 for (option = PQconninfoOptions; option->keyword != NULL; option++)
1358 if (!strcmp(option->keyword, keyword))
1369 PQconninfoOption *option;
1371 for (option = PQconninfoOptions; option->keyword != NULL; option++)
1373 if (option->val != NULL)
1381 /* =========== accessor functions for PGconn ========= */
1387 fprintf(stderr, "PQdb() -- pointer to PGconn is null\n");
1388 return (char *) NULL;
1390 return conn->dbName;
1394 PQuser(PGconn *conn)
1398 fprintf(stderr, "PQuser() -- pointer to PGconn is null\n");
1399 return (char *) NULL;
1401 return conn->pguser;
1405 PQhost(PGconn *conn)
1409 fprintf(stderr, "PQhost() -- pointer to PGconn is null\n");
1410 return (char *) NULL;
1413 return conn->pghost;
1417 PQoptions(PGconn *conn)
1421 fprintf(stderr, "PQoptions() -- pointer to PGconn is null\n");
1422 return (char *) NULL;
1424 return conn->pgoptions;
1432 fprintf(stderr, "PQtty() -- pointer to PGconn is null\n");
1433 return (char *) NULL;
1439 PQport(PGconn *conn)
1443 fprintf(stderr, "PQport() -- pointer to PGconn is null\n");
1444 return (char *) NULL;
1446 return conn->pgport;
1450 PQstatus(PGconn *conn)
1454 fprintf(stderr, "PQstatus() -- pointer to PGconn is null\n");
1455 return CONNECTION_BAD;
1457 return conn->status;
1461 PQerrorMessage(PGconn *conn)
1465 fprintf(stderr, "PQerrorMessage() -- pointer to PGconn is null\n");
1466 return (char *) NULL;
1468 return conn->errorMessage;
1472 PQsocket(PGconn *conn)
1476 fprintf(stderr, "PQsocket() -- pointer to PGconn is null\n");
1483 PQtrace(PGconn *conn, FILE *debug_port)
1486 conn->status == CONNECTION_BAD)
1489 conn->Pfdebug = debug_port;
1493 PQuntrace(PGconn *conn)
1495 /* note: better allow untrace even when connection bad */
1500 fflush(conn->Pfdebug);
1501 conn->Pfdebug = NULL;