]> granicus.if.org Git - postgresql/blob - src/port/sprompt.c
Allow win32 client compiles with MSC.
[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.2 2003/10/26 04:29:15 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 #undef ERROR
30 #endif
31 #endif
32
33 bool            prompt_state = false;
34 extern char *simple_prompt(const char *prompt, int maxlen, bool echo);
35
36 char *
37 simple_prompt(const char *prompt, int maxlen, bool echo)
38 {
39         int                     length;
40         char       *destination;
41         FILE       *termin,
42                            *termout;
43
44 #ifdef HAVE_TERMIOS_H
45         struct termios t_orig,
46                                 t;
47
48 #else
49 #ifdef WIN32
50         HANDLE          t;
51         LPDWORD         t_orig;
52 #endif
53 #endif
54
55         destination = (char *) malloc(maxlen + 1);
56         if (!destination)
57                 return NULL;
58
59         prompt_state = true;            /* disable SIGINT */
60
61         /*
62          * Do not try to collapse these into one "w+" mode file. Doesn't work
63          * on some platforms (eg, HPUX 10.20).
64          */
65         termin = fopen("/dev/tty", "r");
66         termout = fopen("/dev/tty", "w");
67         if (!termin || !termout)
68         {
69                 if (termin)
70                         fclose(termin);
71                 if (termout)
72                         fclose(termout);
73                 termin = stdin;
74                 termout = stderr;
75         }
76
77 #ifdef HAVE_TERMIOS_H
78         if (!echo)
79         {
80                 tcgetattr(fileno(termin), &t);
81                 t_orig = t;
82                 t.c_lflag &= ~ECHO;
83                 tcsetattr(fileno(termin), TCSAFLUSH, &t);
84         }
85 #else
86 #ifdef WIN32
87         if (!echo)
88         {
89                 /* get a new handle to turn echo off */
90                 t_orig = (LPDWORD) malloc(sizeof(DWORD));
91                 t = GetStdHandle(STD_INPUT_HANDLE);
92
93                 /* save the old configuration first */
94                 GetConsoleMode(t, t_orig);
95
96                 /* set to the new mode */
97                 SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
98         }
99 #endif
100 #endif
101
102         if (prompt)
103         {
104                 fputs(gettext(prompt), termout);
105                 fflush(termout);
106         }
107
108         if (fgets(destination, maxlen + 1, termin) == NULL)
109                 destination[0] = '\0';
110
111         length = strlen(destination);
112         if (length > 0 && destination[length - 1] != '\n')
113         {
114                 /* eat rest of the line */
115                 char            buf[128];
116                 int                     buflen;
117
118                 do
119                 {
120                         if (fgets(buf, sizeof(buf), termin) == NULL)
121                                 break;
122                         buflen = strlen(buf);
123                 } while (buflen > 0 && buf[buflen - 1] != '\n');
124         }
125
126         if (length > 0 && destination[length - 1] == '\n')
127                 /* remove trailing newline */
128                 destination[length - 1] = '\0';
129
130 #ifdef HAVE_TERMIOS_H
131         if (!echo)
132         {
133                 tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
134                 fputs("\n", termout);
135                 fflush(termout);
136         }
137 #else
138 #ifdef WIN32
139         if (!echo)
140         {
141                 /* reset to the original console mode */
142                 SetConsoleMode(t, *t_orig);
143                 fputs("\n", termout);
144                 fflush(termout);
145                 free(t_orig);
146         }
147 #endif
148 #endif
149
150         if (termin != stdin)
151         {
152                 fclose(termin);
153                 fclose(termout);
154         }
155
156         prompt_state = false;           /* SIGINT okay again */
157
158         return destination;
159 }