home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume14 / mush6.0 / part07 / curses.c next >
C/C++ Source or Header  |  1988-04-12  |  21KB  |  712 lines

  1. /* @(#)curses.c    (c) copyright 3/18/87 (Dan Heller) */
  2.  
  3. /* curses.c -- routine to deal with the curses interface */
  4. #ifdef CURSES
  5.  
  6. #include "mush.h"
  7. #include "bindings.h"
  8.  
  9. curses_init(argc, argv)
  10. register char **argv;
  11. {
  12.     char buf[80];
  13.     extern char *UP, ttytype[];
  14.  
  15.     if (argv && *++argv && !strcmp(*argv, "-?"))
  16.     return help(0, "curses", cmd_help);
  17.     if (iscurses) {
  18.     print("You can't run curses from the curses mode (silly).");
  19.     return -1;
  20.     }
  21.     if (ison(glob_flags, IS_GETTING)) {
  22.     print("Finish your letter first.\n");
  23.     return -1;
  24.     }
  25. #ifdef SUNTOOL
  26.     if (istool) {
  27.     print("My, aren't we the adventuresome type!");
  28.     timerclear(&(mail_timer.it_interval));
  29.     timerclear(&(mail_timer.it_value));
  30.     tool_destroy(tool), istool = FALSE;
  31.     curses_init(0, 0);
  32.     do_loop(); /* doesn't return */
  33.     }
  34. #endif /* SUNTOOL */
  35.  
  36. #ifndef attrset        /* terminfo version of curses */
  37.     /* you can not start curses in no echo mode.. must be in normal mode */
  38.     echom();
  39.     nocrmode();
  40. #endif /* attrset */
  41.     (void) initscr();
  42. #ifdef SIGCONT
  43.     /* initscr will play with signals -- make sure they're set right. */
  44.     (void) signal(SIGTSTP, stop_start);
  45.     (void) signal(SIGCONT, stop_start);
  46. #endif /* SIGCONT */
  47. #if !defined(SYSV) && !defined(USG)
  48.     if (!UP || !*UP)
  49. #else /* ~SYSV && ~USG */
  50.     if (!stdscr)
  51. #endif /* ~SYSV && ~USG */
  52.          {
  53.     print("Terminal type %s can not use the curses interface.\n", ttytype);
  54.     return -1;
  55.     }
  56.     iscurses = TRUE;
  57.     noechom(); /* reset tty state -- */
  58.     crmode(); /* do not use "echo_on/off()" */
  59.     scrollok(stdscr, TRUE);
  60.     /* if the user hasn't set his screen explicitely, set it for him */
  61.     if (!do_set(set_options, "screen"))
  62. #ifdef USG
  63.     switch (_tty.sg_ospeed & CBAUD)
  64. #else /* USG */
  65.     switch (_tty.sg_ospeed)
  66. #endif /* USG */
  67.     {
  68.         case B300 :  screen = min(LINES-2, 7);
  69.         when B1200 : screen = min(LINES-2, 14);
  70.         when B2400 : screen = min(LINES-2, 22);
  71.         otherwise :  screen = LINES-2;
  72.     }
  73.     else
  74.     screen = min(screen, LINES-2);
  75.     crt = LINES;
  76.     (void) cmd_line(sprintf(buf, "set screen = %d crt = %d", screen, crt),
  77.     msg_list);
  78.     if (argc)
  79.     (void) cmd_line(sprintf(buf, "headers %d", current_msg+1), msg_list);
  80.     if (!do_set(set_options, "no_reverse"))
  81.     turnon(glob_flags, REV_VIDEO);
  82.     turnoff(glob_flags, CONT_PRNT);
  83.     return -1; /* doesn't affect messages */
  84. }
  85.  
  86. /*
  87.  * get input in cbreak mode and execute the appropriate command.
  88.  * when the command is done (usually), the user is prompted to
  89.  * hit any key to continue. At this point, the user may enter a
  90.  * new command so no screen refreshing needds to be done. This
  91.  * new command is returned to caller and may be passed back.
  92.  *
  93.  * The flag CNTD_CMD (continued command) is set if
  94.  * this routine is called with the passed parameter (c) > 0. If
  95.  * so, then the character passed is the character input by the
  96.  * user at the last "hit return" prompt indicating that he wants
  97.  * to execute a new command and not draw the screen.
  98.  *
  99.  * CNTD_CMD is also set if the command that the user invokes
  100.  * causes any sort of output that requires a screen refresh.  The
  101.  * variable redo is set to 1 if the header page not only requires
  102.  * redrawing, but updating ... (new call to do_hdrs)
  103.  *
  104.  * calls that say: print("%s", compose_hdr(current_msg)) are constructed
  105.  * that way cuz if the header has a `%' in it, then print will try to
  106.  * expand it.
  107.  */
  108. curses_command(c)
  109. register int c;
  110. {
  111.     char     buf[BUFSIZ], file[128], list[128];
  112.     int     n, curlin;
  113.     static int  redo;  /* set if headers should be redrawn */
  114.  
  115.     if (c > 0)
  116.     turnon(glob_flags, CNTD_CMD);
  117.     else
  118.     turnoff(glob_flags, CNTD_CMD);
  119.     clear_msg_list(msg_list); /* play it safe */
  120.     if (isoff(glob_flags, CNTD_CMD)) {
  121.     (void) check_new_mail();
  122.     curlin = max(1, current_msg - n_array[0] + 1);
  123.     (void) strncpy(buf, stdscr->_y[curlin], COLS-1);
  124.     buf[COLS-1] = 0; /* strncpy does not null terminate */
  125.     if (ison(glob_flags, REV_VIDEO) && msg_cnt)
  126.         STANDOUT(curlin, 0, buf);
  127.     mail_status(0);
  128.     move(curlin, 0), refresh();
  129.     /* reprint to remove reverse video from current line (don't refresh) */
  130.     if (ison(glob_flags, REV_VIDEO))
  131.         mvaddstr(curlin, 0, buf);
  132.     c = getcmd(); /* get input AFTER line redrawn without reverse video */
  133.     }
  134.     buf[0] = list[0] = file[0] = '\0';
  135.  
  136.     /* goto a specific line number */
  137.     if (c == C_GOTO_MSG) {
  138.     c = C_NULL;
  139.     if (msg_cnt <= 1)
  140.         print("Not enough messages."), getchar(); /* flush digit typed */
  141.     else if (curses_msg_list(strcpy(buf, "goto msg: "), list, msg_list)) {
  142.         n = current_msg;
  143.         do if (++n >= msg_cnt)
  144.         n = 0;
  145.         while (n != current_msg && !msg_bit(msg_list, n));
  146.         if (n == current_msg && !msg_bit(msg_list, n))
  147.         print("Message not found.");
  148.         else if ((current_msg = n) < n_array[0] || n > n_array[screen-1])
  149.         redo = 1;
  150.     }
  151.     if (ison(glob_flags, CNTD_CMD) && msg_cnt)
  152.         print("%-.*s", COLS-2, compose_hdr(current_msg));
  153.     if (ison(glob_flags, CNTD_CMD))
  154.         putchar('\n');
  155.     } else if (c == C_WRITE_LIST || c == C_SAVE_LIST || c == C_COPY_LIST
  156.                    || c == C_DELETE_LIST || c == C_UNDEL_LIST) {
  157.     
  158.     if (msg_cnt <= 1)
  159.         print("Not enough messages."), c = C_NULL;
  160.     else if (ison(glob_flags, READ_ONLY))
  161.         print("Folder is read-only."), c = C_NULL;
  162.     else if (!curses_msg_list(sprintf(buf, "%s msg list: ",
  163.         (c == C_WRITE_LIST)? "write" : (c == C_SAVE_LIST)?  "save" :
  164.         (c == C_DELETE_LIST)? "delete" : "undelete"), list, msg_list))
  165.         c = C_NULL;
  166.     if (ison(glob_flags, CNTD_CMD))
  167.         putchar('\n');
  168.     }
  169.  
  170.     /* first do non-mail command stype stuff */
  171.     switch (c) {
  172.     case C_NULL : ;
  173.  
  174.     /* screen optimization stuff */
  175.     when C_REVERSE :
  176.         if (ison(glob_flags, REV_VIDEO))
  177.         turnoff(glob_flags, REV_VIDEO);
  178.         else
  179.         turnon(glob_flags, REV_VIDEO);
  180.  
  181.     when C_REDRAW : if (!redo) redraw();
  182.  
  183.     /*
  184.      * screen movement
  185.      */
  186.     when C_NEXT_MSG :
  187.     /* case 'j' : case 'J' : case '+' : case '\n' : /* next */
  188.         if (current_msg + 2 > msg_cnt ||
  189.         isoff(glob_flags, CNTD_CMD) && curlin == screen)
  190.         bell(); /* reached the end */
  191.         else {
  192.         if (++current_msg > n_array[screen-1])
  193.             redo = 1;
  194.         if (ison(glob_flags, CNTD_CMD)) {
  195.             print("%-.*s", COLS-2, compose_hdr(current_msg));
  196.             putchar('\n');
  197.         }
  198.         }
  199.  
  200.     when C_PREV_MSG :
  201.     /* when 'k' : case 'K' : case '-' : case CTRL(k) : /* previous */
  202.         if (isoff(glob_flags, CNTD_CMD) && curlin == 1 || current_msg == 0)
  203.         bell();  /* at the beginning */
  204.         else {
  205.         if (--current_msg < n_array[0])
  206.             redo = 1;
  207.         if (ison(glob_flags, CNTD_CMD)) {
  208.             print("%-.*s", COLS-2, compose_hdr(current_msg));
  209.             putchar('\n');
  210.         }
  211.         }
  212.  
  213.     when C_FIRST_MSG : case C_LAST_MSG :
  214.         n = current_msg;
  215.         move(LINES-1, 0), refresh();
  216.         if (c == C_FIRST_MSG && (current_msg = 0) < n_array[0] ||
  217.         c == C_LAST_MSG && (current_msg = msg_cnt-1)> n_array[screen-1])
  218.         if (isoff(glob_flags, CNTD_CMD))
  219.             (void) cmd_line(sprintf(buf, "headers %d", current_msg+1),
  220.                  msg_list);
  221.         else
  222.             redo = 1;
  223.         if (ison(glob_flags, CNTD_CMD) && n != current_msg)
  224.         print("%-.*s", COLS-2, compose_hdr(current_msg)), putchar('\n');
  225.  
  226.     /* top and bottom of headers screen */
  227.     when C_TOP_PAGE : case C_BOTTOM_PAGE :
  228.         if (isoff(glob_flags, CNTD_CMD))
  229.         if (c == C_TOP_PAGE)
  230.             current_msg = n_array[0];
  231.         else
  232.             current_msg = min(n_array[screen-1], msg_cnt-1);
  233.         else
  234.         bell();
  235.  
  236.     when C_NEXT_SCREEN : /* next page */
  237.         move(LINES-1, 0), refresh();
  238.         if (msg_cnt > screen) {
  239.         clear();
  240.         (void) cmd_line(strcpy(buf, "headers +"), msg_list);
  241.         current_msg = n_array[0];
  242.         return redo = 0;
  243.         } else
  244.         bell();
  245.  
  246.     when C_PREV_SCREEN : /* previous page */
  247.         move(LINES-1, 0), refresh();
  248.         if (n_array[0] > 0) {
  249.         clear();
  250.         (void) cmd_line(strcpy(buf, "headers -"), msg_list);
  251.         current_msg = n_array[0];
  252.         return redo = 0;
  253.         } else
  254.         bell();
  255.  
  256.     when C_SHOW_HDR :
  257.         if (ison(glob_flags, CNTD_CMD) && msg_cnt)
  258.         puts(compose_hdr(current_msg));
  259.  
  260.     /* read from/save to record file (.mushrc) */
  261.     when C_SOURCE : case C_SAVEOPTS : {
  262.         int argc;
  263.         char *argv[3];
  264.         print("%s filename [default]: ",
  265.         (c == C_SOURCE)? "source" : "save options to");
  266.         argc = Getstr(file, LINES-40, 0);
  267.         clr_bot_line();
  268.         if (argc < 0)
  269.         return 0;
  270.         if (argc > 0)
  271.         argv[1] = file, argc = 2;
  272.         else
  273.         argc = 1;
  274.         argv[argc] = NULL;
  275.         turnon(glob_flags, PRE_CURSES);
  276.         if (c == C_SOURCE)
  277.         (void) source(argc, argv);
  278.         else
  279.         (void) save_opts(argc, argv);
  280.         turnoff(glob_flags, PRE_CURSES);
  281.     }
  282.  
  283.     /*
  284.      * search commands
  285.      */
  286.     when C_NEXT_SEARCH : case C_PREV_SEARCH : case C_CONT_SEARCH :
  287.         if (c != C_CONT_SEARCH)
  288.         c = search(0 + (c == C_PREV_SEARCH));
  289.         else
  290.         c = search(-1);
  291.         if (ison(glob_flags, CNTD_CMD))
  292.         putchar('\n');
  293.         if (c == 0)
  294.         break;
  295.         if (ison(glob_flags, CNTD_CMD))
  296.         print("%-.*s",COLS-2, compose_hdr(current_msg)), putchar('\n');
  297.         if (n_array[0] > current_msg || n_array[screen-1] < current_msg) {
  298.         redo = 1;
  299.         if (isoff(glob_flags, CNTD_CMD))
  300.             (void) cmd_line(sprintf(buf, "headers %d",
  301.                         current_msg+1), msg_list);
  302.         }
  303.  
  304.     /*
  305.      * actions on messages
  306.      */
  307.     /* delete/undelete */
  308.     when C_DELETE_MSG : case C_DELETE_LIST :
  309.     case C_UNDEL_MSG : case C_UNDEL_LIST :
  310.         if (!msg_cnt) {
  311.         print("No messages.");
  312.         if (ison(glob_flags, CNTD_CMD))
  313.             putchar('\n');
  314.         break;
  315.         }
  316.         if (ison(glob_flags, READ_ONLY)) {
  317.         print("Folder is read-only.");
  318.         if (ison(glob_flags, CNTD_CMD))
  319.             putchar('\n');
  320.         break;
  321.         }
  322.         if (!*list)
  323.         set_msg_bit(msg_list, current_msg);
  324.         turnon(glob_flags, DO_UPDATE);
  325.         for (n = 0; n < msg_cnt; n++)
  326.         if (msg_bit(msg_list, n)) {
  327.             if (c == C_DELETE_MSG || c == C_DELETE_LIST)
  328.             turnon(msg[n].m_flags, DELETE);
  329.             else
  330.             turnoff(msg[n].m_flags, DELETE);
  331.             if (isoff(glob_flags, CNTD_CMD) && (msg_cnt < screen ||
  332.             n >= n_array[0] && n <= n_array[screen-1]))
  333.             mvprintw(max(1, n - n_array[0] + 1), 0,
  334.                 "%-.*s", COLS-1, compose_hdr(n));
  335.             else
  336.             redo = 1;
  337.         }
  338.         if (ison(glob_flags, CNTD_CMD) || *list) {
  339.         /* print(), THEN putchar() -- overwrite line */
  340.         if (ison(glob_flags, CNTD_CMD)) {
  341.             print("%sdeleted %s",
  342.             (c == C_DELETE_MSG || c == C_DELETE_LIST)? "":"un", list);
  343.             putchar('\n');
  344.         }
  345.         if (ison(msg[current_msg].m_flags, DELETE))
  346.             (void) next_msg();
  347.         if (isoff(msg[current_msg].m_flags, DELETE) &&
  348.             do_set(set_options, "autoprint"))
  349.             return C_DISPLAY_MSG;
  350.         if (ison(glob_flags, CNTD_CMD))
  351.             puts(compose_hdr(current_msg));
  352.         }
  353.  
  354.     /*
  355.      * write/save messages.  If a list is necessary, the user already
  356.      * entered it above since he must have used a capital letter. If so,
  357.      * list will contain good data (already been validated above).
  358.      * if a list is given, set iscurses to 0 so that print statements
  359.      * will scroll and the user sees the multiple output. else, one
  360.      * line can go on the bottom line just fine.
  361.      */
  362.     when C_WRITE_MSG : case C_SAVE_MSG : case C_COPY_MSG :
  363.     case C_WRITE_LIST : case C_SAVE_LIST : case C_COPY_LIST : {
  364.         register char *p =
  365.         (c == C_WRITE_MSG || c == C_WRITE_LIST)? "write" :
  366.         (c == C_SAVE_MSG  || c == C_SAVE_LIST)? "save" : "copy";
  367.         if (!msg_cnt) {
  368.         print("No messages.");
  369.         if (ison(glob_flags, CNTD_CMD))
  370.             putchar('\n');
  371.         break;
  372.         }
  373.         print(sprintf(buf, "filename to %s%s: ", p,
  374.         (c != C_WRITE_MSG && c != C_WRITE_LIST)? " [mbox]" : ""));
  375.         if (Getstr(file, COLS-1-strlen(buf), 0) >= 0) {
  376.         char *argv[3];
  377.         clr_bot_line();
  378.         argv[0] = strcpy(buf, p);
  379.         argv[1] = (*file) ? file : NULL;
  380.         argv[2] = NULL;
  381.         if (!*list)
  382.             set_msg_bit(msg_list, current_msg);
  383.         move(LINES-1, 0), refresh();
  384.         if (*list)
  385.             iscurses = FALSE;
  386.         /* Turn on piping to make save_msg look at msg_list */
  387.         turnon(glob_flags, IS_PIPE);
  388.         if (save_msg(1 + (*file != '\0'), argv, msg_list) < 0)
  389.             *list = 0;
  390.         turnoff(glob_flags, IS_PIPE);
  391.         if (ison(glob_flags, CNTD_CMD))
  392.             redo = 1, putchar('\n'), puts(compose_hdr(current_msg));
  393.         if (*list)
  394.             iscurses = redo = TRUE, turnon(glob_flags, CNTD_CMD);
  395.         else if (isoff(glob_flags, CNTD_CMD) && msg_cnt)
  396.             mvprintw(curlin, 0, "%-.*s",
  397.             COLS-1, compose_hdr(current_msg));
  398.         } else {
  399.         print("No messages saved.");
  400.         if (ison(glob_flags, CNTD_CMD))
  401.             putchar('\n');
  402.         }
  403.     }
  404.  
  405.     /* preserve message */
  406.     when C_PRESERVE :
  407.         if (!msg_cnt) {
  408.         print("No messages.");
  409.         if (ison(glob_flags, CNTD_CMD))
  410.             putchar('\n');
  411.         break;
  412.         }
  413.         if (ison(msg[current_msg].m_flags, PRESERVE))
  414.         turnoff(msg[current_msg].m_flags, PRESERVE);
  415.         else
  416.         turnon(msg[current_msg].m_flags, PRESERVE);
  417.         turnon(glob_flags, DO_UPDATE);
  418.         if (ison(glob_flags, CNTD_CMD)) {
  419.         wprint("%-.*s\n", COLS-1, compose_hdr(current_msg));
  420.         redo = 1;
  421.         } else
  422.         mvprintw(curlin, 0, "%-.*s", COLS-1, compose_hdr(current_msg));
  423.  
  424.     /* order messages (sort) and rediesplay the headers */
  425.     when C_SORT : case C_REV_SORT :
  426.         (void) strcpy(file, "sort");
  427.         if (c == C_REV_SORT) {
  428.         print("Reverse "), turnon(glob_flags, CONT_PRNT);
  429.         (void) strcat(file, " -");
  430.         }
  431.         print("Order messages by [Status, date, subject, author]: ");
  432.         if ((c = getchar()) == 's' || c == 'S' || c == 'd' || c == 'a') {
  433.         print("reordering messages...");
  434.         (void) cmd_line(sprintf(buf, "%s %c", file, c), msg_list);
  435.         print_more("done.");
  436.         if (ison(glob_flags, CNTD_CMD))
  437.             putchar('\n'), puts(compose_hdr(current_msg));
  438.         redo = 1;
  439.         } else
  440.         clr_bot_line();
  441.  
  442.     when C_QUIT_HARD :
  443.         (void) quit(0, DUBL_NULL);
  444.         redo = 1; /* new mail must have come in */
  445.  
  446.     /* quit or update -- vrfy_update (returns 1 if updated) */
  447.     when C_QUIT : case C_UPDATE : {
  448.         u_long do_update = ison(glob_flags, DO_UPDATE);
  449.         clr_bot_line();
  450.         if (!vrfy_update(&redo))
  451.         if (c == C_UPDATE)
  452.             break;
  453.         else
  454.             turnoff(glob_flags, DO_UPDATE);
  455.         if (c == C_QUIT) {
  456.         if (do_update)
  457.             putchar('\n');
  458.         cleanup(0);
  459.         redo = 1;
  460.         } else if (isoff(glob_flags, CNTD_CMD))
  461.         (void) cmd_line(sprintf(buf, "headers %d", current_msg+1),
  462.                 msg_list);
  463.     }
  464.  
  465.     when C_EXIT : case C_EXIT_HARD :
  466.         clr_bot_line();
  467.         iscurses = FALSE;
  468.         if (c != C_EXIT && c != C_EXIT_HARD)
  469.         putchar('\n');
  470.         cleanup(0);
  471.  
  472.     /* change to a new folder */
  473.     when C_FOLDER :
  474.         for (;;) {
  475.         int (*oldint)(), (*oldquit)();
  476.         on_intr();
  477.         print("New folder (?=list): ");
  478.         c = Getstr(file, COLS-22, 0);
  479.         off_intr();
  480.         if (c > 0) {
  481.             if (!strcmp(file, "?")) {
  482.             clr_bot_line();
  483.             iscurses = 0;
  484.             puts("folders in your folder directory:");
  485.             (void) cmd_line(strcpy(buf, "folders"), msg_list);
  486.     puts("Precede folder names with a +. `%' to specify system mailbox.");
  487.             turnon(glob_flags, CNTD_CMD), iscurses = 1;
  488.             continue;
  489.             }
  490.             clearok(stdscr, FALSE);
  491.             /* if vrfy_update doesn't verify, but folder command fails,
  492.              * then we need to reset the updatability of curren folder
  493.              */
  494.             c = (ison(glob_flags, DO_UPDATE))? TRUE : FALSE;
  495.             if (strcmp(file, "-?"))
  496.             (void) vrfy_update(&redo);
  497.             move(LINES-1, 0), refresh();
  498.             if (cmd_line(sprintf(buf, "folder ! -N %s", file),
  499.                  msg_list) == -1) {
  500.             if (c) /* remember state of updatability of folder */
  501.                 turnon(glob_flags, DO_UPDATE);
  502.             if (ison(glob_flags, CNTD_CMD))
  503.                 putchar('\n');
  504.             } else
  505.             redo = 1, turnoff(glob_flags, CNTD_CMD);
  506.             break;
  507.         } else {
  508.             print("\"%s\" unchanged.", mailfile);
  509.             if (ison(glob_flags, CNTD_CMD))
  510.             putchar('\n');
  511.             break;
  512.         }
  513.         }
  514.  
  515.     /* shell escape */
  516.     when C_SHELL_ESC :
  517.         print("Shell command: ");
  518.         if (Getstr(file, COLS-24, 0) < 0)
  519.         clr_bot_line();
  520.         else {
  521.         putchar('\n');
  522.         iscurses = FALSE;
  523.         (void) cmd_line(sprintf(buf, "sh %s", file), msg_list);
  524.         iscurses = TRUE;
  525.         turnon(glob_flags, CNTD_CMD);
  526.         }
  527.  
  528.     /* do a line-mode like command */
  529.     when C_CURSES_ESC :
  530.         print(":");
  531.         if (Getstr(buf, COLS-2, 0) < 0)
  532.         break;
  533.         putchar('\n');
  534.         iscurses = FALSE;
  535.         if (!*buf) {
  536.         /* return -1 because iscurses = 0 is not enough! */
  537.         redo = 0;
  538.         endwin(); /* this turns echoing back on! */
  539.         echo_off();
  540.         return -1;
  541.         }
  542.         (void) cmd_line(buf, msg_list);
  543.         /* they may have affected message status or had text output */
  544.         turnon(glob_flags, CNTD_CMD), redo = 1;
  545.         iscurses = TRUE;
  546.         if (msg_cnt)
  547.         puts(compose_hdr(current_msg));
  548.  
  549.     /* send message to printer */
  550.     when C_PRINT_MSG : (void) lpr(0, DUBL_NULL, msg_list);
  551.  
  552.     /* cd */
  553.     when C_CHDIR :
  554.         print("chdir to [.]: ");
  555.         if (Getstr(file, COLS-12, 0) < 0)
  556.         break;
  557.         clr_bot_line();
  558.         (void) cmd_line(sprintf(buf, "cd %s", file), msg_list);
  559.         if (ison(glob_flags, CNTD_CMD))
  560.         putchar('\n');
  561.  
  562.     /* variable settings */
  563.     when C_VAR_SET : case C_IGNORE : case C_ALIAS : case C_OWN_HDR :
  564.         curs_vars(c); /* CNTD_CMD is reset if there's output! */
  565.  
  566.     when C_VERSION :
  567.         (void) do_version();
  568.         if (ison(glob_flags, CNTD_CMD))
  569.         putchar('\n');
  570.  
  571.     when C_MAIL_FLAGS :
  572.         print("flags [-?]: ");
  573.         if ((c = Getstr(file, COLS-12, 0)) < 0)
  574.         break;
  575.         putchar('\n');
  576.         if (c == 0)
  577.         (void) strcpy(file, "-?");
  578.     /* Fall thru */
  579.     case C_MAIL : {
  580.         u_long flgs = glob_flags;
  581.         turnon(glob_flags, IGN_BANG);
  582.         clr_bot_line();
  583.         iscurses = FALSE;
  584.         (void) cmd_line(sprintf(buf, "mail %s", file), msg_list);
  585.         glob_flags = flgs;
  586.         iscurses = TRUE, turnon(glob_flags, CNTD_CMD);
  587.         if (msg_cnt)
  588.         print("%-.*s", COLS-2, compose_hdr(current_msg)), putchar('\n');
  589.     }
  590.  
  591.     /* reply to mail */
  592.     when C_REPLY_SENDER : case C_REPLY_ALL : {
  593.         register char *p = (c == C_REPLY_ALL)? "replyall" : "replysender";
  594.         clr_bot_line();
  595.         iscurses = FALSE;
  596.         if (isoff(msg[current_msg].m_flags, REPLIED))
  597.         redo = 1;
  598.         (void) cmd_line(sprintf(buf, "%s %d", p, current_msg+1),
  599.         msg_list);
  600.         if (msg_cnt)
  601.         puts(compose_hdr(current_msg));
  602.         iscurses = TRUE, turnon(glob_flags, CNTD_CMD);
  603.     }
  604.  
  605.     /* type out a message */
  606.     when C_DISPLAY_MSG : case C_TOP_MSG : case C_DISPLAY_NEXT :
  607.         if (!msg_cnt ||
  608.         c != C_DISPLAY_NEXT && ison(msg[current_msg].m_flags, DELETE)) {
  609.         if (!msg_cnt)
  610.             print("No messages.");
  611.         else
  612.             print("Message %d deleted; type 'u' to undelete.",
  613.                       current_msg+1);
  614.         if (ison(glob_flags, CNTD_CMD))
  615.             putchar('\n');
  616.         break;
  617.         }
  618.         clr_bot_line();
  619.         iscurses = FALSE;
  620.         if (ison(glob_flags, CNTD_CMD))
  621.         putchar('\n');
  622.         if (c == C_DISPLAY_MSG)
  623.         c = cmd_line(strcpy(buf, "type"), msg_list);
  624.         else if (c == C_TOP_MSG)
  625.         c = cmd_line(strcpy(buf, "top"), msg_list);
  626.         else
  627.         c = cmd_line(strcpy(buf, "next"), msg_list);
  628.         if (c > -1)
  629.         turnon(glob_flags, CNTD_CMD), redo = 1;
  630.         iscurses = TRUE;
  631.         puts(compose_hdr(current_msg));
  632.  
  633.     /* bind a key or string to a command */
  634.     when C_BIND :  case C_UNBIND : {
  635.         char *argv[2];
  636.         argv[0] = (c == C_BIND) ? "bind" : "unbind";
  637.         argv[1] = NULL;
  638.         if (bind_it(0, argv) < -1)
  639.         turnon(glob_flags, CNTD_CMD);
  640.         else if (ison(glob_flags, CNTD_CMD)) /* if it was set anyway */
  641.         putchar('\n');
  642.     }
  643.  
  644.     /* help stuff */
  645.     when C_HELP :
  646.         (void) c_bind(NULL);
  647.         turnon(glob_flags, CNTD_CMD);
  648.         if (msg_cnt)
  649.         puts(compose_hdr(current_msg));
  650.  
  651.     /* now do interactive stuff as if run from the mush shell */
  652.     otherwise :
  653.         bell();
  654.         if (ison(glob_flags, CNTD_CMD)) {
  655.         /* use print instead of puts to overwrite hit_return msg */
  656.         print("unknown command"), putchar('\n');
  657.         redo = 1;
  658.         }
  659.     }
  660.  
  661.     if (ison(glob_flags, CNTD_CMD)) {
  662.     int old_cnt = msg_cnt;
  663.     if (!(c = hit_return()) && !redo && msg_cnt == old_cnt)
  664.         redraw();
  665.     clr_bot_line();
  666.     if (old_cnt !=  msg_cnt)
  667.         redo = 1;
  668.     if (c)
  669.         return c;
  670.     }
  671.     if (redo) {
  672.     n = current_msg;
  673.     clear();
  674.     if (msg_cnt < screen || n_array[0] < n && n < n_array[screen-1])
  675.         (void) do_hdrs(0, DUBL_NULL, NULL);
  676.     else
  677.         (void) cmd_line(sprintf(buf, "headers %d", n+1), msg_list);
  678.     redo = 0;
  679.     }
  680.     return 0;
  681. }
  682.  
  683. vrfy_update(redo)
  684. int *redo;
  685. {
  686.     char buf[16];
  687.     int c;
  688.  
  689.     /* update current folder */
  690.     if (ison(glob_flags, DO_UPDATE)) {
  691.     if (ison(glob_flags, READ_ONLY)) {
  692.         print("Folder is read-only.");
  693.         if (ison(glob_flags, CNTD_CMD))
  694.         putchar('\n');
  695.         return 0;
  696.     }
  697.     print("Update folder [y]? ");
  698.     if ((c = getchar()) != 'y' && c != 'Y' && c != '\n' && !isspace(c)) {
  699.         print("Folder unchanged.");
  700.         if (ison(glob_flags, CNTD_CMD))
  701.         putchar('\n');
  702.         return 0;
  703.     }
  704.     if (cmd_line(strcpy(buf, "update"), msg_list) != -1 &&
  705.         ison(glob_flags, CNTD_CMD))
  706.         *redo = 1, turnoff(glob_flags, CNTD_CMD);
  707.     }
  708.     turnoff(glob_flags, DO_UPDATE);
  709.     return 1; /* make sure bottom line is clear and no reverse video */
  710. }
  711. #endif /* CURSES */
  712.