]> granicus.if.org Git - postgresql/blob - src/port/sprompt.c
Move simple_prompt()/sprompt.c into /port.
[postgresql] / src / port / sprompt.c
1 /*
2  * psql - the PostgreSQL interactive terminal
3  *
4  * Copyright 2000 by PostgreSQL Global Development Group
5  *
6  * $Header: /cvsroot/pgsql/src/port/sprompt.c,v 1.1 2003/08/08 04:52:22 momjian Exp $
7  */
8
9
10 /*
11  * simple_prompt
12  *
13  * Generalized function especially intended for reading in usernames and
14  * password interactively. Reads from /dev/tty or stdin/stderr.
15  *
16  * prompt:              The prompt to print
17  * maxlen:              How many characters to accept
18  * echo:                Set to false if you want to hide what is entered (for passwords)
19  *
20  * Returns a malloc()'ed string with the input (w/o trailing newline).
21  */
22 #include "postgres.h"
23
24 #ifdef HAVE_TERMIOS_H
25 #include <termios.h>
26 #else
27 #ifdef WIN32
28 #include <windows.h>
29 #endif
30 #endif
31
32 bool            prompt_state = false;
33 extern char *simple_prompt(const char *prompt, int maxlen, bool echo);
34
35 char *
36 simple_prompt(const char *prompt, int maxlen, bool echo)
37 {
38         int                     length;
39         char       *destination;
40         FILE       *termin,
41                            *termout;
42
43 #ifdef HAVE_TERMIOS_H
44         struct termios t_orig,
45                                 t;
46
47 #else
48 #ifdef WIN32
49         HANDLE          t;
50         LPDWORD         t_orig;
51 #endif
52 #endif
53
54         destination = (char *) malloc(maxlen + 1);
55         if (!destination)
56                 return NULL;
57
58         prompt_state = true;            /* disable SIGINT */
59
60         /*
61          * Do not try to collapse these into one "w+" mode file. Doesn't work
62          * on some platforms (eg, HPUX 10.20).
63          */
64         termin = fopen("/dev/tty", "r");
65         termout = fopen("/dev/tty", "w");
66         if (!termin || !termout)
67         {
68                 if (termin)
69                         fclose(termin);
70                 if (termout)
71                         fclose(termout);
72                 termin = stdin;
73                 termout = stderr;
74         }
75
76 #ifdef HAVE_TERMIOS_H
77         if (!echo)
78         {
79                 tcgetattr(fileno(termin), &t);
80                 t_orig = t;
81                 t.c_lflag &= ~ECHO;
82                 tcsetattr(fileno(termin), TCSAFLUSH, &t);
83         }
84 #else
85 #ifdef WIN32
86         if (!echo)
87         {
88                 /* get a new handle to turn echo off */
89                 t_orig = (LPDWORD) malloc(sizeof(DWORD));
90                 t = GetStdHandle(STD_INPUT_HANDLE);
91
92                 /* save the old configuration first */
93                 GetConsoleMode(t, t_orig);
94
95                 /* set to the new mode */
96                 SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
97         }
98 #endif
99 #endif
100
101         if (prompt)
102         {
103                 fputs(gettext(prompt), termout);
104                 fflush(termout);
105         }
106
107         if (fgets(destination, maxlen + 1, termin) == NULL)
108                 destination[0] = '\0';
109
110         length = strlen(destination);
111         if (length > 0 && destination[length - 1] != '\n')
112         {
113                 /* eat rest of the line */
114                 char            buf[128];
115                 int                     buflen;
116
117                 do
118                 {
119                         if (fgets(buf, sizeof(buf), termin) == NULL)
120                                 break;
121                         buflen = strlen(buf);
122                 } while (buflen > 0 && buf[buflen - 1] != '\n');
123         }
124
125         if (length > 0 && destination[length - 1] == '\n')
126                 /* remove trailing newline */
127                 destination[length - 1] = '\0';
128
129 #ifdef HAVE_TERMIOS_H
130         if (!echo)
131         {
132                 tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
133                 fputs("\n", termout);
134                 fflush(termout);
135         }
136 #else
137 #ifdef WIN32
138         if (!echo)
139         {
140                 /* reset to the original console mode */
141                 SetConsoleMode(t, *t_orig);
142                 fputs("\n", termout);
143                 fflush(termout);
144                 free(t_orig);
145         }
146 #endif
147 #endif
148
149         if (termin != stdin)
150         {
151                 fclose(termin);
152                 fclose(termout);
153         }
154
155         prompt_state = false;           /* SIGINT okay again */
156
157         return destination;
158 }