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