]> andersk Git - moira.git/blame - clients/mmoira/tty.c
*** empty log message ***
[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>
698271c7 11#include <string.h>
48a59f6d 12#include <sys/types.h>
13#include <sys/signal.h>
14#include <sgtty.h>
15#include <sys/ioctl.h>
16#include <ctype.h>
48a59f6d 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
698271c7 48#ifndef POSIX
48a59f6d 49 ioctl(0, TIOCFLUSH, &arg);
698271c7 50#endif
df52b790 51 ioctl(0, TIOCGETP, &otty);
52 ntty = otty;
48a59f6d 53 ntty.sg_flags |= RAW;
54 ntty.sg_flags &= ~ECHO;
df52b790 55 raw_mode();
48a59f6d 56
57 while (1) {
df52b790 58 parser(prompt, TtyRoot);
48a59f6d 59 }
48a59f6d 60}
61
df52b790 62cooked_mode()
48a59f6d 63{
df52b790 64 ioctl(0, TIOCSETP, &otty);
48a59f6d 65}
66
df52b790 67raw_mode()
48a59f6d 68{
df52b790 69 ioctl(0, TIOCSETP, &ntty);
48a59f6d 70}
71
48a59f6d 72static NumWords(s)
73char *s;
74{
75 int ret;
76
77 for (ret = 1; *s; s++)
78 if (*s == ' ') ret++;
79 return(ret);
80}
81
82
df52b790 83parse_menus()
48a59f6d 84{
85 int arg;
df52b790 86 struct parse_node *p;
48a59f6d 87
df52b790 88 TtyCommands = (struct parse_node *)malloc(sizeof(struct parse_node) *
89 NumMenus * 3);
698271c7 90 memset(TtyCommands, 0, sizeof(struct parse_node) * NumMenus * 3);
48a59f6d 91 arg = 0;
92 parse_menu_recursive(&MenuRoot, "", &arg);
df52b790 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++;
48a59f6d 101}
102
103
df52b790 104parse_menu_recursive(m, parent, i)
48a59f6d 105MenuItem *m;
106char *parent;
107int *i;
108{
df52b790 109 char buf[64], cmd[64], *word, *s;
48a59f6d 110 struct parse_node *p, **prev;
df52b790 111 int j, len;
48a59f6d 112
113 if (m->submenu == NULL) {
114 if (!strcmp(parent, "file") ||
115 !strcmp(parent, "misc"))
116 parent = "";
df52b790 117 if (NumWords(m->label) > 2 || !*parent)
48a59f6d 118 strcpy(cmd, m->label);
119 else
120 sprintf(cmd, "%s %s", m->label, parent);
121 /* insert command into parse tree */
df52b790 122 p = TtyRoot;
123 prev = (struct parse_node **) &TtyRoot;
698271c7 124 for (word = cmd; word; word = strchr(word, ' ')) {
df52b790 125 if (*word == ' ')
126 word++;
698271c7 127 s = strchr(word, ' ');
48a59f6d 128 if (s)
129 len = s - word;
130 else
131 len = strlen(word);
df52b790 132 for (;;) {
133 if (!p || !p->p_word ||
134 (j = strncmp(p->p_word, word, len)) > 0) {
48a59f6d 135 strcpy(buf, word);
136 buf[len] = 0;
df52b790 137#ifdef DEBUG
138 printf("word: %s\n", buf);
139#endif
48a59f6d 140 TtyCommands[*i].p_word = strsave(buf);
df52b790 141 if (len == strlen(word))
142 TtyCommands[*i].p_menu = m;
48a59f6d 143 TtyCommands[*i].p_peer = p;
144 if (prev)
df52b790 145 *prev = &TtyCommands[*i];
48a59f6d 146 TtyCommands[*i].p_next = (struct parse_node *) NULL;
147 TtyCommands[*i].p_link = (struct parse_node *) NULL;
df52b790 148 prev = &(TtyCommands[*i].p_next);
149 p = (struct parse_node *) NULL;
150 *i = *i + 1;
48a59f6d 151 break;
152 } else if (j == 0) {
153 prev = &(p->p_next);
154 if (p->p_next)
df52b790 155 p = p->p_next;
48a59f6d 156 else
157 p = (struct parse_node *) NULL;
158 break;
159 } else {
160 prev = &(p->p_peer);
df52b790 161 p = p->p_peer;
48a59f6d 162 }
163 }
164 }
48a59f6d 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
180TtyForm(f)
181EntryForm *f;
182{
df52b790 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;
1b6c52dc 227 printf("%s(T/F) [%c]: ", p->prompt, boolval(f, i) ? 'T' : 'F');
df52b790 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;
1b6c52dc 237 else if (buf[0] != 0) {
df52b790 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:
698271c7 258 k = strchr(p->prompt, '|');
df52b790 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
291int mgets(line, linelen)
292char *line;
293int 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
375print_parse_tree(n, l)
376struct parse_node *n;
377int 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));
48a59f6d 387}
This page took 0.106187 seconds and 5 git commands to generate.