]> andersk Git - moira.git/blame - clients/moira/menu.c
Added #define statments that only allows this to be included once per
[moira.git] / clients / moira / menu.c
CommitLineData
07c56447 1/*
2aaf83c2 2 * Copyright 1987 by the Massachusetts Institute of Technology.
3 * For copying and distribution information, see the file
4 * "mit-copyright.h".
5 *
6 * $Source$
7 * $Author$
8 * $Header$
2aaf83c2 9 *
07c56447 10 * Generic menu system module.
11 *
12 * Basically, we define an enormous tree structure which represents the
13 * menu. Some extra pieces (ml_command, ma_doc) get thrown in so we can
14 * also use the structure for a command-based system.
15 *
16 * By making the menu descriptions so general, we can ease porting to just
17 * about anything.
18 */
19
2aaf83c2 20#ifndef lint
21static char rcsid_menu_c[] = "$Header$";
e9db439c 22
2aaf83c2 23#endif lint
24
34f47457 25#include <sys/types.h>
07c56447 26#include <stdio.h>
967b7c08 27#include <signal.h>
07c56447 28#include <curses.h>
2aaf83c2 29#include <ctype.h>
34f47457 30#include <strings.h>
93b28238 31#include <varargs.h>
6298c97d 32#include <com_err.h>
07c56447 33#include "menu.h"
34
967b7c08 35#define MAX(A,B) ((A) > (B) ? (A) : (B))
36#define MIN(A,B) ((A) < (B) ? (A) : (B))
37#define CTL(ch) ((ch) & 037)
07c56447 38
39#define MIN_INPUT 2 /* Minimum number of lines for input window */
40
859891c0 41extern FILE *fdopen();
42extern int getpid();
34f47457 43extern char *calloc();
859891c0 44extern char *whoami;
45
46FILE *log_file = (FILE *) NULL; /* file stream of log file */
e9db439c 47int more_flg = 1;
2aaf83c2 48
07c56447 49/* Structure for holding current displayed menu */
50struct menu_screen {
51 WINDOW *ms_screen; /* Window for this menu */
52 WINDOW *ms_title; /* Title subwindow */
53 WINDOW *ms_menu; /* Menu subwindow */
54 WINDOW *ms_input; /* Input subwindow */
55 int ms_input_y; /* Input subwindow reference coordinate */
e9db439c 56} *cur_ms;
07c56447 57
2aaf83c2 58#define NULLMS ((struct menu_screen *) 0)
59
60Menu *top_menu; /* Root for command search */
61
6298c97d 62/*
63 * Hook function to cause error messages to be printed through
64 * curses instead of around it.
65 */
66
67int
68menu_com_err_hook(who, code, fmt, args)
69 char *who;
70 int code;
71 char *fmt;
72 va_list args;
73{
74 char buf[BUFSIZ], *cp;
75
76 FILE _strbuf;
77
78 (void) strcpy(buf, who);
79 for (cp = buf; *cp; cp++);
80 *cp++ = ':';
81 *cp++ = ' ';
82 if (code) {
83 (void) strcpy(cp, error_message(code));
84 while (*cp)
85 cp++;
86 }
87 _strbuf._flag = _IOWRT + _IOSTRG;
88 _strbuf._ptr = cp;
89 _strbuf._cnt = BUFSIZ - (cp - buf);
90 _doprnt(fmt, args, &_strbuf);
91 (void) putc('\0', &_strbuf);
92 Put_message(buf);
93}
94
07c56447 95/*
96 * Start_menu takes a menu as an argument. It initializes curses u.s.w.,
97 * and a quit in any submenu should unwind back to here. (it might not,
98 * if user functions which run their own menus don't cooperate.)
99 * Start_menu should only be called once, at the start of the program.
100 */
101Start_menu(m)
e9db439c 102 Menu *m;
07c56447 103{
2aaf83c2 104 struct menu_screen *make_ms();
6298c97d 105 register int (*old_hook)() = set_com_err_hook(menu_com_err_hook);
106
e9db439c 107 if (initscr() == ERR) {
07c56447 108 fputs("Can't initialize curses!\n", stderr);
2aaf83c2 109 Start_no_menu(m);
6298c97d 110 } else {
111 (void) raw(); /* We parse & print everything ourselves */
112 (void) noecho();
113 cur_ms = make_ms(0); /* So we always have some current */
114 /* menu_screen */
115 top_menu = m;
116 /* Run the menu */
117 (void) Do_menu(m, -1, (char **) NULL);
07c56447 118 }
6298c97d 119 (void) set_com_err_hook(old_hook);
967b7c08 120 Cleanup_menu();
121}
122
123Cleanup_menu()
124{
125 if (cur_ms) {
34f47457 126 (void) wclear(cur_ms->ms_screen);
127 (void) wrefresh(cur_ms->ms_screen);
967b7c08 128 }
07c56447 129 endwin();
130}
967b7c08 131
07c56447 132
2aaf83c2 133/* Like Start_menu, except it doesn't print menus and doesn't use curses */
134Start_no_menu(m)
e9db439c 135 Menu *m;
2aaf83c2 136{
137 cur_ms = NULLMS;
33a56ee9 138 COLS = 80;
2aaf83c2 139 top_menu = m;
74e7b641 140 /* Run the menu */
967b7c08 141 (void) Do_menu(m, -1, (char **) NULL);
2aaf83c2 142}
143
07c56447 144/*
145 * Create a new menu screen template with the specified menu length
146 * and return it.
147 */
e9db439c 148struct menu_screen *
149make_ms(length)
150 int length;
07c56447 151{
152 struct menu_screen *ms;
153 char *malloc();
154
e9db439c 155 if (MAX_TITLE + length + MIN_INPUT > LINES) {
07c56447 156 fputs("Menu too big!\n", stderr);
157 exit(2);
158 }
159
160 ms = (struct menu_screen *) malloc(sizeof(struct menu_screen));
161
162 ms->ms_screen = newwin(0, 0, 0, 0);
163 ms->ms_title = subwin(ms->ms_screen, MAX_TITLE, 0, 0, 0);
164 ms->ms_menu = subwin(ms->ms_screen,
165 length, 0, MAX_TITLE, 0);
166 ms->ms_input = subwin(ms->ms_screen, 0, 0,
167 ms->ms_input_y = MAX_TITLE + length,
168 0);
169
170 scrollok(ms->ms_input, TRUE);
2aaf83c2 171 (void) wmove(ms->ms_input, 0, 0);
172 (void) wclear(ms->ms_screen);
07c56447 173
e9db439c 174 return (ms);
07c56447 175}
176
177/*
178 * This routine destroys a menu_screen.
179 */
180destroy_ms(ms)
e9db439c 181 struct menu_screen *ms;
07c56447 182{
183 delwin(ms->ms_title);
184 delwin(ms->ms_menu);
185 delwin(ms->ms_input);
186 delwin(ms->ms_screen);
e9db439c 187 free((char *) ms);
07c56447 188}
189
190/*
191 * This guy actually puts up the menu
967b7c08 192 * Note: if margc < 0, no 'r' option will be displayed (i.e., on the
193 * top level menu)
07c56447 194 */
e9db439c 195int
74e7b641 196Do_menu(m, margc, margv)
e9db439c 197 Menu *m;
74e7b641 198 int margc;
199 char *margv[];
07c56447 200{
201 struct menu_screen *my_ms, *old_cur_ms;
202 char argvals[MAX_ARGC][MAX_ARGLEN]; /* This is where args are stored */
2aaf83c2 203 char buf[MAX_ARGC * MAX_ARGLEN];
07c56447 204 char *argv[MAX_ARGC];
205 int line;
2aaf83c2 206 int i;
207 struct menu_line *command, *Find_command();
07c56447 208 int argc;
967b7c08 209 int quitflag, is_topmenu = (margc < 0);
859891c0 210 int toggle_logging();
967b7c08 211
07c56447 212 /* Entry function gets called with old menu_screen still current */
e9db439c 213 if (m->m_entry != NULLFUNC)
74e7b641 214 if (m->m_entry(m, margc, margv) == DM_QUIT)
215 return DM_NORMAL;
07c56447 216
2aaf83c2 217 /* The following get run only in curses mode */
e9db439c 218 if (cur_ms != NULLMS) {
2aaf83c2 219 /* Get a menu_screen */
220 old_cur_ms = cur_ms;
859891c0 221 /* 2 is for the 2 obligatory lines; quit and toggle */
222 cur_ms = my_ms = make_ms(m->m_length + 2 + (is_topmenu ? 0 : 1));
07c56447 223
2aaf83c2 224 /* Now print the title and the menu */
e9db439c 225 (void) wclear(my_ms->ms_menu);
226 (void) wmove(my_ms->ms_title, 0, MAX(0, (COLS -
227 strlen(m->m_title)) >> 1));
2aaf83c2 228 (void) wstandout(my_ms->ms_title);
229 (void) waddstr(my_ms->ms_title, m->m_title);
230 (void) wstandend(my_ms->ms_title);
231
e9db439c 232 for (line = 0; line < m->m_length; line++) {
6298c97d 233 int len = strlen(m->m_lines[line].ml_command);
234 if (len > 12) len=12;
235
2aaf83c2 236 (void) wmove(my_ms->ms_menu, line, 0);
6298c97d 237
238 (void) wprintw(my_ms->ms_menu, "%2d. (%s)%*s %s.", line + 1,
e9db439c 239 m->m_lines[line].ml_command,
6298c97d 240 12-len, "",
e9db439c 241 m->m_lines[line].ml_doc);
2aaf83c2 242 }
243 (void) wmove(my_ms->ms_menu, line++, 0);
967b7c08 244 if (!is_topmenu) {
245 (void) waddstr(my_ms->ms_menu,
6298c97d 246 " r. (return) Return to previous menu.");
859891c0 247 (void) wmove(my_ms->ms_menu, line++, 0);
967b7c08 248 }
859891c0 249 (void) waddstr(my_ms->ms_menu,
250 " t. (toggle) Toggle logging on and off.");
251 (void) wmove(my_ms->ms_menu, line, 0);
6298c97d 252 (void) waddstr(my_ms->ms_menu, " q. (quit) Quit.");
33a56ee9 253 } else {
254 Put_message(m->m_title);
255 for (line = 0; line < m->m_length; line++) {
256 sprintf(buf, "%2d. (%s)%*s %s.", line + 1,
257 m->m_lines[line].ml_command,
258 12 - strlen(m->m_lines[line].ml_command), "",
259 m->m_lines[line].ml_doc);
260 Put_message(buf);
261 }
262 if (!is_topmenu)
263 Put_message(" r. (return) Return to previous menu.");
264 Put_message(" t. (toggle) Toggle logging on and off.");
265 Put_message(" q. (quit) Quit.");
266 Put_message(" ?. Print this information.");
07c56447 267 }
07c56447 268
e9db439c 269 for (;;) {
07c56447 270 /* This will be set by a return val from func or submenu */
271 quitflag = DM_NORMAL;
2aaf83c2 272 /* This is here because we may be coming from another menu */
e9db439c 273 if (cur_ms != NULL)
274 touchwin(my_ms->ms_screen);
07c56447 275 /* Get a command */
967b7c08 276 if (!Prompt_input("Command: ", buf, sizeof(buf)))
277 continue;
2aaf83c2 278 /* Parse it into the argument list */
279 /* If there's nothing there, try again */
280 /* Initialize argv */
e9db439c 281 for (argc = 0; argc < MAX_ARGC; argc++)
282 argv[argc] = argvals[argc];
283
284 if ((argc = Parse_words(buf, argv, MAX_ARGLEN)) == 0)
285 continue;
286 if ((line = atoi(argv[0])) > 0 && line <= m->m_length) {
287 command = &m->m_lines[line - 1];
288 }
967b7c08 289 else if ((!is_topmenu &&
859891c0 290 (!strcmp(argv[0], "r") || !strcmp(argv[0], "return")))
291 || !strcmp(argv[0], "q") || !strcmp(argv[0], "quit")) {
292
07c56447 293 /* here if it's either return or quit */
e9db439c 294 if (cur_ms != NULLMS) {
2aaf83c2 295 cur_ms = old_cur_ms;
296 destroy_ms(my_ms);
297 }
e9db439c 298 if (m->m_exit != NULLFUNC)
299 m->m_exit(m);
300 return (*argv[0] == 'r' ? DM_NORMAL : DM_QUIT);
e9db439c 301 }
33a56ee9 302 else if (argv[0][0] == '?') {
303 for (line = 0; line < m->m_length; line++) {
304 sprintf(buf, "%2d. (%s)%*s %s.", line + 1,
305 m->m_lines[line].ml_command,
306 12 - strlen(m->m_lines[line].ml_command), "",
307 m->m_lines[line].ml_doc);
308 Put_message(buf);
309 }
310 if (!is_topmenu)
311 Put_message(" r. (return) Return to previous menu.");
312 Put_message(" t. (toggle) Toggle logging on and off.");
313 Put_message(" q. (quit) Quit.");
314 continue;
315 }
859891c0 316 else if (!strcmp(argv[0], "t") || !strcmp(argv[0], "toggle")) {
317 toggle_logging(argc, argv);
318 continue;
319 }
320 /* finally, try to find it using Find_command */
e9db439c 321 else if ((command = Find_command(argvals[0])) ==
322 (struct menu_line *) 0) {
323 Put_message("Command not recognized");
324 continue;
325 }
2aaf83c2 326 /* If we got to here, command is a valid menu_line */
327 /* Send the offical command name into the argv */
328 (void) strcpy(argvals[0], command->ml_command);
329 /* Show that we're working on it */
330 Put_message(command->ml_doc);
331 /* Print args that we've already got */
e9db439c 332 for (i = 1; i < argc; i++) {
333 if (command->ml_args[i].ma_prompt == NULL)
334 break;
2aaf83c2 335 (void) sprintf(buf, "%s%s", command->ml_args[i].ma_prompt,
336 argv[i]);
337 Put_message(buf);
338 }
339 /* Get remaining arguments, if any */
e9db439c 340 for (; argc < command->ml_argc; argc++) {
967b7c08 341 if (!Prompt_input(command->ml_args[argc].ma_prompt,
342 argvals[argc], sizeof(argvals[argc])))
343 goto punt_command;
2aaf83c2 344 }
e9db439c 345 if (command->ml_function != NULLFUNC) {
2aaf83c2 346 /* If it's got a function, call it */
347 quitflag = command->ml_function(argc, argv);
e9db439c 348 }
349 else if (command->ml_submenu != NULLMENU) {
2aaf83c2 350 /* Else see if it is a submenu */
74e7b641 351 quitflag = Do_menu(command->ml_submenu, argc, argv);
e9db439c 352 }
353 else {
2aaf83c2 354 /* If it's got neither, something is wrong */
355 Put_message("*INTERNAL ERROR: NO FUNCTION OR MENU FOR LINE*");
07c56447 356 }
e9db439c 357 if (quitflag == DM_QUIT) {
358 if (cur_ms != NULLMS) {
2aaf83c2 359 cur_ms = old_cur_ms;
360 destroy_ms(my_ms);
361 }
e9db439c 362 if (m->m_exit != NULLFUNC)
363 m->m_exit(m);
364 return (DM_QUIT);
07c56447 365 }
967b7c08 366 punt_command:
367 ;
07c56447 368 }
369}
370
371/* Prompt the user for input in the input window of cur_ms */
967b7c08 372int Prompt_input(prompt, buf, buflen)
e9db439c 373 char *prompt;
374 char *buf;
375 int buflen;
07c56447 376{
377 int c;
378 char *p;
379 int y, x, oldx;
380
e9db439c 381 if (cur_ms != NULLMS) {
382 more_flg = 1;
383 getyx(cur_ms->ms_input, y, x);
384 (void) wmove(cur_ms->ms_input, y, 0);
385
386 touchwin(cur_ms->ms_screen);
387 refresh_ms(cur_ms);
2aaf83c2 388 (void) waddstr(cur_ms->ms_input, prompt);
389 getyx(cur_ms->ms_input, y, x);
e9db439c 390
2aaf83c2 391 oldx = x;
f659480d 392 p = buf;
393 while(1) {
2aaf83c2 394 (void) wmove(cur_ms->ms_input, y, x);
859891c0 395 (void) touchwin(cur_ms->ms_screen);
396#ifdef notdef
2aaf83c2 397 (void) wclrtoeol(cur_ms->ms_input);
859891c0 398#endif notdef
2aaf83c2 399 refresh_ms(cur_ms);
36606b78 400 c = getchar() & 0x7f;
2aaf83c2 401 switch (c) {
967b7c08 402 case CTL('C'):
403 return 0;
404 case CTL('Z'):
34f47457 405 (void) kill(getpid(), SIGTSTP);
967b7c08 406 touchwin(curscr);
407 break;
408 case CTL('L'):
e9db439c 409 (void) wclear(cur_ms->ms_input);
410 (void) waddstr(cur_ms->ms_input, prompt);
76124208 411 (void) touchwin(cur_ms->ms_screen);
412#ifdef notdef
859891c0 413 refresh_ms(cur_ms);
76124208 414#endif notdef
e9db439c 415 getyx(cur_ms->ms_input, y, x);
2aaf83c2 416 break;
6298c97d 417
e9db439c 418 case '\n':
419 case '\r':
f659480d 420 goto end_input;
6298c97d 421 /* these should be obtained by doing ioctl() on tty */
2aaf83c2 422 case '\b':
423 case '\177':
424 if (p > buf) {
425 p--;
426 x--;
427 }
428 break;
967b7c08 429 case CTL('U'):
430 case CTL('G'):
431 case CTL('['):
2aaf83c2 432 x = oldx;
e9db439c 433 p = buf;
2aaf83c2 434 break;
435 default:
f659480d 436 if (isprint(c) && (p - buf < buflen)) {
967b7c08 437 (void) waddch(cur_ms->ms_input, c);
438 *p++ = c;
439 x++;
440 } else
441 putchar(CTL('G'));
2aaf83c2 442 break;
07c56447 443 }
07c56447 444 }
f659480d 445 end_input:
446 (void) waddch(cur_ms->ms_input, '\n');
447 (void) waddch(cur_ms->ms_input, '\r');
448
449 (void) wclrtoeol(cur_ms->ms_input);
450 refresh_ms(cur_ms);
451 *p = '\0';
452 Start_paging();
6298c97d 453 goto gotit;
f659480d 454 } else {
2aaf83c2 455 printf("%s", prompt);
967b7c08 456 if (gets(buf) == NULL)
457 return 0;
2aaf83c2 458 Start_paging();
6298c97d 459 goto gotit;
07c56447 460 }
6298c97d 461gotit:
462 strcpy(buf, strtrim(buf));
463 return 1;
07c56447 464}
465
27de3061 466/* Prompt the user for input in the input window of cur_ms, but don't echo
467 and allow some control characters */
468int Password_input(prompt, buf, buflen)
469 char *prompt;
470 char *buf;
471 int buflen;
472{
473 int c;
474 char *p;
475 int y, x, oldx;
476
477 if (cur_ms != NULLMS) {
478 more_flg = 1;
479 getyx(cur_ms->ms_input, y, x);
480 (void) wmove(cur_ms->ms_input, y, 0);
481
482 touchwin(cur_ms->ms_screen);
483 refresh_ms(cur_ms);
484 (void) waddstr(cur_ms->ms_input, prompt);
485 getyx(cur_ms->ms_input, y, x);
486
487 oldx = x;
488 for (p = buf; p - buf < buflen;) {
489 (void) wmove(cur_ms->ms_input, y, x);
490 (void) wclrtoeol(cur_ms->ms_input);
491 refresh_ms(cur_ms);
36606b78 492 c = getchar() & 0x7f;
27de3061 493 switch (c) {
494 case CTL('C'):
495 return 0;
496 case CTL('Z'):
34f47457 497 (void) kill(getpid(), SIGTSTP);
27de3061 498 touchwin(curscr);
499 break;
500 case CTL('L'):
501 (void) wclear(cur_ms->ms_input);
502 (void) waddstr(cur_ms->ms_input, prompt);
76124208 503 refresh_ms(cur_ms);
27de3061 504 getyx(cur_ms->ms_input, y, x);
505 break;
506 case '\n':
507 case '\r':
508 (void) waddch(cur_ms->ms_input, '\n');
509 (void) waddch(cur_ms->ms_input, '\r');
510
511 (void) wclrtoeol(cur_ms->ms_input);
512 refresh_ms(cur_ms);
513 *p = '\0';
514 Start_paging();
515 return 1;
516 case '\b':
517 case '\177':
518 if (p > buf) {
519 p--;
520 x--;
521 }
522 break;
523 case CTL('U'):
524 x = oldx;
525 p = buf;
526 break;
527 default:
528 *p++ = c;
529 break;
530 }
531 }
532 }
533 else {
534 struct sgttyb ttybuf, nttybuf;
535 printf("%s", prompt);
536 /* turn off echoing */
34f47457 537 (void) ioctl(0, TIOCGETP, (char *)&ttybuf);
27de3061 538 nttybuf = ttybuf;
539 nttybuf.sg_flags &= ~ECHO;
34f47457 540 (void)ioctl(0, TIOCSETP, (char *)&nttybuf);
27de3061 541 if (gets(buf) == NULL) {
34f47457 542 (void) ioctl(0, TIOCSETP, (char *)&ttybuf);
27de3061 543 putchar('\n');
544 return 0;
545 }
546 putchar('\n');
34f47457 547 (void) ioctl(0, TIOCSETP, (char *)&ttybuf);
27de3061 548 Start_paging();
549 return 1;
550 }
34f47457 551 return 0;
27de3061 552}
553
2aaf83c2 554int lines_left;
555
556/* Start paging */
557/* This routine will cause the most recently put message to be the
558 one at the top of the screen when a ---More--- prompt is displayed */
559Start_paging()
560{
e9db439c 561 if (cur_ms != NULLMS) {
2aaf83c2 562 lines_left = LINES - cur_ms->ms_input_y - 1;
e9db439c 563 }
564 else {
2aaf83c2 565 lines_left = 23;
566 }
567}
568
569/* Turn off paging */
570Stop_paging()
571{
572 lines_left = -1;
573}
574
f659480d 575/* Print a message in the input window of cur_ms. */
07c56447 576Put_message(msg)
f659480d 577char *msg;
578{
579 char *copy, *line, *s;
580
34f47457 581 copy = (char *) malloc((u_int)COLS);
f659480d 582 s = line = msg;
859891c0 583 if (log_file) { /* if we're doing logging; we assume that the */
584 /* file has already been opened. */
585 (void) fprintf(log_file, "%s\n", msg);
586 fflush(log_file);
587 }
588
f659480d 589 while(*s++) {
590 if (s - line >= COLS-1) {
34f47457 591 (void) strncpy(copy, line, COLS-1);
f659480d 592 line += COLS-1;
593 } else if (*s == '\n') {
594 *s = '\0';
34f47457 595 (void) strcpy(copy, line);
f659480d 596 line = ++s;
597 } else
598 continue;
599 Put_line(copy);
600 }
601 Put_line(line);
602 free(copy);
603}
604
605/* Will be truncated to COLS characters. */
606Put_line(msg)
607char *msg;
07c56447 608{
e9db439c 609 int y, x, i;
610 char *msg1, chr;
611
612 if (!more_flg)
613 return;
2aaf83c2 614
e9db439c 615 if (lines_left >= 0) {
616 if (--lines_left == 0) {
2aaf83c2 617 /* Give the user a more prompt */
e9db439c 618 if (cur_ms != NULLMS) {
2aaf83c2 619 (void) wstandout(cur_ms->ms_input);
620 (void) wprintw(cur_ms->ms_input, "---More---");
621 (void) wstandend(cur_ms->ms_input);
622 refresh_ms(cur_ms);
36606b78 623 chr = getchar() & 0x7f;/* We do care what it is */
e9db439c 624 if (chr == 'q' || chr == 'Q') {
625 more_flg = 0;
626 return;
627 }
2aaf83c2 628 getyx(cur_ms->ms_input, y, x);
34f47457 629 /* x is a bitbucket; avoid lint problems */
630 x=x;
2aaf83c2 631 (void) wmove(cur_ms->ms_input, y, 0);
632 (void) wclrtoeol(cur_ms->ms_input);
e9db439c 633 }
634 else {
2aaf83c2 635 printf("---More (hit return)---");
36606b78 636 (void) getchar() & 0x7f;
2aaf83c2 637 }
638 Start_paging(); /* Reset lines_left */
639 }
640 }
e9db439c 641
642 if (cur_ms != NULLMS) {
34f47457 643 msg1 = (char *) calloc((u_int)COLS, 1);
f659480d 644 (void) strncpy(msg1, msg, COLS-1);
645 for (i = strlen(msg1); i < COLS - 1; i++)
e9db439c 646 msg1[i] = ' ';
647 (void) wprintw(cur_ms->ms_input, "%s\n", msg1);
2aaf83c2 648/* refresh_ms(cur_ms); */
e9db439c 649 }
650 else {
2aaf83c2 651 puts(msg);
652 }
07c56447 653}
654
655/* Refresh a menu_screen onto the real screen */
656refresh_ms(ms)
e9db439c 657 struct menu_screen *ms;
07c56447 658{
659 int y, x;
660
661 getyx(ms->ms_input, y, x);
2aaf83c2 662 (void) wmove(ms->ms_screen, y + ms->ms_input_y, x);
663 (void) wrefresh(ms->ms_screen);
664}
665
666/* Parse buf into a list of words, which will be placed in strings specified by
667 argv. Space for these strings must have already been allocated.
668 Only the first n characters of each word will be copied */
669Parse_words(buf, argv, n)
e9db439c 670 char *buf;
671 char *argv[];
2aaf83c2 672int n;
e9db439c 673
2aaf83c2 674{
675 char *start, *end; /* For sausage machine */
676 int argc;
677
678 start = buf;
e9db439c 679 for (argc = 0; argc < MAX_ARGC; argc++) {
680 while (isspace(*start))
681 start++; /* Kill whitespace */
682 if (*start == '\0')
683 break; /* Nothing left */
2aaf83c2 684 /* Now find the end of the word */
e9db439c 685 for (end = start; *end != '\0' && !isspace(*end); end++);
686 (void) strncpy(argv[argc], start, MIN(end - start, n)); /* Copy it */
687 argv[argc][MIN(end - start, n - 1)] = '\0'; /* Terminate */
2aaf83c2 688 start = end;
689 }
e9db439c 690 return (argc);
2aaf83c2 691}
692
693/* This is the internal form of Find_command, which recursively searches
694 for a menu_line with command command in the specified menu */
695/* It will search to a maximum depth of d */
e9db439c 696struct menu_line *
697find_command_from(c, m, d)
698 char *c;
699 struct menu *m;
700 int d;
2aaf83c2 701{
702 int line;
703 struct menu_line *maybe;
704
e9db439c 705 if (d < 0)
706 return ((struct menu_line *) 0); /* Too deep! */
707 for (line = 0; line < m->m_length; line++) {
708 if (!strcmp(c, m->m_lines[line].ml_command)) {
709 return (&m->m_lines[line]);
710 }
711 else if (m->m_lines[line].ml_submenu != NULLMENU
712 && (maybe =
713 find_command_from(c, m->m_lines[line].ml_submenu, d - 1))
714 != (struct menu_line *) 0) {
715 return (maybe);
716 }
2aaf83c2 717 }
718 /* If we got to here, nothing works */
e9db439c 719 return ((struct menu_line *) 0);
07c56447 720}
2aaf83c2 721
722/* Find_command searches down the current menu tree */
723/* And returns a pointer to a menu_line with the specified command name */
724/* It returns (struct menu_line *) 0 if none is found */
e9db439c 725struct menu_line *
726Find_command(command)
727 char *command;
2aaf83c2 728{
e9db439c 729 if (top_menu == NULLMENU) {
730 return ((struct menu_line *) 0);
731 }
732 else {
733 return (find_command_from(command, top_menu, MAX_MENU_DEPTH));
2aaf83c2 734 }
735}
22705d2b 736
859891c0 737/*ARGSUSED*/
738int
739toggle_logging(argc, argv)
740 int argc;
741 char *argv[];
742{
743 int pid;
744 char buf[BUFSIZ];
745
746 if (log_file == (FILE *) NULL) {
747 pid = getpid();
748 if (!whoami) {
749 char *whoami;
750 Put_message("I've lost my SENSE of DIRECTION! I have no IDEA who I AM!");
751 Put_message("My God... You've turned him into a DEMOCRAT!!");
752 Put_message(" -- Doonesbury");
753 Put_message("");
754 Put_message("translation: your log file can be found in \"/usr/tmp/a.out.pid\".");
755 whoami = "a.out";
756 (void) sprintf(buf, "/usr/tmp/%s-log.%d", whoami, pid);
757 }
758 else
759 (void) sprintf(buf, "/usr/tmp/%s-log.%d", whoami, pid);
760
761 /* open the file */
33a56ee9 762 log_file = fopen(buf,"a");
859891c0 763
764 if (log_file == (FILE *) NULL)
765 Put_message("Open of log file failed. Logging is not on.");
766 else
767 Put_message("Log file successfully opened.");
768 }
769 else { /* log_file is a valid pointer; turn off logging. */
770 (void) fflush(log_file);
771 (void) fclose(log_file);
772 log_file = (FILE *) NULL;
773 Put_message("Logging off.");
774 }
775 return(DM_NORMAL);
776}
777
22705d2b 778/*
779 * Local Variables:
780 * mode: c
781 * c-indent-level: 4
782 * c-continued-statement-offset: 4
783 * c-brace-offset: -4
784 * c-argdecl-indent: 4
785 * c-label-offset: -4
786 * End:
787 */
This page took 0.227677 seconds and 5 git commands to generate.