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