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