Line data Source code
1 : /*
2 : * Copyright (c) 1997 - 2000, 2005 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * 3. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include <config.h>
35 : #include <roken.h>
36 : #include <signal.h>
37 : #ifdef HAVE_TERMIOS_H
38 : #include <termios.h>
39 : #endif
40 :
41 : #include <ui.h>
42 : #ifdef HAVE_CONIO_H
43 : #include <conio.h>
44 : #endif
45 :
46 : static sig_atomic_t intr_flag;
47 :
48 : static void
49 0 : intr(int sig)
50 : {
51 0 : intr_flag++;
52 0 : }
53 :
54 : #ifdef HAVE_CONIO_H
55 :
56 : /*
57 : * Windows does console slightly different then then unix case.
58 : */
59 :
60 : static int
61 : read_string(const char *preprompt, const char *prompt,
62 : char *buf, size_t len, int echo)
63 : {
64 : int of = 0;
65 : int c;
66 : char *p;
67 : void (*oldsigintr)(int);
68 :
69 : _cprintf("%s%s", preprompt, prompt);
70 :
71 : oldsigintr = signal(SIGINT, intr);
72 :
73 : p = buf;
74 : while(intr_flag == 0){
75 : c = ((echo)? _getche(): _getch());
76 : if(c == '\n' || c == '\r')
77 : break;
78 : if(of == 0)
79 : *p++ = c;
80 : of = (p == buf + len);
81 : }
82 : if(of)
83 : p--;
84 : *p = 0;
85 :
86 : if(echo == 0){
87 : printf("\n");
88 : }
89 :
90 : signal(SIGINT, oldsigintr);
91 :
92 : if(intr_flag)
93 : return -2;
94 : if(of)
95 : return -1;
96 : return 0;
97 : }
98 :
99 : #else /* !HAVE_CONIO_H */
100 :
101 : #ifndef NSIG
102 : #define NSIG 47
103 : #endif
104 :
105 : static int
106 30 : read_string(const char *preprompt, const char *prompt,
107 : char *buf, size_t len, int echo)
108 : {
109 0 : struct sigaction sigs[NSIG];
110 0 : int oksigs[NSIG];
111 0 : struct sigaction sa;
112 0 : FILE *tty;
113 30 : int ret = 0;
114 30 : int of = 0;
115 0 : int i;
116 0 : int c;
117 0 : char *p;
118 :
119 0 : struct termios t_new, t_old;
120 :
121 30 : memset(&oksigs, 0, sizeof(oksigs));
122 :
123 30 : memset(&sa, 0, sizeof(sa));
124 30 : sa.sa_handler = intr;
125 30 : sigemptyset(&sa.sa_mask);
126 30 : sa.sa_flags = 0;
127 1950 : for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++)
128 1920 : if (i != SIGALRM)
129 1890 : if (sigaction(i, &sa, &sigs[i]) == 0)
130 1770 : oksigs[i] = 1;
131 :
132 30 : if((tty = fopen("/dev/tty", "r")) != NULL)
133 0 : rk_cloexec_file(tty);
134 : else
135 30 : tty = stdin;
136 :
137 30 : fprintf(stderr, "%s%s", preprompt, prompt);
138 30 : fflush(stderr);
139 :
140 30 : if(echo == 0){
141 30 : tcgetattr(fileno(tty), &t_old);
142 30 : memcpy(&t_new, &t_old, sizeof(t_new));
143 30 : t_new.c_lflag &= ~ECHO;
144 30 : tcsetattr(fileno(tty), TCSANOW, &t_new);
145 : }
146 30 : intr_flag = 0;
147 30 : p = buf;
148 381 : while(intr_flag == 0){
149 381 : c = getc(tty);
150 381 : if(c == EOF){
151 0 : if(!ferror(tty))
152 0 : ret = 1;
153 0 : break;
154 : }
155 381 : if(c == '\n')
156 30 : break;
157 351 : if(of == 0)
158 351 : *p++ = c;
159 351 : of = (p == buf + len);
160 : }
161 30 : if(of)
162 0 : p--;
163 30 : *p = 0;
164 :
165 30 : if(echo == 0){
166 30 : fprintf(stderr, "\n");
167 30 : tcsetattr(fileno(tty), TCSANOW, &t_old);
168 : }
169 :
170 30 : if(tty != stdin)
171 0 : fclose(tty);
172 :
173 1950 : for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++)
174 1920 : if (oksigs[i])
175 1770 : sigaction(i, &sigs[i], NULL);
176 :
177 30 : if(ret)
178 0 : return -3;
179 30 : if(intr_flag)
180 0 : return -2;
181 30 : if(of)
182 0 : return -1;
183 30 : return 0;
184 : }
185 :
186 : #endif /* HAVE_CONIO_H */
187 :
188 : int
189 24 : UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, int verify)
190 : {
191 0 : int ret;
192 :
193 24 : ret = read_string("", prompt, buf, length, 0);
194 24 : if (ret)
195 0 : return ret;
196 :
197 24 : if (verify & UI_UTIL_FLAG_VERIFY) {
198 0 : char *buf2;
199 6 : buf2 = malloc(length);
200 6 : if (buf2 == NULL)
201 0 : return 1;
202 :
203 6 : ret = read_string("Verify password - ", prompt, buf2, length, 0);
204 6 : if (ret) {
205 0 : free(buf2);
206 0 : return ret;
207 : }
208 6 : if (strcmp(buf2, buf) != 0) {
209 0 : if (!(verify & UI_UTIL_FLAG_VERIFY_SILENT)) {
210 0 : fprintf(stderr, "Verify failure\n");
211 0 : fflush(stderr);
212 : }
213 0 : ret = 1;
214 : }
215 6 : free(buf2);
216 : }
217 24 : return ret;
218 : }
|