]> granicus.if.org Git - postgresql/blobdiff - src/bin/psql/psql.c
From: Dan McGuirk <mcguirk@indirect.com>
[postgresql] / src / bin / psql / psql.c
index 8df0998c3e0cdef8f6f204a59a522e8ca3e4fa83..6fd299605b4b7141bd331b7f4c79aeb61ccb28bd 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.52 1997/01/25 22:16:36 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.58 1997/03/12 21:19:14 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "pqsignal.h"
 #include "stringutils.h"
 #include "psqlHelp.h"
-#ifdef NEED_STRDUP
+#ifndef HAVE_STRDUP
 #include "strdup.h"
 #endif
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
 
-#ifndef HAVE_LIBREADLINE
-# include "rlstubs.h"
-#else
+#ifdef HAVE_LIBREADLINE
 # ifdef HAVE_READLINE_H
 #  include <readline.h>
-#  ifndef NO_HISTORY
+#  if defined(HAVE_HISTORY) || defined(HAVE_LIBHISTORY)
 #   include <history.h>
 #  endif
 # else
 #  include <readline/readline.h>
-#  ifndef NO_HISTORY
+#  if defined(HAVE_HISTORY) || defined(HAVE_LIBHISTORY)
 #   include <readline/history.h>
 #  endif
 # endif
@@ -69,6 +70,7 @@ typedef struct _psqlSettings {
     bool            singleStep;        /* prompt before for each query */
     bool            singleLineMode;    /* query terminated by newline */
     bool            useReadline;/* use libreadline routines */
+    bool            getPassword;/* prompt the user for a username and password */
 }               PsqlSettings;
 
 /* declarations for functions in this file */
@@ -80,6 +82,9 @@ handleCopyIn(PGresult * res, const bool mustprompt,
             FILE * copystream);
 static int      tableList(PsqlSettings * ps, bool deep_tablelist);
 static int      tableDesc(PsqlSettings * ps, char *table);
+static void     prompt_for_password(char *username, char *password);
+static char *   make_connect_string(char *host, char *port, char *dbname,
+                                   char *username, char *password);
 
 char           *gets_noreadline(char *prompt, FILE * source);
 char           *gets_readline(char *prompt, FILE * source);
@@ -127,6 +132,7 @@ usage(char *progname)
     fprintf(stderr, "\t -s                      single step mode (prompts for each query)\n");
     fprintf(stderr, "\t -S                      single line mode (i.e. query terminated by newline)\n");
     fprintf(stderr, "\t -t                      turn off printing of headings and row count\n");
+    fprintf(stderr, "\t -u                      ask for a username and password for authentication\n");
     fprintf(stderr, "\t -T html                 set html3.0 table command options (cf. -H)\n");
     fprintf(stderr, "\t -x                      turn on expanded output (field names on left)\n");
     exit(1);
@@ -149,7 +155,7 @@ slashUsage(PsqlSettings * ps)
     fprintf(stderr, " \\a           -- toggle field-alignment (currenty %s)\n", on(ps->opt.align));
     fprintf(stderr, " \\C [<captn>] -- set html3 caption (currently '%s')\n", ps->opt.caption ? ps->opt.caption : "");
     fprintf(stderr, " \\connect <dbname>  -- connect to new database (currently '%s')\n", PQdb(ps->db));
-    fprintf(stderr, " \\copy {<table> to <file> | <file> from <table>}\n");
+    fprintf(stderr, " \\copy table {from | to} <fname>\n");
     fprintf(stderr, " \\d [<table>] -- list tables in database or columns in <table>, * for all\n");
     fprintf(stderr, " \\e [<fname>] -- edit the current query buffer or <fname>, \\E execute too\n");
     fprintf(stderr, " \\f [<sep>]   -- change field separater (currently '%s')\n", ps->opt.fieldSep);
