Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Functions | Variables

common.c File Reference

#include "postgres_fe.h"
#include <pwd.h>
#include <signal.h>
#include <unistd.h>
#include "common.h"
Include dependency graph for common.c:

Go to the source code of this file.

Defines

#define PARAMS_ARRAY_SIZE   7
#define PG_YESLETTER   gettext_noop("y")
#define PG_NOLETTER   gettext_noop("n")

Functions

static void SetCancelConn (PGconn *conn)
static void ResetCancelConn (void)
const char * get_user_name (const char *progname)
void handle_help_version_opts (int argc, char *argv[], const char *fixed_progname, help_handler hlp)
PGconnconnectDatabase (const char *dbname, const char *pghost, const char *pgport, const char *pguser, enum trivalue prompt_password, const char *progname, bool fail_ok)
PGconnconnectMaintenanceDatabase (const char *maintenance_db, const char *pghost, const char *pgport, const char *pguser, enum trivalue prompt_password, const char *progname)
PGresultexecuteQuery (PGconn *conn, const char *query, const char *progname, bool echo)
void executeCommand (PGconn *conn, const char *query, const char *progname, bool echo)
bool executeMaintenanceCommand (PGconn *conn, const char *query, bool echo)
bool yesno_prompt (const char *question)
static void handle_sigint (SIGNAL_ARGS)
void setup_cancel_handler (void)

Variables

static PGcancel *volatile cancelConn = NULL

Define Documentation

#define PARAMS_ARRAY_SIZE   7
#define PG_NOLETTER   gettext_noop("n")

Definition at line 286 of file common.c.

Referenced by yesno_prompt().

#define PG_YESLETTER   gettext_noop("y")

Definition at line 284 of file common.c.

Referenced by yesno_prompt().


Function Documentation

PGconn* connectDatabase ( const char *  dbname,
const char *  pghost,
const char *  pgport,
const char *  pguser,
enum trivalue  prompt_password,
const char *  progname,
bool  fail_ok 
)

Definition at line 93 of file common.c.

References _, conn, CONNECTION_BAD, free, NULL, PARAMS_ARRAY_SIZE, pg_malloc(), PQconnectdbParams(), PQconnectionNeedsPassword(), PQerrorMessage(), PQfinish(), PQstatus(), simple_prompt(), TRI_NO, TRI_YES, and values.

{
    PGconn     *conn;
    char       *password = NULL;
    bool        new_pass;

    if (prompt_password == TRI_YES)
        password = simple_prompt("Password: ", 100, false);

    /*
     * Start the connection.  Loop until we have a password if requested by
     * backend.
     */
    do
    {
#define PARAMS_ARRAY_SIZE   7
        const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
        const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));

        keywords[0] = "host";
        values[0] = pghost;
        keywords[1] = "port";
        values[1] = pgport;
        keywords[2] = "user";
        values[2] = pguser;
        keywords[3] = "password";
        values[3] = password;
        keywords[4] = "dbname";
        values[4] = dbname;
        keywords[5] = "fallback_application_name";
        values[5] = progname;
        keywords[6] = NULL;
        values[6] = NULL;

        new_pass = false;
        conn = PQconnectdbParams(keywords, values, true);

        free(keywords);
        free(values);

        if (!conn)
        {
            fprintf(stderr, _("%s: could not connect to database %s\n"),
                    progname, dbname);
            exit(1);
        }

        if (PQstatus(conn) == CONNECTION_BAD &&
            PQconnectionNeedsPassword(conn) &&
            password == NULL &&
            prompt_password != TRI_NO)
        {
            PQfinish(conn);
            password = simple_prompt("Password: ", 100, false);
            new_pass = true;
        }
    } while (new_pass);

    if (password)
        free(password);

    /* check to see that the backend connection was successfully made */
    if (PQstatus(conn) == CONNECTION_BAD)
    {
        if (fail_ok)
        {
            PQfinish(conn);
            return NULL;
        }
        fprintf(stderr, _("%s: could not connect to database %s: %s"),
                progname, dbname, PQerrorMessage(conn));
        exit(1);
    }

    return conn;
}

PGconn* connectMaintenanceDatabase ( const char *  maintenance_db,
const char *  pghost,
const char *  pgport,
const char *  pguser,
enum trivalue  prompt_password,
const char *  progname 
)

Definition at line 176 of file common.c.

References conn, and connectDatabase().

Referenced by cluster_all_databases(), main(), reindex_all_databases(), and vacuum_all_databases().

{
    PGconn     *conn;

    /* If a maintenance database name was specified, just connect to it. */
    if (maintenance_db)
        return connectDatabase(maintenance_db, pghost, pgport, pguser,
                               prompt_password, progname, false);

    /* Otherwise, try postgres first and then template1. */
    conn = connectDatabase("postgres", pghost, pgport, pguser, prompt_password,
                           progname, true);
    if (!conn)
        conn = connectDatabase("template1", pghost, pgport, pguser,
                               prompt_password, progname, false);

    return conn;
}

void executeCommand ( PGconn conn,
const char *  query,
const char *  progname,
bool  echo 
)

Definition at line 229 of file common.c.

References _, PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQexec(), PQfinish(), and PQresultStatus().

{
    PGresult   *res;

    if (echo)
        printf("%s\n", query);

    res = PQexec(conn, query);
    if (!res ||
        PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr, _("%s: query failed: %s"),
                progname, PQerrorMessage(conn));
        fprintf(stderr, _("%s: query was: %s\n"),
                progname, query);
        PQfinish(conn);
        exit(1);
    }

    PQclear(res);
}

bool executeMaintenanceCommand ( PGconn conn,
const char *  query,
bool  echo 
)

