#include "menu.h"
#include <ctype.h>
+#ifdef HAVE_CURSES
#include <curses.h>
+#endif
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#include <conio.h>
+#include <process.h>
+#ifdef getchar
+#undef getchar
+#endif
+#define getchar() _getch()
+#define getpid _getpid
+#endif /* _WIN32 */
RCSID("$Header$");
+#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)
/* Structure for holding current displayed menu */
struct menu_screen {
+#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)
Menu *top_menu; /* Root for command search */
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, ...);
+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);
/*
* 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(const char *who, long code, const char *fmt, ...)
+void menu_com_err_hook(const char *who, long code, const char *fmt, va_list ap)
{
char buf[BUFSIZ], *cp;
- va_list ap;
- strcpy(buf, who);
- for (cp = buf; *cp; cp++)
- ;
- *cp++ = ':';
- *cp++ = ' ';
+ if (who)
+ {
+ strcpy(buf, who);
+ for (cp = buf; *cp; cp++)
+ ;
+ *cp++ = ':';
+ *cp++ = ' ';
+ }
+ else
+ {
+ cp = buf;
+ *cp = '\0';
+ }
if (code)
{
strcpy(cp, error_message(code));
while (*cp)
cp++;
}
- va_start(ap, fmt);
vsprintf(cp, fmt, ap);
- va_end(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,
void Start_menu(Menu *m)
{
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);
-
- if (initscr() == (WINDOW *)ERR)
+ set_com_err_hook(menu_com_err_hook);
+#ifdef CURSES_HAS_NEWTERM
+ SCREEN *scrn = newterm(NULL, stdout, stdin);
+#else
+ WINDOW *scrn = initscr();
+#endif
+ if (!scrn)
{
- fputs("Can't initialize curses!\n", stderr);
+ fputs("Can't initialize curses!\nReverting to -nomenu mode\n\n", stderr);
Start_no_menu(m);
}
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();
}
set_com_err_hook(old_hook);
- Cleanup_menu();
}
void Cleanup_menu(void)
{
wclear(cur_ms->ms_screen);
wrefresh(cur_ms->ms_screen);
+ endwin();
}
- endwin();
-}
-
-
-/* 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);
}
/*
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);
+}
/*
* This guy actually puts up the menu
parsed_argc = 0;
+#ifdef HAVE_CURSES
/* The following get run only in curses mode */
if (cur_ms != NULLMS)
{
/* 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 - strlen(m->m_title)) >> 1));
+ 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);
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++)
{
/* 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);
}
+#endif /* HAVE_CURSES */
if (margc > 1)
{
/* Initialize argv */
!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);
}
+#endif /* HAVE_CURSES */
if (m->m_exit != NULLFUNC)
m->m_exit(m);
return *argv[0] == 'r' ? DM_NORMAL : DM_QUIT;
}
if (quitflag == DM_QUIT)
{
+#ifdef HAVE_CURSES
if (cur_ms != NULLMS)
{
cur_ms = old_cur_ms;
destroy_ms(my_ms);
}
+#endif /* HAVE_CURSES */
if (m->m_exit != NULLFUNC)
m->m_exit(m);
parsed_argc = 0;
void refresh_screen(void)
{
+#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(char *prompt, char *buf, int buflen)
{
+#ifdef HAVE_CURSES
int c;
char *p;
int y, x, oldx, oldy;
wmove(cur_ms->ms_input, y, 0);
wclrtoeol(cur_ms->ms_input);
y--;
-#ifdef __NetBSD__
- x = cur_ms->ms_input->maxx - 1;
-#else
- x = cur_ms->ms_input->_maxx - 1;
-#endif
+ x = getmaxx(cur_ms->ms_input) - 1;
}
}
break;
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
+ if (x >= getmaxx(cur_ms->ms_input))
{
x = 0;
y++;
return 1;
}
else
+#endif /* HAVE_CURSES */
{
char bigbuf[BUFSIZ];
one at the top of the screen when a ---More--- prompt is displayed */
void Start_paging(void)
{
+#ifdef HAVE_CURSES
if (cur_ms != NULLMS)
lines_left = LINES - cur_ms->ms_input_y - 1;
else
+#endif /* HAVE_CURSES */
lines_left = 23;
}
/* Will be truncated to COLS characters. */
void Put_line(char *msg)
{
- int y, x, i;
- char *msg1, chr;
-
if (!more_flg)
return;
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);
wclrtoeol(cur_ms->ms_input);
}
else
+#endif /* HAVE_CURSES */
{
printf("---More (hit return)---");
getchar();
}
}
+#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++)
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 */
void refresh_ms(struct menu_screen *ms)
{
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.
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
+}
+
int toggle_logging(int argc, char *argv[])
{
char buf[BUFSIZ];
if (!log_file)
{
- sprintf(buf, "/var/tmp/%s-log.%ld", whoami, (long)getpid());
+ sprintf(buf, "%s/%s-log.%ld", get_tmp_dir(), whoami, (long)getpid());
/* open the file */
log_file = fopen(buf, "a");