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