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