home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / com / utils / elm / sources / elm.c < prev    next >
C/C++ Source or Header  |  1992-04-06  |  24KB  |  846 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: elm.c,v 4.1.1.1 90/12/19 09:44:06 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.1.1.1 $   $State: Exp $
  6.  *
  7.  * This file and all associated files and documentation:
  8.  *             Copyright (c) 1986, 1987 Dave Taylor
  9.  *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  10.  *******************************************************************************
  11.  * Bug reports, patches, comments, suggestions should be sent to:
  12.  *
  13.  *    Syd Weinstein, Elm Coordinator
  14.  *    elm@DSI.COM            dsinc!elm
  15.  *
  16.  *******************************************************************************
  17.  * $Log:    elm.c,v $
  18.  * Revision 4.1.1.1  90/12/19  09:44:06  syd
  19.  * Fix not checking for mail before scanning
  20.  * From: Syd via report from Joern Lubkoll
  21.  *
  22.  * Revision 4.1  90/04/28  22:42:54  syd
  23.  * checkin of Elm 2.3 as of Release PL0
  24.  *
  25.  *
  26.  ******************************************************************************/
  27.  
  28. /* Main program of the ELM mail system!
  29. */
  30.  
  31. #include "elm.h"
  32.  
  33. #ifdef BSD
  34. #undef        toupper
  35. #undef        tolower
  36. #endif
  37.  
  38. long bytes();
  39. char *format_long(), *parse_arguments();
  40.  
  41. main(argc, argv)
  42. int argc;
  43. char *argv[];
  44.     {
  45.     int  ch;
  46.     char address[SLEN], to_whom[SLEN], *req_mfile;
  47.     int  key_offset;        /** Position offset within keyboard string   **/
  48.     int  redraw,         /** do we need to rewrite the entire screen? **/
  49.          nucurr,         /** change message list or just the current message pointer...   **/
  50.          nufoot;         /** clear lines 16 thru bottom and new menu  **/
  51.     int  i,j;              /** Random counting variables (etc)          **/
  52.     int  pageon,         /** for when we receive new mail...          **/
  53.          last_in_folder;    /** for when we receive new mail too...      **/
  54.     long num;        /** another variable for fun..               **/
  55.     extern char version_buff[];
  56. #ifndef OS2
  57.     extern int errno;
  58. #endif
  59.  
  60.         initpaths();
  61.  
  62.     req_mfile = parse_arguments(argc, argv, to_whom);
  63.  
  64.     initialize(req_mfile);
  65.  
  66.     if (mail_only) {
  67.        dprint(3, (debugfile, "Mail-only: mailing to\n-> \"%s\"\n",
  68.            format_long(to_whom, 3)));
  69.        if(!batch_only) {
  70.          sprintf(address, "Send only mode [ELM %s]", version_buff);
  71.          Centerline(1, address);
  72.        }
  73.        (void) sendmsg(to_whom, "", batch_subject, TRUE,
  74.          (batch_only ? NO : allow_forms), FALSE);
  75.        leave(0);
  76.     } else if (check_only) {
  77.        do_check_only(to_whom);
  78.        leave(0);
  79.     }
  80.  
  81.     ScreenSize(&LINES, &COLUMNS);
  82.  
  83.     showscreen();
  84.  
  85.     while (1) {
  86.       redraw = 0;
  87.       nufoot = 0;
  88.       nucurr = 0;
  89.       if ((num = bytes(cur_folder)) != mailfile_size) {
  90.         dprint(2, (debugfile, "Just received %d bytes more mail (elm)\n",
  91.             num - mailfile_size));
  92.         error("New mail has arrived! Hang on...");
  93.         fflush(stdin);    /* just to be sure... */
  94.         last_in_folder = message_count;
  95.         pageon = header_page;
  96.  
  97.         if ((errno = can_access(cur_folder, READ_ACCESS)) != 0) {
  98.           dprint(1, (debugfile,
  99.             "Error: given file %s as folder - unreadable (%s)!\n",
  100.             cur_folder, error_name(errno)));
  101.           fprintf(stderr,"Can't open folder '%s' for reading!\n", cur_folder);
  102.           leave();
  103.           }
  104.  
  105.         newmbox(cur_folder, TRUE);    /* last won't be touched! */
  106.         clear_error();
  107.         header_page = pageon;
  108.  
  109.         if (on_page(current))   /* do we REALLY have to rewrite? */
  110.           showscreen();
  111.         else {
  112.           update_title();
  113.           ClearLine(LINES-1);         /* remove reading message... */
  114.           error2("%d new message%s received.",
  115.              message_count - last_in_folder,
  116.              plural(message_count - last_in_folder));
  117.         }
  118.         /* mailfile_size = num; */
  119.         if (cursor_control)
  120.           transmit_functions(ON);    /* insurance */
  121.       }
  122.  
  123.       prompt("Command: ");
  124.  
  125.       CleartoEOLN();
  126.       ch = GetPrompt();
  127.       CleartoEOS();
  128. #ifdef DEBUG
  129.       if (! movement_command(ch))
  130.         dprint(4, (debugfile, "\nCommand: %c [%d]\n\n", ch, ch));
  131. #endif
  132.  
  133.       set_error("");    /* clear error buffer */
  134.  
  135.       MoveCursor(LINES-3,strlen("Command: "));
  136.  
  137.       switch (ch) {
  138.  
  139.         case '?'     :  if (help(FALSE))
  140.                    redraw++;
  141.                else
  142.                  nufoot++;
  143.                break;
  144.  
  145.         case '$'    :  PutLine0(LINES-3, strlen("Command: "),
  146.                      "Resynchronize folder");
  147.                redraw = resync();
  148.                break;
  149.  
  150. next_page:
  151.         case '+'    :  /* move to next page if we're not on the last */
  152.                if((selected &&
  153.                  ((header_page+1)*headers_per_page < selected))
  154.                ||(!selected &&
  155.                  ((header_page+1)*headers_per_page<message_count))){
  156.  
  157.                  header_page++;
  158.                  nucurr = NEW_PAGE;
  159.  
  160.                  if(move_when_paged) {
  161.                    /* move to first message of new page */
  162.                    if(selected)
  163.                  current = visible_to_index(
  164.                    header_page * headers_per_page + 1) + 1;
  165.                    else
  166.                  current = header_page * headers_per_page + 1;
  167.                  }
  168.                } else error("Already on last page.");
  169.                break;
  170.  
  171. prev_page:
  172.         case '-'    :  /* move to prev page if we're not on the first */
  173.                if(header_page > 0) {
  174.                  header_page--;
  175.                  nucurr = NEW_PAGE;
  176.  
  177.                  if(move_when_paged) {
  178.                    /* move to first message of new page */
  179.                    if(selected)
  180.                  current = visible_to_index(
  181.                    header_page * headers_per_page + 1) + 1;
  182.                    else
  183.                  current = header_page * headers_per_page + 1;
  184.                  }
  185.                } else error("Already on first page.");
  186.                break;
  187.  
  188. first_msg:
  189.         case '='    :  if (selected)
  190.                  current = visible_to_index(1)+1;
  191.                else
  192.                  current = 1;
  193.                nucurr = get_page(current);
  194.                break;
  195.  
  196. last_msg:
  197.         case '*'    :  if (selected)
  198.                  current = (visible_to_index(selected)+1);
  199.                else
  200.                  current = message_count;
  201.                nucurr = get_page(current);
  202.                break;
  203.  
  204.         case '|'    :  Writechar('|');
  205.                if (message_count < 1) {
  206.                  error("No mail to pipe!");
  207.                  fflush(stdin);
  208.                } else {
  209.                      softkeys_off();
  210.                              redraw = do_pipe();
  211.                  softkeys_on();
  212.                }
  213.                break;
  214.  
  215. #ifdef ALLOW_SUBSHELL
  216.         case '!'    :  Writechar('!');
  217.                            redraw = subshell();
  218.                break;
  219. #endif
  220.  
  221.         case '%'    :  if (current > 0) {
  222.                  get_return(address, current-1);
  223.                  clear_error();
  224.                  PutLine1(LINES,(COLUMNS-strlen(address))/2,
  225.                       "%.78s", address);
  226.                } else {
  227.                  error("No mail to get return address of!");
  228.                  fflush(stdin);
  229.                }
  230.                break;
  231.  
  232.         case '/'    :  /* scan mbox for string */
  233.                if  (message_count < 1) {
  234.                  error("No mail to scan!");
  235.                  fflush(stdin);
  236.                }
  237.                else if (pattern_match())
  238.                  nucurr = get_page(current);
  239.                else {
  240.                  error("pattern not found!");
  241.                  fflush(stdin);
  242.                }
  243.                break;
  244.  
  245.         case '<'    :  /* scan current message for calendar information */
  246. #ifdef ENABLE_CALENDAR
  247.                if  (message_count < 1) {
  248.                  error("No mail to scan!");
  249.                  fflush(stdin);
  250.                }
  251.                else {
  252.                    PutLine0(LINES-3, strlen("Command: "),
  253.                    "Scan message for calendar entries...");
  254.                    scan_calendar();
  255.                }
  256. #else
  257.                 error("Sorry. Calendar function disabled.");
  258.                fflush(stdin);
  259. #endif
  260.                break;
  261.  
  262.         case 'a'    :  if(alias()) redraw++;
  263.                else nufoot++;
  264.                define_softkeys(MAIN);     break;
  265.  
  266.         case 'b'    :  PutLine0(LINES-3, strlen("Command: "),
  267.                  "Bounce message");
  268.                fflush(stdout);
  269.                if (message_count < 1) {
  270.                    error("No mail to bounce!");
  271.                  fflush(stdin);
  272.                }
  273.                else
  274.                  nufoot = remail();
  275.                break;
  276.  
  277.         case 'c'    :  PutLine0(LINES-3, strlen("Command: "),
  278.                   "Change folder");
  279.                define_softkeys(CHANGE);
  280.                redraw = change_file();
  281.                define_softkeys(MAIN);
  282.                break;
  283.  
  284.         case ctrl('D') :
  285.         case '^'    :
  286.         case 'd'    :  if (message_count < 1) {
  287.                  error("No mail to delete!");
  288.                  fflush(stdin);
  289.                }
  290.                else {
  291.                  if(ch == ctrl('D')) {
  292.  
  293.                    /* if current message did not become deleted,
  294.                 * don't to move to the next undeleted msg. */
  295.                    if(!meta_match(DELETED)) break;
  296.  
  297.                  } else
  298.                     delete_msg((ch == 'd'), TRUE);
  299.  
  300.                  if (resolve_mode)     /* move after mail resolved */
  301.                    if((i=next_message(current-1, TRUE)) != -1) {
  302.                  current = i+1;
  303.                  nucurr = get_page(current);
  304.                    }
  305.                }
  306.                break;
  307.  
  308.  
  309. #ifdef ALLOW_MAILBOX_EDITING
  310.         case 'e'    :  PutLine0(LINES-3,strlen("Command: "),"Edit folder");
  311.                if (current > 0) {
  312.                  edit_mailbox();
  313.                      if (cursor_control)
  314.                    transmit_functions(ON);    /* insurance */
  315.                   }
  316.                else {
  317.                  error("Folder is empty!");
  318.                  fflush(stdin);
  319.                }
  320.                break;
  321. #else
  322.         case 'e'    : error(
  323.             "Folder editing isn't configured in this version of ELM.");
  324.               fflush(stdin);
  325.               break;
  326. #endif
  327.  
  328.         case 'f'    :  PutLine0(LINES-3, strlen("Command: "), "Forward");
  329.                define_softkeys(YESNO);
  330.                if (current > 0) {
  331.                  if(forward()) redraw++;
  332.                  else nufoot++;
  333.                } else {
  334.                  error("No mail to forward!");
  335.                  fflush(stdin);
  336.                }
  337.                define_softkeys(MAIN);
  338.                break;
  339.  
  340.         case 'g'    :  PutLine0(LINES-3,strlen("Command: "), "Group reply");
  341.                fflush(stdout);
  342.                if (current > 0) {
  343.                  if (headers[current-1]->status & FORM_LETTER) {
  344.                    error("Can't group reply to a Form!!");
  345.                    fflush(stdin);
  346.                  }
  347.                  else {
  348.                    define_softkeys(YESNO);
  349.                    redraw = reply_to_everyone();
  350.                    define_softkeys(MAIN);
  351.                  }
  352.                }
  353.                else {
  354.                  error("No mail to reply to!");
  355.                  fflush(stdin);
  356.                }
  357.                break;
  358.  
  359.         case 'h'    :  if (filter)
  360.                  PutLine0(LINES-3, strlen("Command: "),
  361.                 "Message with headers...");
  362.                else
  363.                  PutLine0(LINES-3, strlen("Command: "),"Display message");
  364.                if(current > 0) {
  365.                  fflush(stdout);
  366.                  j = filter;
  367.                  filter = FALSE;
  368.                  i = show_msg(current);
  369.                  while (i)
  370.                 i = process_showmsg_cmd(i);
  371.                  filter = j;
  372.                  redraw++;
  373.                  (void)get_page(current);
  374.                } else error("No mail to read!");
  375.                break;
  376.  
  377.         case 'J'    :  if(current > 0) {
  378.                  if((i=next_message(current-1, FALSE)) != -1) {
  379.                    current = i+1;
  380.                    nucurr = get_page(current);
  381.                  } else error("No more messages below.");
  382.                } else error("No mail in folder!");
  383.                break;
  384.  
  385. next_undel_msg:
  386.         case 'j'    :  if(current > 0) {
  387.                  if((i=next_message(current-1, TRUE)) != -1) {
  388.                    current = i+1;
  389.                    nucurr = get_page(current);
  390.                  } else error("No more undeleted messages below.");
  391.                } else error("No mail in folder!");
  392.                break;
  393.  
  394.         case 'K'    :  if(current > 0) {
  395.                  if((i=prev_message(current-1, FALSE)) != -1) {
  396.                    current = i+1;
  397.                    nucurr = get_page(current);
  398.                  } else error("No more messages above.");
  399.                } else error("No mail in folder!");
  400.                break;
  401.  
  402. prev_undel_msg:
  403.         case 'k'    :  if(current > 0) {
  404.                  if((i=prev_message(current-1, TRUE)) != -1) {
  405.                    current = i+1;
  406.                    nucurr = get_page(current);
  407.                  } else error("No more undeleted messages above.");
  408.                } else error("No mail in folder!");
  409.                break;
  410.  
  411.         case 'l'    :  PutLine0(LINES-3, strlen("Command: "),
  412.                    "Limit displayed messages by...");
  413.                clear_error();
  414.                if (limit() != 0) {
  415.                  get_page(current);
  416.                  redraw++;
  417.                } else {
  418.                  nufoot++;
  419.                }
  420.                break;
  421.  
  422.         case 'm'    :  PutLine0(LINES-3, strlen("Command: "), "Mail");
  423.                redraw = sendmsg("", "", "", TRUE,allow_forms,FALSE);
  424.                break;
  425.  
  426.         case ' '    :
  427.         case ctrl('J'):
  428.         case ctrl('M'):PutLine0(LINES-3, strlen("Command: "),
  429.                       "Display message");
  430.                fflush(stdout);
  431.                if(current > 0 ) {
  432.                  define_softkeys(READ);
  433.  
  434.                  i = show_msg(current);
  435.                  while (i)
  436.                 i = process_showmsg_cmd(i);
  437.                  redraw++;
  438.                  (void)get_page(current);
  439.                }else error ("No mail to read!");
  440.                break;
  441.  
  442.         case 'n'    :  PutLine0(LINES-3,strlen("Command: "),"Next Message");
  443.                fflush(stdout);
  444.                define_softkeys(READ);
  445.  
  446.                if(current > 0 ) {
  447.                  define_softkeys(READ);
  448.  
  449.                  i = show_msg(current);
  450.                  while (i)
  451.                    i = process_showmsg_cmd(i);
  452.                  redraw++;
  453.                  if (++current > message_count)
  454.                    current = message_count;
  455.                  (void)get_page(current);
  456.                }else error ("No mail to read!");
  457.                break;
  458.  
  459.         case 'o'    :  PutLine0(LINES-3, strlen("Command: "), "Options");
  460.                if((i=options()) > 0)
  461.                  get_page(current);
  462.                else if(i < 0)
  463.                  leave();
  464.                redraw++;    /* always fix da screen... */
  465.                break;
  466.  
  467.         case 'p'    :  PutLine0(LINES-3, strlen("Command: "), "Print mail");
  468.                fflush(stdout);
  469.                if (message_count < 1) {
  470.                  error("No mail to print!");
  471.                  fflush(stdin);
  472.                }
  473.                else
  474.                  print_msg();
  475.                break;
  476.  
  477.         case 'q'    :  PutLine0(LINES-3, strlen("Command: "), "Quit");
  478.  
  479.                if (mailfile_size != bytes(cur_folder)) {
  480.                  error("New Mail!  Quit cancelled...");
  481.                  fflush(stdin);
  482.                    if (folder_type == SPOOL) unlock();
  483.                }
  484.                else
  485.                  quit(TRUE);
  486.  
  487.                break;
  488.  
  489.         case 'Q'    :  PutLine0(LINES-3, strlen("Command: "), "Quick quit");
  490.  
  491.                if (mailfile_size != bytes(cur_folder)) {
  492.                  error("New Mail!  Quick Quit cancelled...");
  493.                    if (folder_type == SPOOL) unlock();
  494.                }
  495.                else
  496.                  quit(FALSE);
  497.  
  498.                break;
  499.  
  500.         case 'r'    :  PutLine0(LINES-3, strlen("Command: "),
  501.                   "Reply to message");
  502.                if (current > 0)
  503.                  redraw = reply();
  504.                else {
  505.                  error("No mail to reply to!");
  506.                  fflush(stdin);
  507.                }
  508.                softkeys_on();
  509.                break;
  510.  
  511.         case '>'    : /** backwards compatibility **/
  512.  
  513.         case 'C'    :
  514.         case 's'    :  if  (message_count < 1) {
  515.                  error1("No mail to %s!",
  516.                    ch != 'C' ? "save" : "copy");
  517.                  fflush(stdin);
  518.                }
  519.                else {
  520.                  PutLine1(LINES-3, strlen("Command: "),
  521.                       "%s to folder",
  522.                       ch != 'C' ? "Save" : "Copy");
  523.                  PutLine0(LINES-3,COLUMNS-40,
  524.                 "(Use '?' to list your folders)");
  525.                  if (save(&redraw, FALSE, (ch != 'C'))
  526.                  && resolve_mode && ch != 'C') {
  527.                    if((i=next_message(current-1, TRUE)) != -1) {
  528.                  current = i+1;
  529.                  nucurr = get_page(current);
  530.                    }
  531.                  }
  532.                }
  533.                ClearLine(LINES-2);
  534.                break;
  535.  
  536.             case ctrl('T') :
  537.         case 't'       :  if (message_count < 1) {
  538.                 error("No mail to tag!");
  539.                 fflush(stdin);
  540.                   }
  541.                   else if (ch == 't')
  542.                 tag_message(TRUE);
  543.                   else
  544.                 meta_match(TAGGED);
  545.                   break;
  546.  
  547.         case 'u'    :  if (message_count < 1) {
  548.                  error("No mail to mark as undeleted!");
  549.                  fflush(stdin);
  550.                }
  551.                else {
  552.                  undelete_msg(TRUE);
  553.                  if (resolve_mode)     /* move after mail resolved */
  554.                    if((i=next_message(current-1, FALSE)) != -1) {
  555.                  current = i+1;
  556.                  nucurr = get_page(current);
  557.                    }
  558. /*************************************************************************
  559.  **  What we've done here is to special case the "U)ndelete" command to
  560.  **  ignore whether the next message is marked for deletion or not.  The
  561.  **  reason is obvious upon usage - it's a real pain to undelete a series
  562.  **  of messages without this quirk.  Thanks to Jim Davis @ HPLabs for
  563.  **  suggesting this more intuitive behaviour.
  564.  **
  565.  **  The old way, for those people that might want to see what the previous
  566.  **  behaviour was to call next_message with TRUE, not FALSE.
  567. **************************************************************************/
  568.                }
  569.                break;
  570.  
  571.         case ctrl('U') : if (message_count < 1) {
  572.                    error("No mail to undelete!");
  573.                    fflush(stdin);
  574.                  }
  575.                  else
  576.                    meta_match(UNDELETE);
  577.                  break;
  578.  
  579.         case 'X'    :  PutLine0(LINES-3, strlen("Command: "), "Quick Exit");
  580.                            fflush(stdout);
  581.                leave();
  582.                break;
  583.  
  584.         case ctrl('Q') :
  585.         case 'x'    :  PutLine0(LINES-3, strlen("Command: "), "Exit");
  586.                            fflush(stdout);
  587.                exit_prog();
  588.                break;
  589.  
  590.         case ctrl('L') : redraw++;    break;
  591.  
  592.             case EOF :  leave();  /* Read failed, control tty died? */
  593.                         break;
  594.  
  595.         case '@'    : debug_screen();  redraw++;    break;
  596.  
  597.         case '#'    : if (message_count) {
  598.                 debug_message();
  599.                 redraw++;
  600.               }
  601.               else {
  602.                 error("No mail to check.");
  603.                 fflush(stdin);
  604.               }
  605.               break;
  606.  
  607.         case NO_OP_COMMAND : break;    /* noop for timeout loop */
  608.  
  609.         case ESCAPE : if (cursor_control) {
  610.                 key_offset = 1;
  611.                 ch = ReadCh();
  612.  
  613.                             if ( ch == '[' || ch == 'O')
  614.                             {
  615.                               ch = ReadCh();
  616.                               key_offset++;
  617.                             }
  618.  
  619.                 if(ch == up[key_offset]) goto prev_undel_msg;
  620.                 else if(ch == down[key_offset]) goto next_undel_msg;
  621.                 else if(ch == right[key_offset]) goto next_page;
  622.                 else if(ch == left[key_offset]) goto prev_page;
  623.                 else if (hp_terminal) {
  624.                   switch (ch) {
  625.                   case 'U':        goto next_page;
  626.                   case 'V':        goto prev_page;
  627.                   case 'h':
  628.                   case 'H':        goto first_msg;
  629.                   case 'F':        goto last_msg;
  630.                   case 'A':
  631.                   case 'D':
  632.                   case 'i':        goto next_undel_msg;
  633.                   case 'B':
  634.                   case 'I':
  635.                   case 'C':        goto prev_undel_msg;
  636.                   default: PutLine2(LINES-3, strlen("Command: "),
  637.                     "%c%c", ESCAPE, ch);
  638.                   }
  639.                 } else /* false hit - output */
  640.                   PutLine2(LINES-3, strlen("Command: "),
  641.                       "%c%c", ESCAPE, ch);
  642.               }
  643.  
  644.               /* else fall into the default error message! */
  645.  
  646.         default    : if (ch > '0' && ch <= '9') {
  647.                 PutLine0(LINES-3, strlen("Command: "),
  648.                     "New Current Message");
  649.                 i = read_number(ch);
  650.  
  651.                 if( i > message_count)
  652.                   error("Not that many messages.");
  653.                 else if(selected
  654.                 && isoff(headers[i-1]->status, VISIBLE))
  655.                   error("Message not in limited display.");
  656.                 else {
  657.                   current = i;
  658.                   nucurr = get_page(current);
  659.                 }
  660.               }
  661.               else {
  662.                  error("Unknown command. Use '?' for help.");
  663.                 fflush(stdin);
  664.               }
  665.       }
  666.  
  667.       if (redraw)
  668.         showscreen();
  669.  
  670.       if ((current < 1) || (selected && compute_visible(current) < 1)) {
  671.         if (message_count > 0) {
  672.           /* We are out of range! Get to first message! */
  673.           if (selected)
  674.         current = compute_visible(1);
  675.           else
  676.         current = 1;
  677.         }
  678.         else
  679.           current = 0;
  680.       }
  681.       else if ((current > message_count)
  682.            || (selected && compute_visible(current) > selected)) {
  683.         if (message_count > 0) {
  684.           /* We are out of range! Get to last (visible) message! */
  685.           if (selected)
  686.         current = visible_to_index(selected)+1;
  687.           else
  688.         current = message_count;
  689.         }
  690.         else
  691.           current = 0;
  692.       }
  693.  
  694.       if (nucurr == NEW_PAGE)
  695.         show_headers();
  696.       else if (nucurr == SAME_PAGE)
  697.         show_current();
  698.       else if (nufoot) {
  699.         if (mini_menu) {
  700.           MoveCursor(LINES-7, 0);
  701.               CleartoEOS();
  702.           show_menu();
  703.         }
  704.         else {
  705.           MoveCursor(LINES-4, 0);
  706.           CleartoEOS();
  707.         }
  708.         show_last_error();    /* for those operations that have to
  709.                  * clear the footer except for a message.
  710.                  */
  711.       }
  712.  
  713.     } /* the BIG while loop! */
  714. }
  715.  
  716. debug_screen()
  717. {
  718.     /**** spit out all the current variable settings and the table
  719.           entries for the current 'n' items displayed. ****/
  720.  
  721.     register int i, j;
  722.     char     buffer[SLEN];
  723.  
  724.     ClearScreen();
  725.     Raw(OFF);
  726.  
  727.     PutLine2(0,0,"Current message number = %d\t\t%d message(s) total\r\n",
  728.         current, message_count);
  729.     PutLine2(2,0,"Header_page = %d           \t\t%d possible page(s)\r\n",
  730.         header_page, (int) (message_count / headers_per_page) + 1);
  731.  
  732.     PutLine1(4,0,"\r\nCurrent mailfile is %s.\n\r\n\r", cur_folder);
  733.  
  734.     i = header_page*headers_per_page;    /* starting header */
  735.  
  736.     if ((j = i + (headers_per_page-1)) >= message_count)
  737.       j = message_count-1;
  738.  
  739.     Write_to_screen(
  740. "Num      From                  Subject                         Lines  Offset\n\r\n\r",0);
  741.  
  742.     while (i <= j) {
  743.        sprintf(buffer,
  744.        "%3d  %-16.16s  %-40.40s  %4d  %ld\n\r",
  745.             i+1,
  746.             headers[i]->from,
  747.             headers[i]->subject,
  748.             headers[i]->lines,
  749.             headers[i]->offset);
  750.         Write_to_screen(buffer, 0);
  751.       i++;
  752.     }
  753.  
  754.     Raw(ON);
  755.  
  756.     PutLine0(LINES,0,"Press any key to return.");
  757.     (void) ReadCh();
  758. }
  759.  
  760.  
  761. debug_message()
  762. {
  763.     /**** Spit out the current message record.  Include EVERYTHING
  764.           in the record structure. **/
  765.  
  766.     char buffer[SLEN];
  767.     register struct header_rec *current_header = headers[current-1];
  768.  
  769.     ClearScreen();
  770.     Raw(OFF);
  771.  
  772.     Write_to_screen("\t\t\t----- Message %d -----\n\r\n\r\n\r\n\r", 1,
  773.         current);
  774.  
  775.     Write_to_screen("Lines : %-5d\t\t\tStatus: A  C  D  E  F  N  O  P  T  U  V\n\r", 1,
  776.         current_header->lines);
  777.     Write_to_screen("            \t\t\t        c  o  e  x  o  e  l  r  a  r  i\n\r", 0);
  778.     Write_to_screen("            \t\t\t        t  n  l  p  r  w  d  i  g  g  s\n\r", 0);
  779.     Write_to_screen("            \t\t\t        n  f  d  d  m        v  d  n  i\n\r", 0);
  780.  
  781.     sprintf(buffer,
  782.         "\n\rOffset: %ld\t\t\t        %d  %d  %d  %d  %d",
  783.         current_header->offset,
  784.         (current_header->status & ACTION) != 0,
  785.         (current_header->status & CONFIDENTIAL) != 0,
  786.         (current_header->status & DELETED) != 0,
  787.         (current_header->status & EXPIRED) != 0,
  788.         (current_header->status & FORM_LETTER) != 0);
  789.     sprintf(buffer + strlen(buffer),
  790.         "  %d  %d  %d  %d  %d  %d\n",
  791.         (current_header->status & NEW) != 0,
  792.         (current_header->status & UNREAD) != 0,
  793.         (current_header->status & PRIVATE) != 0,
  794.         (current_header->status & TAGGED) != 0,
  795.         (current_header->status & URGENT) != 0,
  796.         (current_header->status & VISIBLE) != 0);
  797.  
  798.     Write_to_screen(buffer, 0);
  799.  
  800.     sprintf(buffer, "\n\rReceived on: %d/%d/%d at %d:%02d\n\r",
  801.         current_header->received.month+1,
  802.         current_header->received.day,
  803.         current_header->received.year,
  804.         current_header->received.hour,
  805.         current_header->received.minute);
  806.     Write_to_screen(buffer, 0);
  807.  
  808.     sprintf(buffer, "Message sent on: %s, %s %s, %s at %s\n\r",
  809.         current_header->dayname,
  810.         current_header->month,
  811.         current_header->day,
  812.         current_header->year,
  813.         current_header->time);
  814.     Write_to_screen(buffer, 0);
  815.  
  816.     Write_to_screen("From: %s\n\rSubject: %s", 2,
  817.         current_header->from,
  818.         current_header->subject);
  819.  
  820.     Write_to_screen("\n\rPrimary Recipient: %s\nInternal Index Reference Number = %d\n\r", 2,
  821.         current_header->to,
  822.         current_header->index_number);
  823.  
  824.     Write_to_screen("Message-ID: %s\n\r", 1,
  825.         strlen(current_header->messageid) > 0 ?
  826.         current_header->messageid : "<none>");
  827.  
  828.     Write_to_screen("Status: %s\n\r", 1, current_header->mailx_status);
  829.  
  830.     Raw(ON);
  831.  
  832.     PutLine0(LINES,0,"Please Press any key to return.");
  833.     (void) ReadCh();
  834. }
  835.  
  836. do_check_only(to_whom)
  837. char *to_whom;
  838.     {
  839.     char buffer[VERY_LONG_STRING];
  840.  
  841.     dprint(3, (debugfile, "Check-only: checking \n-> \"%s\"\n",
  842.         format_long(to_whom, 3)));
  843.     (void) build_address(strip_commas(to_whom), buffer);
  844.     printf("\r\nExpands to: %s\r\n", format_long(buffer, strlen("Expands to: ")));
  845.     }
  846.