]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/sprompt.c
fix small bug in index.c
[nominatim.git] / nominatim / sprompt.c
1 /*-------------------------------------------------------------------------
2  *
3  * sprompt.c
4  *        simple_prompt() routine
5  *
6  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/port/sprompt.c,v 1.18 2006/10/04 00:30:14 momjian Exp $
12  *
13  *-------------------------------------------------------------------------
14  *
15  * PostgreSQL Database Management System
16  * (formerly known as Postgres, then as Postgres95)
17  *
18  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
19  *
20  * Portions Copyright (c) 1994, The Regents of the University of California
21  *
22  * Permission to use, copy, modify, and distribute this software and its
23  * documentation for any purpose, without fee, and without a written agreement
24  * is hereby granted, provided that the above copyright notice and this
25  * paragraph and the following two paragraphs appear in all copies.
26  *
27  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
28  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
29  * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
30  * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
34  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
35  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
36  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
37  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
38  *
39  */
40
41
42 /*
43  * simple_prompt
44  *
45  * Generalized function especially intended for reading in usernames and
46  * password interactively. Reads from /dev/tty or stdin/stderr.
47  *
48  * prompt:              The prompt to print
49  * maxlen:              How many characters to accept
50  * echo:                Set to false if you want to hide what is entered (for passwords)
51  *
52  * Returns a malloc()'ed string with the input (w/o trailing newline).
53  */
54
55 #define DEVTTY "/dev/tty"
56
57 #include <stdio.h>
58 #include <unistd.h>
59 #include <stdlib.h>
60 #include <string.h>
61 #include <assert.h>
62
63 #include <libpq-fe.h>
64
65 #ifdef __MINGW_H
66 # include <windows.h>
67 #else
68 # define HAVE_TERMIOS_H
69 # include <termios.h>
70 #endif
71
72 /*
73 extern char *simple_prompt(const char *prompt, int maxlen, int echo);
74 */
75
76 char *
77 simple_prompt(const char *prompt, int maxlen, int echo)
78 {
79     int                 length;
80     char           *destination;
81     FILE           *termin,
82     *termout;
83
84 #ifdef HAVE_TERMIOS_H
85     struct termios t_orig,
86                 t;
87 #else
88 #ifdef WIN32
89     HANDLE              t = NULL;
90     LPDWORD             t_orig = NULL;
91 #endif
92 #endif
93
94     destination = (char *) malloc(maxlen + 1);
95     if (!destination)
96         return NULL;
97
98     /*
99      * Do not try to collapse these into one "w+" mode file. Doesn't work on
100      * some platforms (eg, HPUX 10.20).
101      */
102     termin = fopen(DEVTTY, "r");
103     termout = fopen(DEVTTY, "w");
104     if (!termin || !termout
105 #ifdef WIN32
106             /* See DEVTTY comment for msys */
107             || (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
108 #endif
109        )
110 {
111         if (termin)
112             fclose(termin);
113         if (termout)
114             fclose(termout);
115         termin = stdin;
116         termout = stderr;
117     }
118
119 #ifdef HAVE_TERMIOS_H
120     if (!echo)
121     {
122         tcgetattr(fileno(termin), &t);
123         t_orig = t;
124         t.c_lflag &= ~ECHO;
125         tcsetattr(fileno(termin), TCSAFLUSH, &t);
126     }
127 #else
128 #ifdef WIN32
129     if (!echo)
130     {
131         /* get a new handle to turn echo off */
132         t_orig = (LPDWORD) malloc(sizeof(DWORD));
133         t = GetStdHandle(STD_INPUT_HANDLE);
134
135         /* save the old configuration first */
136         GetConsoleMode(t, t_orig);
137
138         /* set to the new mode */
139         SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
140     }
141 #endif
142 #endif
143
144     if (prompt)
145     {
146         fputs(prompt, termout);
147         fflush(termout);
148     }
149
150     if (fgets(destination, maxlen + 1, termin) == NULL)
151         destination[0] = '\0';
152
153     length = strlen(destination);
154     if (length > 0 && destination[length - 1] != '\n')
155     {
156         /* eat rest of the line */
157         char            buf[128];
158         int                     buflen;
159
160         do
161         {
162             if (fgets(buf, sizeof(buf), termin) == NULL)
163                 break;
164             buflen = strlen(buf);
165         }
166         while (buflen > 0 && buf[buflen - 1] != '\n');
167     }
168
169     if (length > 0 && destination[length - 1] == '\n')
170         /* remove trailing newline */
171         destination[length - 1] = '\0';
172
173 #ifdef HAVE_TERMIOS_H
174     if (!echo)
175     {
176         tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
177         fputs("\n", termout);
178         fflush(termout);
179     }
180 #else
181 #ifdef WIN32
182     if (!echo)
183     {
184         /* reset to the original console mode */
185         SetConsoleMode(t, *t_orig);
186         fputs("\n", termout);
187         fflush(termout);
188         free(t_orig);
189     }
190 #endif
191 #endif
192
193     if (termin != stdin)
194     {
195         fclose(termin);
196         fclose(termout);
197     }
198
199     return destination;
200 }