fe-connect.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:32k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * fe-connect.c
  4.  *   functions related to setting up a connection to the backend
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.98 1999/06/17 15:16:04 momjian Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. #include "libpq-fe.h"
  15. #include "libpq-int.h"
  16. #include "fe-auth.h"
  17. #include "postgres.h"
  18. #include <stdlib.h>
  19. #ifdef WIN32
  20. #include "win32.h"
  21. #else
  22. #if !defined(NO_UNISTD_H)
  23. #include <unistd.h>
  24. #endif
  25. #include <netdb.h>
  26. #include <netinet/tcp.h>
  27. #endif
  28. #include <fcntl.h>
  29. #include <string.h>
  30. #include <errno.h>
  31. #include <ctype.h> /* for isspace() */
  32. #ifndef HAVE_STRDUP
  33. #include "strdup.h"
  34. #endif
  35. #ifdef HAVE_CRYPT_H
  36. #include <crypt.h>
  37. #endif
  38. #ifdef MULTIBYTE
  39. #include "mb/pg_wchar.h"
  40. #endif
  41. static ConnStatusType connectDB(PGconn *conn);
  42. static PGconn *makeEmptyPGconn(void);
  43. static void freePGconn(PGconn *conn);
  44. static void closePGconn(PGconn *conn);
  45. static int conninfo_parse(const char *conninfo, char *errorMessage);
  46. static char *conninfo_getval(char *keyword);
  47. static void conninfo_free(void);
  48. static void defaultNoticeProcessor(void *arg, const char *message);
  49. /* XXX Why is this not static? */
  50. void PQsetenv(PGconn *conn);
  51. #define NOTIFYLIST_INITIAL_SIZE 10
  52. #define NOTIFYLIST_GROWBY 10
  53. /* ----------
  54.  * Definition of the conninfo parameters and their fallback resources.
  55.  * If Environment-Var and Compiled-in are specified as NULL, no
  56.  * fallback is available. If after all no value can be determined
  57.  * for an option, an error is returned.
  58.  *
  59.  * The values for dbname and user are treated special in conninfo_parse.
  60.  * If the Compiled-in resource is specified as a NULL value, the
  61.  * user is determined by fe_getauthname() and for dbname the user
  62.  * name is copied.
  63.  *
  64.  * The Label and Disp-Char entries are provided for applications that
  65.  * want to use PQconndefaults() to create a generic database connection
  66.  * dialog. Disp-Char is defined as follows:
  67.  *    "" Normal input field
  68.  * ----------
  69.  */
  70. static PQconninfoOption PQconninfoOptions[] = {
  71. /* ----------------------------------------------------------------- */
  72. /*   Option-name Environment-Var Compiled-in Current value */
  73. /* Label Disp-Char */
  74. /* ----------------- --------------- --------------- --------------- */
  75. /* "authtype" is ignored as it is no longer used. */
  76. {"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
  77. "Database-Authtype", "", 20},
  78. {"user", "PGUSER", NULL, NULL,
  79. "Database-User", "", 20},
  80. {"password", "PGPASSWORD", DefaultPassword, NULL,
  81. "Database-Password", "", 20},
  82. {"dbname", "PGDATABASE", NULL, NULL,
  83. "Database-Name", "", 20},
  84. {"host", "PGHOST", NULL, NULL,
  85. "Database-Host", "", 40},
  86. {"port", "PGPORT", DEF_PGPORT, NULL,
  87. "Database-Port", "", 6},
  88. {"tty", "PGTTY", DefaultTty, NULL,
  89. "Backend-Debug-TTY", "D", 40},
  90. {"options", "PGOPTIONS", DefaultOption, NULL,
  91. "Backend-Debug-Options", "D", 40},
  92. /* ----------------- --------------- --------------- --------------- */
  93. {NULL, NULL, NULL, NULL,
  94. NULL, NULL, 0}
  95. };
  96. static struct EnvironmentOptions
  97. {
  98. const char *envName,
  99.    *pgName;
  100. } EnvironmentOptions[] =
  101. {
  102. /* common user-interface settings */
  103. {
  104. "PGDATESTYLE", "datestyle"
  105. },
  106. {
  107. "PGTZ", "timezone"
  108. },
  109. #ifdef MULTIBYTE
  110. {
  111. "PGCLIENTENCODING", "client_encoding"
  112. },
  113. #endif
  114. /* internal performance-related settings */
  115. {
  116. "PGCOSTHEAP", "cost_heap"
  117. },
  118. {
  119. "PGCOSTINDEX", "cost_index"
  120. },
  121. {
  122. "PGGEQO", "geqo"
  123. },
  124. {
  125. NULL
  126. }
  127. };
  128. /* ----------------
  129.  * PQconnectdb
  130.  *
  131.  * establishes a connection to a postgres backend through the postmaster
  132.  * using connection information in a string.
  133.  *
  134.  * The conninfo string is a list of
  135.  *
  136.  *    option = value
  137.  *
  138.  * definitions. Value might be a single value containing no whitespaces
  139.  * or a single quoted string. If a single quote should appear everywhere
  140.  * in the value, it must be escaped with a backslash like '
  141.  *
  142.  * Returns a PGconn* which is needed for all subsequent libpq calls
  143.  * if the status field of the connection returned is CONNECTION_BAD,
  144.  * then some fields may be null'ed out instead of having valid values
  145.  * ----------------
  146.  */
  147. PGconn *
  148. PQconnectdb(const char *conninfo)
  149. {
  150. PGconn    *conn;
  151. char    *tmp;
  152. /* ----------
  153.  * Allocate memory for the conn structure
  154.  * ----------
  155.  */
  156. conn = makeEmptyPGconn();
  157. if (conn == NULL)
  158. return (PGconn *) NULL;
  159. /* ----------
  160.  * Parse the conninfo string and save settings in conn structure
  161.  * ----------
  162.  */
  163. if (conninfo_parse(conninfo, conn->errorMessage) < 0)
  164. {
  165. conn->status = CONNECTION_BAD;
  166. conninfo_free();
  167. return conn;
  168. }
  169. tmp = conninfo_getval("host");
  170. conn->pghost = tmp ? strdup(tmp) : NULL;
  171. tmp = conninfo_getval("port");
  172. conn->pgport = tmp ? strdup(tmp) : NULL;
  173. tmp = conninfo_getval("tty");
  174. conn->pgtty = tmp ? strdup(tmp) : NULL;
  175. tmp = conninfo_getval("options");
  176. conn->pgoptions = tmp ? strdup(tmp) : NULL;
  177. tmp = conninfo_getval("dbname");
  178. conn->dbName = tmp ? strdup(tmp) : NULL;
  179. tmp = conninfo_getval("user");
  180. conn->pguser = tmp ? strdup(tmp) : NULL;
  181. tmp = conninfo_getval("password");
  182. conn->pgpass = tmp ? strdup(tmp) : NULL;
  183. /* ----------
  184.  * Free the connection info - all is in conn now
  185.  * ----------
  186.  */
  187. conninfo_free();
  188. /* ----------
  189.  * Connect to the database
  190.  * ----------
  191.  */
  192. conn->status = connectDB(conn);
  193. return conn;
  194. }
  195. /* ----------------
  196.  * PQconndefaults
  197.  *
  198.  * Parse an empty string like PQconnectdb() would do and return the
  199.  * address of the connection options structure. Using this function
  200.  * an application might determine all possible options and their
  201.  * current default values.
  202.  * ----------------
  203.  */
  204. PQconninfoOption *
  205. PQconndefaults(void)
  206. {
  207. char errorMessage[ERROR_MSG_LENGTH];
  208. conninfo_parse("", errorMessage);
  209. return PQconninfoOptions;
  210. }
  211. /* ----------------
  212.  * PQsetdbLogin
  213.  *
  214.  * establishes a connection to a postgres backend through the postmaster
  215.  * at the specified host and port.
  216.  *
  217.  * returns a PGconn* which is needed for all subsequent libpq calls
  218.  * if the status field of the connection returned is CONNECTION_BAD,
  219.  * then some fields may be null'ed out instead of having valid values
  220.  *
  221.  * Uses these environment variables:
  222.  *
  223.  *   PGHOST    identifies host to which to connect if <pghost> argument
  224.  *    is NULL or a null string.
  225.  *
  226.  *   PGPORT    identifies TCP port to which to connect if <pgport> argument
  227.  *    is NULL or a null string.
  228.  *
  229.  *   PGTTY    identifies tty to which to send messages if <pgtty> argument
  230.  *    is NULL or a null string.
  231.  *
  232.  *   PGOPTIONS    identifies connection options if <pgoptions> argument is
  233.  *    NULL or a null string.
  234.  *
  235.  *   PGUSER    Postgres username to associate with the connection.
  236.  *
  237.  *   PGPASSWORD   The user's password.
  238.  *
  239.  *   PGDATABASE   name of database to which to connect if <pgdatabase>
  240.  *    argument is NULL or a null string
  241.  *
  242.  *   None of the above need be defined.  There are defaults for all of them.
  243.  *
  244.  * To support "delimited identifiers" for database names, only convert
  245.  * the database name to lower case if it is not surrounded by double quotes.
  246.  * Otherwise, strip the double quotes but leave the reset of the string intact.
  247.  * - thomas 1997-11-08
  248.  *
  249.  * ----------------
  250.  */
  251. PGconn *
  252. PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd)
  253. {
  254. PGconn    *conn;
  255. char    *tmp;
  256. /* An error message from some service we call. */
  257. bool error = FALSE;
  258. /* We encountered an error that prevents successful completion */
  259. int i;
  260. conn = makeEmptyPGconn();
  261. if (conn == NULL)
  262. return (PGconn *) NULL;
  263. if ((pghost == NULL) || pghost[0] == '')
  264. {
  265. if ((tmp = getenv("PGHOST")) != NULL)
  266. conn->pghost = strdup(tmp);
  267. }
  268. else
  269. conn->pghost = strdup(pghost);
  270. if ((pgport == NULL) || pgport[0] == '')
  271. {
  272. if ((tmp = getenv("PGPORT")) == NULL)
  273. tmp = DEF_PGPORT;
  274. conn->pgport = strdup(tmp);
  275. }
  276. else
  277. conn->pgport = strdup(pgport);
  278. if ((pgtty == NULL) || pgtty[0] == '')
  279. {
  280. if ((tmp = getenv("PGTTY")) == NULL)
  281. tmp = DefaultTty;
  282. conn->pgtty = strdup(tmp);
  283. }
  284. else
  285. conn->pgtty = strdup(pgtty);
  286. if ((pgoptions == NULL) || pgoptions[0] == '')
  287. {
  288. if ((tmp = getenv("PGOPTIONS")) == NULL)
  289. tmp = DefaultOption;
  290. conn->pgoptions = strdup(tmp);
  291. }
  292. else
  293. conn->pgoptions = strdup(pgoptions);
  294. if (login)
  295. conn->pguser = strdup(login);
  296. else if ((tmp = getenv("PGUSER")) != NULL)
  297. conn->pguser = strdup(tmp);
  298. else
  299. conn->pguser = fe_getauthname(conn->errorMessage);
  300. if (conn->pguser == NULL)
  301. {
  302. error = TRUE;
  303. sprintf(conn->errorMessage,
  304. "FATAL: PQsetdbLogin(): Unable to determine a Postgres username!n");
  305. }
  306. if (pwd)
  307. conn->pgpass = strdup(pwd);
  308. else if ((tmp = getenv("PGPASSWORD")) != NULL)
  309. conn->pgpass = strdup(tmp);
  310. else
  311. conn->pgpass = strdup(DefaultPassword);
  312. if ((dbName == NULL) || dbName[0] == '')
  313. {
  314. if ((tmp = getenv("PGDATABASE")) != NULL)
  315. conn->dbName = strdup(tmp);
  316. else if (conn->pguser)
  317. conn->dbName = strdup(conn->pguser);
  318. }
  319. else
  320. conn->dbName = strdup(dbName);
  321. if (conn->dbName)
  322. {
  323. /*
  324.  * if the database name is surrounded by double-quotes, then don't
  325.  * convert case
  326.  */
  327. if (*conn->dbName == '"')
  328. {
  329. strcpy(conn->dbName, conn->dbName + 1);
  330. conn->dbName[strlen(conn->dbName) - 1] = '';
  331. }
  332. else
  333. for (i = 0; conn->dbName[i]; i++)
  334. if (isascii((unsigned char) conn->dbName[i]) &&
  335. isupper(conn->dbName[i]))
  336. conn->dbName[i] = tolower(conn->dbName[i]);
  337. }
  338. if (error)
  339. conn->status = CONNECTION_BAD;
  340. else
  341. conn->status = connectDB(conn);
  342. return conn;
  343. }
  344. /*
  345.  * update_db_info -
  346.  * get all additional infos out of dbName
  347.  *
  348.  */
  349. static int
  350. update_db_info(PGconn *conn)
  351. {
  352. char    *tmp,
  353.    *old = conn->dbName;
  354. if (strchr(conn->dbName, '@') != NULL)
  355. {
  356. /* old style: dbname[@server][:port] */
  357. tmp = strrchr(conn->dbName, ':');
  358. if (tmp != NULL) /* port number given */
  359. {
  360. conn->pgport = strdup(tmp + 1);
  361. *tmp = '';
  362. }
  363. tmp = strrchr(conn->dbName, '@');
  364. if (tmp != NULL) /* host name given */
  365. {
  366. conn->pghost = strdup(tmp + 1);
  367. *tmp = '';
  368. }
  369. conn->dbName = strdup(old);
  370. free(old);
  371. }
  372. else
  373. {
  374. int offset;
  375. /*
  376.  * only allow protocols tcp and unix
  377.  */
  378. if (strncmp(conn->dbName, "tcp:", 4) == 0)
  379. offset = 4;
  380. else if (strncmp(conn->dbName, "unix:", 5) == 0)
  381. offset = 5;
  382. else
  383. return 0;
  384. if (strncmp(conn->dbName + offset, "postgresql://", strlen("postgresql://")) == 0)
  385. {
  386. /*
  387.  * new style:
  388.  * <tcp|unix>:postgresql://server[:port][/dbname][?options]
  389.  */
  390. offset += strlen("postgresql://");
  391. tmp = strrchr(conn->dbName + offset, '?');
  392. if (tmp != NULL) /* options given */
  393. {
  394. conn->pgoptions = strdup(tmp + 1);
  395. *tmp = '';
  396. }
  397. tmp = strrchr(conn->dbName + offset, '/');
  398. if (tmp != NULL) /* database name given */
  399. {
  400. conn->dbName = strdup(tmp + 1);
  401. *tmp = '';
  402. }
  403. else
  404. {
  405. if ((tmp = getenv("PGDATABASE")) != NULL)
  406. conn->dbName = strdup(tmp);
  407. else if (conn->pguser)
  408. conn->dbName = strdup(conn->pguser);
  409. }
  410. tmp = strrchr(old + offset, ':');
  411. if (tmp != NULL) /* port number given */
  412. {
  413. conn->pgport = strdup(tmp + 1);
  414. *tmp = '';
  415. }
  416. if (strncmp(old, "unix:", 5) == 0)
  417. {
  418. conn->pghost = NULL;
  419. if (strcmp(old + offset, "localhost") != 0)
  420. {
  421. (void) sprintf(conn->errorMessage,
  422.    "connectDB() -- non-tcp access only possible on localhostn");
  423. return 1;
  424. }
  425. }
  426. else
  427. conn->pghost = strdup(old + offset);
  428. free(old);
  429. }
  430. }
  431. return 0;
  432. }
  433. /*
  434.  * connectDB -
  435.  * make a connection to the backend so it is ready to receive queries.
  436.  * return CONNECTION_OK if successful, CONNECTION_BAD if not.
  437.  *
  438.  */
  439. static ConnStatusType
  440. connectDB(PGconn *conn)
  441. {
  442. PGresult   *res;
  443. struct hostent *hp;
  444. StartupPacket sp;
  445. AuthRequest areq;
  446. SOCKET_SIZE_TYPE laddrlen;
  447. int portno,
  448. family;
  449. char beresp;
  450. int on = 1;
  451. /*
  452.  * parse dbName to get all additional info in it, if any
  453.  */
  454. if (update_db_info(conn) != 0)
  455. goto connect_errReturn;
  456. /*
  457.  * Initialize the startup packet.
  458.  */
  459. MemSet((char *) &sp, 0, sizeof(StartupPacket));
  460. sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LIBPQ);
  461. strncpy(sp.user, conn->pguser, SM_USER);
  462. strncpy(sp.database, conn->dbName, SM_DATABASE);
  463. strncpy(sp.tty, conn->pgtty, SM_TTY);
  464. if (conn->pgoptions)
  465. strncpy(sp.options, conn->pgoptions, SM_OPTIONS);
  466. /*
  467.  * Open a connection to postmaster/backend.
  468.  */
  469. if (conn->pghost != NULL)
  470. {
  471. hp = gethostbyname(conn->pghost);
  472. if ((hp == NULL) || (hp->h_addrtype != AF_INET))
  473. {
  474. (void) sprintf(conn->errorMessage,
  475.    "connectDB() --  unknown hostname: %sn",
  476.    conn->pghost);
  477. goto connect_errReturn;
  478. }
  479. family = AF_INET;
  480. }
  481. else
  482. {
  483. hp = NULL;
  484. family = AF_UNIX;
  485. }
  486. MemSet((char *) &conn->raddr, 0, sizeof(conn->raddr));
  487. conn->raddr.sa.sa_family = family;
  488. portno = atoi(conn->pgport);
  489. if (family == AF_INET)
  490. {
  491. memmove((char *) &(conn->raddr.in.sin_addr),
  492. (char *) hp->h_addr,
  493. hp->h_length);
  494. conn->raddr.in.sin_port = htons((unsigned short) (portno));
  495. conn->raddr_len = sizeof(struct sockaddr_in);
  496. }
  497. #if !defined(WIN32) && !defined(__CYGWIN32__)
  498. else
  499. conn->raddr_len = UNIXSOCK_PATH(conn->raddr.un, portno);
  500. #endif
  501. /* Connect to the server  */
  502. if ((conn->sock = socket(family, SOCK_STREAM, 0)) < 0)
  503. {
  504. (void) sprintf(conn->errorMessage,
  505.    "connectDB() -- socket() failed: errno=%dn%sn",
  506.    errno, strerror(errno));
  507. goto connect_errReturn;
  508. }
  509. if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
  510. {
  511. (void) sprintf(conn->errorMessage,
  512.    "connectDB() -- connect() failed: %sn"
  513.    "Is the postmaster running%s at '%s' and accepting connections on %s '%s'?n",
  514.    strerror(errno),
  515.    (family == AF_INET) ? " (with -i)" : "",
  516.    conn->pghost ? conn->pghost : "localhost",
  517.  (family == AF_INET) ? "TCP/IP port" : "Unix socket",
  518.    conn->pgport);
  519. goto connect_errReturn;
  520. }
  521. /*
  522.  * Set the right options. We need nonblocking I/O, and we don't want
  523.  * delay of outgoing data.
  524.  */
  525. #ifndef WIN32
  526. if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) < 0)
  527. #else
  528. if (ioctlsocket(conn->sock, FIONBIO, &on) != 0)
  529. #endif
  530. {
  531. (void) sprintf(conn->errorMessage,
  532.    "connectDB() -- fcntl() failed: errno=%dn%sn",
  533.    errno, strerror(errno));
  534. goto connect_errReturn;
  535. }
  536. if (family == AF_INET)
  537. {
  538. struct protoent *pe;
  539. pe = getprotobyname("TCP");
  540. if (pe == NULL)
  541. {
  542. (void) sprintf(conn->errorMessage,
  543.    "connectDB(): getprotobyname failedn");
  544. goto connect_errReturn;
  545. }
  546. if (setsockopt(conn->sock, pe->p_proto, TCP_NODELAY,
  547. #ifdef WIN32
  548.    (char *)
  549. #endif
  550.    &on,
  551.    sizeof(on)) < 0)
  552. {
  553. (void) sprintf(conn->errorMessage,
  554.   "connectDB() -- setsockopt failed: errno=%dn%sn",
  555.    errno, strerror(errno));
  556. #ifdef WIN32
  557. printf("Winsock error: %in", WSAGetLastError());
  558. #endif
  559. goto connect_errReturn;
  560. }
  561. }
  562. /* Fill in the client address */
  563. laddrlen = sizeof(conn->laddr);
  564. if (getsockname(conn->sock, &conn->laddr.sa, &laddrlen) < 0)
  565. {
  566. (void) sprintf(conn->errorMessage,
  567.    "connectDB() -- getsockname() failed: errno=%dn%sn",
  568.    errno, strerror(errno));
  569. goto connect_errReturn;
  570. }
  571. /* Ensure our buffers are empty */
  572. conn->inStart = conn->inCursor = conn->inEnd = 0;
  573. conn->outCount = 0;
  574. /* Send the startup packet. */
  575. if (pqPacketSend(conn, (char *) &sp, sizeof(StartupPacket)) != STATUS_OK)
  576. {
  577. sprintf(conn->errorMessage,
  578.   "connectDB() --  couldn't send startup packet: errno=%dn%sn",
  579. errno, strerror(errno));
  580. goto connect_errReturn;
  581. }
  582. /*
  583.  * Perform the authentication exchange: wait for backend messages and
  584.  * respond as necessary. We fall out of this loop when done talking to
  585.  * the postmaster.
  586.  */
  587. for (;;)
  588. {
  589. /* Wait for some data to arrive (or for the channel to close) */
  590. if (pqWait(TRUE, FALSE, conn))
  591. goto connect_errReturn;
  592. /* Load data, or detect EOF */
  593. if (pqReadData(conn) < 0)
  594. goto connect_errReturn;
  595. /*
  596.  * Scan the message. If we run out of data, loop around to try
  597.  * again.
  598.  */
  599. conn->inCursor = conn->inStart;
  600. if (pqGetc(&beresp, conn))
  601. continue; /* no data yet */
  602. /* Handle errors. */
  603. if (beresp == 'E')
  604. {
  605. if (pqGets(conn->errorMessage, sizeof(conn->errorMessage), conn))
  606. continue;
  607. goto connect_errReturn;
  608. }
  609. /* Otherwise it should be an authentication request. */
  610. if (beresp != 'R')
  611. {
  612. (void) sprintf(conn->errorMessage,
  613.  "connectDB() -- expected authentication requestn");
  614. goto connect_errReturn;
  615. }
  616. /* Get the type of request. */
  617. if (pqGetInt((int *) &areq, 4, conn))
  618. continue;
  619. /* Get the password salt if there is one. */
  620. if (areq == AUTH_REQ_CRYPT)
  621. {
  622. if (pqGetnchar(conn->salt, sizeof(conn->salt), conn))
  623. continue;
  624. }
  625. /* OK, we successfully read the message; mark data consumed */
  626. conn->inStart = conn->inCursor;
  627. /* Respond to the request if necessary. */
  628. if (fe_sendauth(areq, conn, conn->pghost, conn->pgpass,
  629. conn->errorMessage) != STATUS_OK)
  630. goto connect_errReturn;
  631. if (pqFlush(conn))
  632. goto connect_errReturn;
  633. /* Are we done? */
  634. if (areq == AUTH_REQ_OK)
  635. break;
  636. }
  637. /*
  638.  * Now we expect to hear from the backend. A ReadyForQuery message
  639.  * indicates that startup is successful, but we might also get an
  640.  * Error message indicating failure. (Notice messages indicating
  641.  * nonfatal warnings are also allowed by the protocol, as is a
  642.  * BackendKeyData message.) Easiest way to handle this is to let
  643.  * PQgetResult() read the messages. We just have to fake it out about
  644.  * the state of the connection.
  645.  */
  646. conn->status = CONNECTION_OK;
  647. conn->asyncStatus = PGASYNC_BUSY;
  648. res = PQgetResult(conn);
  649. /* NULL return indicating we have gone to IDLE state is expected */
  650. if (res)
  651. {
  652. if (res->resultStatus != PGRES_FATAL_ERROR)
  653. sprintf(conn->errorMessage,
  654. "connectDB() -- unexpected message during startupn");
  655. PQclear(res);
  656. goto connect_errReturn;
  657. }
  658. /*
  659.  * Given the new protocol that sends a ReadyForQuery message after
  660.  * successful backend startup, it should no longer be necessary to
  661.  * send an empty query to test for startup.
  662.  */
  663. #ifdef NOT_USED
  664. /*
  665.  * Send a blank query to make sure everything works; in particular,
  666.  * that the database exists.
  667.  */
  668. res = PQexec(conn, " ");
  669. if (res == NULL || res->resultStatus != PGRES_EMPTY_QUERY)
  670. {
  671. /* PQexec has put error message in conn->errorMessage */
  672. closePGconn(conn);
  673. PQclear(res);
  674. goto connect_errReturn;
  675. }
  676. PQclear(res);
  677. #endif
  678. /*
  679.  * Post-connection housekeeping. Send environment variables to server
  680.  */
  681. PQsetenv(conn);
  682. return CONNECTION_OK;
  683. connect_errReturn:
  684. if (conn->sock >= 0)
  685. {
  686. #ifdef WIN32
  687. closesocket(conn->sock);
  688. #else
  689. close(conn->sock);
  690. #endif
  691. conn->sock = -1;
  692. }
  693. return CONNECTION_BAD;
  694. }
  695. void
  696. PQsetenv(PGconn *conn)
  697. {
  698. struct EnvironmentOptions *eo;
  699. char setQuery[80]; /* mjl: size okay? XXX */
  700. #ifdef MULTIBYTE
  701. char    *envname = "PGCLIENTENCODING";
  702. static char envbuf[64]; /* big enough? */
  703. char    *env;
  704. char    *encoding = 0;
  705. PGresult   *rtn;
  706. #endif
  707. #ifdef MULTIBYTE
  708. /* query server encoding */
  709. env = getenv(envname);
  710. if (!env || *env == '')
  711. {
  712. rtn = PQexec(conn, "select getdatabaseencoding()");
  713. if (rtn && PQresultStatus(rtn) == PGRES_TUPLES_OK)
  714. {
  715. encoding = PQgetvalue(rtn, 0, 0);
  716. if (encoding)
  717. {
  718. /* set client encoding */
  719. sprintf(envbuf, "%s=%s", envname, encoding);
  720. putenv(envbuf);
  721. }
  722. }
  723. PQclear(rtn);
  724. if (!encoding)
  725. { /* this should not happen */
  726. sprintf(envbuf, "%s=%s", envname, pg_encoding_to_char(MULTIBYTE));
  727. putenv(envbuf);
  728. }
  729. }
  730. #endif
  731. for (eo = EnvironmentOptions; eo->envName; eo++)
  732. {
  733. const char *val;
  734. if ((val = getenv(eo->envName)))
  735. {
  736. PGresult   *res;
  737. if (strcasecmp(val, "default") == 0)
  738. sprintf(setQuery, "SET %s = %.60s", eo->pgName, val);
  739. else
  740. sprintf(setQuery, "SET %s = '%.60s'", eo->pgName, val);
  741. #ifdef CONNECTDEBUG
  742. printf("Use environment variable %s to send %sn", eo->envName, setQuery);
  743. #endif
  744. res = PQexec(conn, setQuery);
  745. PQclear(res); /* Don't care? */
  746. }
  747. }
  748. } /* PQsetenv() */
  749. /*
  750.  * makeEmptyPGconn
  751.  *  - create a PGconn data structure with (as yet) no interesting data
  752.  */
  753. static PGconn *
  754. makeEmptyPGconn(void)
  755. {
  756. PGconn    *conn = (PGconn *) malloc(sizeof(PGconn));
  757. if (conn == NULL)
  758. return conn;
  759. /* Zero all pointers */
  760. MemSet((char *) conn, 0, sizeof(PGconn));
  761. conn->noticeHook = defaultNoticeProcessor;
  762. conn->status = CONNECTION_BAD;
  763. conn->asyncStatus = PGASYNC_IDLE;
  764. conn->notifyList = DLNewList();
  765. conn->sock = -1;
  766. conn->inBufSize = PQ_BUFFER_SIZE;
  767. conn->inBuffer = (char *) malloc(conn->inBufSize);
  768. conn->outBufSize = PQ_BUFFER_SIZE;
  769. conn->outBuffer = (char *) malloc(conn->outBufSize);
  770. if (conn->inBuffer == NULL || conn->outBuffer == NULL)
  771. {
  772. freePGconn(conn);
  773. conn = NULL;
  774. }
  775. return conn;
  776. }
  777. /*
  778.  * freePGconn
  779.  *  - free the PGconn data structure
  780.  *
  781.  */
  782. static void
  783. freePGconn(PGconn *conn)
  784. {
  785. if (!conn)
  786. return;
  787. pqClearAsyncResult(conn); /* deallocate result and curTuple */
  788. if (conn->sock >= 0)
  789. #ifdef WIN32
  790. closesocket(conn->sock);
  791. #else
  792. close(conn->sock);
  793. #endif
  794. if (conn->pghost)
  795. free(conn->pghost);
  796. if (conn->pgport)
  797. free(conn->pgport);
  798. if (conn->pgtty)
  799. free(conn->pgtty);
  800. if (conn->pgoptions)
  801. free(conn->pgoptions);
  802. if (conn->dbName)
  803. free(conn->dbName);
  804. if (conn->pguser)
  805. free(conn->pguser);
  806. if (conn->pgpass)
  807. free(conn->pgpass);
  808. /* Note that conn->Pfdebug is not ours to close or free */
  809. if (conn->notifyList)
  810. DLFreeList(conn->notifyList);
  811. if (conn->lobjfuncs)
  812. free(conn->lobjfuncs);
  813. if (conn->inBuffer)
  814. free(conn->inBuffer);
  815. if (conn->outBuffer)
  816. free(conn->outBuffer);
  817. free(conn);
  818. }
  819. /*
  820.    closePGconn
  821.  - properly close a connection to the backend
  822. */
  823. static void
  824. closePGconn(PGconn *conn)
  825. {
  826. if (conn->sock >= 0)
  827. {
  828. /*
  829.  * Try to send "close connection" message to backend. Ignore any
  830.  * error. Note: this routine used to go to substantial lengths to
  831.  * avoid getting SIGPIPE'd if the connection were already closed.
  832.  * Now we rely on pqFlush to avoid the signal.
  833.  */
  834. (void) pqPuts("X", conn);
  835. (void) pqFlush(conn);
  836. }
  837. /*
  838.  * Close the connection, reset all transient state, flush I/O buffers.
  839.  */
  840. if (conn->sock >= 0)
  841. #ifdef WIN32
  842. closesocket(conn->sock);
  843. #else
  844. close(conn->sock);
  845. #endif
  846. conn->sock = -1;
  847. conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just
  848.  * absent */
  849. conn->asyncStatus = PGASYNC_IDLE;
  850. pqClearAsyncResult(conn); /* deallocate result and curTuple */
  851. if (conn->lobjfuncs)
  852. free(conn->lobjfuncs);
  853. conn->lobjfuncs = NULL;
  854. conn->inStart = conn->inCursor = conn->inEnd = 0;
  855. conn->outCount = 0;
  856. }
  857. /*
  858.    PQfinish:
  859.   properly close a connection to the backend
  860.   also frees the PGconn data structure so it shouldn't be re-used
  861.   after this
  862. */
  863. void
  864. PQfinish(PGconn *conn)
  865. {
  866. if (conn)
  867. {
  868. closePGconn(conn);
  869. freePGconn(conn);
  870. }
  871. }
  872. /* PQreset :
  873.    resets the connection to the backend
  874.    closes the existing connection and makes a new one
  875. */
  876. void
  877. PQreset(PGconn *conn)
  878. {
  879. if (conn)
  880. {
  881. closePGconn(conn);
  882. conn->status = connectDB(conn);
  883. }
  884. }
  885. /*
  886.  * PQrequestCancel: attempt to request cancellation of the current operation.
  887.  *
  888.  * The return value is TRUE if the cancel request was successfully
  889.  * dispatched, FALSE if not (in which case errorMessage is set).
  890.  * Note: successful dispatch is no guarantee that there will be any effect at
  891.  * the backend.  The application must read the operation result as usual.
  892.  *
  893.  * CAUTION: we want this routine to be safely callable from a signal handler
  894.  * (for example, an application might want to call it in a SIGINT handler).
  895.  * This means we cannot use any C library routine that might be non-reentrant.
  896.  * malloc/free are often non-reentrant, and anything that might call them is
  897.  * just as dangerous.  We avoid sprintf here for that reason.  Building up
  898.  * error messages with strcpy/strcat is tedious but should be quite safe.
  899.  */
  900. int
  901. PQrequestCancel(PGconn *conn)
  902. {
  903. int tmpsock = -1;
  904. struct
  905. {
  906. uint32 packetlen;
  907. CancelRequestPacket cp;
  908. } crp;
  909. /* Check we have an open connection */
  910. if (!conn)
  911. return FALSE;
  912. if (conn->sock < 0)
  913. {
  914. strcpy(conn->errorMessage,
  915.    "PQrequestCancel() -- connection is not openn");
  916. return FALSE;
  917. }
  918. /*
  919.  * We need to open a temporary connection to the postmaster. Use the
  920.  * information saved by connectDB to do this with only kernel calls.
  921.  */
  922. if ((tmpsock = socket(conn->raddr.sa.sa_family, SOCK_STREAM, 0)) < 0)
  923. {
  924. strcpy(conn->errorMessage, "PQrequestCancel() -- socket() failed: ");
  925. goto cancel_errReturn;
  926. }
  927. if (connect(tmpsock, &conn->raddr.sa, conn->raddr_len) < 0)
  928. {
  929. strcpy(conn->errorMessage, "PQrequestCancel() -- connect() failed: ");
  930. goto cancel_errReturn;
  931. }
  932. /*
  933.  * We needn't set nonblocking I/O or NODELAY options here.
  934.  */
  935. /* Create and send the cancel request packet. */
  936. crp.packetlen = htonl((uint32) sizeof(crp));
  937. crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE);
  938. crp.cp.backendPID = htonl(conn->be_pid);
  939. crp.cp.cancelAuthCode = htonl(conn->be_key);
  940. if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
  941. {
  942. strcpy(conn->errorMessage, "PQrequestCancel() -- send() failed: ");
  943. goto cancel_errReturn;
  944. }
  945. /* Sent it, done */
  946. #ifdef WIN32
  947. closesocket(tmpsock);
  948. #else
  949. close(tmpsock);
  950. #endif
  951. return TRUE;
  952. cancel_errReturn:
  953. strcat(conn->errorMessage, strerror(errno));
  954. strcat(conn->errorMessage, "n");
  955. if (tmpsock >= 0)
  956. {
  957. #ifdef WIN32
  958. closesocket(tmpsock);
  959. #else
  960. close(tmpsock);
  961. #endif
  962. }
  963. return FALSE;
  964. }
  965. /*
  966.  * pqPacketSend() -- send a single-packet message.
  967.  * this is like PacketSend(), defined in backend/libpq/pqpacket.c
  968.  *
  969.  * RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
  970.  * SIDE_EFFECTS: may block.
  971. */
  972. int
  973. pqPacketSend(PGconn *conn, const char *buf, size_t len)
  974. {
  975. /* Send the total packet size. */
  976. if (pqPutInt(4 + len, 4, conn))
  977. return STATUS_ERROR;
  978. /* Send the packet itself. */
  979. if (pqPutnchar(buf, len, conn))
  980. return STATUS_ERROR;
  981. if (pqFlush(conn))
  982. return STATUS_ERROR;
  983. return STATUS_OK;
  984. }
  985. /* ----------------
  986.  * Conninfo parser routine
  987.  * ----------------
  988.  */
  989. static int
  990. conninfo_parse(const char *conninfo, char *errorMessage)
  991. {
  992. char    *pname;
  993. char    *pval;
  994. char    *buf;
  995. char    *tmp;
  996. char    *cp;
  997. char    *cp2;
  998. PQconninfoOption *option;
  999. char errortmp[ERROR_MSG_LENGTH];
  1000. conninfo_free();
  1001. if ((buf = strdup(conninfo)) == NULL)
  1002. {
  1003. strcpy(errorMessage,
  1004.   "FATAL: cannot allocate memory for copy of conninfo stringn");
  1005. return -1;
  1006. }
  1007. cp = buf;
  1008. while (*cp)
  1009. {
  1010. /* Skip blanks before the parameter name */
  1011. if (isspace(*cp))
  1012. {
  1013. cp++;
  1014. continue;
  1015. }
  1016. /* Get the parameter name */
  1017. pname = cp;
  1018. while (*cp)
  1019. {
  1020. if (*cp == '=')
  1021. break;
  1022. if (isspace(*cp))
  1023. {
  1024. *cp++ = '';
  1025. while (*cp)
  1026. {
  1027. if (!isspace(*cp))
  1028. break;
  1029. cp++;
  1030. }
  1031. break;
  1032. }
  1033. cp++;
  1034. }
  1035. /* Check that there is a following '=' */
  1036. if (*cp != '=')
  1037. {
  1038. sprintf(errorMessage,
  1039. "ERROR: PQconnectdb() - Missing '=' after '%s' in conninfon",
  1040. pname);
  1041. free(buf);
  1042. return -1;
  1043. }
  1044. *cp++ = '';
  1045. /* Skip blanks after the '=' */
  1046. while (*cp)
  1047. {
  1048. if (!isspace(*cp))
  1049. break;
  1050. cp++;
  1051. }
  1052. pval = cp;
  1053. if (*cp != ''')
  1054. {
  1055. cp2 = pval;
  1056. while (*cp)
  1057. {
  1058. if (isspace(*cp))
  1059. {
  1060. *cp++ = '';
  1061. break;
  1062. }
  1063. if (*cp == '\')
  1064. {
  1065. cp++;
  1066. if (*cp != '')
  1067. *cp2++ = *cp++;
  1068. }
  1069. else
  1070. *cp2++ = *cp++;
  1071. }
  1072. *cp2 = '';
  1073. }
  1074. else
  1075. {
  1076. cp2 = pval;
  1077. cp++;
  1078. for (;;)
  1079. {
  1080. if (*cp == '')
  1081. {
  1082. sprintf(errorMessage,
  1083. "ERROR: PQconnectdb() - unterminated quoted string in conninfon");
  1084. free(buf);
  1085. return -1;
  1086. }
  1087. if (*cp == '\')
  1088. {
  1089. cp++;
  1090. if (*cp != '')
  1091. *cp2++ = *cp++;
  1092. continue;
  1093. }
  1094. if (*cp == ''')
  1095. {
  1096. *cp2 = '';
  1097. cp++;
  1098. break;
  1099. }
  1100. *cp2++ = *cp++;
  1101. }
  1102. }
  1103. /* ----------
  1104.  * Now we have the name and the value. Search
  1105.  * for the param record.
  1106.  * ----------
  1107.  */
  1108. for (option = PQconninfoOptions; option->keyword != NULL; option++)
  1109. {
  1110. if (!strcmp(option->keyword, pname))
  1111. break;
  1112. }
  1113. if (option->keyword == NULL)
  1114. {
  1115. sprintf(errorMessage,
  1116. "ERROR: PQconnectdb() - unknown option '%s'n",
  1117. pname);
  1118. free(buf);
  1119. return -1;
  1120. }
  1121. /* ----------
  1122.  * Store the value
  1123.  * ----------
  1124.  */
  1125. option->val = strdup(pval);
  1126. }
  1127. free(buf);
  1128. /* ----------
  1129.  * Get the fallback resources for parameters not specified
  1130.  * in the conninfo string.
  1131.  * ----------
  1132.  */
  1133. for (option = PQconninfoOptions; option->keyword != NULL; option++)
  1134. {
  1135. if (option->val != NULL)
  1136. continue; /* Value was in conninfo */
  1137. /* ----------
  1138.  * Try to get the environment variable fallback
  1139.  * ----------
  1140.  */
  1141. if (option->envvar != NULL)
  1142. {
  1143. if ((tmp = getenv(option->envvar)) != NULL)
  1144. {
  1145. option->val = strdup(tmp);
  1146. continue;
  1147. }
  1148. }
  1149. /* ----------
  1150.  * No environment variable specified or this one isn't set -
  1151.  * try compiled in
  1152.  * ----------
  1153.  */
  1154. if (option->compiled != NULL)
  1155. {
  1156. option->val = strdup(option->compiled);
  1157. continue;
  1158. }
  1159. /* ----------
  1160.  * Special handling for user
  1161.  * ----------
  1162.  */
  1163. if (!strcmp(option->keyword, "user"))
  1164. {
  1165. option->val = fe_getauthname(errortmp);
  1166. continue;
  1167. }
  1168. /* ----------
  1169.  * Special handling for dbname
  1170.  * ----------
  1171.  */
  1172. if (!strcmp(option->keyword, "dbname"))
  1173. {
  1174. tmp = conninfo_getval("user");
  1175. if (tmp)
  1176. option->val = strdup(tmp);
  1177. continue;
  1178. }
  1179. }
  1180. return 0;
  1181. }
  1182. static char *
  1183. conninfo_getval(char *keyword)
  1184. {
  1185. PQconninfoOption *option;
  1186. for (option = PQconninfoOptions; option->keyword != NULL; option++)
  1187. {
  1188. if (!strcmp(option->keyword, keyword))
  1189. return option->val;
  1190. }
  1191. return NULL;
  1192. }
  1193. static void
  1194. conninfo_free()
  1195. {
  1196. PQconninfoOption *option;
  1197. for (option = PQconninfoOptions; option->keyword != NULL; option++)
  1198. {
  1199. if (option->val != NULL)
  1200. {
  1201. free(option->val);
  1202. option->val = NULL;
  1203. }
  1204. }
  1205. }
  1206. /* =========== accessor functions for PGconn ========= */
  1207. char *
  1208. PQdb(PGconn *conn)
  1209. {
  1210. if (!conn)
  1211. return (char *) NULL;
  1212. return conn->dbName;
  1213. }
  1214. char *
  1215. PQuser(PGconn *conn)
  1216. {
  1217. if (!conn)
  1218. return (char *) NULL;
  1219. return conn->pguser;
  1220. }
  1221. char *
  1222. PQpass(PGconn *conn)
  1223. {
  1224. if (!conn)
  1225. return (char *) NULL;
  1226. return conn->pgpass;
  1227. }
  1228. char *
  1229. PQhost(PGconn *conn)
  1230. {
  1231. if (!conn)
  1232. return (char *) NULL;
  1233. return conn->pghost;
  1234. }
  1235. char *
  1236. PQport(PGconn *conn)
  1237. {
  1238. if (!conn)
  1239. return (char *) NULL;
  1240. return conn->pgport;
  1241. }
  1242. char *
  1243. PQtty(PGconn *conn)
  1244. {
  1245. if (!conn)
  1246. return (char *) NULL;
  1247. return conn->pgtty;
  1248. }
  1249. char *
  1250. PQoptions(PGconn *conn)
  1251. {
  1252. if (!conn)
  1253. return (char *) NULL;
  1254. return conn->pgoptions;
  1255. }
  1256. ConnStatusType
  1257. PQstatus(PGconn *conn)
  1258. {
  1259. if (!conn)
  1260. return CONNECTION_BAD;
  1261. return conn->status;
  1262. }
  1263. char *
  1264. PQerrorMessage(PGconn *conn)
  1265. {
  1266. static char noConn[] = "PQerrorMessage: conn pointer is NULLn";
  1267. if (!conn)
  1268. return noConn;
  1269. return conn->errorMessage;
  1270. }
  1271. int
  1272. PQsocket(PGconn *conn)
  1273. {
  1274. if (!conn)
  1275. return -1;
  1276. return conn->sock;
  1277. }
  1278. int
  1279. PQbackendPID(PGconn *conn)
  1280. {
  1281. if (!conn || conn->status != CONNECTION_OK)
  1282. return 0;
  1283. return conn->be_pid;
  1284. }
  1285. void
  1286. PQtrace(PGconn *conn, FILE *debug_port)
  1287. {
  1288. if (conn == NULL ||
  1289. conn->status == CONNECTION_BAD)
  1290. return;
  1291. PQuntrace(conn);
  1292. conn->Pfdebug = debug_port;
  1293. }
  1294. void
  1295. PQuntrace(PGconn *conn)
  1296. {
  1297. /* note: better allow untrace even when connection bad */
  1298. if (conn == NULL)
  1299. return;
  1300. if (conn->Pfdebug)
  1301. {
  1302. fflush(conn->Pfdebug);
  1303. conn->Pfdebug = NULL;
  1304. }
  1305. }
  1306. void
  1307. PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
  1308. {
  1309. if (conn == NULL)
  1310. return;
  1311. conn->noticeHook = proc;
  1312. conn->noticeArg = arg;
  1313. }
  1314. /*
  1315.  * The default notice/error message processor just prints the
  1316.  * message on stderr.  Applications can override this if they
  1317.  * want the messages to go elsewhere (a window, for example).
  1318.  * Note that simply discarding notices is probably a bad idea.
  1319.  */
  1320. static void
  1321. defaultNoticeProcessor(void *arg, const char *message)
  1322. {
  1323. /* Note: we expect the supplied string to end with a newline already. */
  1324. fprintf(stderr, "%s", message);
  1325. }