]> andersk Git - moira.git/blob - clients/userreg/display.c
Initial revision
[moira.git] / clients / userreg / display.c
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Locker$
5  *      $Header$
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>.
10  */
11
12 #ifndef lint
13 static char *rcsid_display_c = "$Header$";
14 #endif  lint
15
16 #include <mit-copyright.h>
17 #include <stdio.h>
18 #include <curses.h>
19 #include <sys/time.h>
20 #include "userreg.h"
21
22 #define DESC_WIDTH 18
23 #define HEADER "*** Project Athena User Registration ***"
24 #ifdef ibm032
25 #define HELP   " Press backspace to delete a character.  Press Ctrl-C to start over."
26 #else
27 #ifdef vax
28 #define HELP   " Press the key marked <X| to delete a character.  Press Ctrl-C to start over."
29 #endif
30 #endif
31 #define BORDER_CHAR '-'
32 #define MIN_COLS 80
33 #define MIN_LINES 24
34
35 WINDOW * displayw, *queryw;
36 WINDOW * dataw, *helpw;
37 WINDOW * fnamew, *midw, *lnamew, *idw, *loginw;
38
39 /* Set up the windows and subwindows on the display */
40 setup_display () {
41   FILE * freopen ();
42
43   initscr ();                   /* Start up curses */
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
50   noecho ();                    /* And the tty input */
51   raw ();
52   freopen ("/dev/null", "w", stderr);/* Toss the standard error output */
53
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");
91   waddstr (dataw, "Family Name:\n");
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);
120   mvwprintw (midw, 0, 0, "%-24s", user.u_mid_init);
121   mvwprintw (lnamew, 0, 0, "%-24s", user.u_last);
122   mvwprintw (idw, 0, 0, "%-24s", typed_mit_id);
123   mvwprintw (loginw, 0, 0, "%-24s", user.u_login);
124
125   wrefresh (dataw);
126 }
127
128
129 /* Input and input_no_echo exist only to save on retyping */
130 input (prompt, buf, maxsize, timeout, emptyok)
131 char *prompt;
132 char *buf;
133 int   maxsize, timeout, emptyok;
134 {
135   query_user (prompt, buf, maxsize, timeout, TRUE, emptyok, TRUE);
136 }
137
138 input_no_echo (prompt, buf, maxsize, timeout)
139 char *prompt;
140 char *buf;
141 int   maxsize, timeout;
142 {
143   query_user (prompt, buf, maxsize, timeout, FALSE, FALSE, TRUE);
144 }
145
146
147 /* make the user press any key to continue */
148 wait_for_user ()
149 {
150     char buf[BUFSIZ];
151
152     redisp();
153     query_user ("Press RETURN or ENTER to continue", buf, 1,
154                 15 * 60, FALSE, TRUE, FALSE);
155 }
156
157
158 /* Gets input through the query buffer */
159 /* Exit(1)'s on read errors */
160 /* Signals SIGALRM after 'timeout' seconds */
161 query_user (prompt, buf, maxsize, timeout, echop, emptyok, valuep)
162 char *prompt;
163 char *buf;
164 int   maxsize, timeout;
165 bool echop, emptyok, valuep;
166 {
167   char  c;
168   int   i;
169   struct itimerval it;
170
171 retry:
172   /* Set up interval timer */
173   it.it_interval.tv_sec = 0;
174   it.it_interval.tv_usec = 0;
175   it.it_value.tv_sec = timeout;
176   it.it_value.tv_usec = 0;
177   setitimer (ITIMER_REAL, &it, (struct itimerval *) 0);
178
179   /* Erase the query window and put up a prompt */
180   werase (queryw);
181   mvwaddstr (queryw, 0, 0, prompt);
182   waddch (queryw, ' ');         /* Put in a space, as Blox does */
183   wrefresh (queryw);
184
185   i = 0;
186   while ((c = getchar ()) != '\r') {
187    switch (c) {
188      case '\025':               /* Ctl-U */
189         goto retry;
190         break;
191       case EOF:
192         /* We're in raw mode, so EOF means disaster */
193         exit(1);
194         break;
195       case '\177':              /* Delete */
196       case '\010':              /* Backspace */
197         if (i) {
198           i--;
199           if (echop) {
200             wmove (queryw, queryw -> _cury, queryw -> _curx - 1);
201             wclrtoeol (queryw);
202             wrefresh (queryw);
203           }
204         }
205         break;
206       case '\003':              /* Ctrl-C */
207         if (getuid() != 0) 
208           { clear();            /* Exit if not root. */
209             restore_display();
210             exit(0);
211           }
212         else
213           restart();  
214         break;
215       default: 
216         if (c >= ' ') {         /* Ignore all other control chars */
217           buf[i++] = c;
218           if (echop) {
219             waddch (queryw, c);
220             wrefresh (queryw);
221           }
222         }
223         break;
224     }
225     if (valuep && i >= maxsize) {
226       wprintw (displayw,
227   "You are not allowed to type more than %d characters for this answer.\n",
228           maxsize);
229       wrefresh (displayw);
230       goto retry;
231     }
232  }
233
234   if (i == 0) {
235       if (emptyok && valuep &&
236           (askyn("Do you really want this field left blank (y/n)? ") == NO))
237         goto retry;
238       if (!emptyok) {
239           wprintw(displayw, "You must enter something here.\n");
240           wrefresh(displayw);
241           goto retry;
242       }
243   }
244     
245
246   /* Input is complete so disable interval timer. */
247   it.it_interval.tv_sec = 0;
248   it.it_interval.tv_usec = 0;
249   it.it_value.tv_sec = 0;
250   it.it_value.tv_usec = 0;
251   setitimer (ITIMER_REAL, &it, (struct itimerval *) 0);
252
253   buf[i] = '\0';                /* Put a null on the end */
254
255   werase (queryw);              /* Clean up the query window */
256   wrefresh (queryw);
257
258   return;                       /* And get out of here. */
259 }
260
261 int
262 askyn(prompt)
263      char *prompt;
264 {
265   int ypos, xpos;
266   int answer;
267   struct itimerval it;
268   char c;
269
270  start:
271   werase (queryw);
272   mvwaddstr (queryw, 0, 0, prompt);
273   wrefresh (queryw);
274
275   xpos = queryw->_curx;
276   ypos = queryw->_cury;
277   answer = 2;                   /* No answer. */
278   
279   /* Reset interval timer for y/n question. */
280   it.it_interval.tv_sec = 0;
281   it.it_interval.tv_usec = 0;
282   it.it_value.tv_sec = YN_TIMEOUT;
283   it.it_value.tv_usec = 0;
284   setitimer (ITIMER_REAL, &it, (struct itimerval *) 0);
285     
286   while ((c = getchar ()) != '\r') {    /* Wait for CR. */
287       switch (c) {
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 /*      if (getuid() != 0) */
318           { clear();            /* Exit if not root. */
319             restore_display();
320             exit(0);
321           }
322         break;
323       default:                  /* Ignore everything else. */
324         break;
325       }
326     }
327
328   if (answer == 2)              /* No answer. */
329     { display_text_line(0);
330       display_text_line("Please answer y or n.");
331       goto start;
332     }
333   
334   return(answer);
335 }
336
337 /* Display_text_line puts up a line of text in the display window */
338 /* Special case: if line is 0, clear the display area */
339 display_text_line (line)
340 char *line;
341 {
342   if (line) {
343     waddstr (displayw, line);
344     waddch (displayw, '\n');
345     wrefresh (displayw);
346   }
347   else {
348     werase (displayw);
349   }
350   wrefresh (displayw);
351 }
352
353 /* Display_text displays a canned message from a file */
354 display_text (filename)
355 char *filename;
356 {
357   FILE * fp;
358   char  buf[100];
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)) {
367   /* get rid of the newline */
368     buf[strlen (buf) - 1] = 0;
369     display_text_line (buf);
370   }
371
372   fclose (fp);
373 }
374
375 /* Clear_display wipes the display and turns off curses */
376 restore_display()
377 {
378   clear();
379   refresh();
380   noraw();
381   echo();
382   endwin();
383 }
384
385 timer_on()
386 {
387   struct itimerval it;
388
389   it.it_interval.tv_sec = 0;
390   it.it_interval.tv_usec = 0;
391   it.it_value.tv_sec = TIMER_TIMEOUT;
392   it.it_value.tv_usec = 0;
393   setitimer (ITIMER_REAL, &it, (struct itimerval *) 0);
394 }
395
396 timer_off()
397 {
398   struct itimerval it;
399
400   it.it_interval.tv_sec = 0;
401   it.it_interval.tv_usec = 0;
402   it.it_value.tv_sec = 0;
403   it.it_value.tv_usec = 0;
404   setitimer (ITIMER_REAL, &it, (struct itimerval *) 0);
405 }
406
407
408 wfeep()
409 {
410     char buf = '\007';
411     write(1, &buf, 1);
412 }
This page took 0.069615 seconds and 5 git commands to generate.