@@ -404,7 +410,14 @@ gets_noreadline(char *prompt, FILE * source)
 char           *
 gets_readline(char *prompt, FILE * source)
 {
-    char *s = readline(prompt);
+    char *s;
+#ifdef HAVE_LIBREADLINE
+    s = readline(prompt);
+#else
+    char buf[500];
+    printf("%s", prompt);
+    s = fgets(buf, 500, stdin);
+#endif
     fputc('\r', stdout);
     fflush(stdout);
     return s;
@@ -1158,8 +1171,10 @@ HandleSlashCmds(PsqlSettings * settings,
     case 's':                  /* \s is save history to a file */
        if (!optarg)
            optarg = "/dev/tty";
+#ifdef HAVE_HISTORY
        if (write_history(optarg) != 0)
            fprintf(stderr, "cannot write history to %s\n", optarg);
+#endif
        break;
     case 'm':                  /* monitor like type-setting */
        if (toggle(settings, &settings->opt.standard, "standard SQL separaters and padding")) {
@@ -1254,7 +1269,9 @@ MainLoop(PsqlSettings * settings, FILE * source)
        else
            sprintf(settings->prompt, "%s%s", PQdb(settings->db), PROMPT);
        if (settings->useReadline) {
+#ifdef HAVE_HISTORY
            using_history();
+#endif
            GetNextLine = gets_readline;
        } else
            GetNextLine = gets_noreadline;
@@ -1282,8 +1299,10 @@ MainLoop(PsqlSettings * settings, FILE * source)
                    settings->prompt[strlen(settings->prompt)-3] = '=';
            }
            line = GetNextLine(settings->prompt, source);
+#ifdef HAVE_HISTORY
            if (interactive && settings->useReadline && line != NULL)
                add_history(line);      /* save non-empty lines in history */
+#endif
        }
 
        query_start = line;
@@ -1448,12 +1467,17 @@ main(int argc, char **argv)
     settings.opt.pager = 1;
     if (!isatty(0) || !isatty(1))
        settings.quiet = settings.notty = 1;
-#ifndef NOREADLINE
+#ifdef HAVE_LIBREADLINE
     else
        settings.useReadline = 1;
 #endif
+#ifdef PSQL_ALWAYS_GET_PASSWORDS
+    settings.getPassword = 1;
+#else
+    settings.getPassword = 0;
+#endif
 
-    while ((c = getopt(argc, argv, "Aa:c:d:ef:F:lh:Hnso:p:qStT:x")) != EOF) {
+    while ((c = getopt(argc, argv, "Aa:c:d:ef:F:lh:Hnso:p:qStT:ux")) != EOF) {
        switch (c) {
        case 'A':
            settings.opt.align = 0;
@@ -1512,6 +1536,9 @@ main(int argc, char **argv)
        case 'T':
            settings.opt.tableOpt = optarg;
            break;
+       case 'u':
+           settings.getPassword = 1;
+           break;
        case 'x':
            settings.opt.expanded = 1;
            break;
@@ -1527,7 +1554,21 @@ main(int argc, char **argv)
     if (listDatabases)
        dbname = "template1";
 
-    settings.db = PQsetdb(host, port, NULL, NULL, dbname);
+    if(settings.getPassword) {
+       char username[9];
+       char password[9];
+       char *connect_string;
+
+       prompt_for_password(username, password);
+
+       /* now use PQconnectdb so we can pass these options */
+       connect_string = make_connect_string(host, port, dbname, username, password);
+       settings.db = PQconnectdb(connect_string);
+       free(connect_string);
+    } else {
+       settings.db = PQsetdb(host, port, NULL, NULL, dbname);
+    }
+
     dbname = PQdb(settings.db);
 
     if (PQstatus(settings.db) == CONNECTION_BAD) {
@@ -1700,3 +1741,87 @@ setFout(PsqlSettings * ps, char *fname)
     }
     return ps->queryFout;
 }
+
+static void prompt_for_password(char *username, char *password)
+{
+    int length;
+#ifdef HAVE_TERMIOS_H
+    struct termios t_orig, t;
+#endif
+
+    printf("Username: ");
+    fgets(username, 9, stdin);
+    length = strlen(username);
+    if(length > 0 && username[length-1] == '\n') username[length-1] = '\0';
+
+    printf("Password: ");
+#ifdef HAVE_TERMIOS_H
+    tcgetattr(0, &t);
+    t_orig = t;
+    t.c_lflag &= ~ECHO;
+    tcsetattr(0, TCSADRAIN, &t);
+#endif
+    fgets(password, 9, stdin);
+#ifdef HAVE_TERMIOS_H
+    tcsetattr(0, TCSADRAIN, &t_orig);
+#endif
+
+    length = strlen(password);
+    if(length > 0 && password[length-1] == '\n') password[length-1] = '\0';
+
+    printf("\n\n");
+}
+
+static char *make_connect_string(char *host, char *port, char *dbname,
+                                char *username, char *password)
+{
+    int connect_string_len = 0;
+    char *connect_string;
+    
+    if(host)
+       connect_string_len += 6 + strlen(host);       /* 6 == "host=" + " " */
+    if(username) 
+       connect_string_len += 6 + strlen(username);   /* 6 == "user=" + " " */
+    if(password)
+       connect_string_len += 10 + strlen(password);  /* 10 == "password=" + " " */
+    if(port)
+       connect_string_len += 6 + strlen(port);       /* 6 == "port=" + " " */
+    if(dbname)
+       connect_string_len += 8 + strlen(dbname);     /* 8 == "dbname=" + " " */
+    connect_string_len += 18;   /* "authtype=password" + null */
+    
+    connect_string = (char *)malloc(connect_string_len);
+    if(!connect_string) {
+       return 0;
+    }
+    connect_string[0] = '\0';
+    if(host) {
+       strcat(connect_string, "host=");
+       strcat(connect_string, host);
+       strcat(connect_string, " ");
+    }
+    if(username) {
+       strcat(connect_string, "user=");
+       strcat(connect_string, username);
+       strcat(connect_string, " ");
+    }
+    if(password) {
+       strcat(connect_string, "password=");
+       strcat(connect_string, password);
+       strcat(connect_string, " ");
+    }
+    if(port) {
+       strcat(connect_string, "port=");
+       strcat(connect_string, port);
+       strcat(connect_string, " ");
+    }
+    if(dbname) {
+       strcat(connect_string, "dbname=");
+       strcat(connect_string, dbname);
+       strcat(connect_string, " ");
+    }
+    strcat(connect_string, "authtype=password");
+
+    return connect_string;
+}
+