home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / BTMTSRC3.ZIP / MAILER.C < prev    next >
C/C++ Source or Header  |  1991-08-25  |  21KB  |  785 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  (C) Copyright 1987-90, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*                 This module was written by Bob Hartman                   */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*                   BinkleyTerm Mail Control Routines                      */
  17. /*                                                                          */
  18. /*                                                                          */
  19. /*                                                                          */
  20. /*    For complete  details  of the licensing restrictions, please refer    */
  21. /*    to the License  agreement,  which  is published in its entirety in    */
  22. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.240.    */
  23. /*                                                                          */
  24. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  25. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  26. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  27. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  28. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  29. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  30. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  31. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  32. /*                                                                          */
  33. /*                                                                          */
  34. /* You can contact Bit Bucket Software Co. at any one of the following      */
  35. /* addresses:                                                               */
  36. /*                                                                          */
  37. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:132/491, 1:141/491  */
  38. /* P.O. Box 460398                AlterNet 7:491/0                          */
  39. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  40. /*                                Internet f491.n132.z1.fidonet.org         */
  41. /*                                                                          */
  42. /* Please feel free to contact us at any time to share your comments about  */
  43. /* our software and/or licensing policies.                                  */
  44. /*                                                                          */
  45. /*--------------------------------------------------------------------------*/
  46. #include <stdio.h>
  47. #include <signal.h>
  48. #include <ctype.h>
  49. #include <conio.h>
  50. #include <sys/types.h>
  51. #include <sys/stat.h>
  52. #include <string.h>
  53. #include <fcntl.h>
  54. #include <time.h>
  55. #include <process.h>
  56. #include <stdlib.h>
  57. #include <io.h>
  58.  
  59. #include "com.h"
  60. #include "xfer.h"
  61. #include "zmodem.h"
  62. #include "keybd.h"
  63. #include "sbuf.h"
  64. #include "sched.h"
  65. #include "externs.h"
  66. #include "prototyp.h"
  67. #include "vfossil.h"
  68.  
  69.  
  70.  
  71. int unattended()
  72.     {
  73.     MAILP mp;
  74.     int i, j, m, r, tmp;
  75.     long init_timer, t, t1;                       /* used for the timeouts  */
  76.     int done = 1;                                 /* if we exit with this, get out of BT */
  77.     FILE *tfile;
  78.     char jbuf[60];
  79.  
  80.     un_attended = 1;
  81.     clear_statusline ();
  82.  
  83.     comm_bits = BITS_8;
  84.     parity = NO_PARITY;
  85.     stop_bits = STOP_1;
  86.     set_prior(4);                                 /* Always High */
  87.     MDM_ENABLE (lock_baud && (btypes[baud].rate_value >= lock_baud) ? max_baud.rate_mask : btypes[baud].rate_mask);
  88.     set_prior(2);                                 /* Regular  */
  89.  
  90.     if (fullscreen)
  91.         {
  92.         screen_clear();
  93.         sb_dirty();
  94.         }
  95.  
  96.     opening_banner();
  97.  
  98.     if (fullscreen)
  99.         mailer_banner();
  100.  
  101.     if ((tfile = fopen ("BINKLEY.BAN", "rb")) != NULL)
  102.         {
  103.         fread (BBSwelcome, 1, 1000, tfile);
  104.         fclose (tfile);
  105.         }
  106.     else
  107.         BBSwelcome[0] = '\0';
  108.  
  109.     /* Initialize the random number generator */
  110.     i = (int) time (NULL);
  111.     srand ((unsigned int) i);
  112.  
  113.     status_line ("+begin, %s", xfer_id);
  114.     set_xy ("");
  115.     set_prior(4);                                 /* Always High */
  116.     XON_DISABLE ();
  117.     set_prior(2);                                 /* Regular  */
  118.  
  119.     /* Turn off forced events */
  120.     if (noforce)
  121.         {
  122.         find_event ();
  123.         noforce = 0;
  124.         }
  125.     if (redo_dynam)
  126.         {
  127.         for (i = 0; i < num_events; i++)
  128.             e_ptrs[i]->behavior &= ~MAT_SKIP;
  129.         redo_dynam = 0;
  130.         }
  131.  
  132.     /*
  133.     * See if we should exit before initializing the modem (and therefore
  134.     * possibly letting a call sneak through)
  135.     */
  136.  
  137.     find_event ();
  138.     do_ready (msgtxt[M_READY_INIT]);
  139.  
  140.     /* Make sure we have all necessary parameters and that the nodelist
  141.     * index gets read in. If not, then we must exit right now.
  142.     */
  143.  
  144.     if (!net_params || !nodefind (&boss_addr, 0))
  145.     if (boss_addr.Net != -1)
  146.         {
  147.         status_line (msgtxt[M_MISCONFIGURED]);
  148.         errl_exit (254);
  149.         }
  150.  
  151.     /* Set up outbound mail */
  152.     list_next_event ();
  153.     set_up_outbound ();
  154.  
  155.     if (!CARRIER)
  156.         {
  157.         set_prior(4);                              /* Always High */
  158.         mdm_init (modem_init);                     /* Reinitialize the modem  */
  159.         set_prior(2);                              /* Regular  */
  160.         }
  161.  
  162.     init_timer = timerset ((unsigned int)60000);  /* Set a 10 minute timer */
  163.     t1 = timerset ((unsigned) next_minute ());                         /* Set a 1 minute timer  */
  164.  
  165.     top_of_mail:
  166.     un_attended = 1;
  167.     i = 0;
  168.     m = 1;
  169.  
  170.     /* As long as we don't press a key */
  171. bad_char:
  172.     r = 0;
  173.     more_mail = 1;
  174.     while (!(KEYPRESS () || ctrlc_ctr))
  175.         {
  176.         find_event ();
  177.  
  178.         /* Show that we are ready */
  179.         if (m)
  180.             {
  181.             if (fullscreen)
  182.                 {
  183.                 do_ready (msgtxt[M_READY_WAITING]);
  184.                 list_next_event ();
  185.                 }
  186.             else
  187.                 status_line (msgtxt[M_EVENT_WAITING], cur_event + 1);
  188.             init_timer = timerset ((unsigned int)60000); /* Set a 10 minute timer */
  189.             t1 = timerset ((unsigned) next_minute ());              /* Set a 1 minute timer */
  190.             }
  191.  
  192.         if (timeup (t1))
  193.             {
  194.             put_up_time ();
  195.             list_next_event ();
  196.             t1 = timerset ((unsigned) next_minute ());                   /* Set a 1 minute timer */
  197.             }
  198.  
  199.         /* If we haven't gotten anything in 10 minutes, re-init the modem */
  200.         if (timeup (init_timer))
  201.             {
  202.             set_prior(4);                           /* Always High */
  203.             mdm_init (modem_init);
  204.             set_prior(2);                           /* Regular  */
  205.             init_timer = timerset ((unsigned int)60000); /* Set a 10 minute timer */
  206.  
  207.             /*
  208.             * Say that we have more mail so that things entered through other
  209.             * side of a multi-tasker will still go out
  210.             */
  211.             set_up_outbound ();
  212.             more_mail = 1;
  213.  
  214.             screen_blank = 1;
  215.             if (fullscreen)
  216.                 sb_show ();
  217.             }
  218.  
  219.         m = 0;
  220.  
  221.         if (cur_event >= 0)
  222.             {
  223.             i = (e_ptrs[cur_event]->behavior & MAT_OUTONLY);
  224.             t = random_time (e_ptrs[cur_event]->wait_time);
  225.             }
  226.         else
  227.             {
  228.             i = 1;
  229.             t = random_time (5);
  230.             }
  231.  
  232.         /*  variable 'i' will be TRUE if we are either manually dialing out
  233.         *  or if we are in an event where we do not want incoming stuff.
  234.         */
  235.  
  236.         while ((!timeup (t)) && (!KEYPRESS ()) && (m == 0) && !ctrlc_ctr)
  237.             {
  238.             find_event ();
  239.             time_release ();
  240.             if (timeup (t1))
  241.                 {
  242.                 put_up_time ();
  243.                 list_next_event ();
  244.                 t1 = timerset ((unsigned) next_minute ());             /* Set a 1 minute timer */
  245.                 }
  246.         
  247.         /* If we want inbound, see if there is any. If we send anything, clean up afterwards ...       */
  248.  
  249.         if (!i)
  250.             {
  251.             m = handle_inbound_mail ();
  252.             if (m)
  253.                 xmit_sameplace ();
  254.             }
  255.         }
  256.  
  257.     if ((m) && (fullscreen))
  258.         {
  259.         do_ready (msgtxt[M_READY_WAITING]);
  260.         list_next_event ();
  261.         }
  262.  
  263.     immed_call:
  264.  
  265.     find_event ();
  266.  
  267.     /* If we are not in an event, loop again */
  268.     if (cur_event < 0)
  269.         {
  270.         time_release ();
  271.         continue;
  272.         }
  273.  
  274.     /* If we have pressed a key, get out */
  275.     if (KEYPRESS () || ctrlc_ctr)
  276.         break;
  277.  
  278.     /* See if we are supposed to do any mail */
  279.     if (cur_event >= 0)
  280.         if (e_ptrs[cur_event]->behavior & MAT_NOOUT)
  281.             continue;
  282.  
  283.     if (more_mail)
  284.         {
  285.         more_mail = xmit_next (&next_addr);
  286.         if (more_mail)
  287.             {
  288.             /* save the next call in the list in case we exit */
  289.             if ((next_mail == NULL) || (next_mail->next == NULL))
  290.                 {
  291.                 mp = mail_top;
  292.                 }
  293.             else
  294.                 {
  295.                 mp = next_mail->next;
  296.                 }
  297.             hist.next_zone = mp->mail_addr.Zone;
  298.             hist.next_net = mp->mail_addr.Net;
  299.             hist.next_node = mp->mail_addr.Node;
  300.  
  301.             set_prior(4);                        /* Always High */
  302.             m = do_mail (&next_addr, 0);
  303.             set_prior(2);                        /* Regular */
  304.  
  305.             r = (m == 1) ? 1 : 0;
  306.  
  307.             if (r)                               /* Did we connect? */
  308.                 {
  309.                 if (!sent_mail)
  310.                     {
  311.                     /* We connected but the transfer didn't work */
  312.                     bad_call (&next_addr, 1);
  313.                     }
  314.                 else
  315.                     {
  316.                     /* We got through, so delete his status file */
  317.                     bad_call (&next_addr, -1);
  318.                     xmit_delete ();
  319.                     }
  320.                 }
  321.  
  322.             else if (m == 2)                     /* Nothing happened */
  323.                 bad_call (&next_addr, 2);
  324.  
  325.             /* If we did some processing */
  326.             if (m > 0)
  327.                 {
  328.                 /* We got inbound mail */
  329.                 if (got_arcmail || got_packet || got_mail)
  330.                     receive_exit ();
  331.                 }
  332.             else if (m == -1)
  333.                 {
  334.                 status_line (msgtxt[M_INCOMING_CALL]);
  335.                 }
  336.             }
  337.         }
  338.  
  339.     if (!more_mail)
  340.         {
  341.         /* No more mail to do, was it dynamic? */
  342.         if (cur_event >= 0)
  343.             if (e_ptrs[cur_event]->behavior & MAT_DYNAM)
  344.                 {
  345.                 if (!blank_on_key)
  346.                     screen_blank = 0;
  347.                 e_ptrs[cur_event]->behavior |= MAT_SKIP;
  348.                 status_line (":%s %s %d", msgtxt[M_END_OF], msgtxt[M_DYNAMIC_EVENT], cur_event + 1);
  349.                 goto top_of_mail;
  350.                 }
  351.             }
  352.         }
  353.  
  354.     screen_blank = 0;
  355.     if (fullscreen)
  356.         sb_show ();
  357.  
  358.     /* Eat the character we pressed */
  359.     if (ctrlc_ctr || !KEYPRESS ())
  360.         {
  361.  
  362.         /*
  363.             * Be serious, there had to be a key pressed or we wouldn't be here I
  364.             * know it sounds silly, but ^C will sometimes do crap like this
  365.             */
  366.         status_line (msgtxt[M_EXIT_REQUEST]);
  367.         }
  368.     else
  369.         {
  370.         i = (int) FOSSIL_CHAR ();
  371.         if ((i & 0xff) == 0)
  372.             {
  373.             switch (i)
  374.                 {
  375.                 case PF1:
  376.                 case PF2:
  377.                 case PF3:
  378.                 case PF4:
  379.                 case PF5:
  380.                 case PF6:
  381.                 case PF7:
  382.                 case PF8:
  383.                 case PF9:
  384.                 case PF10:
  385.                     j = (int) (((unsigned) i) >> 8);
  386.                     status_line (msgtxt[M_FUNCTION_KEY], (j - 0x3a) * 10);
  387.                     errl_exit ((j - 0x3a) * 10);
  388.                     break;
  389.  
  390.                 case ALTB:
  391.                     screen_blank = 1;
  392.                     if (fullscreen)
  393.                         sb_show ();
  394.                     goto bad_char;
  395.  
  396.                 case ALTC:
  397.                     tmp = hist.which_day;
  398.                     memset (&hist, 0, sizeof (HISTORY));
  399.                     hist.which_day = tmp;
  400.                     if (fullscreen)
  401.                         {
  402.                         do_today ();
  403.                         sb_show ();
  404.                         }
  405.                     goto bad_char;
  406.  
  407.                 case ALTE:
  408.                     if (BBSreader != NULL)
  409.                         {
  410.                         vfossil_cursor (1);
  411.                         status_line (msgtxt[M_DISABLE_MODEM]);
  412.                         set_prior(4);                  /* Always High */
  413.                         mdm_init (modem_busy);
  414.                         exit_DTR ();
  415.                         set_prior(2);                  /* Regular */
  416.                         status_line (msgtxt[M_BEGIN_MESSAGE_READER]);
  417.                         vfossil_close ();
  418.                         b_spawn (BBSreader);
  419.                         come_back();     /* CML */
  420.                         vfossil_init ();
  421.                         if (fullscreen)
  422.                             {
  423.                             screen_clear ();
  424.                             sb_dirty ();
  425.                             opening_banner ();
  426.                             mailer_banner ();
  427.                             }
  428.                         status_line (msgtxt[M_END_MESSAGE_READER]);
  429.                         set_up_outbound ();
  430.                         m = 1;
  431.                         more_mail = 1;
  432.                         status_line (msgtxt[M_ENABLE_MODEM]);
  433.                         set_prior(4);                  /* Always High */
  434.                         DTR_ON ();
  435.                         mdm_init (modem_init);
  436.                         set_prior(2);                  /* Regular */
  437.                         goto immed_call;
  438.                         }
  439.                     else
  440.                         {
  441.                         set_xy (NULL);
  442.                         status_line (msgtxt[M_NO_MESSAGE_READER]);
  443.                         set_xy (NULL);
  444.                         m = 1;
  445.                         goto bad_char;
  446.                         }
  447.  
  448.                 case ALTG:
  449.                     if (sb_popup (10, 10, 7, 60, Do_Get, 0))
  450.                         status_line (msgtxt[M_NO_GET]);
  451.                     else
  452.                         {
  453.                         set_up_outbound ();
  454.                         m = 1;
  455.                         more_mail = 1;
  456.                         }
  457.                     goto bad_char;
  458.  
  459.                 case ALTI:
  460.                     /* The idea for this code came from Holger Schurig */
  461.                     mdm_hangup ();
  462.                     set_up_outbound ();
  463.                     m = 1;
  464.                     more_mail = 1;
  465.                     goto bad_char;
  466.  
  467.                 case ALTJ:            /* CML took out stupid ESC to shell -- what kind of *IDIOT* would use ESC to shell? */
  468.                     status_line (msgtxt[M_SHELLING]);
  469.                     if (fullscreen)
  470.                         gotoxy (0, SB_ROWS);
  471.                     vfossil_cursor (1);
  472.                     cputs (msgtxt[M_TYPE_EXIT]);
  473.                     DTR_OFF ();
  474.                     change_prompt ();
  475.                     b_spawn (NULL);
  476.                     come_back();     /* CML */
  477.                     if (fullscreen)
  478.                         {
  479.                         screen_clear ();
  480.                         sb_dirty ();
  481.                         opening_banner ();
  482.                         mailer_banner ();
  483.                         }
  484.                     status_line (msgtxt[M_BINKLEY_BACK]);
  485.                     m = 1;
  486.                     set_up_outbound ();
  487.                     set_prior(4);                     /* Always High */
  488.                     DTR_ON ();
  489.                     set_prior(2);                     /* Regular */
  490.                     goto bad_char;
  491.  
  492.                 case ALTK:
  493.                     if (sb_popup (10, 5, 4, 70, Do_Kill, 0))
  494.                         status_line (msgtxt[M_NO_KILL]);
  495.                     else
  496.                         {
  497.                         set_up_outbound ();
  498.                         m = 1;
  499.                         more_mail = 1;
  500.                         }
  501.                     goto bad_char;
  502.  
  503.                 case ALTY:
  504.                     next_addr = boss_addr;
  505.                     goto polling;
  506.  
  507.                 case ALTM:
  508.                     status_line (msgtxt[M_POLL_MODE]);
  509.                     if (fullscreen)
  510.                         gotoxy (0, SB_ROWS - 2);
  511.                     vfossil_cursor (1);
  512.                     scr_printf ("\r\n");
  513.                     clear_eol ();
  514.                     scr_printf (msgtxt[M_ENTER_NET_NODE]);
  515.                     m = get_number (jbuf);
  516.                     if (m)
  517.                         m = find_address (jbuf, &next_addr);
  518.                     if (fullscreen)
  519.                         {
  520.                         gotoxy (0, SB_ROWS - 1);
  521.                         clear_eol ();
  522.                         bottom_line ();
  523.                         vfossil_cursor (0);
  524.                         sb_show ();
  525.                         }
  526.                     if (m >= 1 && nodefind (&next_addr, 1))
  527.                         {
  528.                         if (!next_addr.Zone)
  529.                             next_addr.Zone = found_zone;
  530. polling:
  531.                         doing_poll = 1;
  532.                         if (fullscreen)
  533.                             {
  534.                             sb_move (filewin, 1, 2);
  535.                             sb_puts (filewin, (unsigned char *) msgtxt[M_CURRENTLY_POLLING]);
  536.                             sb_puts (filewin, (unsigned char *) Full_Addr_Str (&next_addr));
  537.                             }
  538.                         set_prior(4);                  /* Always High */
  539.                         if ((do_mail (&next_addr, 1) == 1) && sent_mail)
  540.                             {
  541.                             next_mail = find_mail (&next_addr);
  542.                             bad_call (&next_addr, -1);
  543.                             xmit_delete ();
  544.                             }
  545.                         set_prior(2);                  /* Regular */
  546.                         doing_poll = 0;
  547.                         }
  548.                     status_line (msgtxt[M_POLL_COMPLETED]);
  549.                     if (fullscreen)
  550.                         {
  551.                         clear_filetransfer ();
  552.                         }
  553.                     set_prior(4);                     /* Always High */
  554.                     DTR_ON ();
  555.                     mdm_init (modem_init);
  556.                     set_prior(2);                     /* Regular */
  557.                     m = 1;
  558.                     goto bad_char;
  559.  
  560.                 case ALTQ:
  561.                     if (cur_event >= 0)
  562.                         e_ptrs[cur_event]->behavior |= MAT_SKIP;
  563.                     goto top_of_mail;
  564.  
  565.                 case ALTR:
  566.                     for (j = 0; j < num_events; j++)
  567.                         {
  568.                         /* Don't redo forced events */
  569.                         if (!(e_ptrs[j]->behavior & MAT_FORCED))
  570.                             {
  571.                             e_ptrs[j]->last_ran = -1;
  572.                             e_ptrs[j]->behavior &= ~MAT_SKIP;
  573.                             }
  574.                         }
  575.                     goto top_of_mail;
  576.  
  577.                 case ALTS:
  578.                     if (sb_popup (10, 5, 6, 70, Do_Send, 0))
  579.                         status_line (msgtxt[M_NO_SEND]);
  580.                     else
  581.                         {
  582.                         set_up_outbound ();
  583.                         m = 1;
  584.                         more_mail = 1;
  585.                         }
  586.                     goto bad_char;
  587.  
  588.                 case ALTT:
  589.                     status_line (msgtxt[M_ENTER_TERMINAL_MODE]);
  590.                     b_init ();
  591.                     done = 0;                         /* We won't exit now */
  592.                     goto mail_done;
  593.  
  594.                 case ALTW:
  595.                     if (fullscreen)
  596.                         {
  597.                         screen_clear ();
  598.                         sb_dirty ();
  599.                         sb_show ();
  600.                         }
  601.                     goto bad_char;
  602.  
  603.                 case ALTF10:
  604.                     mailer_help ();
  605.                     if (fullscreen)
  606.                         {
  607.                         screen_clear ();
  608.                         sb_dirty ();
  609.                         opening_banner ();
  610.                         mailer_banner ();
  611.                         }
  612.                     m = 1;
  613.                     goto bad_char;
  614.  
  615.                 case ALTX:
  616.                     status_line (msgtxt[M_EXIT_REQUEST]);
  617.                     goto mail_done;
  618.  
  619.                 case ALTF1:
  620.                 case ALTF2:
  621.                 case ALTF3:
  622.                 case ALTF4:
  623.                 case ALTF5:
  624.                 case ALTF6:
  625.                 case ALTF7:
  626.                 case ALTF8:
  627.                 case ALTF9:
  628.                     j = (int) (((unsigned) i) >> 8) - 0x68;
  629.                     if (shells[j] != NULL)
  630.                         {
  631.                         status_line (msgtxt[M_KEYBOARD_SHELL], j + 1);
  632.                         set_prior(3);                  /* Foreground-Server */
  633.                         mdm_init (modem_busy);
  634.                         exit_DTR ();
  635.                         set_prior(2);                  /* Regular */
  636.                         close_up ();
  637.                         vfossil_cursor (1);
  638.                         b_spawn (shells[j]);
  639.                         come_back();     /* CML */
  640.                         m = 1;
  641.                         status_line (msgtxt[M_END_KEYBOARD_SHELL]);
  642.                         screen_clear ();
  643.                         if (fullscreen)
  644.                             sb_dirty ();
  645.                         opening_banner ();
  646.                         mailer_banner ();
  647.                         set_up_outbound ();
  648.                         set_prior(4);                  /* Always High */
  649.                         DTR_ON ();
  650.                         mdm_init (modem_init);
  651.                         set_prior(2);                  /* Regular */
  652.                         goto immed_call;
  653.                         }
  654.  
  655.                     status_line (msgtxt[M_NO_KEYBOARD_SHELL], j + 1);
  656.                     goto bad_char;
  657.  
  658.                 case PGUP:
  659.                     if (next_mail == NULL)
  660.                         next_mail = mail_top;
  661.  
  662.                     if (next_mail != NULL)
  663.                         {
  664.                         for (j = 0; j < 4; j++)
  665.                             {
  666.                             if (next_mail->prev != NULL)
  667.                                 next_mail = next_mail->prev;
  668.                             }
  669.                         xmit_window (next_mail);
  670.                         }
  671.                     goto bad_char;
  672.  
  673.                 case PGDN:
  674.                     if (next_mail == NULL)
  675.                         next_mail = mail_top;
  676.  
  677.                     if (next_mail != NULL)
  678.                         {
  679.                         for (j = 0; j < 4; j++)
  680.                             {
  681.                             if (next_mail->next != NULL)
  682.                                 next_mail = next_mail->next;
  683.                             }
  684.                         xmit_window (next_mail);
  685.                         }
  686.                     goto bad_char;
  687.  
  688.                 case UPAR:
  689.                     if (next_mail == NULL)
  690.                         next_mail = mail_top;
  691.                     if (next_mail != NULL)
  692.                         {
  693.                         if (next_mail->prev != NULL)
  694.                             next_mail = next_mail->prev;
  695.                         xmit_window (next_mail);
  696.                         }
  697.                     goto bad_char;
  698.  
  699.                 case DNAR:
  700.                     if (next_mail == NULL)
  701.                         next_mail = mail_top;
  702.  
  703.                     if (next_mail != NULL)
  704.                         {
  705.                         if (next_mail->next != NULL)
  706.                             next_mail = next_mail->next;
  707.                         xmit_window (next_mail);
  708.                         }
  709.                     goto bad_char;
  710.  
  711.                 case HOME:
  712.                     next_mail = mail_top;
  713.                     xmit_window (next_mail);
  714.                     goto bad_char;
  715.  
  716.                 case END:
  717.                     if (next_mail == NULL)
  718.                         next_mail = mail_top;
  719.  
  720.                     if (next_mail != NULL)
  721.                         {
  722.                         while (next_mail->next != NULL)
  723.                             next_mail = next_mail->next;
  724.                         }
  725.  
  726.                     for (j = 0; j < 3; j++)
  727.                         {
  728.                         if (next_mail->prev != NULL)
  729.                             next_mail = next_mail->prev;
  730.                         }
  731.                     xmit_window (next_mail);
  732.                     goto bad_char;
  733.  
  734.                 default:
  735.                     status_line (msgtxt[M_JUNK_CHARACTER]);
  736.                     m = 1;
  737.                     goto bad_char;
  738.                 }
  739.             }
  740.         else
  741.             {
  742.             switch (i & 0xff)
  743.                 {
  744.                 case 'C':
  745.                 case 'c':
  746.                     if (cur_event >= 0)
  747.                         if (e_ptrs[cur_event]->behavior & MAT_NOOUT)
  748.                             {
  749.                             status_line (msgtxt[M_NO_CALLS_NOW]);
  750.                             goto immed_call;
  751.                             }
  752.  
  753.                     status_line (msgtxt[M_IMMEDIATE_CALL]);
  754.                     m = 0;
  755.                     more_mail = 1;
  756.                     goto immed_call;
  757.  
  758.                 case 3:
  759.                     status_line (msgtxt[M_EXIT_REQUEST]);
  760.                     goto mail_done;
  761.  
  762.                 case 0x20:
  763.                     m = 1;
  764.                     goto bad_char;
  765.  
  766.                 default:
  767.                     status_line (msgtxt[M_JUNK_CHARACTER]);
  768.                     m = 1;
  769.                     goto bad_char;
  770.                 }
  771.             }
  772.         }
  773.  
  774. mail_done:
  775.     write_sched ();
  776.     status_line ("+end, %s", xfer_id);
  777.     un_attended = 0;
  778.     if (fullscreen)
  779.         gotoxy (0, SB_ROWS);
  780.     set_prior(4);                                 /* Always High */
  781.     XON_ENABLE ();
  782.     set_prior(2);                                 /* Regular */
  783.     return (done);
  784.     }
  785.