3 * Copyright 1992 by the Massachusetts Institute of Technology.
5 * For further information on copyright and distribution
6 * see the file mit-copyright.h
9 #include <mit-copyright.h>
12 #include <sys/types.h>
13 #include <sys/signal.h>
15 #include <sys/ioctl.h>
17 #include <X11/Intrinsic.h>
22 static char rcsid[] = "$Header$";
25 struct parse_node *TtyCommands = NULL, *TtyRoot = NULL;
28 extern MenuItem MenuRoot;
29 char prompt[] = "moira> ";
31 static struct sgttyb otty, ntty;
36 char buf[1024], cbuf[2], c, *p;
39 if (TtyCommands == NULL)
43 print_parse_tree(TtyRoot, 0);
49 ioctl(0, TIOCFLUSH, &arg);
51 ioctl(0, TIOCGETP, &otty);
54 ntty.sg_flags &= ~ECHO;
58 parser(prompt, TtyRoot);
64 ioctl(0, TIOCSETP, &otty);
69 ioctl(0, TIOCSETP, &ntty);
77 for (ret = 1; *s; s++)
88 TtyCommands = (struct parse_node *)malloc(sizeof(struct parse_node) *
90 memset(TtyCommands, 0, sizeof(struct parse_node) * NumMenus * 3);
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)
98 TtyCommands[arg].p_peer = p->p_peer->p_peer;
99 p->p_peer = &TtyCommands[arg];
104 parse_menu_recursive(m, parent, i)
109 char buf[64], cmd[64], *word, *s;
110 struct parse_node *p, **prev;
113 if (m->submenu == NULL) {
114 if (!strcmp(parent, "file") ||
115 !strcmp(parent, "misc"))
117 if (NumWords(m->label) > 2 || !*parent)
118 strcpy(cmd, m->label);
120 sprintf(cmd, "%s %s", m->label, parent);
121 /* insert command into parse tree */
123 prev = (struct parse_node **) &TtyRoot;
124 for (word = cmd; word; word = strchr(word, ' ')) {
127 s = strchr(word, ' ');
133 if (!p || !p->p_word ||
134 (j = strncmp(p->p_word, word, len)) > 0) {
138 printf("word: %s\n", buf);
140 TtyCommands[*i].p_word = strsave(buf);
141 if (len == strlen(word))
142 TtyCommands[*i].p_menu = m;
143 TtyCommands[*i].p_peer = p;
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;
157 p = (struct parse_node *) NULL;
167 if (!strcmp(m->label, "?help")) return;
168 for (j = 0; m->submenu[j]; j++) {
171 else if (strlen(parent))
172 sprintf(buf, "%s %s", parent, m->label);
174 strcpy(buf, m->label);
175 parse_menu_recursive(m->submenu[j], buf, i);
183 int i, j, done, best, choice;
187 printf("%s\r\n", f->instructions);
189 for (i = 0, p = f->inputlines[i]; p = f->inputlines[i]; i++)
197 for (i = 0, p = f->inputlines[i]; p = f->inputlines[i]; i++) {
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);
205 strcat(buf, p->prompt);
207 if (buf[strlen(buf)-1] == ' ') buf[strlen(buf)-1] = 0;
209 printf(" %s\r\nSelect by [1]: ", buf);
210 if (mgets(buf, sizeof(buf)))
212 if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
213 if (strlen(buf) == 0)
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;
227 printf("%s(T/F) [%c]: ", p->prompt, boolval(f, i) ? 'T' : 'F');
229 if (mgets(buf, sizeof(buf)))
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) {
239 printf("Please answer True or False\r\n");
244 if (*StringValue(f, i))
245 printf("%s[%s]: ", p->prompt, StringValue(f, i));
247 printf("%s: ", p->prompt);
249 if (mgets(buf, sizeof(buf)))
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, "");
258 k = strchr(p->prompt, '|');
262 if (*StringValue(f, i))
263 printf("%s[%s]: ", p->prompt, StringValue(f, i));
265 printf("%s: ", p->prompt);
267 if (mgets(buf, sizeof(buf)))
269 if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
270 if (strlen(buf) == 0)
271 strcpy(buf, StringValue(f, i));
273 for (j = 0; p->keywords[j]; j++)
274 if (!strncasecmp(p->keywords[j], buf, strlen(buf)))
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]);
282 StoreField(f, i, p->keywords[best]);
287 process_form(f, TRUE);
291 int mgets(line, linelen)
300 for (c = (getchar() & 0x7f); 1; c = (getchar() & 0x7f)) {
301 if (c == 0) continue;
310 write(1, "\b \b", 3);
321 printf("\b^%c", c + '@');
330 while ((p >= &line[0]) && isspace(*p)) {
331 write(1, "\b \b", 3);
334 while ((p >= &line[0]) && !isspace(*p)) {
335 write(1, "\b \b", 3);
347 kill(getpid(), SIGSTOP);
348 /* when continued, fall through to */
351 printf("\r\n%s", line);
355 while (p-- > &line[0])
356 write(1, "\b \b", 3);
375 print_parse_tree(n, l)
376 struct parse_node *n;
381 for (i = l; i > 0; i--) putchar(' ');
382 printf("%s%c\n", n->p_word, n->p_menu ? '*' : ' ');
384 print_parse_tree(n->p_next, l+1);
386 return(print_parse_tree(n->p_peer, l));