#endif lint
+#include <mit-copyright.h>
#include <sys/types.h>
#include <stdio.h>
+#include <string.h>
#include <signal.h>
#include <curses.h>
+#ifdef POSIX
+#include <unistd.h>
+#include <termios.h>
+#endif /* POSIX */
#include <ctype.h>
-#include <strings.h>
+#ifndef sun
#include <varargs.h>
+#endif
#include <com_err.h>
+#include <moira.h>
#include "menu.h"
+#ifndef __STDC__
+#define const
+#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 */
+extern int interrupt; /* will be set if ^C is received */
extern FILE *fdopen();
+#ifndef sgi
extern int getpid();
+#endif
extern char *calloc();
extern char *whoami;
FILE *log_file = (FILE *) NULL; /* file stream of log file */
int more_flg = 1;
+#ifdef POSIX
+extern char *malloc();
+#endif
+
/* Structure for holding current displayed menu */
struct menu_screen {
WINDOW *ms_screen; /* Window for this menu */
#define NULLMS ((struct menu_screen *) 0)
Menu *top_menu; /* Root for command search */
+int parsed_argc; /* used by extern routines to get additional */
+char **parsed_argv; /* comand line input */
/*
* Hook function to cause error messages to be printed through
- * curses instead of around it.
+ * curses instead of around it. Takes at most 5 args to the
+ * printf string (crock...)
*/
-int
-menu_com_err_hook(who, code, fmt, args)
- char *who;
- int code;
- char *fmt;
- va_list args;
+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;
{
char buf[BUFSIZ], *cp;
- FILE _strbuf;
-
(void) strcpy(buf, who);
for (cp = buf; *cp; cp++);
*cp++ = ':';
while (*cp)
cp++;
}
- _strbuf._flag = _IOWRT + _IOSTRG;
- _strbuf._ptr = cp;
- _strbuf._cnt = BUFSIZ - (cp - buf);
- _doprnt(fmt, args, &_strbuf);
- (void) putc('\0', &_strbuf);
+ sprintf(cp, fmt, arg1, arg2, arg3, arg4, arg5);
Put_message(buf);
}
Menu *m;
{
struct menu_screen *make_ms();
- register int (*old_hook)() = set_com_err_hook(menu_com_err_hook);
+#ifdef __STDC__
+ register void (*old_hook)(const char *, long, const char *, va_list) = set_com_err_hook(menu_com_err_hook);
+#else
+ register void (*old_hook)() = set_com_err_hook(menu_com_err_hook);
+#endif
- if (initscr() == ERR) {
+ 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 */
- top_menu = m;
+ /* menu_screen */
/* Run the menu */
(void) Do_menu(m, -1, (char **) NULL);
}
{
cur_ms = NULLMS;
COLS = 80;
- top_menu = m;
/* Run the menu */
(void) Do_menu(m, -1, (char **) NULL);
}
int length;
{
struct menu_screen *ms;
- char *malloc();
if (MAX_TITLE + length + MIN_INPUT > LINES) {
fputs("Menu too big!\n", stderr);
int margc;
char *margv[];
{
- struct menu_screen *my_ms, *old_cur_ms;
+ 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 toggle_logging();
/* Entry function gets called with old menu_screen still current */
- if (m->m_entry != NULLFUNC)
+ 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) {
/* This is here because we may be coming from another menu */
if (cur_ms != NULL)
touchwin(my_ms->ms_screen);
- /* Get a command */
- if (!Prompt_input("Command: ", buf, sizeof(buf)))
- 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;
+ 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;
+ }
if ((line = atoi(argv[0])) > 0 && line <= m->m_length) {
command = &m->m_lines[line - 1];
}
continue;
}
/* finally, try to find it using Find_command */
- else if ((command = Find_command(argvals[0])) ==
+ else if ((command = Find_command(m, argvals[0])) ==
(struct menu_line *) 0) {
- Put_message("Command not recognized");
+ sprintf(buf, "Command not recognized: %s\n", argvals[0]);
+ Put_message(buf);
continue;
}
/* If we got to here, command is a valid menu_line */
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);
}
if (m->m_exit != NULLFUNC)
m->m_exit(m);
+ parsed_argc = 0;
return (DM_QUIT);
}
punt_command:
- ;
+ parsed_argc = 0;
}
}
+refresh_screen()
+{
+ if (cur_ms != NULLMS) {
+ touchwin(cur_ms->ms_screen);
+ refresh_ms(cur_ms);
+ }
+}
+
+
/* Prompt the user for input in the input window of cur_ms */
int Prompt_input(prompt, buf, buflen)
char *prompt;
{
int c;
char *p;
- int y, x, oldx;
+ 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);
- touchwin(cur_ms->ms_screen);
- refresh_ms(cur_ms);
+ 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);
-#ifdef notdef
(void) wclrtoeol(cur_ms->ms_input);
-#endif notdef
- refresh_ms(cur_ms);
+ (void) wrefresh(cur_ms->ms_input);
c = getchar() & 0x7f;
switch (c) {
case CTL('C'):
+ *p = '\0';
return 0;
case CTL('Z'):
(void) kill(getpid(), SIGTSTP);
case CTL('L'):
(void) wclear(cur_ms->ms_input);
(void) waddstr(cur_ms->ms_input, prompt);
- (void) touchwin(cur_ms->ms_screen);
-#ifdef notdef
- refresh_ms(cur_ms);
-#endif notdef
+ (void) touchwin(cur_ms->ms_input);
+ (void) move(LINES - 1, 0);
+ (void) wrefresh(curscr);
getyx(cur_ms->ms_input, y, x);
+ oldy = y;
+ oldx = x;
+ p = buf;
break;
case '\n':
if (p > buf) {
p--;
x--;
+ if (x < 0) {
+ (void) wmove(cur_ms->ms_input, y, 0);
+ (void) wclrtoeol(cur_ms->ms_input);
+ y--;
+ x = cur_ms->ms_input->_maxx-1;
+ }
}
break;
case CTL('U'):
case CTL('G'):
case CTL('['):
x = oldx;
+ y = oldy;
p = buf;
break;
default:
- if (isprint(c) && (p - buf < buflen)) {
+ /* (buflen - 1) leaves room for the \0 */
+ if (isprint(c) && (p - buf < buflen - 1)) {
(void) waddch(cur_ms->ms_input, c);
*p++ = c;
x++;
+ if (x >= cur_ms->ms_input->_maxx) {
+ x = 0;
+ y++;
+ }
} else
putchar(CTL('G'));
break;
}
end_input:
(void) waddch(cur_ms->ms_input, '\n');
- (void) waddch(cur_ms->ms_input, '\r');
(void) wclrtoeol(cur_ms->ms_input);
refresh_ms(cur_ms);
printf("%s", prompt);
if (gets(buf) == NULL)
return 0;
+ if (interrupt) {
+ interrupt = 0;
+ return 0;
+ }
Start_paging();
goto gotit;
}
(void) wclear(cur_ms->ms_input);
(void) waddstr(cur_ms->ms_input, prompt);
refresh_ms(cur_ms);
+ (void) move(LINES - 1, 0);
+ (void) wrefresh(curscr);
getyx(cur_ms->ms_input, y, x);
break;
case '\n':
case '\r':
(void) waddch(cur_ms->ms_input, '\n');
- (void) waddch(cur_ms->ms_input, '\r');
(void) wclrtoeol(cur_ms->ms_input);
refresh_ms(cur_ms);
}
}
else {
+#ifdef POSIX
+ struct termios ttybuf, nttybuf;
+#else
struct sgttyb ttybuf, nttybuf;
+#endif /* POSIX */
printf("%s", prompt);
/* turn off echoing */
+#ifdef POSIX
+ tcgetattr(0, &ttybuf);
+ nttybuf = ttybuf;
+ nttybuf.c_lflag &= ~ECHO;
+ tcsetattr(0, TCSANOW, &nttybuf);
+ if (gets(buf) == NULL) {
+ tcsetattr(0, TCSANOW, &ttybuf);
+ putchar('\n');
+ return 0;
+ }
+ putchar('\n');
+ (void) ioctl(0, TCSETA, (char *)&ttybuf);
+#else
(void) ioctl(0, TIOCGETP, (char *)&ttybuf);
nttybuf = ttybuf;
nttybuf.sg_flags &= ~ECHO;
}
putchar('\n');
(void) ioctl(0, TIOCSETP, (char *)&ttybuf);
+#endif /* POSIX */
Start_paging();
return 1;
}
(void) wstandend(cur_ms->ms_input);
refresh_ms(cur_ms);
chr = getchar() & 0x7f;/* We do care what it is */
- if (chr == 'q' || chr == 'Q') {
+ if (chr == 'q' || chr == 'Q' || chr == 3 /* ^C */) {
more_flg = 0;
return;
}
}
else {
printf("---More (hit return)---");
- (void) getchar() & 0x7f;
+ getchar();
}
Start_paging(); /* Reset lines_left */
}
for (i = strlen(msg1); i < COLS - 1; i++)
msg1[i] = ' ';
(void) wprintw(cur_ms->ms_input, "%s\n", msg1);
-/* refresh_ms(cur_ms); */
}
else {
puts(msg);
refresh_ms(ms)
struct menu_screen *ms;
{
- int y, x;
-
- getyx(ms->ms_input, y, x);
- (void) wmove(ms->ms_screen, y + ms->ms_input_y, x);
- (void) wrefresh(ms->ms_screen);
+ (void) wrefresh(ms->ms_title);
+ (void) wrefresh(ms->ms_menu);
+ (void) wrefresh(ms->ms_input);
}
/* Parse buf into a list of words, which will be placed in strings specified by
if (!strcmp(c, m->m_lines[line].ml_command)) {
return (&m->m_lines[line]);
}
- else 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) {
+ }
+ 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);
}
}
/* 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(command)
+Find_command(m, command)
+ Menu *m;
char *command;
{
- if (top_menu == NULLMENU) {
+ if (m == NULLMENU) {
return ((struct menu_line *) 0);
}
else {
- return (find_command_from(command, top_menu, MAX_MENU_DEPTH));
+ return (find_command_from(command, m, MAX_MENU_DEPTH));
}
}
if (log_file == (FILE *) NULL) {
pid = getpid();
if (!whoami) {
- char *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");
}
return(DM_NORMAL);
}
-
-/*
- * Local Variables:
- * mode: c
- * c-indent-level: 4
- * c-continued-statement-offset: 4
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * End:
- */