*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.8 1996/08/19 13:38:42 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.9 1996/10/10 08:20:09 bryanh Exp $
*
*-------------------------------------------------------------------------
*/
#include <string.h>
#include <netdb.h>
#include <errno.h>
-#include "libpq/pqcomm.h" /* for decls of MsgType, PacketBuf, StartupInfo */
-#include "fe-auth.h"
+#include <signal.h>
+#include <libpq/pqcomm.h> /* for decls of MsgType, PacketBuf, StartupInfo */
+#include <fe-auth.h>
#include "libpq-fe.h"
#if defined(PORTNAME_ultrix4) || defined(PORTNAME_next)
/* ----------------
* PQsetdb
*
- * establishes a connectin to a postgres backend through the postmaster
+ * establishes a connection to a postgres backend through the postmaster
* at the specified host and port.
*
* returns a PGconn* which is needed for all subsequent libpq calls
* if the status field of the connection returned is CONNECTION_BAD,
* then some fields may be null'ed out instead of having valid values
+ *
+ * Uses these environment variables:
+ *
+ * PGHOST identifies host to which to connect if <pghost> argument
+ * is NULL or a null string.
+ *
+ * PGPORT identifies TCP port to which to connect if <pgport> argument
+ * is NULL or a null string.
+ *
+ * PGTTY identifies tty to which to send messages if <pgtty> argument
+ * is NULL or a null string.
+ *
+ * PGOPTIONS identifies connection options if <pgoptions> argument is
+ * NULL or a null string.
+ *
+ * PGUSER Postgres username to associate with the connection.
+ *
+ * PGDATABASE name of database to which to connect if <pgdatabase>
+ * argument is NULL or a null string
+ *
+ * None of the above need be defined. There are defaults for all of them.
+ *
* ----------------
*/
PGconn*
PQsetdb(const char *pghost, const char* pgport, const char* pgoptions, const char* pgtty, const char* dbName)
{
PGconn *conn;
- const char *tmp;
+ char *tmp;
+ char errorMessage[ERROR_MSG_LENGTH];
+ /* An error message from some service we call. */
+ bool error;
+ /* We encountered an error that prevents successful completion */
conn = (PGconn*)malloc(sizeof(PGconn));
conn->pgoptions = strdup(tmp);
} else
conn->pgoptions = strdup(pgoptions);
- if (((tmp = dbName) && (dbName[0] != '\0')) ||
- ((tmp = getenv("PGDATABASE")))) {
- conn->dbName = strdup(tmp);
+
+ if (tmp = getenv("PGUSER")) {
+ error = FALSE;
+ conn->pguser = strdup(tmp);
} else {
- char errorMessage[ERROR_MSG_LENGTH];
- if ((tmp = fe_getauthname(errorMessage)) != 0) {
- conn->dbName = strdup(tmp);
- free((char*)tmp);
- } else {
+ tmp = fe_getauthname(errorMessage);
+ if (tmp == 0) {
+ error = TRUE;
sprintf(conn->errorMessage,
- "FATAL: PQsetdb: Unable to determine a database name!\n");
- conn->dbName = NULL;
- return conn;
+ "FATAL: PQsetdb: Unable to determine a Postgres username!\n");
+ } else {
+ error = FALSE;
+ conn->pguser = tmp;
}
}
- conn->status = connectDB(conn);
- if (conn->status == CONNECTION_OK) {
- PGresult *res;
- /* Send a blank query to make sure everything works; in particular, that
- the database exists.
- */
- res = PQexec(conn," ");
- if (res == NULL || res->resultStatus != PGRES_EMPTY_QUERY) {
- /* PQexec has put error message in conn->errorMessage */
- closePGconn(conn);
+
+ if (!error) {
+ if (((tmp = (char *)dbName) && (dbName[0] != '\0')) ||
+ ((tmp = getenv("PGDATABASE")))) {
+ conn->dbName = strdup(tmp);
+ } else conn->dbName = conn->pguser;
+ } else conn->dbName = NULL;
+
+ if (error) conn->status = CONNECTION_BAD;
+ else {
+ conn->status = connectDB(conn);
+ /* Puts message in conn->errorMessage */
+ if (conn->status == CONNECTION_OK) {
+ PGresult *res;
+ /* Send a blank query to make sure everything works;
+ in particular, that the database exists.
+ */
+ res = PQexec(conn," ");
+ if (res == NULL || res->resultStatus != PGRES_EMPTY_QUERY) {
+ /* PQexec has put error message in conn->errorMessage */
+ closePGconn(conn);
+ }
+ PQclear(res);
}
- PQclear(res);
}
}
return conn;
Port *port = conn->port;
int portno;
- char *user;
/*
//
// Initialize the startup packet.
//
//
*/
- user = fe_getauthname(conn->errorMessage);
- if (!user)
- goto connect_errReturn;
- strncpy(startup.user,user,sizeof(startup.user));
- free(user);
+ strncpy(startup.user,conn->pguser,sizeof(startup.user));
strncpy(startup.database,conn->dbName,sizeof(startup.database));
strncpy(startup.tty,conn->pgtty,sizeof(startup.tty));
if (conn->pgoptions) {
if (conn->pgoptions) free(conn->pgoptions);
if (conn->pgport) free(conn->pgport);
if (conn->dbName) free(conn->dbName);
+ if (conn->pguser) free(conn->pguser);
if (conn->notifyList) DLFreeList(conn->notifyList);
free(conn);
}
static void
closePGconn(PGconn *conn)
{
+ const struct sigaction ignore_action = {SIG_IGN, 0, 0, NULL};
+ struct sigaction oldaction;
+
+ /* If connection is already gone, that's cool. No reason for kernel
+ to kill us when we try to write to it. So ignore SIGPIPE signals.
+ */
+ sigaction(SIGPIPE, (struct sigaction *) &ignore_action, &oldaction);
fputs("X\0", conn->Pfout);
fflush(conn->Pfout);
+ sigaction(SIGPIPE, &oldaction, NULL);
if (conn->Pfout) fclose(conn->Pfout);
if (conn->Pfin) fclose(conn->Pfin);
if (conn->Pfdebug) fclose(conn->Pfdebug);