]>
Commit | Line | Data |
---|---|---|
989a2c2c | 1 | /* |
2 | * $Source$ | |
3 | * $Author$ | |
4 | * $Locker$ | |
5 | * $Header$ | |
7189310c | 6 | * |
7 | * (c) Copyright 1988 by the Massachusetts Institute of Technology. | |
8 | * For copying and distribution information, please see the file | |
9 | * <mit-copyright.h>. | |
989a2c2c | 10 | */ |
11 | ||
12 | #ifndef lint | |
13 | static char *rcsid_display_c = "$Header$"; | |
7ff930df | 14 | #endif |
989a2c2c | 15 | |
7189310c | 16 | #include <mit-copyright.h> |
989a2c2c | 17 | #include <stdio.h> |
18 | #include <curses.h> | |
19 | #include <sys/time.h> | |
20 | #include "userreg.h" | |
21 | ||
22 | #define DESC_WIDTH 18 | |
a2b4a2ee | 23 | #define HEADER "*** Athena User Account Registration ***" |
a2b4a2ee | 24 | #define HELP " Press backspace to delete a character. Press Ctrl-C to start over." |
989a2c2c | 25 | #define BORDER_CHAR '-' |
26 | #define MIN_COLS 80 | |
27 | #define MIN_LINES 24 | |
28 | ||
29 | WINDOW * displayw, *queryw; | |
30 | WINDOW * dataw, *helpw; | |
31 | WINDOW * fnamew, *midw, *lnamew, *idw, *loginw; | |
7ff930df | 32 | extern char typed_mit_id[100]; |
989a2c2c | 33 | |
34 | /* Set up the windows and subwindows on the display */ | |
5eaef520 | 35 | setup_display(void) |
36 | { | |
37 | FILE *freopen(); | |
989a2c2c | 38 | |
5eaef520 | 39 | initscr(); /* Start up curses */ |
989a2c2c | 40 | |
5eaef520 | 41 | if (COLS < MIN_COLS || LINES < MIN_LINES) |
42 | { | |
43 | fprintf(stderr, "Screen must be at least %d x %d\n", | |
44 | MIN_LINES, MIN_COLS); | |
45 | exit(1); | |
46 | } | |
94464a85 | 47 | |
5eaef520 | 48 | noecho(); /* And the tty input */ |
49 | raw(); | |
50 | freopen("/dev/null", "w", stderr);/* Toss the standard error output */ | |
989a2c2c | 51 | |
5eaef520 | 52 | /* Make sure the place is clean */ |
53 | clear(); | |
989a2c2c | 54 | |
5eaef520 | 55 | /* Set up the top-level windows */ |
56 | /* First line is the header */ | |
57 | displayw = subwin(stdscr, 12, 0, 2, 0);/* Lines 2-13 */ | |
58 | scrollok(displayw, TRUE); | |
989a2c2c | 59 | |
5eaef520 | 60 | queryw = subwin(stdscr, 1, 0, 15, 0);/* Line 15 */ |
61 | scrollok(queryw, TRUE); | |
989a2c2c | 62 | |
5eaef520 | 63 | dataw = subwin(stdscr, 5, 0, 17, 0);/* Lines 17-21 */ |
989a2c2c | 64 | |
5eaef520 | 65 | /* Set up the data windows */ |
66 | fnamew = subwin(stdscr, 1, 0, 17, DESC_WIDTH); | |
67 | midw = subwin(stdscr, 1, 0, 18, DESC_WIDTH); | |
68 | lnamew = subwin(stdscr, 1, 0, 19, DESC_WIDTH); | |
69 | idw = subwin(stdscr, 1, 0, 20, DESC_WIDTH); | |
70 | loginw = subwin(stdscr, 1, 0, 21, DESC_WIDTH); | |
989a2c2c | 71 | } |
72 | ||
73 | /* Clear and restore the display */ | |
5eaef520 | 74 | reset_display(void) |
75 | { | |
76 | clear(); | |
77 | ||
78 | /* Put back the borders */ | |
79 | make_border(1); | |
80 | make_border(14); | |
81 | make_border(16); | |
82 | make_border(22); | |
83 | ||
84 | /* Put in the window dressing */ | |
85 | wmove(dataw, 0, 0); | |
86 | waddstr(dataw, "First Name:\n"); | |
87 | waddstr(dataw, "Middle Initial:\n"); | |
88 | waddstr(dataw, "Family Name:\n"); | |
89 | waddstr(dataw, "MIT ID #:\n\n"); | |
90 | waddstr(dataw, "Username:\n"); | |
91 | wclrtoeol(dataw); | |
92 | ||
93 | /* Set up the header */ | |
94 | mvaddstr(0, (COLS - strlen (HEADER)) / 2, HEADER); | |
95 | mvaddstr(23, 0, HELP); | |
96 | ||
97 | /* Put it all up */ | |
98 | refresh(); | |
989a2c2c | 99 | } |
100 | ||
101 | ||
102 | /* Make a one-line border on line l of stdscr */ | |
5eaef520 | 103 | make_border(int l) |
989a2c2c | 104 | { |
5eaef520 | 105 | int i; |
989a2c2c | 106 | |
5eaef520 | 107 | move(l, 0); |
108 | for(i = 0; i < COLS - 1; i++) | |
109 | addch(BORDER_CHAR); | |
989a2c2c | 110 | } |
111 | ||
112 | /* This replaces several "useful" display functions in the old userreg */ | |
5eaef520 | 113 | redisp(void) |
114 | { | |
115 | mvwprintw(fnamew, 0, 0, "%-24s", user.u_first); | |
e6b3a349 | 116 | wrefresh(fnamew); |
5eaef520 | 117 | mvwprintw(midw, 0, 0, "%-24s", user.u_mid_init); |
e6b3a349 | 118 | wrefresh(midw); |
5eaef520 | 119 | mvwprintw(lnamew, 0, 0, "%-24s", user.u_last); |
e6b3a349 | 120 | wrefresh(lnamew); |
5eaef520 | 121 | mvwprintw(idw, 0, 0, "%-24s", typed_mit_id); |
e6b3a349 | 122 | wrefresh(idw); |
5eaef520 | 123 | mvwprintw(loginw, 0, 0, "%-24s", user.u_login); |
e6b3a349 | 124 | wrefresh(loginw); |
989a2c2c | 125 | } |
126 | ||
127 | ||
128 | /* Input and input_no_echo exist only to save on retyping */ | |
5eaef520 | 129 | input(char *prompt, char *buf, int maxsize, int timeout, int emptyok) |
989a2c2c | 130 | { |
5eaef520 | 131 | query_user(prompt, buf, maxsize, timeout, TRUE, emptyok, TRUE); |
989a2c2c | 132 | } |
133 | ||
5eaef520 | 134 | input_no_echo(char *prompt, char *buf, int maxsize, int timeout) |
989a2c2c | 135 | { |
5eaef520 | 136 | query_user(prompt, buf, maxsize, timeout, FALSE, FALSE, TRUE); |
989a2c2c | 137 | } |
138 | ||
139 | ||
4127ae1e | 140 | /* make the user press any key to continue */ |
5eaef520 | 141 | wait_for_user(void) |
4127ae1e | 142 | { |
5eaef520 | 143 | char buf[BUFSIZ]; |
4127ae1e | 144 | |
5eaef520 | 145 | redisp(); |
146 | query_user("Press RETURN or ENTER to continue", buf, 1, | |
147 | 15 * 60, FALSE, TRUE, FALSE); | |
4127ae1e | 148 | } |
149 | ||
989a2c2c | 150 | |
151 | /* Gets input through the query buffer */ | |
152 | /* Exit(1)'s on read errors */ | |
153 | /* Signals SIGALRM after 'timeout' seconds */ | |
5eaef520 | 154 | query_user(char *prompt, char *buf, int maxsize, int timeout, |
155 | int echop, int emptyok, int valuep) | |
989a2c2c | 156 | { |
5eaef520 | 157 | int c; |
158 | int i; | |
989a2c2c | 159 | struct itimerval it; |
160 | ||
161 | retry: | |
162 | /* Set up interval timer */ | |
163 | it.it_interval.tv_sec = 0; | |
164 | it.it_interval.tv_usec = 0; | |
165 | it.it_value.tv_sec = timeout; | |
166 | it.it_value.tv_usec = 0; | |
5eaef520 | 167 | setitimer(ITIMER_REAL, &it, NULL); |
989a2c2c | 168 | |
169 | /* Erase the query window and put up a prompt */ | |
5eaef520 | 170 | werase(queryw); |
171 | mvwaddstr(queryw, 0, 0, prompt); | |
172 | waddch(queryw, ' '); /* Put in a space, as Blox does */ | |
173 | wrefresh(queryw); | |
989a2c2c | 174 | |
175 | i = 0; | |
5eaef520 | 176 | while ((c = getchar()) != '\r' && c != '\n') |
177 | { | |
178 | switch (c) | |
179 | { | |
180 | case '\025': /* Ctl-U */ | |
181 | goto retry; | |
182 | case EOF: | |
183 | /* We're in raw mode, so EOF means disaster */ | |
184 | exit(1); | |
185 | break; | |
186 | delchar: | |
187 | case '\177': /* Delete */ | |
188 | case '\010': /* Backspace */ | |
189 | if (i) | |
190 | { | |
191 | i--; | |
192 | if (echop) | |
193 | { | |
194 | int x, y; | |
195 | getyx(queryw, y, x); | |
196 | wmove(queryw, y, x - 1); | |
197 | wclrtoeol(queryw); | |
198 | wrefresh(queryw); | |
199 | } | |
200 | } | |
201 | break; | |
202 | case '\003': /* Ctrl-C */ | |
203 | clear(); | |
204 | restore_display(); | |
205 | exit(0); | |
206 | break; | |
207 | default: | |
208 | if (c >= ' ') /* Ignore all other control chars */ | |
209 | { | |
210 | buf[i++] = c; | |
211 | if (echop) | |
212 | { | |
213 | waddch(queryw, c); | |
214 | wrefresh(queryw); | |
215 | } | |
216 | } | |
217 | break; | |
989a2c2c | 218 | } |
5eaef520 | 219 | if (valuep && i >= maxsize) |
220 | { | |
221 | wfeep(); | |
222 | wprintw(displayw, "You are not allowed to type more than %d " | |
223 | "characters for this answer.\n", maxsize - 1); | |
224 | wrefresh(displayw); | |
225 | goto delchar; | |
989a2c2c | 226 | } |
989a2c2c | 227 | } |
989a2c2c | 228 | |
5eaef520 | 229 | if (i == 0) |
230 | { | |
4127ae1e | 231 | if (emptyok && valuep && |
232 | (askyn("Do you really want this field left blank (y/n)? ") == NO)) | |
233 | goto retry; | |
5eaef520 | 234 | if (!emptyok) |
235 | { | |
4127ae1e | 236 | wprintw(displayw, "You must enter something here.\n"); |
237 | wrefresh(displayw); | |
238 | goto retry; | |
5eaef520 | 239 | } |
240 | } | |
241 | ||
989a2c2c | 242 | |
243 | /* Input is complete so disable interval timer. */ | |
244 | it.it_interval.tv_sec = 0; | |
245 | it.it_interval.tv_usec = 0; | |
246 | it.it_value.tv_sec = 0; | |
247 | it.it_value.tv_usec = 0; | |
5eaef520 | 248 | setitimer(ITIMER_REAL, &it, NULL); |
989a2c2c | 249 | |
250 | buf[i] = '\0'; /* Put a null on the end */ | |
251 | ||
5eaef520 | 252 | werase(queryw); /* Clean up the query window */ |
253 | wrefresh(queryw); | |
989a2c2c | 254 | |
255 | return; /* And get out of here. */ | |
256 | } | |
257 | ||
5eaef520 | 258 | int askyn(char *prompt) |
989a2c2c | 259 | { |
260 | int ypos, xpos; | |
261 | int answer; | |
262 | struct itimerval it; | |
8b2d95d4 | 263 | int c; |
989a2c2c | 264 | |
5eaef520 | 265 | start: |
266 | werase(queryw); | |
267 | mvwaddstr(queryw, 0, 0, prompt); | |
268 | wrefresh(queryw); | |
989a2c2c | 269 | |
7ff930df | 270 | getyx(queryw, ypos, xpos); |
989a2c2c | 271 | answer = 2; /* No answer. */ |
5eaef520 | 272 | |
989a2c2c | 273 | /* Reset interval timer for y/n question. */ |
274 | it.it_interval.tv_sec = 0; | |
275 | it.it_interval.tv_usec = 0; | |
276 | it.it_value.tv_sec = YN_TIMEOUT; | |
277 | it.it_value.tv_usec = 0; | |
5eaef520 | 278 | setitimer(ITIMER_REAL, &it, NULL); |
279 | ||
280 | while ((c = getchar ()) != '\r' && c != '\n') /* Wait for CR. */ | |
281 | { | |
282 | switch (c) | |
283 | { | |
284 | case 'n': /* No. */ | |
285 | case 'N': | |
286 | wmove(queryw, ypos, xpos); | |
287 | wclrtoeol(queryw); | |
288 | waddstr(queryw, "no"); | |
289 | wrefresh(queryw); | |
290 | answer = NO; | |
291 | continue; | |
292 | case 'y': /* Yes. */ | |
293 | case 'Y': | |
294 | wmove(queryw, ypos, xpos); | |
295 | wclrtoeol(queryw); | |
296 | waddstr(queryw, "yes"); | |
297 | wrefresh(queryw); | |
298 | answer = YES; | |
299 | continue; | |
300 | case '\177': /* Delete */ | |
301 | case '\010': /* Backspace */ | |
302 | case '\025': /* Ctl-U */ | |
303 | wmove(queryw, ypos, xpos); | |
304 | wclrtoeol(queryw); | |
305 | wrefresh(queryw); | |
306 | answer = 2; /* No answer. */ | |
307 | break; | |
308 | case EOF: | |
309 | /* We're in raw mode, so EOF means disaster */ | |
310 | exit(1); | |
311 | break; | |
312 | case '\003': /* Ctrl-C */ | |
313 | clear(); | |
314 | restore_display(); | |
315 | exit(0); | |
316 | break; | |
317 | default: /* Ignore everything else. */ | |
318 | break; | |
319 | } | |
989a2c2c | 320 | } |
321 | ||
322 | if (answer == 2) /* No answer. */ | |
5eaef520 | 323 | { |
324 | display_text_line(0); | |
989a2c2c | 325 | display_text_line("Please answer y or n."); |
326 | goto start; | |
327 | } | |
5eaef520 | 328 | |
329 | return answer; | |
989a2c2c | 330 | } |
331 | ||
332 | /* Display_text_line puts up a line of text in the display window */ | |
333 | /* Special case: if line is 0, clear the display area */ | |
5eaef520 | 334 | display_text_line(char *line) |
989a2c2c | 335 | { |
5eaef520 | 336 | if (line) |
337 | { | |
338 | waddstr(displayw, line); | |
339 | waddch(displayw, '\n'); | |
340 | } | |
341 | else | |
342 | werase(displayw); | |
343 | wrefresh(displayw); | |
989a2c2c | 344 | } |
345 | ||
a2b4a2ee | 346 | /* Display_text displays a canned message from a file. The string |
347 | * will get imbedded in any %s's in the text. | |
348 | */ | |
5eaef520 | 349 | display_text(char *filename, char *string) |
989a2c2c | 350 | { |
351 | FILE * fp; | |
5eaef520 | 352 | char buf[100], buf1[110]; |
989a2c2c | 353 | |
5eaef520 | 354 | werase(displayw); |
355 | if (!(fp = fopen (filename, "r"))) | |
356 | { | |
357 | wprintw (displayw, "Can't open file %s for reading.\n", filename); | |
358 | return; | |
359 | } | |
989a2c2c | 360 | |
5eaef520 | 361 | while (fgets (buf, 100, fp)) |
362 | { | |
a2b4a2ee | 363 | /* get rid of the newline */ |
5eaef520 | 364 | buf[strlen(buf) - 1] = '\0'; |
a2b4a2ee | 365 | sprintf(buf1, buf, string); |
366 | waddstr(displayw, buf1); | |
367 | waddch(displayw, '\n'); | |
5eaef520 | 368 | } |
989a2c2c | 369 | |
a2b4a2ee | 370 | wrefresh(displayw); |
5eaef520 | 371 | fclose(fp); |
989a2c2c | 372 | } |
373 | ||
374 | /* Clear_display wipes the display and turns off curses */ | |
5eaef520 | 375 | restore_display(void) |
989a2c2c | 376 | { |
377 | clear(); | |
378 | refresh(); | |
379 | noraw(); | |
380 | echo(); | |
381 | endwin(); | |
382 | } | |
383 | ||
5eaef520 | 384 | timer_on(void) |
989a2c2c | 385 | { |
386 | struct itimerval it; | |
387 | ||
388 | it.it_interval.tv_sec = 0; | |
389 | it.it_interval.tv_usec = 0; | |
390 | it.it_value.tv_sec = TIMER_TIMEOUT; | |
391 | it.it_value.tv_usec = 0; | |
5eaef520 | 392 | setitimer(ITIMER_REAL, &it, NULL); |
989a2c2c | 393 | } |
394 | ||
5eaef520 | 395 | timer_off(void) |
989a2c2c | 396 | { |
397 | struct itimerval it; | |
398 | ||
399 | it.it_interval.tv_sec = 0; | |
400 | it.it_interval.tv_usec = 0; | |
401 | it.it_value.tv_sec = 0; | |
402 | it.it_value.tv_usec = 0; | |
5eaef520 | 403 | setitimer(ITIMER_REAL, &it, NULL); |
989a2c2c | 404 | } |
405 | ||
4127ae1e | 406 | |
5eaef520 | 407 | wfeep(void) |
4127ae1e | 408 | { |
5eaef520 | 409 | char buf = '\007'; |
410 | write(1, &buf, 1); | |
4127ae1e | 411 | } |