X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/c3e6578786d635c27f023d3f1c9688b9b13201ee..c7e6f1bd9a4bfe8db29c31fc3baafcdeb50c87d3:/clients/moira/menu.c diff --git a/clients/moira/menu.c b/clients/moira/menu.c index 015d7e17..4c15bb01 100644 --- a/clients/moira/menu.c +++ b/clients/moira/menu.c @@ -1,52 +1,47 @@ -/* - * Copyright 1987 by the Massachusetts Institute of Technology. - * For copying and distribution information, see the file - * "mit-copyright.h". - * - * $Source$ - * $Author$ - * $Header$ +/* $Id$ * * Generic menu system module. * - * Basically, we define an enormous tree structure which represents the - * menu. Some extra pieces (ml_command, ma_doc) get thrown in so we can - * also use the structure for a command-based system. - * - * By making the menu descriptions so general, we can ease porting to just - * about anything. + * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology. + * For copying and distribution information, see the file + * . */ -#ifndef lint -static char rcsid_menu_c[] = "$Header$"; -#endif - #include -#include +#include +#include "menu.h" + +#include +#ifdef HAVE_CURSES +#include +#endif +#include #include #include #include -#include -#include -#ifdef POSIX +#ifdef HAVE_UNISTD_H #include -#include -#include -#else -#include -#include -#endif /* POSIX */ -#include -#include -#include -#include "menu.h" +#endif -#ifndef __STDC__ -#define const +#ifdef _WIN32 +#include +#include +#include +#ifdef getchar +#undef getchar #endif +#define getchar() _getch() +#define getpid _getpid +#endif /* _WIN32 */ + +RCSID("$Header$"); -#define MAX(A,B) ((A) > (B) ? (A) : (B)) -#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#ifdef MAX +#undef MAX +#undef MIN +#endif +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) #define CTL(ch) ((ch) & 037) #define MIN_INPUT 2 /* Minimum number of lines for input window */ @@ -59,12 +54,18 @@ int more_flg = 1; /* Structure for holding current displayed menu */ struct menu_screen { - WINDOW *ms_screen; /* Window for this menu */ - WINDOW *ms_title; /* Title subwindow */ - WINDOW *ms_menu; /* Menu subwindow */ - WINDOW *ms_input; /* Input subwindow */ - int ms_input_y; /* Input subwindow reference coordinate */ -} *cur_ms; +#ifdef HAVE_CURSES + WINDOW *ms_screen; /* Window for this menu */ + WINDOW *ms_title; /* Title subwindow */ + WINDOW *ms_menu; /* Menu subwindow */ + WINDOW *ms_input; /* Input subwindow */ +#endif /* HAVE_CURSES */ + int ms_input_y; /* Input subwindow reference coordinate */ +} *cur_ms; + +#ifndef HAVE_CURSES +int COLS; +#endif #define NULLMS ((struct menu_screen *) 0) @@ -72,128 +73,148 @@ Menu *top_menu; /* Root for command search */ int parsed_argc; /* used by extern routines to get additional */ char **parsed_argv; /* comand line input */ +int Parse_words(char *buf, char *argv[], int n); +void refresh_ms(struct menu_screen *ms); +void Put_line(char *msg); +void menu_com_err_hook(const char *who, long code, + const char *fmt, va_list ap); +struct menu_screen *make_ms(int length); +void destroy_ms(struct menu_screen *ms); +struct menu_line *find_command_from(char *c, struct menu *m, int d); +struct menu_line *Find_command(Menu *m, char *command); +int toggle_logging(int argc, char *argv[]); + /* * Hook function to cause error messages to be printed through - * curses instead of around it. Takes at most 5 args to the - * printf string (crock...) + * curses instead of around it. */ -void -menu_com_err_hook(who, code, fmt, arg1, arg2, arg3, arg4, arg5) - const char *who; - long code; - const char *fmt; - caddr_t arg1, arg2, arg3, arg4, arg5; +void menu_com_err_hook(const char *who, long code, const char *fmt, va_list ap) { - char buf[BUFSIZ], *cp; - - (void) strcpy(buf, who); - for (cp = buf; *cp; cp++); - *cp++ = ':'; - *cp++ = ' '; - if (code) { - (void) strcpy(cp, error_message(code)); - while (*cp) - cp++; + char buf[BUFSIZ], *cp; + + if (who) + { + strcpy(buf, who); + for (cp = buf; *cp; cp++) + ; + *cp++ = ':'; + *cp++ = ' '; } - sprintf(cp, fmt, arg1, arg2, arg3, arg4, arg5); - Put_message(buf); + else + { + cp = buf; + *cp = '\0'; + } + if (code) + { + strcpy(cp, error_message(code)); + while (*cp) + cp++; + } + vsprintf(cp, fmt, ap); + Put_message(buf); } +#ifdef HAVE_CURSES /* * Start_menu takes a menu as an argument. It initializes curses u.s.w., * and a quit in any submenu should unwind back to here. (it might not, * if user functions which run their own menus don't cooperate.) * Start_menu should only be called once, at the start of the program. */ -Start_menu(m) - Menu *m; +void Start_menu(Menu *m) { - struct menu_screen *make_ms(); -#ifdef __STDC__ - register void (*old_hook)(const char *, long, const char *, va_list) = set_com_err_hook((void (*) (const char *, long, const char *, va_list))menu_com_err_hook); + void (*old_hook)(const char *, long, const char *, va_list) = + set_com_err_hook(menu_com_err_hook); +#ifdef CURSES_HAS_NEWTERM + SCREEN *scrn = newterm(NULL, stdout, stdin); #else - register void (*old_hook)() = set_com_err_hook(menu_com_err_hook); + WINDOW *scrn = initscr(); #endif - - if (initscr() == (WINDOW *)ERR) { - fputs("Can't initialize curses!\n", stderr); - Start_no_menu(m); - } else { - (void) raw(); /* We parse & print everything ourselves */ - (void) noecho(); - cur_ms = make_ms(0); /* So we always have some current */ - /* menu_screen */ - /* Run the menu */ - (void) Do_menu(m, -1, (char **) NULL); + if (!scrn) + { + fputs("Can't initialize curses!\nReverting to -nomenu mode\n\n", stderr); + Start_no_menu(m); } - (void) set_com_err_hook(old_hook); - Cleanup_menu(); -} - -Cleanup_menu() -{ - if (cur_ms) { - (void) wclear(cur_ms->ms_screen); - (void) wrefresh(cur_ms->ms_screen); + else + { +#ifdef CURSES_HAS_NEWTERM + set_term(scrn); + endwin(); + initscr(); +#endif + raw(); /* We parse & print everything ourselves */ + noecho(); + cur_ms = make_ms(0); /* So we always have some current */ + /* menu_screen */ + /* Run the menu */ + Do_menu(m, -1, NULL); + Cleanup_menu(); } - endwin(); + set_com_err_hook(old_hook); } - -/* Like Start_menu, except it doesn't print menus and doesn't use curses */ -Start_no_menu(m) - Menu *m; +void Cleanup_menu(void) { - cur_ms = NULLMS; - COLS = 80; - /* Run the menu */ - (void) Do_menu(m, -1, (char **) NULL); + if (cur_ms) + { + wclear(cur_ms->ms_screen); + wrefresh(cur_ms->ms_screen); + endwin(); + } } /* * Create a new menu screen template with the specified menu length * and return it. */ -struct menu_screen * -make_ms(length) - int length; +struct menu_screen *make_ms(int length) { - struct menu_screen *ms; + struct menu_screen *ms; - if (MAX_TITLE + length + MIN_INPUT > LINES) { - fputs("Menu too big!\n", stderr); - exit(2); + if (MAX_TITLE + length + MIN_INPUT > LINES) + { + fputs("Menu too big!\n", stderr); + exit(2); } - ms = (struct menu_screen *) malloc(sizeof(struct menu_screen)); + ms = malloc(sizeof(struct menu_screen)); - ms->ms_screen = newwin(0, 0, 0, 0); - ms->ms_title = subwin(ms->ms_screen, MAX_TITLE, 0, 0, 0); - ms->ms_menu = subwin(ms->ms_screen, - length, 0, MAX_TITLE, 0); - ms->ms_input = subwin(ms->ms_screen, 0, 0, - ms->ms_input_y = MAX_TITLE + length, - 0); + ms->ms_screen = newwin(0, 0, 0, 0); + ms->ms_title = subwin(ms->ms_screen, MAX_TITLE, 0, 0, 0); + ms->ms_menu = subwin(ms->ms_screen, length, 0, MAX_TITLE, 0); + ms->ms_input = subwin(ms->ms_screen, 0, 0, + ms->ms_input_y = MAX_TITLE + length, + 0); - scrollok(ms->ms_input, TRUE); - (void) wmove(ms->ms_input, 0, 0); - (void) wclear(ms->ms_screen); + scrollok(ms->ms_input, TRUE); + wmove(ms->ms_input, 0, 0); + wclear(ms->ms_screen); - return (ms); + return ms; } /* * This routine destroys a menu_screen. */ -destroy_ms(ms) - struct menu_screen *ms; +void destroy_ms(struct menu_screen *ms) { - delwin(ms->ms_title); - delwin(ms->ms_menu); - delwin(ms->ms_input); - delwin(ms->ms_screen); - free((char *) ms); + delwin(ms->ms_title); + delwin(ms->ms_menu); + delwin(ms->ms_input); + delwin(ms->ms_screen); + free(ms); +} +#endif /* HAVE_CURSES */ + +/* Like Start_menu, except it doesn't print menus and doesn't use curses */ +void Start_no_menu(Menu *m) +{ + cur_ms = NULLMS; + COLS = 80; + /* Run the menu */ + Do_menu(m, -1, NULL); } /* @@ -201,340 +222,375 @@ destroy_ms(ms) * Note: if margc < 0, no 'r' option will be displayed (i.e., on the * top level menu) */ -int -Do_menu(m, margc, margv) - Menu *m; - int margc; - char *margv[]; +int Do_menu(Menu *m, int margc, char *margv[]) { - struct menu_screen *my_ms = NULLMS, *old_cur_ms = NULLMS; - char argvals[MAX_ARGC][MAX_ARGLEN]; /* This is where args are stored */ - char buf[MAX_ARGC * MAX_ARGLEN]; - char *argv[MAX_ARGC]; - int line; - int i; - struct menu_line *command, *Find_command(); - int argc; - int quitflag, is_topmenu = (margc < 0); - int toggle_logging(); - - /* Entry function gets called with old menu_screen still current */ - if (m->m_entry != NULLFUNC) { - if (m->m_entry(m, margc, margv) == DM_QUIT) - return DM_NORMAL; - if (parsed_argc > 0) { - margc = parsed_argc + 1; - margv = --parsed_argv; - } else { - margc--; - margv++; + struct menu_screen *my_ms = NULLMS, *old_cur_ms = NULLMS; + char argvals[MAX_ARGC][MAX_ARGLEN]; /* This is where args are stored */ + char buf[MAX_ARGC * MAX_ARGLEN]; + char *argv[MAX_ARGC]; + int line; + int i; + struct menu_line *command; + int argc; + int quitflag, is_topmenu = (margc < 0); + + /* Entry function gets called with old menu_screen still current */ + if (m->m_entry != NULLFUNC) + { + if (m->m_entry(m, margc, margv) == DM_QUIT) + return DM_NORMAL; + if (parsed_argc > 0) + { + margc = parsed_argc + 1; + margv = --parsed_argv; + } + else + { + margc--; + margv++; } } - parsed_argc = 0; - - /* The following get run only in curses mode */ - if (cur_ms != NULLMS) { - /* Get a menu_screen */ - old_cur_ms = cur_ms; - /* 2 is for the 2 obligatory lines; quit and toggle */ - cur_ms = my_ms = make_ms(m->m_length + 2 + (is_topmenu ? 0 : 1)); - - /* Now print the title and the menu */ - (void) wclear(my_ms->ms_screen); - (void) wrefresh(my_ms->ms_screen); - (void) wmove(my_ms->ms_title, 0, MAX(0, (COLS - - strlen(m->m_title)) >> 1)); - (void) wstandout(my_ms->ms_title); - (void) waddstr(my_ms->ms_title, m->m_title); - (void) wstandend(my_ms->ms_title); - - for (line = 0; line < m->m_length; line++) { - int len = strlen(m->m_lines[line].ml_command); - if (len > 12) len=12; - - (void) wmove(my_ms->ms_menu, line, 0); - - (void) wprintw(my_ms->ms_menu, "%2d. (%s)%*s %s.", line + 1, - m->m_lines[line].ml_command, - 12-len, "", - m->m_lines[line].ml_doc); + parsed_argc = 0; + +#ifdef HAVE_CURSES + /* The following get run only in curses mode */ + if (cur_ms != NULLMS) + { + /* Get a menu_screen */ + old_cur_ms = cur_ms; + /* 2 is for the 2 obligatory lines; quit and toggle */ + cur_ms = my_ms = make_ms(m->m_length + 2 + (is_topmenu ? 0 : 1)); + + /* Now print the title and the menu */ + wclear(my_ms->ms_screen); + wrefresh(my_ms->ms_screen); + wmove(my_ms->ms_title, 0, MAX(0, (COLS - (int)strlen(m->m_title)) >> 1)); + wstandout(my_ms->ms_title); + waddstr(my_ms->ms_title, m->m_title); + wstandend(my_ms->ms_title); + + for (line = 0; line < m->m_length; line++) + { + int len = strlen(m->m_lines[line].ml_command); + if (len > 12) + len = 12; + + wmove(my_ms->ms_menu, line, 0); + + wprintw(my_ms->ms_menu, "%2d. (%s)%*s %s.", line + 1, + m->m_lines[line].ml_command, 12 - len, "", + m->m_lines[line].ml_doc); } - (void) wmove(my_ms->ms_menu, line++, 0); - if (!is_topmenu) { - (void) waddstr(my_ms->ms_menu, - " r. (return) Return to previous menu."); - (void) wmove(my_ms->ms_menu, line++, 0); + wmove(my_ms->ms_menu, line++, 0); + if (!is_topmenu) + { + waddstr(my_ms->ms_menu, + " r. (return) Return to previous menu."); + wmove(my_ms->ms_menu, line++, 0); } - (void) waddstr(my_ms->ms_menu, - " t. (toggle) Toggle logging on and off."); - (void) wmove(my_ms->ms_menu, line, 0); - (void) waddstr(my_ms->ms_menu, " q. (quit) Quit."); - } else { - Put_message(m->m_title); - for (line = 0; line < m->m_length; line++) { - sprintf(buf, "%2d. (%s)%*s %s.", line + 1, - m->m_lines[line].ml_command, - 12 - strlen(m->m_lines[line].ml_command), "", - m->m_lines[line].ml_doc); - Put_message(buf); + waddstr(my_ms->ms_menu, " t. (toggle) Toggle logging on and off."); + wmove(my_ms->ms_menu, line, 0); + waddstr(my_ms->ms_menu, " q. (quit) Quit."); + } + else +#endif /* HAVE_CURSES */ + { + Put_message(m->m_title); + for (line = 0; line < m->m_length; line++) + { + sprintf(buf, "%2d. (%s)%*s %s.", line + 1, + m->m_lines[line].ml_command, + 12 - strlen(m->m_lines[line].ml_command), "", + m->m_lines[line].ml_doc); + Put_message(buf); } - if (!is_topmenu) - Put_message(" r. (return) Return to previous menu."); - Put_message(" t. (toggle) Toggle logging on and off."); - Put_message(" q. (quit) Quit."); - Put_message(" ?. Print this information."); + if (!is_topmenu) + Put_message(" r. (return) Return to previous menu."); + Put_message(" t. (toggle) Toggle logging on and off."); + Put_message(" q. (quit) Quit."); + Put_message(" ?. Print this information."); } - for (;;) { - /* This will be set by a return val from func or submenu */ - quitflag = DM_NORMAL; - /* This is here because we may be coming from another menu */ - if (cur_ms != NULL) { - touchwin(my_ms->ms_screen); - wrefresh(my_ms->ms_screen); + for (;;) + { + /* This will be set by a return val from func or submenu */ + quitflag = DM_NORMAL; +#ifdef HAVE_CURSES + /* This is here because we may be coming from another menu */ + if (cur_ms != NULL) + { + touchwin(my_ms->ms_screen); + wrefresh(my_ms->ms_screen); } - if (margc > 1) { - /* Initialize argv */ - for (argc = 0; argc < MAX_ARGC; argc++) - argv[argc] = argvals[argc]; - argc = margc - 1; - for (i = 1; i < margc; i++) - strcpy(argvals[i - 1], margv[i]); - margc = 0; - } else { - /* Get a command */ - if (!Prompt_input("Command: ", buf, sizeof(buf))) { - if (cur_ms == NULLMS && - feof(stdin)) - sprintf(buf, "quit"); - else - continue; - } - /* Parse it into the argument list */ - /* If there's nothing there, try again */ - /* Initialize argv */ - for (argc = 0; argc < MAX_ARGC; argc++) - argv[argc] = argvals[argc]; - - if ((argc = Parse_words(buf, argv, MAX_ARGLEN)) == 0) - continue; +#endif /* HAVE_CURSES */ + if (margc > 1) + { + /* Initialize argv */ + for (argc = 0; argc < MAX_ARGC; argc++) + argv[argc] = argvals[argc]; + argc = margc - 1; + for (i = 1; i < margc; i++) + strcpy(argvals[i - 1], margv[i]); + margc = 0; } - if ((line = atoi(argv[0])) > 0 && line <= m->m_length) { - command = &m->m_lines[line - 1]; + else + { + /* Get a command */ + if (!Prompt_input("Command: ", buf, sizeof(buf))) + { + if (cur_ms == NULLMS && feof(stdin)) + sprintf(buf, "quit"); + else + continue; + } + /* Parse it into the argument list */ + /* If there's nothing there, try again */ + /* Initialize argv */ + for (argc = 0; argc < MAX_ARGC; argc++) + argv[argc] = argvals[argc]; + + if ((argc = Parse_words(buf, argv, MAX_ARGLEN)) == 0) + continue; } - else if ((!is_topmenu && - (!strcmp(argv[0], "r") || !strcmp(argv[0], "return"))) - || !strcmp(argv[0], "q") || !strcmp(argv[0], "quit")) { - - /* here if it's either return or quit */ - if (cur_ms != NULLMS) { - cur_ms = old_cur_ms; - destroy_ms(my_ms); + if ((line = atoi(argv[0])) > 0 && line <= m->m_length) + command = &m->m_lines[line - 1]; + else if ((!is_topmenu && + (!strcmp(argv[0], "r") || !strcmp(argv[0], "return"))) || + !strcmp(argv[0], "q") || !strcmp(argv[0], "quit")) + { + /* here if it's either return or quit */ +#ifdef HAVE_CURSES + if (cur_ms != NULLMS) + { + cur_ms = old_cur_ms; + destroy_ms(my_ms); } - if (m->m_exit != NULLFUNC) - m->m_exit(m); - return (*argv[0] == 'r' ? DM_NORMAL : DM_QUIT); +#endif /* HAVE_CURSES */ + if (m->m_exit != NULLFUNC) + m->m_exit(m); + return *argv[0] == 'r' ? DM_NORMAL : DM_QUIT; } - else if (argv[0][0] == '?') { - for (line = 0; line < m->m_length; line++) { - sprintf(buf, "%2d. (%s)%*s %s.", line + 1, - m->m_lines[line].ml_command, - 12 - strlen(m->m_lines[line].ml_command), "", - m->m_lines[line].ml_doc); - Put_message(buf); + else if (argv[0][0] == '?') + { + for (line = 0; line < m->m_length; line++) + { + sprintf(buf, "%2d. (%s)%*s %s.", line + 1, + m->m_lines[line].ml_command, + 12 - strlen(m->m_lines[line].ml_command), "", + m->m_lines[line].ml_doc); + Put_message(buf); } - if (!is_topmenu) - Put_message(" r. (return) Return to previous menu."); - Put_message(" t. (toggle) Toggle logging on and off."); - Put_message(" q. (quit) Quit."); - continue; + if (!is_topmenu) + Put_message(" r. (return) Return to previous menu."); + Put_message(" t. (toggle) Toggle logging on and off."); + Put_message(" q. (quit) Quit."); + continue; } - else if (!strcmp(argv[0], "t") || !strcmp(argv[0], "toggle")) { - toggle_logging(argc, argv); - continue; - } - /* finally, try to find it using Find_command */ - else if ((command = Find_command(m, argvals[0])) == - (struct menu_line *) 0) { - sprintf(buf, "Command not recognized: %s\n", argvals[0]); - Put_message(buf); - continue; + else if (!strcmp(argv[0], "t") || !strcmp(argv[0], "toggle")) + { + toggle_logging(argc, argv); + continue; + } + /* finally, try to find it using Find_command */ + else if (!(command = Find_command(m, argvals[0]))) + { + sprintf(buf, "Command not recognized: %s\n", argvals[0]); + Put_message(buf); + continue; } - /* If we got to here, command is a valid menu_line */ - /* Send the offical command name into the argv */ - (void) strcpy(argvals[0], command->ml_command); - /* Show that we're working on it */ - Put_message(command->ml_doc); - /* Print args that we've already got */ - for (i = 1; i < argc; i++) { - if (command->ml_args[i].ma_prompt == NULL) - break; - (void) sprintf(buf, "%s%s", command->ml_args[i].ma_prompt, - argv[i]); - Put_message(buf); + /* If we got to here, command is a valid menu_line */ + /* Send the offical command name into the argv */ + strcpy(argvals[0], command->ml_command); + /* Show that we're working on it */ + Put_message(command->ml_doc); + /* Print args that we've already got */ + for (i = 1; i < argc; i++) + { + if (!command->ml_args[i].ma_prompt) + break; + sprintf(buf, "%s%s", command->ml_args[i].ma_prompt, argv[i]); + Put_message(buf); } - /* Get remaining arguments, if any */ - for (; argc < command->ml_argc; argc++) { - if (!Prompt_input(command->ml_args[argc].ma_prompt, - argvals[argc], sizeof(argvals[argc]))) - goto punt_command; + /* Get remaining arguments, if any */ + for (; argc < command->ml_argc; argc++) + { + if (!Prompt_input(command->ml_args[argc].ma_prompt, + argvals[argc], sizeof(argvals[argc]))) + goto punt_command; } - parsed_argc = argc - command->ml_argc; - parsed_argv = &(argv[command->ml_argc]); - if (command->ml_function != NULLFUNC) { - /* If it's got a function, call it */ - quitflag = command->ml_function(argc, argv); + parsed_argc = argc - command->ml_argc; + parsed_argv = &(argv[command->ml_argc]); + if (command->ml_function != NULLFUNC) + { + /* If it's got a function, call it */ + quitflag = command->ml_function(argc, argv); } - else if (command->ml_submenu != NULLMENU) { - /* Else see if it is a submenu */ - quitflag = Do_menu(command->ml_submenu, argc, argv); + else if (command->ml_submenu != NULLMENU) + { + /* Else see if it is a submenu */ + quitflag = Do_menu(command->ml_submenu, argc, argv); } - else { - /* If it's got neither, something is wrong */ - Put_message("*INTERNAL ERROR: NO FUNCTION OR MENU FOR LINE*"); + else + { + /* If it's got neither, something is wrong */ + Put_message("*INTERNAL ERROR: NO FUNCTION OR MENU FOR LINE*"); } - if (quitflag == DM_QUIT) { - if (cur_ms != NULLMS) { - cur_ms = old_cur_ms; - destroy_ms(my_ms); + if (quitflag == DM_QUIT) + { +#ifdef HAVE_CURSES + if (cur_ms != NULLMS) + { + cur_ms = old_cur_ms; + destroy_ms(my_ms); } - if (m->m_exit != NULLFUNC) - m->m_exit(m); - parsed_argc = 0; - return (DM_QUIT); +#endif /* HAVE_CURSES */ + if (m->m_exit != NULLFUNC) + m->m_exit(m); + parsed_argc = 0; + return DM_QUIT; } punt_command: - parsed_argc = 0; + parsed_argc = 0; } } -refresh_screen() +void refresh_screen(void) { - if (cur_ms != NULLMS) { - touchwin(cur_ms->ms_screen); - refresh_ms(cur_ms); +#ifdef HAVE_CURSES + if (cur_ms != NULLMS) + { + touchwin(cur_ms->ms_screen); + refresh_ms(cur_ms); } +#endif /* HAVE_CURSES */ } /* Prompt the user for input in the input window of cur_ms */ -int Prompt_input(prompt, buf, buflen) - char *prompt; - char *buf; - int buflen; +int Prompt_input(char *prompt, char *buf, int buflen) { - int c; - char *p; - int y, x, oldx, oldy; - - if (cur_ms != NULLMS) { - more_flg = 1; - getyx(cur_ms->ms_input, y, x); - (void) wmove(cur_ms->ms_input, y, 0); - - refresh_screen(); - (void) waddstr(cur_ms->ms_input, prompt); - getyx(cur_ms->ms_input, y, x); - - oldx = x; - oldy = y; - p = buf; - while(1) { - (void) wmove(cur_ms->ms_input, y, x); - (void) touchwin(cur_ms->ms_screen); - (void) wclrtoeol(cur_ms->ms_input); - (void) wrefresh(cur_ms->ms_input); - c = getchar() & 0x7f; - switch (c) { +#ifdef HAVE_CURSES + int c; + char *p; + int y, x, oldx, oldy; + + if (cur_ms != NULLMS) + { + more_flg = 1; + getyx(cur_ms->ms_input, y, x); + wmove(cur_ms->ms_input, y, 0); + + refresh_screen(); + waddstr(cur_ms->ms_input, prompt); + getyx(cur_ms->ms_input, y, x); + + oldx = x; + oldy = y; + p = buf; + while (1) + { + wmove(cur_ms->ms_input, y, x); + touchwin(cur_ms->ms_screen); + wclrtoeol(cur_ms->ms_input); + wrefresh(cur_ms->ms_input); + c = getchar() & 0x7f; + switch (c) + { case CTL('C'): - *p = '\0'; - return 0; + *p = '\0'; + return 0; case CTL('Z'): - (void) kill(getpid(), SIGTSTP); - touchwin(cur_ms->ms_screen); - break; + kill(getpid(), SIGTSTP); + touchwin(cur_ms->ms_screen); + break; case CTL('L'): - (void) wclear(cur_ms->ms_input); - (void) wmove(cur_ms->ms_input, 0, 0); - (void) waddstr(cur_ms->ms_input, prompt); - (void) touchwin(cur_ms->ms_input); - (void) wrefresh(cur_ms->ms_screen); - getyx(cur_ms->ms_input, y, x); - oldy = y; - oldx = x; - p = buf; - break; + wclear(cur_ms->ms_input); + wmove(cur_ms->ms_input, 0, 0); + waddstr(cur_ms->ms_input, prompt); + touchwin(cur_ms->ms_input); + wrefresh(cur_ms->ms_screen); + getyx(cur_ms->ms_input, y, x); + oldy = y; + oldx = x; + p = buf; + break; case '\n': case '\r': - goto end_input; - /* these should be obtained by doing ioctl() on tty */ + goto end_input; + /* these should be obtained by doing ioctl() on tty */ case '\b': case '\177': - if (p > buf) { - p--; - x--; - if (x < 0) { - (void) wmove(cur_ms->ms_input, y, 0); - (void) wclrtoeol(cur_ms->ms_input); - y--; -#ifdef __NetBSD__ - x = cur_ms->ms_input->maxx - 1; -#else - x = cur_ms->ms_input->_maxx - 1; -#endif + if (p > buf) + { + p--; + x--; + if (x < 0) + { + wmove(cur_ms->ms_input, y, 0); + wclrtoeol(cur_ms->ms_input); + y--; + x = getmaxx(cur_ms->ms_input) - 1; } } - break; + break; case CTL('U'): case CTL('G'): case CTL('['): - x = oldx; - y = oldy; - p = buf; - break; + x = oldx; + y = oldy; + p = buf; + break; default: - /* (buflen - 1) leaves room for the \0 */ - if (isprint(c) && (p - buf < buflen - 1)) { - (void) waddch(cur_ms->ms_input, c); - *p++ = c; - x++; -#ifdef __NetBSD__ - if (x >= cur_ms->ms_input->maxx) { -#else - if (x >= cur_ms->ms_input->_maxx) { -#endif - x = 0; - y++; + /* (buflen - 1) leaves room for the \0 */ + if (isprint(c) && (p - buf < buflen - 1)) + { + waddch(cur_ms->ms_input, c); + *p++ = c; + x++; + if (x >= getmaxx(cur_ms->ms_input)) + { + x = 0; + y++; } - } else - putchar(CTL('G')); - break; + } + else + putchar(CTL('G')); + break; } } end_input: - (void) waddch(cur_ms->ms_input, '\n'); - - (void) wclrtoeol(cur_ms->ms_input); - refresh_ms(cur_ms); - *p = '\0'; - Start_paging(); - goto gotit; - } else { - printf("%s", prompt); - if (fgets(buf, buflen, stdin) == NULL) - return 0; - if (interrupt) { - interrupt = 0; - return 0; + waddch(cur_ms->ms_input, '\n'); + + wclrtoeol(cur_ms->ms_input); + refresh_ms(cur_ms); + *p = '\0'; + Start_paging(); + strcpy(buf, strtrim(buf)); + return 1; + } + else +#endif /* HAVE_CURSES */ + { + char bigbuf[BUFSIZ]; + + printf("%s", prompt); + if (!fgets(bigbuf, BUFSIZ, stdin)) + return 0; + if (interrupt) + { + interrupt = 0; + return 0; } - Start_paging(); - goto gotit; + Start_paging(); + strncpy(buf, strtrim(bigbuf), buflen); + if (strchr(buf, '\n')) + *strchr(buf, '\n') = '\0'; + else + buf[buflen - 1] = '\0'; + return 1; } -gotit: - strcpy(buf, strtrim(buf)); - return 1; } int lines_left; @@ -542,220 +598,229 @@ int lines_left; /* Start paging */ /* This routine will cause the most recently put message to be the one at the top of the screen when a ---More--- prompt is displayed */ -Start_paging() +void Start_paging(void) { - if (cur_ms != NULLMS) { - lines_left = LINES - cur_ms->ms_input_y - 1; - } - else { - lines_left = 23; - } +#ifdef HAVE_CURSES + if (cur_ms != NULLMS) + lines_left = LINES - cur_ms->ms_input_y - 1; + else +#endif /* HAVE_CURSES */ + lines_left = 23; } /* Turn off paging */ -Stop_paging() +void Stop_paging(void) { - lines_left = -1; + lines_left = -1; } /* Print a message in the input window of cur_ms. */ -Put_message(msg) -char *msg; +void Put_message(char *msg) { - char *copy, *line, *s; - - copy = (char *) malloc((u_int)COLS); - s = line = msg; - if (log_file) { /* if we're doing logging; we assume that the */ - /* file has already been opened. */ - (void) fprintf(log_file, "%s\n", msg); - fflush(log_file); - } - - while(*s++) { - if (s - line >= COLS-1) { - (void) strncpy(copy, line, COLS-1); - copy[COLS-1] = '\0'; - line += COLS-1; - } else if (*s == '\n') { - *s = '\0'; - (void) strcpy(copy, line); - line = ++s; - } else - continue; - Put_line(copy); + char *copy, *line, *s; + + copy = malloc(COLS); + s = line = msg; + if (log_file) + { + /* if we're doing logging; we assume that the file has already + been opened. */ + fprintf(log_file, "%s\n", msg); + fflush(log_file); } - Put_line(line); - free(copy); + + while (*s++) + { + if (s - line >= COLS - 1) + { + strncpy(copy, line, COLS - 1); + copy[COLS - 1] = '\0'; + line += COLS - 1; + } + else if (*s == '\n') + { + *s = '\0'; + strcpy(copy, line); + line = ++s; + } + else + continue; + Put_line(copy); + } + Put_line(line); + free(copy); } /* Will be truncated to COLS characters. */ -Put_line(msg) -char *msg; +void Put_line(char *msg) { - int y, x, i; - char *msg1, chr; - - if (!more_flg) - return; - - if (lines_left >= 0) { - if (--lines_left == 0) { - /* Give the user a more prompt */ - if (cur_ms != NULLMS) { - (void) wstandout(cur_ms->ms_input); - (void) wprintw(cur_ms->ms_input, "---More---"); - (void) wstandend(cur_ms->ms_input); - refresh_ms(cur_ms); - chr = getchar() & 0x7f;/* We do care what it is */ - if (chr == 'q' || chr == 'Q' || chr == 3 /* ^C */) { - more_flg = 0; - return; + if (!more_flg) + return; + + if (lines_left >= 0) + { + if (--lines_left == 0) + { + /* Give the user a more prompt */ +#ifdef HAVE_CURSES + if (cur_ms != NULLMS) + { + int x, y; + char chr; + + wstandout(cur_ms->ms_input); + wprintw(cur_ms->ms_input, "---More---"); + wstandend(cur_ms->ms_input); + refresh_ms(cur_ms); + chr = getchar() & 0x7f;/* We do care what it is */ + if (chr == 'q' || chr == 'Q' || chr == 3 /* ^C */) + { + more_flg = 0; + return; } - getyx(cur_ms->ms_input, y, x); - /* x is a bitbucket; avoid lint problems */ - x=x; - (void) wmove(cur_ms->ms_input, y, 0); - (void) wclrtoeol(cur_ms->ms_input); + getyx(cur_ms->ms_input, y, x); + /* x is a bitbucket; avoid lint problems */ + x = x; + wmove(cur_ms->ms_input, y, 0); + wclrtoeol(cur_ms->ms_input); } - else { - printf("---More (hit return)---"); - getchar(); + else +#endif /* HAVE_CURSES */ + { + printf("---More (hit return)---"); + getchar(); } - Start_paging(); /* Reset lines_left */ + Start_paging(); /* Reset lines_left */ } } - if (cur_ms != NULLMS) { - msg1 = (char *) calloc((u_int)COLS, 1); - (void) strncpy(msg1, msg, COLS-1); - for (i = strlen(msg1); i < COLS - 1; i++) - msg1[i] = ' '; - (void) wprintw(cur_ms->ms_input, "%s\n", msg1); - } - else { - puts(msg); +#ifdef HAVE_CURSES + if (cur_ms != NULLMS) + { + int i; + char *msg1; + + msg1 = calloc(COLS, 1); + strncpy(msg1, msg, COLS - 1); + for (i = strlen(msg1); i < COLS - 1; i++) + msg1[i] = ' '; + wprintw(cur_ms->ms_input, "%s\n", msg1); } + else +#endif /* HAVE_CURSES */ + puts(msg); } +#ifdef HAVE_CURSES /* Refresh a menu_screen onto the real screen */ -refresh_ms(ms) - struct menu_screen *ms; +void refresh_ms(struct menu_screen *ms) { - (void) wrefresh(ms->ms_title); - (void) wrefresh(ms->ms_menu); - (void) wrefresh(ms->ms_input); + wrefresh(ms->ms_title); + wrefresh(ms->ms_menu); + wrefresh(ms->ms_input); } +#endif /* HAVE_CURSES */ /* Parse buf into a list of words, which will be placed in strings specified by argv. Space for these strings must have already been allocated. Only the first n characters of each word will be copied */ -Parse_words(buf, argv, n) - char *buf; - char *argv[]; -int n; - +int Parse_words(char *buf, char *argv[], int n) { - char *start, *end; /* For sausage machine */ - int argc; - - start = buf; - for (argc = 0; argc < MAX_ARGC; argc++) { - while (isspace(*start)) - start++; /* Kill whitespace */ - if (*start == '\0') - break; /* Nothing left */ - /* Now find the end of the word */ - for (end = start; *end != '\0' && !isspace(*end); end++); - (void) strncpy(argv[argc], start, MIN(end - start, n)); /* Copy it */ - argv[argc][MIN(end - start, n - 1)] = '\0'; /* Terminate */ - start = end; + char *start, *end; /* For sausage machine */ + int argc; + + start = buf; + for (argc = 0; argc < MAX_ARGC; argc++) + { + while (isspace(*start)) + start++; /* Kill whitespace */ + if (*start == '\0') + break; /* Nothing left */ + /* Now find the end of the word */ + for (end = start; *end != '\0' && !isspace(*end); end++) + ; + strncpy(argv[argc], start, MIN(end - start, n)); /* Copy it */ + argv[argc][MIN(end - start, n - 1)] = '\0'; /* Terminate */ + start = end; } - return (argc); + return argc; } /* This is the internal form of Find_command, which recursively searches for a menu_line with command command in the specified menu */ /* It will search to a maximum depth of d */ -struct menu_line * -find_command_from(c, m, d) - char *c; - struct menu *m; - int d; +struct menu_line *find_command_from(char *c, struct menu *m, int d) { - int line; - struct menu_line *maybe; - - if (d < 0) - return ((struct menu_line *) 0); /* Too deep! */ - for (line = 0; line < m->m_length; line++) { - if (!strcmp(c, m->m_lines[line].ml_command)) { - return (&m->m_lines[line]); - } + int line; + struct menu_line *maybe; + + if (d < 0) + return NULL; /* Too deep! */ + for (line = 0; line < m->m_length; line++) + { + if (!strcmp(c, m->m_lines[line].ml_command)) + return &m->m_lines[line]; } - for (line = 0; line < m->m_length; line++) { - if (m->m_lines[line].ml_submenu != NULLMENU && - (maybe = find_command_from(c, m->m_lines[line].ml_submenu, d - 1)) - != (struct menu_line *) 0) { - return (maybe); - } + for (line = 0; line < m->m_length; line++) + { + if (m->m_lines[line].ml_submenu != NULLMENU && + (maybe = find_command_from(c, m->m_lines[line].ml_submenu, d - 1))) + return maybe; } - /* If we got to here, nothing works */ - return ((struct menu_line *) 0); + /* If we got to here, nothing works */ + return NULL; } /* Find_command searches down the current menu tree */ /* And returns a pointer to a menu_line with the specified command name */ /* It returns (struct menu_line *) 0 if none is found */ -struct menu_line * -Find_command(m, command) - Menu *m; - char *command; +struct menu_line *Find_command(Menu *m, char *command) { - if (m == NULLMENU) { - return ((struct menu_line *) 0); - } - else { - return (find_command_from(command, m, MAX_MENU_DEPTH)); + if (m == NULLMENU) + return NULL; + else + return find_command_from(command, m, MAX_MENU_DEPTH); +} + +static char *get_tmp_dir(void) +{ +#ifdef _WIN32 + static char tmp[BUFSIZ]; + DWORD len; + if (!tmp[0]) + { + len = GetTempPath(sizeof(tmp), tmp); + if (!len || (len > sizeof(tmp))) + strcpy(tmp, "."); } + return tmp; +#else + return "/var/tmp"; +#endif } -/*ARGSUSED*/ -int -toggle_logging(argc, argv) - int argc; - char *argv[]; +int toggle_logging(int argc, char *argv[]) { - int pid; - char buf[BUFSIZ]; - - if (log_file == (FILE *) NULL) { - pid = getpid(); - if (!whoami) { - Put_message("I've lost my SENSE of DIRECTION! I have no IDEA who I AM!"); - Put_message("My God... You've turned him into a DEMOCRAT!!"); - Put_message(" -- Doonesbury"); - Put_message(""); - Put_message("translation: your log file can be found in \"/usr/tmp/a.out.pid\"."); - whoami = "a.out"; - (void) sprintf(buf, "/usr/tmp/%s-log.%d", whoami, pid); - } - else - (void) sprintf(buf, "/usr/tmp/%s-log.%d", whoami, pid); - - /* open the file */ - log_file = fopen(buf,"a"); - - if (log_file == (FILE *) NULL) - Put_message("Open of log file failed. Logging is not on."); - else - Put_message("Log file successfully opened."); - } - else { /* log_file is a valid pointer; turn off logging. */ - (void) fflush(log_file); - (void) fclose(log_file); - log_file = (FILE *) NULL; - Put_message("Logging off."); + char buf[BUFSIZ]; + + if (!log_file) + { + sprintf(buf, "%s/%s-log.%ld", get_tmp_dir(), whoami, (long)getpid()); + + /* open the file */ + log_file = fopen(buf, "a"); + + if (!log_file) + Put_message("Open of log file failed. Logging is not on."); + else + Put_message("Log file successfully opened."); } - return(DM_NORMAL); -} + else + { /* log_file is a valid pointer; turn off logging. */ + fflush(log_file); + fclose(log_file); + log_file = NULL; + Put_message("Logging off."); + } + return DM_NORMAL; +}