]> andersk Git - moira.git/blobdiff - clients/moira/menu.c
Enlarge magic constant. Fix this a better way at some point.
[moira.git] / clients / moira / menu.c
index 100ae685123341b71c5fe4cd2e7ea8564eb50011..4c15bb0167701f3ad3cbf427140e38c874c0d9c3 100644 (file)
@@ -1,41 +1,45 @@
-/*
- * 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
+ * <mit-copyright.h>.
  */
 
-#ifndef lint
-static char rcsid_menu_c[] = "$Header$";
-#endif
-
 #include <mit-copyright.h>
-#include <sys/types.h>
+#include <moira.h>
+#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>
-#include <signal.h>
-#include <curses.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#include <termios.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <com_err.h>
-#include <moira.h>
-#include "menu.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)
@@ -50,94 +54,115 @@ int more_flg = 1;
 
 /* 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 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(const char *who, long code, const char *fmt,
-                      caddr_t arg1, caddr_t arg2, caddr_t arg3,
-                      caddr_t arg4, caddr_t arg5)
+void menu_com_err_hook(const char *who, long code, const char *fmt, va_list ap)
 {
   char buf[BUFSIZ], *cp;
 
-  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++;
     }
-  sprintf(cp, fmt, arg1, arg2, arg3, arg4, arg5);
+  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.
  */
-int Start_menu(Menu *m)
+void Start_menu(Menu *m)
 {
-  struct menu_screen *make_ms();
-  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);
-
-  if (initscr() == (WINDOW *)ERR)
+  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
+  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();
 }
 
-int Cleanup_menu(void)
+void Cleanup_menu(void)
 {
   if (cur_ms)
     {
       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 */
-int Start_no_menu(Menu *m)
-{
-  cur_ms = NULLMS;
-  COLS = 80;
-  /* Run the menu */
-  Do_menu(m, -1, NULL);
 }
 
 /*
@@ -173,7 +198,7 @@ struct menu_screen *make_ms(int length)
 /*
  * This routine destroys a menu_screen.
  */
-int destroy_ms(struct menu_screen *ms)
+void destroy_ms(struct menu_screen *ms)
 {
   delwin(ms->ms_title);
   delwin(ms->ms_menu);
@@ -181,6 +206,16 @@ int destroy_ms(struct menu_screen *ms)
   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
@@ -195,10 +230,9 @@ int Do_menu(Menu *m, int margc, char *margv[])
   char *argv[MAX_ARGC];
   int line;
   int i;
-  struct menu_line *command, *Find_command();
+  struct menu_line *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)
@@ -219,6 +253,7 @@ int Do_menu(Menu *m, int margc, char *margv[])
 
   parsed_argc = 0;
 
+#ifdef HAVE_CURSES
   /* The following get run only in curses mode */
   if (cur_ms != NULLMS)
     {
@@ -230,7 +265,7 @@ int Do_menu(Menu *m, int margc, char *margv[])
       /* 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);
@@ -259,6 +294,7 @@ int Do_menu(Menu *m, int margc, char *margv[])
       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++)
@@ -280,12 +316,14 @@ int Do_menu(Menu *m, int margc, char *margv[])
     {
       /* 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 */
@@ -322,11 +360,13 @@ int Do_menu(Menu *m, int margc, char *margv[])
               !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;
@@ -398,11 +438,13 @@ int Do_menu(Menu *m, int margc, char *margv[])
        }
       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;
@@ -413,19 +455,22 @@ int Do_menu(Menu *m, int margc, char *margv[])
     }
 }
 
-int refresh_screen(void)
+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;
@@ -486,11 +531,7 @@ int Prompt_input(char *prompt, char *buf, int buflen)
                      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;
@@ -508,11 +549,7 @@ int Prompt_input(char *prompt, char *buf, int buflen)
                  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++;
@@ -530,12 +567,16 @@ int Prompt_input(char *prompt, char *buf, int buflen)
       refresh_ms(cur_ms);
       *p = '\0';
       Start_paging();
-      goto gotit;
+      strcpy(buf, strtrim(buf));
+      return 1;
     }
   else
+#endif /* HAVE_CURSES */
     {
+      char bigbuf[BUFSIZ];
+
       printf("%s", prompt);
-      if (!fgets(buf, buflen, stdin))
+      if (!fgets(bigbuf, BUFSIZ, stdin))
        return 0;
       if (interrupt)
        {
@@ -543,11 +584,13 @@ int Prompt_input(char *prompt, char *buf, int buflen)
          return 0;
        }
       Start_paging();
-      goto gotit;
+      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;
@@ -555,22 +598,24 @@ 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 */
-int Start_paging(void)
+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;
 }
 
 /* Turn off paging */
-int Stop_paging(void)
+void Stop_paging(void)
 {
   lines_left = -1;
 }
 
 /* Print a message in the input window of cur_ms.  */
-int Put_message(char *msg)
+void Put_message(char *msg)
 {
   char *copy, *line, *s;
 
@@ -607,11 +652,8 @@ int Put_message(char *msg)
 }
 
 /* Will be truncated to COLS characters.  */
-int Put_line(char *msg)
+void Put_line(char *msg)
 {
-  int y, x, i;
-  char *msg1, chr;
-
   if (!more_flg)
     return;
 
@@ -620,8 +662,12 @@ int Put_line(char *msg)
       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);
@@ -639,6 +685,7 @@ int Put_line(char *msg)
              wclrtoeol(cur_ms->ms_input);
            }
          else
+#endif /* HAVE_CURSES */
            {
              printf("---More (hit return)---");
              getchar();
@@ -647,8 +694,12 @@ int Put_line(char *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++)
@@ -656,16 +707,19 @@ int Put_line(char *msg)
       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 */
-int refresh_ms(struct menu_screen *ms)
+void refresh_ms(struct menu_screen *ms)
 {
   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.
@@ -728,26 +782,30 @@ struct menu_line *Find_command(Menu *m, char *command)
     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[])
 {
-  int pid;
   char buf[BUFSIZ];
 
   if (!log_file)
     {
-      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";
-         sprintf(buf, "/usr/tmp/%s-log.%d", whoami, pid);
-       }
-      else
-       sprintf(buf, "/usr/tmp/%s-log.%d", whoami, pid);
+      sprintf(buf, "%s/%s-log.%ld", get_tmp_dir(), whoami, (long)getpid());
 
       /* open the file */
       log_file = fopen(buf, "a");
This page took 0.054104 seconds and 4 git commands to generate.