]> andersk Git - moira.git/blame - clients/moira/menu.c
clear to end of line after moving the cursor (so ^U, ^H, etc work)
[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);
2aaf83c2 396 (void) wclrtoeol(cur_ms->ms_input);
397 refresh_ms(cur_ms);
36606b78 398 c = getchar() & 0x7f;
2aaf83c2 399 switch (c) {
967b7c08 400 case CTL('C'):
401 return 0;
402 case CTL('Z'):
34f47457 403 (void) kill(getpid(), SIGTSTP);
967b7c08 404 touchwin(curscr);
405 break;
406 case CTL('L'):
e9db439c 407 (void) wclear(cur_ms->ms_input);
408 (void) waddstr(cur_ms->ms_input, prompt);
76124208 409 (void) touchwin(cur_ms->ms_screen);
410#ifdef notdef
859891c0 411 refresh_ms(cur_ms);
76124208 412#endif notdef
e9db439c 413 getyx(cur_ms->ms_input, y, x);
2aaf83c2 414 break;
6298c97d 415
e9db439c 416 case '\n':
417 case '\r':
f659480d 418 goto end_input;
6298c97d 419 /* these should be obtained by doing ioctl() on tty */
2aaf83c2 420 case '\b':
421 case '\177':
422 if (p > buf) {
423 p--;
424 x--;
425 }
426 break;
967b7c08 427 case CTL('U'):
428 case CTL('G'):
429 case CTL('['):
2aaf83c2 430 x = oldx;
e9db439c 431 p = buf;
2aaf83c2 432 break;
433 default:
f659480d 434 if (isprint(c) && (p - buf < buflen)) {
967b7c08 435 (void) waddch(cur_ms->ms_input, c);
436 *p++ = c;
437 x++;
438 } else
439 putchar(CTL('G'));
2aaf83c2 440 break;
07c56447 441 }
07c56447 442 }
f659480d 443 end_input:
444 (void) waddch(cur_ms->ms_input, '\n');
445 (void) waddch(cur_ms->ms_input, '\r');
446
447 (void) wclrtoeol(cur_ms->ms_input);
448 refresh_ms(cur_ms);
449 *p = '\0';
450 Start_paging();
6298c97d 451 goto gotit;
f659480d 452 } else {
2aaf83c2 453 printf("%s", prompt);
967b7c08 454 if (gets(buf) == NULL)
455 return 0;
2aaf83c2 456 Start_paging();
6298c97d 457 goto gotit;
07c56447 458 }
6298c97d 459gotit:
460 strcpy(buf, strtrim(buf));
461 return 1;
07c56447 462}
463
27de3061 464/* Prompt the user for input in the input window of cur_ms, but don't echo
465 and allow some control characters */
466int Password_input(prompt, buf, buflen)
467 char *prompt;
468 char *buf;
469 int buflen;
470{
471 int c;
472 char *p;
473 int y, x, oldx;
474
475 if (cur_ms != NULLMS) {
476 more_flg = 1;
477 getyx(cur_ms->ms_input, y, x);
478 (void) wmove(cur_ms->ms_input, y, 0);
479
480 touchwin(cur_ms->ms_screen);
481 refresh_ms(cur_ms);
482 (void) waddstr(cur_ms->ms_input, prompt);
483 getyx(cur_ms->ms_input, y, x);
484
485 oldx = x;
486 for (p = buf; p - buf < buflen;) {
487 (void) wmove(cur_ms->ms_input, y, x);
488 (void) wclrtoeol(cur_ms->ms_input);
489 refresh_ms(cur_ms);
36606b78 490 c = getchar() & 0x7f;
27de3061 491 switch (c) {
492 case CTL('C'):
493 return 0;
494 case CTL('Z'):
34f47457 495 (void) kill(getpid(), SIGTSTP);
27de3061 496 touchwin(curscr);
497 break;
498 case CTL('L'):
499 (void) wclear(cur_ms->ms_input);
500 (void) waddstr(cur_ms->ms_input, prompt);
76124208 501 refresh_ms(cur_ms);
27de3061 502 getyx(cur_ms->ms_input, y, x);
503 break;
504 case '\n':
505 case '\r':
506 (void) waddch(cur_ms->ms_input, '\n');
507 (void) waddch(cur_ms->ms_input, '\r');
508
509 (void) wclrtoeol(cur_ms->ms_input);
510 refresh_ms(cur_ms);
511 *p = '\0';
512 Start_paging();
513 return 1;
514 case '\b':
515 case '\177':
516 if (p > buf) {
517 p--;
518 x--;
519 }
520 break;
521 case CTL('U'):
522 x = oldx;
523 p = buf;
524 break;
525 default:
526 *p++ = c;
527 break;
528 }
529 }
530 }
531 else {
532 struct sgttyb ttybuf, nttybuf;
533 printf("%s", prompt);
534 /* turn off echoing */
34f47457 535 (void) ioctl(0, TIOCGETP, (char *)&ttybuf);
27de3061 536 nttybuf = ttybuf;
537 nttybuf.sg_flags &= ~ECHO;
34f47457 538 (void)ioctl(0, TIOCSETP, (char *)&nttybuf);
27de3061 539 if (gets(buf) == NULL) {
34f47457 540 (void) ioctl(0, TIOCSETP, (char *)&ttybuf);
27de3061 541 putchar('\n');
542 return 0;
543 }
544 putchar('\n');
34f47457 545 (void) ioctl(0, TIOCSETP, (char *)&ttybuf);
27de3061 546 Start_paging();
547 return 1;
548 }
34f47457 549 return 0;
27de3061 550}
551
2aaf83c2 552int lines_left;
553
554/* Start paging */
555/* This routine will cause the most recently put message to be the
556 one at the top of the screen when a ---More--- prompt is displayed */
557Start_paging()
558{
e9db439c 559 if (cur_ms != NULLMS) {
2aaf83c2 560 lines_left = LINES - cur_ms->ms_input_y - 1;
e9db439c 561 }
562 else {
2aaf83c2 563 lines_left = 23;
564 }
565}
566
567/* Turn off paging */
568Stop_paging()
569{
570 lines_left = -1;
571}
572
f659480d 573/* Print a message in the input window of cur_ms. */
07c56447 574Put_message(msg)
f659480d 575char *msg;
576{
577 char *copy, *line, *s;
578
34f47457 579 copy = (char *) malloc((u_int)COLS);
f659480d 580 s = line = msg;
859891c0 581 if (log_file) { /* if we're doing logging; we assume that the */
582 /* file has already been opened. */
583 (void) fprintf(log_file, "%s\n", msg);
584 fflush(log_file);
585 }
586
f659480d 587 while(*s++) {
588 if (s - line >= COLS-1) {
34f47457 589 (void) strncpy(copy, line, COLS-1);
f659480d 590 line += COLS-1;
591 } else if (*s == '\n') {
592 *s = '\0';
34f47457 593 (void) strcpy(copy, line);
f659480d 594 line = ++s;
595 } else
596 continue;
597 Put_line(copy);
598 }
599 Put_line(line);
600 free(copy);
601}
602
603/* Will be truncated to COLS characters. */
604Put_line(msg)
605char *msg;
07c56447 606{
e9db439c 607 int y, x, i;
608 char *msg1, chr;
609
610 if (!more_flg)
611 return;
2aaf83c2 612
e9db439c 613 if (lines_left >= 0) {
614 if (--lines_left == 0) {
2aaf83c2 615 /* Give the user a more prompt */
e9db439c 616 if (cur_ms != NULLMS) {
2aaf83c2 617 (void) wstandout(cur_ms->ms_input);
618 (void) wprintw(cur_ms->ms_input, "---More---");
619 (void) wstandend(cur_ms->ms_input);
620 refresh_ms(cur_ms);
36606b78 621 chr = getchar() & 0x7f;/* We do care what it is */
e9db439c 622 if (chr == 'q' || chr == 'Q') {
623 more_flg = 0;
624 return;
625 }
2aaf83c2 626 getyx(cur_ms->ms_input, y, x);
34f47457 627 /* x is a bitbucket; avoid lint problems */
628 x=x;
2aaf83c2 629 (void) wmove(cur_ms->ms_input, y, 0);
630 (void) wclrtoeol(cur_ms->ms_input);
e9db439c 631 }
632 else {
2aaf83c2 633 printf("---More (hit return)---");
b862b2df 634 getchar() & 0x7f;
2aaf83c2 635 }
636 Start_paging(); /* Reset lines_left */
637 }
638 }
e9db439c 639
640 if (cur_ms != NULLMS) {
34f47457 641 msg1 = (char *) calloc((u_int)COLS, 1);
f659480d 642 (void) strncpy(msg1, msg, COLS-1);
643 for (i = strlen(msg1); i < COLS - 1; i++)
e9db439c 644 msg1[i] = ' ';
645 (void) wprintw(cur_ms->ms_input, "%s\n", msg1);
2aaf83c2 646/* refresh_ms(cur_ms); */
e9db439c 647 }
648 else {
2aaf83c2 649 puts(msg);
650 }
07c56447 651}
652
653/* Refresh a menu_screen onto the real screen */
654refresh_ms(ms)
e9db439c 655 struct menu_screen *ms;
07c56447 656{
657 int y, x;
658
659 getyx(ms->ms_input, y, x);
2aaf83c2 660 (void) wmove(ms->ms_screen, y + ms->ms_input_y, x);
661 (void) wrefresh(ms->ms_screen);
662}
663
664/* Parse buf into a list of words, which will be placed in strings specified by
665 argv. Space for these strings must have already been allocated.
666 Only the first n characters of each word will be copied */
667Parse_words(buf, argv, n)
e9db439c 668 char *buf;
669 char *argv[];
2aaf83c2 670int n;
e9db439c 671
2aaf83c2 672{
673 char *start, *end; /* For sausage machine */
674 int argc;
675
676 start = buf;
e9db439c 677 for (argc = 0; argc < MAX_ARGC; argc++) {
678 while (isspace(*start))
679 start++; /* Kill whitespace */
680 if (*start == '\0')
681 break; /* Nothing left */
2aaf83c2 682 /* Now find the end of the word */
e9db439c 683 for (end = start; *end != '\0' && !isspace(*end); end++);
684 (void) strncpy(argv[argc], start, MIN(end - start, n)); /* Copy it */
685 argv[argc][MIN(end - start, n - 1)] = '\0'; /* Terminate */
2aaf83c2 686 start = end;
687 }
e9db439c 688 return (argc);
2aaf83c2 689}
690
691/* This is the internal form of Find_command, which recursively searches
692 for a menu_line with command command in the specified menu */
693/* It will search to a maximum depth of d */
e9db439c 694struct menu_line *
695find_command_from(c, m, d)
696 char *c;
697 struct menu *m;
698 int d;
2aaf83c2 699{
700 int line;
701 struct menu_line *maybe;
702
e9db439c 703 if (d < 0)
704 return ((struct menu_line *) 0); /* Too deep! */
705 for (line = 0; line < m->m_length; line++) {
706 if (!strcmp(c, m->m_lines[line].ml_command)) {
707 return (&m->m_lines[line]);
708 }
709 else if (m->m_lines[line].ml_submenu != NULLMENU
710 && (maybe =
711 find_command_from(c, m->m_lines[line].ml_submenu, d - 1))
712 != (struct menu_line *) 0) {
713 return (maybe);
714 }
2aaf83c2 715 }
716 /* If we got to here, nothing works */
e9db439c 717 return ((struct menu_line *) 0);
07c56447 718}
2aaf83c2 719
720/* Find_command searches down the current menu tree */
721/* And returns a pointer to a menu_line with the specified command name */
722/* It returns (struct menu_line *) 0 if none is found */
e9db439c 723struct menu_line *
724Find_command(command)
725 char *command;
2aaf83c2 726{
e9db439c 727 if (top_menu == NULLMENU) {
728 return ((struct menu_line *) 0);
729 }
730 else {
731 return (find_command_from(command, top_menu, MAX_MENU_DEPTH));
2aaf83c2 732 }
733}
22705d2b 734
859891c0 735/*ARGSUSED*/
736int
737toggle_logging(argc, argv)
738 int argc;
739 char *argv[];
740{
741 int pid;
742 char buf[BUFSIZ];
743
744 if (log_file == (FILE *) NULL) {
745 pid = getpid();
746 if (!whoami) {
747 char *whoami;
748 Put_message("I've lost my SENSE of DIRECTION! I have no IDEA who I AM!");
749 Put_message("My God... You've turned him into a DEMOCRAT!!");
750 Put_message(" -- Doonesbury");
751 Put_message("");
752 Put_message("translation: your log file can be found in \"/usr/tmp/a.out.pid\".");
753 whoami = "a.out";
754 (void) sprintf(buf, "/usr/tmp/%s-log.%d", whoami, pid);
755 }
756 else
757 (void) sprintf(buf, "/usr/tmp/%s-log.%d", whoami, pid);
758
759 /* open the file */
33a56ee9 760 log_file = fopen(buf,"a");
859891c0 761
762 if (log_file == (FILE *) NULL)
763 Put_message("Open of log file failed. Logging is not on.");
764 else
765 Put_message("Log file successfully opened.");
766 }
767 else { /* log_file is a valid pointer; turn off logging. */
768 (void) fflush(log_file);
769 (void) fclose(log_file);
770 log_file = (FILE *) NULL;
771 Put_message("Logging off.");
772 }
773 return(DM_NORMAL);
774}
775
22705d2b 776/*
777 * Local Variables:
778 * mode: c
779 * c-indent-level: 4
780 * c-continued-statement-offset: 4
781 * c-brace-offset: -4
782 * c-argdecl-indent: 4
783 * c-label-offset: -4
784 * End:
785 */
This page took 0.349316 seconds and 5 git commands to generate.