]> andersk Git - moira.git/blob - clients/mmoira/tty.c
added access_host() and access_ahal()
[moira.git] / clients / mmoira / tty.c
1 /* $Header$
2  *
3  *      Copyright 1992 by the Massachusetts Institute of Technology.
4  *
5  *      For further information on copyright and distribution 
6  *      see the file mit-copyright.h
7  */
8
9 #include        <mit-copyright.h>
10 #include        <stdio.h>
11 #include        <string.h>
12 #include        <sys/types.h>
13 #include        <sys/signal.h>
14 #include        <sgtty.h>
15 #include        <sys/ioctl.h>
16 #include        <ctype.h>
17 #include        <X11/Intrinsic.h>
18 #include        <moira.h>
19 #include        "mmoira.h"
20 #include        "parser.h"
21
22 static char rcsid[] = "$Header$";
23
24
25 struct parse_node *TtyCommands = NULL, *TtyRoot = NULL;
26
27 extern int NumMenus;
28 extern MenuItem MenuRoot;
29 char prompt[] = "moira> ";
30
31 static struct sgttyb otty, ntty;
32
33
34 TtyMainLoop()
35 {
36     char buf[1024], cbuf[2], c, *p;
37     int arg, i, done;
38
39     if (TtyCommands == NULL)
40       parse_menus();
41
42 #ifdef DEBUG
43     print_parse_tree(TtyRoot, 0);
44     fflush(stdout);
45     sleep(10);
46 #endif /* DEBUG */
47
48 #ifndef POSIX
49     ioctl(0, TIOCFLUSH, &arg);
50 #endif
51     ioctl(0, TIOCGETP, &otty);
52     ntty = otty;
53     ntty.sg_flags |= RAW;
54     ntty.sg_flags &= ~ECHO;
55     raw_mode();
56
57     while (1) {
58         parser(prompt, TtyRoot);
59     }
60 }
61
62 cooked_mode()
63 {
64     ioctl(0, TIOCSETP, &otty);
65 }
66
67 raw_mode()
68 {
69     ioctl(0, TIOCSETP, &ntty);
70 }
71
72 static NumWords(s)
73 char *s;
74 {
75     int ret;
76
77     for (ret = 1; *s; s++)
78       if (*s == ' ') ret++;
79     return(ret);
80 }
81
82
83 parse_menus()
84 {
85     int arg;
86     struct parse_node *p;
87
88     TtyCommands = (struct parse_node *)malloc(sizeof(struct parse_node) *
89                                               NumMenus * 3);
90     memset(TtyCommands, 0, sizeof(struct parse_node) * NumMenus * 3);
91     arg = 0;
92     parse_menu_recursive(&MenuRoot, "", &arg);
93     TtyCommands[arg].p_word = "help";
94     TtyCommands[arg].p_next = TtyRoot;
95     for (p = TtyRoot; p; p = p->p_peer)
96       if (strcmp(p->p_peer->p_word, "help") > 0)
97         break;
98     TtyCommands[arg].p_peer = p->p_peer->p_peer;
99     p->p_peer = &TtyCommands[arg];
100     arg++;
101 }
102
103
104 parse_menu_recursive(m, parent, i)
105 MenuItem *m;
106 char *parent;
107 int *i;
108 {
109     char buf[64], cmd[64], *word, *s;
110     struct parse_node *p, **prev;
111     int j, len;
112
113     if (m->submenu == NULL) {
114         if (!strcmp(parent, "file") ||
115             !strcmp(parent, "misc"))
116           parent = "";
117         if (NumWords(m->label) > 2 || !*parent)
118           strcpy(cmd, m->label);
119         else
120           sprintf(cmd, "%s %s", m->label, parent);
121         /* insert command into parse tree */
122         p = TtyRoot;
123         prev = (struct parse_node **) &TtyRoot;
124         for (word = cmd; word; word = strchr(word, ' ')) {
125             if (*word == ' ')
126               word++;
127             s = strchr(word, ' ');
128             if (s)
129               len = s - word;
130             else
131               len = strlen(word);
132             for (;;) {
133                 if (!p || !p->p_word ||
134                     (j = strncmp(p->p_word, word, len)) > 0) {
135                     strcpy(buf, word);
136                     buf[len] = 0;
137 #ifdef DEBUG
138                     printf("word: %s\n", buf);
139 #endif
140                     TtyCommands[*i].p_word = strsave(buf);
141                     if (len == strlen(word))
142                       TtyCommands[*i].p_menu = m;
143                     TtyCommands[*i].p_peer = p;
144                     if (prev)
145                       *prev = &TtyCommands[*i];
146                     TtyCommands[*i].p_next = (struct parse_node *) NULL;
147                     TtyCommands[*i].p_link = (struct parse_node *) NULL;
148                     prev = &(TtyCommands[*i].p_next);
149                     p = (struct parse_node *) NULL;
150                     *i = *i + 1;
151                     break;
152                 } else if (j == 0) {
153                     prev = &(p->p_next);
154                     if (p->p_next)
155                       p = p->p_next;
156                     else
157                       p = (struct parse_node *) NULL;
158                     break;
159                 } else {
160                     prev = &(p->p_peer);
161                     p = p->p_peer;
162                 }
163             }
164         }
165         return;
166     }
167     if (!strcmp(m->label, "?help")) return;
168     for (j = 0; m->submenu[j]; j++) {
169         if (m == &MenuRoot)
170           buf[0] = 0;
171         else if (strlen(parent))
172           sprintf(buf, "%s %s", parent, m->label);
173         else
174           strcpy(buf, m->label);
175         parse_menu_recursive(m->submenu[j], buf, i);
176     }
177 }
178
179
180 TtyForm(f)
181 EntryForm *f;
182 {
183     int i, j, done, best, choice;
184     char buf[512], *k;
185     UserPrompt *p;
186
187     printf("%s\r\n", f->instructions);
188     choice = 0;
189     for (i = 0, p = f->inputlines[i]; p = f->inputlines[i]; i++)
190       if (p->choice) {
191           choice = 1;
192           break;
193       }
194     if (choice) {
195         j = 0;
196         *buf = 0;
197         for (i = 0, p = f->inputlines[i]; p = f->inputlines[i]; i++) {
198             if (p->choice) {
199                 printf("  %s\r\n", buf);
200                 sprintf(buf, "%d: %s", ++j, p->prompt);
201             } else if (*buf == 0) {
202                 sprintf(buf, "%d: %s", ++j, p->prompt);
203             } else {
204                 strcat(buf, "/");
205                 strcat(buf, p->prompt);
206             }
207             if (buf[strlen(buf)-1] == ' ') buf[strlen(buf)-1] = 0;
208         }
209         printf("  %s\r\nSelect by [1]: ", buf);
210         if (mgets(buf, sizeof(buf)))
211           return;
212         if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
213         if (strlen(buf) == 0)
214           choice = 1;
215         else
216           choice = atoi(buf);
217     } else choice = -1;
218     for (i = 0, p = f->inputlines[i]; p = f->inputlines[i]; i++) {
219         if (choice > 0 && p->choice) choice--;
220         if (choice != -1 && choice != 1) continue;
221         if (p->insensitive == True) continue;
222         switch (p->type) {
223         case FT_BOOLEAN:
224             done = 0;
225             while (!done) {
226                 done = 1;
227                 printf("%s(T/F) [%c]: ", p->prompt, boolval(f, i) ? 'T' : 'F');
228                 fflush(stdout);
229                 if (mgets(buf, sizeof(buf)))
230                   return;
231                 if (buf[0] == 'T' || buf[0] == 't' ||
232                     buf[0] == 'Y' || buf[0] == 'y')
233                   p->returnvalue.booleanvalue = True;
234                 else if (buf[0] == 'F' || buf[0] == 'f' ||
235                          buf[0] == 'N' || buf[0] == 'n')
236                   p->returnvalue.booleanvalue = False;
237                 else if (buf[0] != 0) {
238                     done = 0;
239                     printf("Please answer True or False\r\n");
240                 }
241             }
242             break;
243         case FT_STRING:
244             if (*StringValue(f, i))
245               printf("%s[%s]: ", p->prompt, StringValue(f, i));
246             else
247               printf("%s: ", p->prompt);
248             fflush(stdout);
249             if (mgets(buf, sizeof(buf)))
250               return;
251             if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
252             if (strlen(buf) != 0)
253               StoreField(f, i, buf);
254             if (!strcmp(buf, "\"\""))
255               StoreField(f, i, "");
256             break;
257         case FT_KEYWORD:
258             k = strchr(p->prompt, '|');
259             if (k) *k = 0;
260             done = 0;
261             while (done != 1) {
262                 if (*StringValue(f, i))
263                   printf("%s[%s]: ", p->prompt, StringValue(f, i));
264                 else
265                   printf("%s: ", p->prompt);
266                 fflush(stdout);
267                 if (mgets(buf, sizeof(buf)))
268                   return;
269                 if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
270                 if (strlen(buf) == 0)
271                   strcpy(buf, StringValue(f, i));
272                 done = 0;
273                 for (j = 0; p->keywords[j]; j++)
274                   if (!strncasecmp(p->keywords[j], buf, strlen(buf)))
275                     done++, best = j;
276                 if (done != 1) {
277                     printf("You must enter one of these keywords:\r\n");
278                     for (j = 0; p->keywords[j]; j++) {
279                         printf("  %s\r\n", p->keywords[j]);
280                     }
281                 } else
282                   StoreField(f, i, p->keywords[best]);
283             }
284             break;
285         }
286     }
287     process_form(f, TRUE);
288 }
289
290
291 int mgets(line, linelen)
292 char *line;
293 int linelen;
294 {
295     char c, *p;
296
297     raw_mode();
298     p = &line[0];
299     *p = 0;
300     for (c = (getchar() & 0x7f); 1; c = (getchar() & 0x7f)) {
301         if (c == 0) continue;
302         switch (c) {
303         case 127:
304         case '\b':
305             if (p == &line[0]) {
306                 putchar(7);
307                 break;
308             }
309             *(--p) = 0;
310             write(1, "\b \b", 3);
311             break;
312         case 'C' - '@':
313         case 'G' - '@':
314             cooked_mode();
315             return(-1);
316         case 'Q' - '@':
317         case 'V' - '@':
318             putchar('\\');
319             c = getchar();
320             if (c < ' ')
321               printf("\b^%c", c + '@');
322             else
323               printf("\b%c", c);
324             fflush(stdout);
325             *p++ = c;
326             break;
327         case 'W' - '@':
328             if (p > &line[0])
329               p--;
330             while ((p >= &line[0]) && isspace(*p)) {
331                 write(1, "\b \b", 3);
332                 p--;
333             }
334             while ((p >= &line[0]) && !isspace(*p)) {
335                 write(1, "\b \b", 3);
336                 p--;
337             }
338             if (p > &line[0]) {
339                 p++;
340             } else {
341                 p = &line[0];
342             }
343             *p = 0;
344             break;
345         case 'Z' - '@':
346             printf("\r\n");
347             kill(getpid(), SIGSTOP);
348             /* when continued, fall through to */
349         case 'R' - '@':
350             *p = 0;
351             printf("\r\n%s", line);
352             fflush(stdout);
353             break;
354         case 'U' - '@':
355             while (p-- > &line[0])
356               write(1, "\b \b", 3);
357             *(++p) = 0;
358             fflush(stdout);
359             break;
360         case '\n':
361         case '\r':
362             write(1, "\r\n", 2);
363             cooked_mode();
364             return(0);
365             break;
366         default:
367             putchar(c);
368             *p++ = c;
369             *p = 0;
370         }
371     }
372 }
373
374
375 print_parse_tree(n, l)
376 struct parse_node *n;
377 int l;
378 {
379     int i;
380
381     for (i = l; i > 0; i--) putchar(' ');
382     printf("%s%c\n", n->p_word, n->p_menu ? '*' : ' ');
383     if (n->p_next)
384       print_parse_tree(n->p_next, l+1);
385     if (n->p_peer)
386       return(print_parse_tree(n->p_peer, l));
387 }
This page took 0.196098 seconds and 5 git commands to generate.