Definition at line 259 of file common.c.

References PQclear(), PQexec(), PQresultStatus(), ResetCancelConn(), and SetCancelConn().

Referenced by cluster_one_database(), reindex_one_database(), reindex_system_catalogs(), and vacuum_one_database().

{
    PGresult   *res;
    bool        r;

    if (echo)
        printf("%s\n", query);

    SetCancelConn(conn);
    res = PQexec(conn, query);
    ResetCancelConn();

    r = (res && PQresultStatus(res) == PGRES_COMMAND_OK);

    if (res)
        PQclear(res);

    return r;
}

PGresult* executeQuery ( PGconn conn,
const char *  query,
const char *  progname,
bool  echo 
)

Definition at line 202 of file common.c.

References _, PGRES_TUPLES_OK, PQerrorMessage(), PQexec(), PQfinish(), and PQresultStatus().

{
    PGresult   *res;

    if (echo)
        printf("%s\n", query);

    res = PQexec(conn, query);
    if (!res ||
        PQresultStatus(res) != PGRES_TUPLES_OK)
    {
        fprintf(stderr, _("%s: query failed: %s"),
                progname, PQerrorMessage(conn));
        fprintf(stderr, _("%s: query was: %s\n"),
                progname, query);
        PQfinish(conn);
        exit(1);
    }

    return res;
}

const char* get_user_name ( const char *  progname  ) 

Definition at line 36 of file common.c.

References _, strerror(), and username.

Referenced by main().

{
#ifndef WIN32
    struct passwd *pw;

    pw = getpwuid(geteuid());
    if (!pw)
    {
        fprintf(stderr, _("%s: could not obtain information about current user: %s\n"),
                progname, strerror(errno));
        exit(1);
    }
    return pw->pw_name;
#else
    static char username[128];  /* remains after function exit */
    DWORD       len = sizeof(username) - 1;

    if (!GetUserName(username, &len))
    {
        fprintf(stderr, _("%s: could not get current user name: %s\n"),
                progname, strerror(errno));
        exit(1);
    }
    return username;
#endif
}

void handle_help_version_opts ( int  argc,
char *  argv[],
const char *  fixed_progname,
help_handler  hlp 
)

Definition at line 69 of file common.c.

References get_progname().

Referenced by main().

{
    if (argc > 1)
    {
        if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
        {
            hlp(get_progname(argv[0]));
            exit(0);
        }
        if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
        {
            printf("%s (PostgreSQL) " PG_VERSION "\n", fixed_progname);
            exit(0);
        }
    }
}

static void handle_sigint ( SIGNAL_ARGS   )  [static]

Definition at line 386 of file common.c.

References _, NULL, and PQcancel().

Referenced by setup_cancel_handler().

{
    int         save_errno = errno;
    char        errbuf[256];

    /* Send QueryCancel if we are processing a database query */
    if (cancelConn != NULL)
    {
        if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
            fprintf(stderr, _("Cancel request sent\n"));
        else
            fprintf(stderr, _("Could not send cancel request: %s"), errbuf);
    }

    errno = save_errno;         /* just in case the write changed it */
}

static void ResetCancelConn ( void   )  [static]

Definition at line 358 of file common.c.

References NULL, and PQfreeCancel().

{
    PGcancel   *oldCancelConn;

#ifdef WIN32
    EnterCriticalSection(&cancelConnLock);
#endif

    oldCancelConn = cancelConn;

    /* be sure handle_sigint doesn't use pointer while freeing */
    cancelConn = NULL;

    if (oldCancelConn != NULL)
        PQfreeCancel(oldCancelConn);

#ifdef WIN32
    LeaveCriticalSection(&cancelConnLock);
#endif
}

static void SetCancelConn ( PGconn conn  )  [static]

Definition at line 328 of file common.c.

References NULL, PQfreeCancel(), and PQgetCancel().

{
    PGcancel   *oldCancelConn;

#ifdef WIN32
    EnterCriticalSection(&cancelConnLock);
#endif

    /* Free the old one if we have one */
    oldCancelConn = cancelConn;

    /* be sure handle_sigint doesn't use pointer while freeing */
    cancelConn = NULL;

    if (oldCancelConn != NULL)
        PQfreeCancel(oldCancelConn);

    cancelConn = PQgetCancel(conn);

#ifdef WIN32
    LeaveCriticalSection(&cancelConnLock);
#endif
}

void setup_cancel_handler ( void   ) 

Definition at line 404 of file common.c.

References handle_sigint(), and pqsignal().

{
    pqsignal(SIGINT, handle_sigint);
}

bool yesno_prompt ( const char *  question  ) 

Definition at line 289 of file common.c.

References _, free, PG_NOLETTER, PG_YESLETTER, simple_prompt(), and snprintf().

Referenced by main().

{
    char        prompt[256];

    /*------
       translator: This is a question followed by the translated options for
       "yes" and "no". */
    snprintf(prompt, sizeof(prompt), _("%s (%s/%s) "),
             _(question), _(PG_YESLETTER), _(PG_NOLETTER));

    for (;;)
    {
        char       *resp;

        resp = simple_prompt(prompt, 1, true);

        if (strcmp(resp, _(PG_YESLETTER)) == 0)
        {
            free(resp);
            return true;
        }
        else if (strcmp(resp, _(PG_NOLETTER)) == 0)
        {
            free(resp);
            return false;
        }

        free(resp);
        printf(_("Please answer \"%s\" or \"%s\".\n"),
               _(PG_YESLETTER), _(PG_NOLETTER));
    }
}


Variable Documentation

PGcancel* volatile cancelConn = NULL [static]

Definition at line 26 of file common.c.