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