home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / DOOR / BD2K260A.ZIP / SRC.ZIP / SRC / FTSC.C < prev    next >
C/C++ Source or Header  |  1998-10-03  |  22KB  |  855 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-96, Bit Bucket Software Co.              */
  11. /*                                                                          */
  12. /*                 This module was written by Bob Hartman                   */
  13. /*                                                                          */
  14. /*                 BinkleyTerm FTSC Mail Session Routines                   */
  15. /*                                                                          */
  16. /*                                                                          */
  17. /*    For complete  details  of the licensing restrictions, please refer    */
  18. /*    to the License  agreement,  which  is published in its entirety in    */
  19. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.260.    */
  20. /*                                                                          */
  21. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  22. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  23. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  24. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  25. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  26. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  27. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  28. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  29. /*                                                                          */
  30. /*                                                                          */
  31. /* You can contact Bit Bucket Software Co. at any one of the following      */
  32. /* addresses:                                                               */
  33. /*                                                                          */
  34. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  35. /* P.O. Box 460398                AlterNet 7:42/1491                        */
  36. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  37. /*                                Internet f491.n343.z1.fidonet.org         */
  38. /*                                                                          */
  39. /* Please feel free to contact us at any time to share your comments about  */
  40. /* our software and/or licensing policies.                                  */
  41. /*                                                                          */
  42. /*--------------------------------------------------------------------------*/
  43.  
  44. /* Include this file before any other includes or defines! */
  45.  
  46. #include "includes.h"
  47.  
  48. #define rb_plus "r+b"
  49.  
  50. static int FTSC_callback (char *);
  51. static int FTSC_time (long);
  52. static int LOCALFUNC FTSC_sendmail (void);
  53. static int LOCALFUNC FTSC_recvmail (int);
  54.  
  55. #define NUM_FLAGS 4
  56.  
  57. void 
  58. FTSC_sender (int wz)
  59. {
  60.     int j;
  61.     char junkbuff[128];
  62.     long t1;
  63.  
  64.     XON_DISABLE ();
  65.     first_block = 0;
  66.  
  67.     if (!wz)
  68.     {
  69.         first_block = 1;
  70.         status_line (MSG_TXT (M_SEND_FALLBACK));
  71.         who_is_he = 0;
  72.         (void) sprintf (junkbuff, "*%s (%s)",
  73.             newnodedes.SystemName,
  74.             Full_Addr_Str (&remote_addr));
  75.         status_line (junkbuff);
  76.     }
  77.  
  78.     Netmail_Session = 1;
  79.  
  80.     (void) FTSC_sendmail ();
  81.     t1 = timerset (4500);
  82.  
  83.     /* See what the receiver would like us to do */
  84.  
  85.     while ((!timeup (t1)) && CARRIER)
  86.     {
  87.         if ((j = PEEKBYTE ()) >= 0)
  88.         {
  89.             switch (j)
  90.             {
  91.             case TSYNC:
  92.                 CLEAR_INBOUND ();
  93.                 if (FTSC_recvmail (1))
  94.                     goto get_out;
  95.                 t1 = timerset (4500);
  96.                 break;
  97.  
  98.             case SYN:
  99.                 CLEAR_INBOUND ();
  100.                 if (on_our_nickel)
  101.                     (void) SEA_recvreq ();
  102.                 else
  103.                 {
  104.                     SENDBYTE (CAN);
  105.                     status_line (MSG_TXT (M_REFUSING_IN_FREQ));
  106.                 }
  107.                 t1 = timerset (4500);
  108.                 break;
  109.  
  110.             case ENQ:
  111.                 CLEAR_INBOUND ();
  112.                 SEA_sendreq ();
  113.                 goto get_out;
  114.  
  115.             case NAK:
  116.             case 'C':
  117.                 CLEAR_INBOUND ();
  118.                 SENDBYTE (EOT);
  119.                 t1 = timerset (4500);
  120.                 break;
  121.  
  122.             default:
  123.                 CLEAR_INBOUND ();
  124.                 SENDBYTE (SUB);
  125.                 break;
  126.             }
  127.         }
  128.         else
  129.         {
  130.             time_release ();
  131.         }
  132.     }
  133.  
  134.     if (!CARRIER)
  135.     {
  136.         status_line (MSG_TXT (M_NO_CARRIER));
  137.         CLEAR_INBOUND ();
  138.         first_block = 0;
  139.         return;
  140.     }
  141.  
  142.     if (timeup (t1))
  143.     {
  144.         (void) FTSC_recvmail (1);
  145.         status_line (MSG_TXT (M_TOO_LONG));
  146.     }
  147.  
  148. get_out:
  149.  
  150.     first_block = 0;
  151.     t1 = timerset (100);
  152.     while (!timeup (t1))
  153.         time_release ();
  154.     if (!wz)
  155.         status_line (MSG_TXT (M_0001_END));
  156. }
  157.  
  158. int 
  159. FTSC_receiver (int wz)
  160. {
  161.     char fname[64];
  162.     int havemail, done, np;
  163.     unsigned int i;
  164.     long t1, t2;
  165.     struct stat buf;
  166.     char *HoldName;
  167.     struct FILEINFO dta =
  168.     {0};
  169.     ADDR tmp;
  170.  
  171.     first_block = 0;
  172.     XON_DISABLE ();
  173.  
  174.     if (!wz)
  175.     {
  176.         first_block = 1;
  177.         status_line (MSG_TXT (M_RECV_FALLBACK));
  178.         who_is_he = 1;
  179.     }
  180.  
  181.     Netmail_Session = 1;
  182.  
  183.     CLEAR_INBOUND ();
  184.  
  185.     /* Save the state of pickup for now */
  186.  
  187.     done = no_pickup;
  188.     no_pickup = 0;
  189.     if (FTSC_recvmail (0))
  190.     {
  191.         /* Restore the state of pickup */
  192.  
  193.         no_pickup = done;
  194.         if (!wz)
  195.             status_line (MSG_TXT (M_0001_END));
  196.         first_block = 0;
  197.         return (1);
  198.     }
  199.  
  200.     /* Restore the state of pickup */
  201.  
  202.     no_pickup = done;
  203.  
  204.     remote_addr = called_addr;
  205.  
  206.     HoldName = HoldAreaNameMunge (&called_addr);
  207.  
  208.     /* Now see if we should send anything back to him */
  209.  
  210.     (void) sprintf (fname, "%s%s.?UT", HoldName, Hex_Addr_Str (&remote_addr));
  211.     havemail = !dfind (&dta, fname, 0);
  212.  
  213.     if (!havemail)
  214.     {
  215.         (void) sprintf (fname, "%s%s.?LO", HoldName, Hex_Addr_Str (&remote_addr));
  216.         havemail = !dfind (&dta, fname, 0);
  217.     }
  218.  
  219.     if (!havemail)
  220.     {
  221.         for (np = 0; np <= ALIAS_CNT; np++)
  222.         {
  223.             if (alias[np].Net == 0)
  224.                 break;
  225.             (void) sprintf (fname, "%s%s.REQ", CURRENT.sc_Inbound, Hex_Addr_Str (&(alias[np])));
  226.             havemail = !dfind (&dta, fname, 0);
  227.             if (havemail)
  228.                 break;
  229.         }
  230.     }
  231.  
  232.     if (!havemail)
  233.     {
  234.         status_line (MSG_TXT (M_NOTHING_TO_SEND), Full_Addr_Str (&remote_addr));
  235.     }
  236.     else
  237.     {
  238.         /* Release any resource involved in finding the mail */
  239.  
  240.         (void) dfind (&dta, NULL, 2);
  241.         status_line (MSG_TXT (M_GIVING_MAIL), Full_Addr_Str (&remote_addr));
  242.  
  243.         /* Send the TSYNC's until we get a C or NAK or CAN back */
  244.  
  245.         t1 = timerset (3000);    /* set 30 second timeout */
  246.         done = 0;
  247.         while (!timeup (t1) && CARRIER && !done)    /* till then or CD lost  */
  248.         {
  249.             SENDBYTE (TSYNC);
  250.  
  251.             t2 = timerset (300);
  252.             while (CARRIER && (!timeup (t2)) && !done)
  253.             {
  254.                 switch (TIMED_READ (0))
  255.                 {
  256.                 case 'C':
  257.                 case NAK:
  258.                     done = 1;
  259.                     (void) FTSC_sendmail ();
  260.                     break;
  261.  
  262.                 case CAN:
  263.                     done = 1;
  264.                     status_line (MSG_TXT (M_REFUSE_PICKUP), Full_Addr_Str (&remote_addr));
  265.                     break;
  266.  
  267.                 default:
  268.                     time_release ();
  269.                 }
  270.             }
  271.         }
  272.     }
  273.  
  274.     first_block = 0;
  275.  
  276.     if (wz)
  277.         return TRUE;            /* All done if this is WaZOO */
  278.  
  279.     /* Now see if we want to request anything */
  280.  
  281.     tmp = remote_addr;
  282.  
  283.     /* For a point, massage the address to get the right .REQ filename */
  284.  
  285.     if (tmp.Point != 0)
  286.     {
  287.         tmp.Node = tmp.Point;
  288.         tmp.Point = 0;
  289.         tmp.Net = (pvtnet > 0) ? (unsigned int) pvtnet : 0;
  290.     }
  291.  
  292.     (void) sprintf (fname, "%s%s.REQ", HoldName, Hex_Addr_Str (&tmp));
  293.     if (!stat (fname, &buf))
  294.     {
  295.         /* Send the SYN character and wait for an ENQ or CAN */
  296.  
  297.         t1 = timerset (3000);    /* set 30 second timeout */
  298.         done = 0;
  299.         while (!timeup (t1) && CARRIER && !done)    /* till then or CD lost  */
  300.         {
  301.             SENDBYTE (SYN);
  302.  
  303.             t2 = timerset (500);
  304.             while (CARRIER && (!timeup (t2)) && !done)
  305.             {
  306.                 i = (unsigned) TIMED_READ (0);
  307.  
  308.                 switch (i)
  309.                 {
  310.                 case ENQ:
  311.                     SEA_sendreq ();
  312.                     break;
  313.  
  314.                 case CAN:
  315.                     done = 1;
  316.                     break;
  317.  
  318.                 case 'C':
  319.                 case NAK:
  320.                     SENDBYTE (EOT);
  321.                     break;
  322.  
  323.                 case SUB:
  324.                     SENDBYTE (SYN);
  325.                     break;
  326.  
  327.                 default:
  328.                     time_release ();
  329.                 }
  330.             }
  331.         }
  332.     }
  333.  
  334.     /* Finally, can he request anything from us */
  335.  
  336.     if (!no_requests)
  337.         (void) SEA_recvreq ();
  338.  
  339.     status_line (MSG_TXT (M_0001_END));
  340.     return TRUE;
  341. }
  342.  
  343. static int LOCALFUNC
  344. FTSC_sendmail ()
  345. {
  346.     FILE *fp;
  347.     char fname[80];
  348.     char s[80];
  349.     char *sptr;
  350.     char *HoldName;
  351.     int c;
  352.     int i;
  353.     int j = 0;
  354.     struct stat buf;
  355.     struct _pkthdr *tmppkt;
  356.     time_t t1;
  357.     struct tm *tm1;
  358.  
  359.     XON_DISABLE ();
  360.  
  361.     (void) n_getpassword (&called_addr);    /* Update "assumed" */
  362.  
  363.     sptr = s;
  364.  
  365.     /*--------------------------------------------------------------------*/
  366.     /* Send all waiting ?UT files (mail packets)                          */
  367.     /*--------------------------------------------------------------------*/
  368.  
  369.     *ext_flags = 'O';
  370.     HoldName = HoldAreaNameMunge (&called_addr);
  371.     for (c = 0; c < NUM_FLAGS; c++)
  372.     {
  373. #ifndef JACK_DECKER
  374.         if (caller && (ext_flags[c] == 'H'))
  375.             continue;
  376. #endif
  377.         (void) sprintf (fname,
  378.             "%s%s.%cUT",
  379.             HoldName, Hex_Addr_Str (&called_addr), ext_flags[c]);
  380.  
  381.         if (!stat (fname, &buf))
  382.             break;
  383.     }                            /* for */
  384.  
  385.     /*--- Build a dummy PKT file name */
  386.  
  387.     invent_pkt_name (s);
  388.  
  389.     status_line (MSG_TXT (M_PACKET_MSG));
  390.  
  391.     if (c == NUM_FLAGS)
  392.     {
  393.         (void) sprintf (fname,
  394.             "%s%s.OUT",
  395.             HoldName, Hex_Addr_Str (&called_addr));
  396.         if ((fp = fopen (fname, write_binary)) == NULL)
  397.         {
  398.             (void) got_error (MSG_TXT (M_OPEN_MSG), fname);
  399.             return (1);
  400.         }
  401.         t1 = time (NULL);
  402.         tm1 = localtime (&t1);
  403.  
  404.         tmppkt = (struct _pkthdr *) calloc (1, sizeof (struct _pkthdr));
  405.  
  406.         if (tmppkt == NULL)
  407.         {
  408.             status_line (MSG_TXT (M_MEM_ERROR));
  409.             (void) fclose (fp);
  410.             return (1);
  411.         }
  412.         tmppkt->orig_node = (int) alias[assumed].Node;
  413.         tmppkt->dest_node = called_addr.Node;
  414.         tmppkt->ver = PKTVER;
  415.         tmppkt->orig_net = (int) alias[assumed].Net;
  416.         tmppkt->dest_net = called_addr.Net;
  417.         tmppkt->product = PRDCT_CODE;
  418.         if (n_getpassword (&called_addr) > 0)
  419.         {
  420.             if (remote_password != NULL)
  421.             {
  422.                 (void) strupr (remote_password);
  423.                 (void) strncpy ((char *) (tmppkt->password), remote_password, 8);
  424.             }
  425.         }
  426.         tmppkt->orig_zone = (int) alias[assumed].Zone;
  427.         tmppkt->dest_zone = called_addr.Zone;
  428.  
  429.         if (((called_addr.Domain != NULL)
  430.                 && (called_addr.Domain != alias[assumed].Domain)
  431.                 && (my_addr.Domain != NULL))
  432.             || (alias[assumed].Point != 0))
  433.         {
  434.             /* Make it a type 2.2 packet instead */
  435.             /* [Y2K] Ok as is.  The point value is hacked into the
  436.              * year field.  In the year 2000, the point value probably
  437.              * won't change :)
  438.              */
  439.             tmppkt->year = alias[assumed].Point;
  440.             tmppkt->month = called_addr.Point;
  441.             tmppkt->day = 0;
  442.             tmppkt->hour = 0;
  443.             tmppkt->minute = 0;
  444.             tmppkt->second = 0;
  445.             tmppkt->rate = 2;
  446.             if (alias[assumed].Domain != NULL)
  447.             {
  448.                 for (i = 0; domain_name[i] != NULL; i++)
  449.                 {
  450.                     if (domain_name[i] == alias[assumed].Domain)
  451.                     {
  452.                         break;
  453.                     }
  454.                 }
  455.                 if (i < 49)
  456.                 {
  457.                     (void) strncpy ((char *) tmppkt->B_fill2, domain_abbrev[i], 8);
  458.                 }
  459.             }
  460.  
  461.             for (i = 0; domain_name[i] != NULL; i++)
  462.             {
  463.                 if (domain_name[i] == called_addr.Domain)
  464.                 {
  465.                     break;
  466.                 }
  467.             }
  468.             if ((i < 49) && (domain_name[i] != NULL))
  469.             {
  470.                 (void) strncpy ((char *) &(tmppkt->B_fill2[8]), domain_abbrev[i], 8);
  471.             }
  472.         }
  473.         else
  474.         {
  475. #ifdef Y2K_FIXES
  476.             /* [Y2K] Fixed - made this four digits.  I think this was
  477.              * a bug.  See note in bink.h about how this field is handled.
  478.              */
  479.             tmppkt->year = 1980 + tm1->tm_year;
  480. #else
  481.             tmppkt->year = tm1->tm_year;
  482. #endif
  483.             tmppkt->month = tm1->tm_mon;
  484.             tmppkt->day = tm1->tm_mday;
  485.             tmppkt->hour = tm1->tm_hour;
  486.             tmppkt->minute = tm1->tm_min;
  487.             tmppkt->second = tm1->tm_sec;
  488.             tmppkt->rate = 0;
  489.         }
  490.  
  491.         (void) fwrite ((char *) tmppkt, sizeof (struct _pkthdr), 1, fp);
  492.  
  493.         free (tmppkt);
  494.         (void) fwrite ("\0\0", 2, 1, fp);
  495.         (void) fclose (fp);
  496.     }
  497.     else
  498.     {
  499.         if ((fp = fopen (fname, rb_plus)) == NULL)
  500.         {
  501.             (void) got_error (MSG_TXT (M_OPEN_MSG), fname);
  502.             return (1);
  503.         }
  504.         tmppkt = (struct _pkthdr *) calloc (1, sizeof (struct _pkthdr));
  505.  
  506.         if (tmppkt == NULL)
  507.         {
  508.             status_line (MSG_TXT (M_MEM_ERROR));
  509.             return (1);
  510.         }
  511.         if (fread (tmppkt, 1, sizeof (struct _pkthdr), fp) < sizeof (struct _pkthdr))
  512.         {
  513.             (void) got_error (MSG_TXT (M_READ_MSG), fname);
  514.             free (tmppkt);
  515.             (void) fclose (fp);
  516.             return (1);
  517.         }
  518.  
  519.         if (n_getpassword (&called_addr) > 0)
  520.         {
  521.             if (remote_password != NULL)
  522.             {
  523.                 (void) strupr (remote_password);
  524.                 (void) strncpy ((char *) (tmppkt->password), remote_password, 8);
  525.             }
  526.         }
  527.  
  528.         /* Make sure the zone info is in there */
  529.  
  530.         tmppkt->orig_node = (int) alias[assumed].Node;
  531.         tmppkt->orig_net = (int) alias[assumed].Net;
  532.         tmppkt->orig_zone = (int) alias[assumed].Zone;
  533.         tmppkt->dest_zone = called_addr.Zone;
  534.  
  535.         if ((called_addr.Domain != NULL) &&
  536.             (called_addr.Domain != alias[assumed].Domain) &&
  537.             (my_addr.Domain != NULL))
  538.         {
  539.             /* Make it a type 2.2 packet instead */
  540.  
  541.             /* [Y2K] Ok as is.  The point value is Y2K compliant :)
  542.              */
  543.             tmppkt->year = alias[assumed].Point;
  544.             tmppkt->month = called_addr.Point;
  545.             tmppkt->day = 0;
  546.             tmppkt->hour = 0;
  547.             tmppkt->minute = 0;
  548.             tmppkt->second = 0;
  549.             tmppkt->rate = 2;
  550.             if (alias[assumed].Domain != NULL)
  551.             {
  552.                 for (i = 0; domain_name[i] != NULL; i++)
  553.                 {
  554.                     if (domain_name[i] == alias[assumed].Domain)
  555.                     {
  556.                         break;
  557.                     }
  558.                 }
  559.                 if (i < 49)
  560.                 {
  561.                     (void) strncpy ((char *) tmppkt->B_fill2, domain_abbrev[i], 8);
  562.                 }
  563.             }
  564.             for (i = 0; domain_name[i] != NULL; i++)
  565.             {
  566.                 if (domain_name[i] == called_addr.Domain)
  567.                 {
  568.                     break;
  569.                 }
  570.             }
  571.             if (i < 49)
  572.             {
  573.                 (void) strncpy ((char *) &(tmppkt->B_fill2[8]), domain_abbrev[i], 8);
  574.             }
  575.         }
  576.  
  577.         (void) fseek (fp, 0L, SEEK_SET);
  578.         (void) fwrite (tmppkt, 1, sizeof (struct _pkthdr), fp);
  579.  
  580.         (void) fclose (fp);
  581.         free (tmppkt);
  582.     }
  583.  
  584.     net_problems = (no_sealink) ? Telink_Send_File (fname, s) : SEAlink_Send_File (fname, s);
  585.  
  586.     if (net_problems != 0)
  587.     {
  588.         if (c == NUM_FLAGS)
  589.             (void) unlink (fname);
  590.         return (net_problems);
  591.     }
  592.  
  593.     /* Delete the sent packet */
  594.     (void) unlink (fname);
  595.  
  596.     /*--------------------------------------------------------------------*/
  597.     /* Send files listed in ?LO files (attached files)                    */
  598.     /*--------------------------------------------------------------------*/
  599.  
  600.     *ext_flags = 'F';
  601.     status_line (" %s %s", MSG_TXT (M_OUTBOUND), MSG_TXT (M_FILE_ATTACHES));
  602.  
  603.     if (!do_FLOfile (ext_flags, FTSC_callback))
  604.         return FALSE;
  605.  
  606.     /*--------------------------------------------------------------------*/
  607.     /* Send our File requests to other system if it's a WaZOO             */
  608.     /*--------------------------------------------------------------------*/
  609.  
  610.     if (requests_ok && remote_capabilities)
  611.     {
  612.         (void) sprintf (fname, "%s%s.REQ", HoldName, Hex_Addr_Str (&called_addr));
  613.         if (!stat (fname, &buf))
  614.         {
  615.             if (!(((unsigned) remote_capabilities) & WZ_FREQ))
  616.                 status_line (MSG_TXT (M_FREQ_DECLINED));
  617.             else
  618.             {
  619.                 status_line (MSG_TXT (M_MAKING_FREQ));
  620.                 if (FTSC_callback (fname))
  621.                     (void) unlink (fname);
  622.             }
  623.         }
  624.     }
  625.  
  626.     /*--------------------------------------------------------------------*/
  627.     /* Process WaZOO file requests from other system                      */
  628.     /*--------------------------------------------------------------------*/
  629.  
  630.     j = respond_to_file_requests (j, FTSC_callback, FTSC_time);
  631.  
  632.     /* Now close out the file attaches */
  633.     sent_mail = 1;
  634.     *sptr = 0;
  635.     status_line (" %s %s %s", MSG_TXT (M_END_OF), MSG_TXT (M_OUTBOUND), MSG_TXT (M_FILE_ATTACHES));
  636.     (void) Batch_Send (NULL);
  637.     return TRUE;
  638. }
  639.  
  640. static int LOCALFUNC 
  641. FTSC_recvmail (int outbound_session)
  642. {
  643.     char fname[80];
  644.     char fname1[80];
  645.     char fname2[80];
  646.     struct _pkthdr tmppkt;
  647.     FILE *fp, *fp1;
  648.     int done;
  649.     int i = 0;
  650.     int j;
  651.     int logit = TRUE;
  652.     char *starting_inbound;
  653.  
  654.     status_line (MSG_TXT (M_RECV_MAIL));
  655.  
  656.     if (!CARRIER)
  657.     {
  658.         status_line (MSG_TXT (M_NO_CARRIER));
  659.         CLEAR_INBOUND ();
  660.         return (1);
  661.     }
  662.  
  663.     XON_DISABLE ();
  664.  
  665.     done = 0;
  666.  
  667.     /* If we don't want to pickup stuff */
  668.  
  669.     if (no_pickup)
  670.     {
  671.         status_line (MSG_TXT (M_NO_PICKUP));
  672.         SENDBYTE (CAN);
  673.     }
  674.     else
  675.     {
  676.         status_line (" %s %s", MSG_TXT (M_INBOUND), MSG_TXT (M_MAIL_PACKET));
  677.  
  678.         /* Invent a dummy name for the packet */
  679.  
  680.         invent_pkt_name (fname1);
  681.  
  682.         /* Receive the packet with special netmail protocol */
  683.  
  684.         CLEAR_INBOUND ();
  685.  
  686.         starting_inbound = CURRENT.sc_Inbound;
  687.  
  688.         if (Xmodem_Receive_File (CURRENT.sc_Inbound, fname1) == 0)
  689.         {
  690.             got_packet = 1;
  691.         }
  692.         (void) sprintf (fname, "%s%s", starting_inbound, fname1);
  693.  
  694.         /* Check the password if there is one */
  695.  
  696.         if ((!remote_capabilities) && (!outbound_session))
  697.             i = n_getpassword (&remote_addr);
  698.  
  699.         if (i < 0)
  700.         {
  701.             status_line (MSG_TXT (M_NUISANCE_CALLER));
  702.             LOWER_DTR ();        /* Hang up right now      */
  703.             goto bad_caller;
  704.         }
  705.  
  706.         if (i != 0)
  707.         {
  708.             if (remote_password != NULL)
  709.             {
  710.                 got_packet = 0;
  711.                 if ((fp = fopen (fname, rb_plus)) == NULL)
  712.                 {
  713.                     (void) got_error (MSG_TXT (M_OPEN_MSG), fname);
  714.                     status_line (MSG_TXT (M_PWD_ERR_ASSUMED));
  715.                     return (1);
  716.                 }
  717.                 if (fread (&tmppkt, 1, sizeof (struct _pkthdr), fp) < sizeof (struct _pkthdr))
  718.                 {
  719.                     (void) got_error (MSG_TXT (M_OPEN_MSG), fname);
  720.                     status_line (MSG_TXT (M_PWD_ERR_ASSUMED));
  721.                     (void) fclose (fp);
  722.                     return (1);
  723.                 }
  724.                 (void) fclose (fp);
  725.                 if (n_password ((char *) (tmppkt.password), remote_password, &logit))
  726.                 {
  727. bad_caller:
  728.                     (void) strcpy (fname1, fname);
  729.                     j = (int) strlen (fname) - 3;
  730.                     (void) strcpy (&(fname[j]), "Bad");
  731.                     if (rename (fname1, fname))
  732.                     {
  733.                         status_line (MSG_TXT (M_CANT_RENAME_MAIL), fname1);
  734.                     }
  735.                     else
  736.                     {
  737.                         status_line (MSG_TXT (M_MAIL_PACKET_RENAMED), fname);
  738.                     }
  739.                     return (1);
  740.                 }
  741.             }
  742.             got_packet = 1;
  743.         }
  744.   /*
  745.    *  See if things changed after the fact. If so, we want to move
  746.    *  the mail packet from the non-secured directory into the
  747.    *  secured one. This is slightly tricky. Start with a simple rename
  748.    *  and if that doesn't work (it might not if we're spanning drives)
  749.    *  do a simple copy/unlink.
  750.    *
  751.    *  Steal resources such as 'done' and 'Secbuf' wherever that makes sense.
  752.    */
  753.  
  754.         if (strcmp (starting_inbound, CURRENT.sc_Inbound) != 0)
  755.         {
  756.             (void) strcpy (fname2, CURRENT.sc_Inbound);
  757.             (void) strcat (fname2, fname1);
  758.  
  759.             /*  Try the easy case first. A straight rename. */
  760.  
  761.             done = 1;
  762.  
  763.             if (rename (fname2, fname))
  764.             {
  765.  
  766.      /*     If we get here, the straight rename didn't work. Let's
  767.       *     do a copy. Use Secbuf since while we are here, we're
  768.       *     not doing any file transfers.
  769.       */
  770.                 done = 0;        /* default is failure till files are open */
  771.  
  772.                 if ((fp = fopen (fname, rb_plus)) == NULL)
  773.                 {
  774.                     (void) got_error (MSG_TXT (M_OPEN_MSG), fname);
  775.                 }
  776.                 else if ((fp1 = fopen (fname2, write_binary)) == NULL)
  777.                 {
  778.                     (void) got_error (MSG_TXT (M_OPEN_MSG), fname2);
  779.                 }
  780.                 else
  781.                 {
  782.                     /* Here both packets are open */
  783.                     /* Steal Secbuf because nobody's using it now */
  784.  
  785.                     done = 1;    /* default is success now */
  786.  
  787.                     while ((j = fread (Secbuf, 1, WAZOOMAX, fp)) > 0)
  788.                     {
  789.                         if (fwrite (Secbuf, j, 1, fp1) != 1)
  790.                         {
  791.                             (void) got_error (MSG_TXT (M_WRITE_MSG), fname2);
  792.                             done = 0;    /* only possible failure = write err */
  793.                             break;
  794.                         }
  795.                     }
  796.                     (void) fclose (fp1);
  797.  
  798.                     if (done == 0)    /* Figure out which file to delete */
  799.                         (void) unlink (fname2);
  800.                     else
  801.                         (void) unlink (fname);
  802.                 }
  803.             }
  804.             if (done == 0)
  805.                 status_line (MSG_TXT (M_CANT_RENAME_MAIL), fname);
  806.             else
  807.                 status_line (MSG_TXT (M_MAIL_PACKET_RENAMED), fname2);
  808.         }
  809.  
  810.   /*
  811.    * If this was an inbound session, we need to set up the
  812.    * node flags for the node.
  813.    */
  814.         got_mail = got_packet;
  815.         if (!outbound_session)
  816.         {
  817.             if (flag_file (TEST_AND_SET, &remote_addr, 1))
  818.                 return (1);
  819.             called_addr = remote_addr;
  820.         }
  821.  
  822.         done = 0;
  823.  
  824.         /* Now receive the files if possible */
  825.  
  826.         status_line (" %s %s", MSG_TXT (M_INBOUND), MSG_TXT (M_FILE_ATTACHES));
  827.         done = Batch_Receive (CURRENT.sc_Inbound);
  828.     }
  829.  
  830.     status_line (" %s %s %s", MSG_TXT (M_END_OF), MSG_TXT (M_INBOUND), MSG_TXT (M_FILE_ATTACHES));
  831.     CLEAR_INBOUND ();
  832.     return (done);
  833. }
  834.  
  835. static int 
  836. FTSC_callback (char *sptr)
  837. {
  838.     net_problems = Batch_Send (sptr);
  839.     if (net_problems != 0)
  840.     {
  841.         net_problems = 1;
  842.         return FALSE;
  843.     }
  844.     return TRUE;
  845. }
  846.  
  847. static int 
  848. FTSC_time (long filesize)
  849. {
  850.     long ltemp;
  851.  
  852.     ltemp = filesize * 10L / cur_baud.rate_value * 100L / 94L;
  853.     return (ltemp < 20L) ? 20 : (int) ltemp;
  854. }
  855.