home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / FTSC.C < prev    next >
C/C++ Source or Header  |  1998-05-17  |  37KB  |  1,587 lines

  1.  
  2. // LoraBBS Version 2.41 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include <stdio.h>
  20. #include <conio.h>
  21. #include <dos.h>
  22. #include <io.h>
  23. #include <fcntl.h>
  24. #include <sys\stat.h>
  25. #include <time.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <ctype.h>
  29. #include <dir.h>
  30.  
  31. #include <cxl\cxlvid.h>
  32. #include <cxl\cxlwin.h>
  33.  
  34. #include "lsetup.h"
  35. #include "sched.h"
  36. #include "msgapi.h"
  37. #include "externs.h"
  38. #include "prototyp.h"
  39. #include "zmodem.h"
  40.  
  41. extern long elapsed, timeout;
  42. extern char nomailproc;
  43.  
  44. char *n_frproc(char *, int *, int);
  45. int n_getpassword(int, int, int, int);
  46. long get_phone_cost (int, int, int, long);
  47. void import_sequence (void);
  48.  
  49. static int recvmdm7(char *);
  50. int xfermdm7(char *);
  51. static int FTSC_sendmail(void);
  52. static int FTSC_recvmail(void);
  53. static int SEA_sendreq(void);
  54. static int SEA_recvreq(void);
  55. static int try_sealink(void);
  56. static int req_out(char *,char *);
  57. static int get_req_str(char *,char *,int *);
  58. static int gen_req_name(char *,char *,int *);
  59.  
  60. struct _pkthdr22
  61. {
  62.    int  orig_node;         /* originating node               */
  63.    int  dest_node;         /* destination node               */
  64.    int  orig_point;        /* originating point              */
  65.    int  dest_point;        /* Destination point              */
  66.    byte reserved[8];
  67.    int  subver;            /* packet subversion              */
  68.    int  ver;               /* packet version                 */
  69.    int  orig_net;          /* originating network number     */
  70.    int  dest_net;          /* destination network number     */
  71.    char product;           /* product type                   */
  72.    char serial;            /* serial number (some systems)   */
  73.    byte password[8];       /* session/pickup password        */
  74.    int  orig_zone;         /* originating zone               */
  75.    int  dest_zone;         /* Destination zone               */
  76.    char orig_domain[8];    /* originating domain name        */
  77.    char dest_domain[8];    /* destination domain name        */
  78.    byte filler[4];
  79. };
  80.  
  81. /*------------------------------------------------------------------------*/
  82. /*                 Protocolli Trasferimento Network                       */
  83. /*------------------------------------------------------------------------*/
  84. #define WAZOO_SECTION
  85. #define MATRIX_SECTION
  86.  
  87. #define PRODUCT_CODE 0x4E
  88. #define isLORA       0x4E
  89. #define no_zapzed    0
  90. #define NUM_FLAGS    5
  91.  
  92. #include "version.h"
  93.  
  94. #define Z_PUTHEX(i,c) {i=(c);SENDBYTE(hex[((i)&0xF0)>>4]);SENDBYTE(hex[(i)&0xF]);}
  95. #define ZATTNLEN     32
  96.  
  97. static int net_problems;
  98.  
  99.  
  100. int FTSC_sender (wz)
  101. int wz;
  102. {
  103.    int j, wh;
  104.    char req[120];
  105.    long t1, t, olc;
  106.  
  107.    XON_DISABLE ();
  108.    first_block = 0;
  109.  
  110.    if (!wz) {
  111.       status_line(msgtxt[M_SEND_FALLBACK]);
  112.  
  113.       timeout = 0L;
  114.       filetransfer_system ();
  115.       update_filesio (0, 0);
  116.  
  117.       wh = wopen (12, 0, 24, 79, 0, LGREY|_BLACK, WHITE|_BLACK);
  118.       wactiv (wh);
  119.       wtitle ("OUTBOUND CALL STATUS", TLEFT, LCYAN|_BLACK);
  120.       printc (12, 0, LGREY|_BLACK, '├');
  121.       printc (12, 52, LGREY|_BLACK, '┴');
  122.       printc (12, 79, LGREY|_BLACK, '┤');
  123.       whline (8, 0, 80, 0, LGREY|_BLACK);
  124.  
  125.       sprintf (req, "%u:%u/%u.%u, %s, %s, %s", remote_zone, remote_net, remote_node, remote_point, nodelist.sysop, nodelist.name, nodelist.city);
  126.       if (strlen (req) > 78)
  127.          req[78] = '\0';
  128.       wcenters (0, LGREY|_BLACK, req);
  129.       sprintf (req, "Connected at %lu baud", rate);
  130.       wcenters (1, LGREY|_BLACK, req);
  131.       wcenters (2, LGREY|_BLACK, "AKAs: No aka presented");
  132.  
  133.       wprints (5, 2, LCYAN|_BLACK, "Files");
  134.       wprints (6, 2, LCYAN|_BLACK, "Bytes");
  135.  
  136.       wprints (4, 9, LCYAN|_BLACK, " ┌────MailPKT───────Data─────┐");
  137.       wprints (5, 9, LCYAN|_BLACK, "·······························");
  138.       wprints (6, 9, LCYAN|_BLACK, "·······························");
  139.       wprints (7, 9, LCYAN|_BLACK, " └──────INBOUND TRAFFIC──────┘");
  140.  
  141.       wrjusts (5, 20, YELLOW|_BLACK, "N/A");
  142.       wrjusts (6, 20, YELLOW|_BLACK, "N/A");
  143.       wrjusts (5, 31, YELLOW|_BLACK, "N/A");
  144.       wrjusts (6, 31, YELLOW|_BLACK, "N/A");
  145.  
  146.       wprints (4, 44, LCYAN|_BLACK, " ┌────MailPKT───────Data─────┐");
  147.       wprints (5, 44, LCYAN|_BLACK, "·······························");
  148.       wprints (6, 44, LCYAN|_BLACK, "·······························");
  149.       wprints (7, 44, LCYAN|_BLACK, " └─────OUTBOUND TRAFFIC──────┘");
  150.  
  151.       sprintf (req, "%d", call_list[next_call].n_mail);
  152.       wrjusts (5, 55, YELLOW|_BLACK, req);
  153.       sprintf (req, "%ld", call_list[next_call].b_mail);
  154.       wrjusts (6, 55, YELLOW|_BLACK, req);
  155.       sprintf (req, "%d", call_list[next_call].n_data);
  156.       wrjusts (5, 66, YELLOW|_BLACK, req);
  157.       sprintf (req, "%ld", call_list[next_call].b_data);
  158.       wrjusts (6, 66, YELLOW|_BLACK, req);
  159.  
  160.       prints (7, 65, YELLOW|_BLACK, "FSC-0001");
  161.       who_is_he = 0;
  162.    }
  163.  
  164.    FTSC_sendmail ();
  165.    t1 = timerset (1000);
  166.  
  167.    while ((!timeup (t1)) && CARRIER) {
  168.       if ((j = PEEKBYTE()) >= 0) {
  169.          switch (j) {
  170.             case TSYNC:
  171.                CLEAR_INBOUND();
  172.                if (FTSC_recvmail())
  173.                   goto get_out;
  174.                t1 = timerset (1000);
  175.                break;
  176.  
  177.             case SYN:
  178.                CLEAR_INBOUND();
  179.                SEA_recvreq();
  180.                t1 = timerset (1000);
  181.                break;
  182.  
  183.             case ENQ:
  184.                CLEAR_INBOUND();
  185.                SEA_sendreq();
  186.                goto get_out;
  187.  
  188.             case NAK:
  189.             case 'C':
  190.                TIMED_READ(0);
  191.                TIMED_READ(1);
  192.                TIMED_READ(1);
  193.                SENDBYTE(EOT);
  194.                t1 = timerset (1000);
  195.                break;
  196.  
  197.             default:
  198.                TIMED_READ(0);
  199.                SENDBYTE(EOT);
  200.                break;
  201.          }
  202.       }
  203.    }
  204.  
  205.    if (!CARRIER) {
  206.         status_line(msgtxt[M_HE_HUNG_UP]);
  207.         something_wrong=1;
  208.         CLEAR_INBOUND();
  209.         if (!wz)
  210.             wclose ();
  211.         return FALSE;
  212.     }
  213.  
  214.     if (timeup(t1)) {
  215.         FTSC_recvmail();
  216.         status_line (msgtxt[M_TOO_LONG]);
  217.     }
  218.  
  219. get_out:
  220.     t1 = timerset (100);
  221.     while (!timeup (t1));
  222.  
  223.     if (!wz) {
  224.         if (cur_event > -1 && (e_ptrs[cur_event]->behavior & MAT_DYNAM)) {
  225.             e_ptrs[cur_event]->behavior |= MAT_SKIP;
  226.             write_sched ();
  227.         }
  228.  
  229.         status_line (msgtxt[M_0001_END]);
  230.         terminating_call();
  231.         wclose ();
  232.  
  233.         t = time (NULL) - elapsed + 20L;
  234.         olc = get_phone_cost (remote_zone, remote_net, remote_node, t);
  235.         status_line ("*Session with %d:%d/%d.%d Time: %ld:%02ld, Cost: $%ld.%02ld", remote_zone, remote_net, remote_node, remote_point, t / 60L, t % 60L, olc / 100L, olc % 100L);
  236.  
  237.         HoldAreaNameMunge (call_list[next_call].zone);
  238.         bad_call (call_list[next_call].net, call_list[next_call].node, -2, 0);
  239.         sysinfo.today.completed++;
  240.         sysinfo.week.completed++;
  241.         sysinfo.month.completed++;
  242.         sysinfo.year.completed++;
  243.         sysinfo.today.outconnects += t;
  244.         sysinfo.week.outconnects += t;
  245.         sysinfo.month.outconnects += t;
  246.         sysinfo.year.outconnects += t;
  247.         sysinfo.today.cost += olc;
  248.         sysinfo.week.cost += olc;
  249.         sysinfo.month.cost += olc;
  250.         sysinfo.year.cost += olc;
  251.  
  252.         if (!nomailproc && got_arcmail) {
  253.             if (cur_event > -1 && e_ptrs[cur_event]->errlevel[2])
  254.                 aftermail_exit = e_ptrs[cur_event]->errlevel[2];
  255.  
  256.             if (cur_event > -1 && (e_ptrs[cur_event]->echomail & (ECHO_PROT|ECHO_KNOW|ECHO_NORMAL|ECHO_EXPORT))) {
  257.                 if (modem_busy != NULL)
  258.                     mdm_sendcmd (modem_busy);
  259.  
  260.                 t = time (NULL);
  261.  
  262.                 import_sequence ();
  263.  
  264.                 if (e_ptrs[cur_event]->echomail & ECHO_EXPORT) {
  265.                     if (config->mail_method) {
  266.                         export_mail (NETMAIL_RSN);
  267.                         export_mail (ECHOMAIL_RSN);
  268.                     }
  269.                     else
  270.                         export_mail (NETMAIL_RSN|ECHOMAIL_RSN);
  271.                 }
  272.  
  273.                 sysinfo.today.echoscan += time (NULL) - t;
  274.                 sysinfo.week.echoscan += time (NULL) - t;
  275.                 sysinfo.month.echoscan += time (NULL) - t;
  276.                 sysinfo.year.echoscan += time (NULL) - t;
  277.             }
  278.  
  279.             if (aftermail_exit) {
  280.                 status_line(msgtxt[M_EXIT_AFTER_MAIL],aftermail_exit);
  281.                 get_down (aftermail_exit, 3);
  282.             }
  283.         }
  284.  
  285.         get_down(0, 2);
  286.     }
  287.  
  288.     return(TRUE);
  289. }
  290.  
  291. int FTSC_receiver (wz)
  292. int wz;
  293. {
  294.     char fname[64], i, *HoldName, req[120];
  295.     int havemail, done, wh;
  296.     unsigned char j;
  297.     long t1, t2, t;
  298.     struct ffblk dt1;
  299.     struct stat buf;
  300.  
  301.     first_block = 0;
  302.     XON_DISABLE ();
  303.     HoldName = HoldAreaNameMunge (called_zone);
  304.  
  305.     if (!wz) {
  306.         status_line(msgtxt[M_RECV_FALLBACK]);
  307.  
  308.         timeout = 0L;
  309.         filetransfer_system ();
  310.         update_filesio (0, 0);
  311.  
  312.         wh = wopen (12, 0, 24, 79, 0, LGREY|_BLACK, WHITE|_BLACK);
  313.         wactiv (wh);
  314.         wtitle ("INBOUND CALL STATUS", TLEFT, LCYAN|_BLACK);
  315.         printc (12, 0, LGREY|_BLACK, '├');
  316.         printc (12, 52, LGREY|_BLACK, '┴');
  317.         printc (12, 79, LGREY|_BLACK, '┤');
  318.         whline (8, 0, 80, 0, LGREY|_BLACK);
  319.  
  320.         sprintf (req, "Connected at %lu baud", rate);
  321.         wcenters (1, LGREY|_BLACK, req);
  322.  
  323.         wprints (5, 2, LCYAN|_BLACK, "Files");
  324.         wprints (6, 2, LCYAN|_BLACK, "Bytes");
  325.  
  326.         wprints (4, 9, LCYAN|_BLACK, " ┌────MailPKT───────Data─────┐");
  327.         wprints (5, 9, LCYAN|_BLACK, "·······························");
  328.         wprints (6, 9, LCYAN|_BLACK, "·······························");
  329.         wprints (7, 9, LCYAN|_BLACK, " └──────INBOUND TRAFFIC──────┘");
  330.  
  331.         wrjusts (5, 20, YELLOW|_BLACK, "N/A");
  332.         wrjusts (6, 20, YELLOW|_BLACK, "N/A");
  333.         wrjusts (5, 31, YELLOW|_BLACK, "N/A");
  334.         wrjusts (6, 31, YELLOW|_BLACK, "N/A");
  335.  
  336.         wprints (4, 44, LCYAN|_BLACK, " ┌────MailPKT───────Data─────┐");
  337.         wprints (5, 44, LCYAN|_BLACK, "·······························");
  338.         wprints (6, 44, LCYAN|_BLACK, "·······························");
  339.         wprints (7, 44, LCYAN|_BLACK, " └─────OUTBOUND TRAFFIC──────┘");
  340.  
  341.         prints (7, 65, YELLOW|_BLACK, "FSC-0001");
  342.         who_is_he = 1;
  343.     }
  344.  
  345.     CLEAR_INBOUND();
  346.  
  347.     done = 0;
  348.     if (FTSC_recvmail ()) {
  349.         if (!wz) {
  350.             status_line (msgtxt[M_0001_END]);
  351.             wclose ();
  352.         }
  353.         return 1;
  354.     }
  355.  
  356.     HoldName = HoldAreaNameMunge (called_zone);
  357.     sprintf (fname,"%s%04x%04x.?UT",HoldName,called_net,called_node);
  358.     havemail = findfirst(fname,&dt1,0);
  359.  
  360.     if (havemail) {
  361.         sprintf(fname,"%s%04x%04x.?LO",HoldName,called_net,called_node);
  362.         havemail=findfirst(fname,&dt1,0);
  363.     }
  364.  
  365.     if (havemail) {
  366.         sprintf(fname,"%s%04x%04x.REQ",filepath,config->alias[assumed].net,config->alias[assumed].node);
  367.         havemail=findfirst(fname,&dt1,0);
  368.     }
  369.  
  370.     if (havemail && remote_point) {
  371.         sprintf (fname,"%s%04x%04x.PNT\\%08x.?UT",HoldName,remote_net,remote_node, remote_point);
  372.         havemail = findfirst(fname,&dt1,0);
  373.  
  374.         if (havemail) {
  375.             sprintf(fname,"%s%04x%04x.PNT\\%08x.?LO",HoldName,remote_net,remote_node,remote_point);
  376.             havemail=findfirst(fname,&dt1,0);
  377.         }
  378.     }
  379.  
  380.     if (havemail)
  381.         status_line ("*No mail waiting for %d:%d/%d.%d", remote_zone, remote_net, remote_node, remote_point);
  382.     else {
  383.         status_line (msgtxt[M_GIVING_MAIL], remote_zone, remote_net, remote_node, remote_point);
  384.         t1 = timerset(3000);
  385.         j = 0;
  386.         done = 0;
  387.         while (!timeup(t1) && CARRIER && !done) {
  388.             SENDBYTE(TSYNC);
  389.  
  390.             t2 = timerset (300);
  391.             while (CARRIER && (!timeup(t2)) && !done) {
  392.                 i = TIMED_READ (0);
  393.  
  394.                 switch (i) {
  395.                     case 'C':
  396.                     case 0x00:
  397.                     case 0x01:
  398.                         if (j == 'C') {
  399.                             done = 1;
  400.                             FTSC_sendmail ();
  401.                         }
  402.                         break;
  403.  
  404.                     case 0xfe:
  405.                         if (j == 0x01) {
  406.                             done = 1;
  407.                             FTSC_sendmail ();
  408.                         }
  409.                         break;
  410.  
  411.                     case 0xff:
  412.                         if (j == 0x00) {
  413.                             done = 1;
  414.                             FTSC_sendmail ();
  415.                         }
  416.                         break;
  417.  
  418.                     case NAK:
  419.                         if (j == NAK) {
  420.                             done = 1;
  421.                             FTSC_sendmail ();
  422.                         }
  423.                         break;
  424.                 }
  425.                 if (i != -1)
  426.                     j = i;
  427.             }
  428.         }
  429.     }
  430.  
  431.     sprintf( fname, "%s%04x%04x.REQ",HoldName,called_net,called_node);
  432.     if (!stat(fname,&buf)) {
  433.         t1 = timerset(3000);
  434.         done = 0;
  435.         while (!timeup(t1) && CARRIER && !done) {
  436.             SENDBYTE(SYN);
  437.  
  438.             t2 = timerset (300);
  439.             while (CARRIER && (!timeup(t2)) && !done) {
  440.                 i = TIMED_READ (0);
  441.  
  442.                 switch (i) {
  443.                     case ENQ:
  444.                         SEA_sendreq ();
  445.  
  446.                     case CAN:
  447.                         done = 1;
  448.                         break;
  449.  
  450.                     case 'C':
  451.                     case NAK:
  452.                         SENDBYTE (EOT);
  453.                         break;
  454.                 }
  455.             }
  456.         }
  457.     }
  458.  
  459.     if (!no_requests)
  460.         SEA_recvreq ();
  461.  
  462.     if (!wz) {
  463.         if (cur_event > -1 && (e_ptrs[cur_event]->behavior & MAT_DYNAM)) {
  464.             e_ptrs[cur_event]->behavior |= MAT_SKIP;
  465.             write_sched ();
  466.         }
  467.  
  468.         status_line (msgtxt[M_0001_END]);
  469.         terminating_call();
  470.         wclose ();
  471.  
  472.         t = time (NULL) - elapsed;
  473.         status_line ("*Session with %d:%d/%d.%d Time: %ld:%02ld", remote_zone, remote_net, remote_node, remote_point, t / 60L, t % 60L);
  474.  
  475.         sysinfo.today.incalls++;
  476.         sysinfo.week.incalls++;
  477.         sysinfo.month.incalls++;
  478.         sysinfo.year.incalls++;
  479.         sysinfo.today.inconnects += t;
  480.         sysinfo.week.inconnects += t;
  481.         sysinfo.month.inconnects += t;
  482.         sysinfo.year.inconnects += t;
  483.  
  484.         if (!nomailproc && got_arcmail) {
  485.             if (cur_event > -1 && e_ptrs[cur_event]->errlevel[2])
  486.                 aftermail_exit = e_ptrs[cur_event]->errlevel[2];
  487.  
  488.             if (cur_event > -1 && (e_ptrs[cur_event]->echomail & (ECHO_PROT|ECHO_KNOW|ECHO_NORMAL|ECHO_EXPORT))) {
  489.                 if (modem_busy != NULL)
  490.                     mdm_sendcmd (modem_busy);
  491.  
  492.                 t = time (NULL);
  493.  
  494.                 import_sequence ();
  495.  
  496.                 if (e_ptrs[cur_event]->echomail & ECHO_EXPORT) {
  497.                     if (config->mail_method) {
  498.                         export_mail (NETMAIL_RSN);
  499.                         export_mail (ECHOMAIL_RSN);
  500.                     }
  501.                     else
  502.                         export_mail (NETMAIL_RSN|ECHOMAIL_RSN);
  503.                 }
  504.  
  505.                 sysinfo.today.echoscan += time (NULL) - t;
  506.                 sysinfo.week.echoscan += time (NULL) - t;
  507.                 sysinfo.month.echoscan += time (NULL) - t;
  508.                 sysinfo.year.echoscan += time (NULL) - t;
  509.             }
  510.  
  511.             if (aftermail_exit) {
  512.                 status_line(msgtxt[M_EXIT_AFTER_MAIL],aftermail_exit);
  513.                 get_down (aftermail_exit, 3);
  514.             }
  515.         }
  516.  
  517.         get_down(0, 2);
  518.     }
  519.  
  520.     return 1;
  521. }
  522.  
  523. static int FTSC_sendmail ()
  524. {
  525.     FILE *fp;
  526.     char fname[80], s[80], *sptr, *password, p, *HoldName;
  527.     int c, i, j;
  528.     long t1;
  529.     struct stat buf;
  530.     struct _pkthdr2 *pkthdr;
  531.     struct date datep;
  532.     struct time timep;
  533.     long current, last_start;
  534.  
  535.     XON_DISABLE ();
  536.     HoldName = HoldAreaNameMunge (called_zone);
  537.  
  538.     sptr = s;
  539.    *ext_flags  = 'O';
  540.    for (c = 0; c < NUM_FLAGS; c++) {
  541.       if (caller && (ext_flags[c] == 'H'))
  542.          continue;
  543.  
  544.       sprintf( fname, "%s%04x%04x.%cUT", HoldName, called_net, called_node, ext_flags[c]);
  545.  
  546.       if (!stat(fname,&buf))
  547.          break;
  548.    }
  549.  
  550.    if (c == NUM_FLAGS && remote_point) {
  551.       sptr = s;
  552.       *ext_flags  = 'O';
  553.       for (c = 0; c < NUM_FLAGS; c++) {
  554.          if (caller && (ext_flags[c] == 'H'))
  555.             continue;
  556.  
  557.             sprintf( fname, "%s%04x%04x.PNT\\%08x.%cUT", HoldName, remote_net, remote_node, remote_point, ext_flags[c]);
  558.  
  559.             if (!stat(fname,&buf))
  560.                 break;
  561.         }
  562.     }
  563.  
  564.     invent_pkt_name (s);
  565.     gettime (&timep);
  566.     getdate (&datep);
  567.  
  568.     status_line(" Sending bundle to %d:%d/%d", called_zone, called_net, called_node);
  569.  
  570.     if (c == NUM_FLAGS) {
  571.         sprintf (fname, "%s%04x%04x.OUT", HoldName, called_net, called_node);
  572.         fp = fopen (fname, "wb");
  573.         if (fp == NULL)
  574.             return 1;
  575.  
  576.         pkthdr = (struct _pkthdr2 *) calloc (sizeof (struct _pkthdr2), 1);
  577.         if (pkthdr == NULL) {
  578.             status_line ("!Mem err in sending");
  579.             something_wrong=1;
  580.             fclose (fp);
  581.             return 1;
  582.         }
  583.  
  584.         memset ((char *)pkthdr, 0, sizeof (struct _pkthdr2));
  585.  
  586.         pkthdr->hour = timep.ti_hour;
  587.         pkthdr->minute = timep.ti_min;
  588.         pkthdr->second = timep.ti_sec;
  589.         pkthdr->year = datep.da_year;
  590.         pkthdr->month = datep.da_mon - 1;
  591.         pkthdr->day = datep.da_day;
  592.         pkthdr->ver = PKTVER;
  593.         pkthdr->product = 0x4E;
  594.         pkthdr->serial = 2 * 16 + 10;
  595.         pkthdr->capability = 1;
  596.         pkthdr->cwvalidation = 256;
  597.         if (config->alias[assumed].point && config->alias[assumed].fakenet) {
  598.             pkthdr->orig_node = config->alias[assumed].point;
  599.             pkthdr->orig_net = config->alias[assumed].fakenet;
  600.             pkthdr->orig_point = 0;
  601.         }
  602.         else {
  603.             pkthdr->orig_node = config->alias[assumed].node;
  604.             pkthdr->orig_net = config->alias[assumed].net;
  605.             pkthdr->orig_point = config->alias[assumed].point;
  606.         }
  607.         pkthdr->orig_zone = config->alias[assumed].zone;
  608.         pkthdr->orig_zone2 = config->alias[assumed].zone;
  609.         pkthdr->dest_point = remote_point;
  610.         pkthdr->dest_node = called_node;
  611.         pkthdr->dest_net = called_net;
  612.         pkthdr->dest_zone = called_zone;
  613.         pkthdr->dest_zone2 = called_zone;
  614.  
  615.         if (get_bbs_record (called_zone, called_net, called_node, remote_point)) {
  616.             strcpy (remote_password, nodelist.password);
  617.             if (remote_password[0]) {
  618.                 strncpy (pkthdr->password, strupr (remote_password), 8);
  619.             }
  620.         }
  621.         fwrite ((char *) pkthdr, sizeof (struct _pkthdr2), 1, fp);
  622.         free (pkthdr);
  623.         fwrite ("\0\0", 2, 1, fp);
  624.         fclose (fp);
  625.     }
  626.     else {
  627.         if (get_bbs_record (called_zone, called_net, called_node, remote_point)) {
  628.             strcpy (remote_password, nodelist.password);
  629.             fp = fopen (fname, "rb+");
  630.             if (fp == NULL)
  631.                 return 1;
  632.             pkthdr = (struct _pkthdr2 *) calloc (sizeof (struct _pkthdr2), 1);
  633.             if (pkthdr == NULL) {
  634.                 status_line ("!Mem err in sending");
  635.                 return 1;
  636.             }
  637.             fread (pkthdr, 1, sizeof (struct _pkthdr2), fp);
  638.             pkthdr->hour = timep.ti_hour;
  639.             pkthdr->minute = timep.ti_min;
  640.             pkthdr->second = timep.ti_sec;
  641.             pkthdr->year = datep.da_year;
  642.             pkthdr->month = datep.da_mon - 1;
  643.             pkthdr->day = datep.da_day;
  644.             if (remote_password[0])
  645.                 strncpy (pkthdr->password, strupr (remote_password), 8);
  646.  
  647.             fseek (fp, 0L, SEEK_SET);
  648.             fwrite (pkthdr, 1, sizeof (struct _pkthdr), fp);
  649.             fclose (fp);
  650.             free (pkthdr);
  651.         }
  652.     }
  653.  
  654.     net_problems = fsend (fname, 'B');
  655.     if ((net_problems == TSYNC) || (net_problems == 0)) {
  656.         if (c == NUM_FLAGS)
  657.             unlink (fname);
  658.             something_wrong=1;
  659.         return (net_problems);
  660.     }
  661.  
  662.     unlink (fname);
  663.  
  664.     *ext_flags  = 'F';
  665.     status_line (" Outbound file attaches");
  666.     for(c=0; c<NUM_FLAGS+1; c++) {
  667.         if (caller && (ext_flags[c] == 'H'))
  668.             continue;
  669.  
  670.         if (c < NUM_FLAGS)
  671.             sprintf( fname, "%s%04x%04x.%cLO",HoldName,called_net,called_node,ext_flags[c]);
  672.         else
  673.             sprintf( fname, "%s%04x%04x.REQ",filepath,config->alias[assumed].net, config->alias[assumed].node);
  674.  
  675.         if (!stat(fname,&buf)) {
  676.             fp = fopen( fname, "rb+" );
  677.             if (fp == NULL)
  678.                 continue;
  679.  
  680.             current  = 0L;
  681.             while(!feof(fp)) {
  682.                 s[0] = 0;
  683.                 last_start = current;
  684.                 fgets(s,79,fp);
  685.  
  686.                 sptr = s;
  687.                 password = NULL;
  688.  
  689.                 for(i=0; sptr[i]; i++)
  690.                     if (sptr[i]=='!')
  691.                         password = sptr+i+1;
  692.  
  693.                 if (password) {
  694.                     password = sptr+i+1;
  695.                     for(i=0; password[i]; i++)
  696.                         if (password[i]<=' ')
  697.                             password[i]=0;
  698.                     if (strcmp(strupr(password),strupr(remote_password))) {
  699.                         status_line("!RemotePwdErr %s %s",password,remote_password);
  700.                         continue;
  701.                     }
  702.                 }
  703.  
  704.                 for(i=0; sptr[i]; i++)
  705.                     if (sptr[i]<=' ')
  706.                         sptr[i]=0;
  707.  
  708.                 current = ftell(fp);
  709.  
  710.                 if (sptr[0] == '#') {
  711.                     sptr++;
  712.                     i = TRUNC_AFTER;
  713.                 }
  714.                 else if (sptr[0] == '^') {
  715.                     sptr++;
  716.                     i = DELETE_AFTER;
  717.                 }
  718.                 else
  719.                     i = NOTHING_AFTER;
  720.  
  721.                 if (!sptr[0])
  722.                     continue;
  723.  
  724.                 if (sptr[0] != '~') {
  725.                     if (stat(sptr,&buf))
  726.                               continue;
  727.                     else
  728.                          if (!buf.st_size)
  729.                               continue;
  730.  
  731.                     j = xfermdm7 (sptr);
  732.  
  733.                     p = 'B';
  734.                     if (j == 0) {
  735.                         net_problems = 1;
  736.                         return FALSE;
  737.                     }
  738.                     else if (j == 2)
  739.                         p = 'F';
  740.  
  741.                     if (!fsend (sptr, p)) {
  742.                         fclose(fp);
  743.                         net_problems   = 1;
  744.                         return FALSE;
  745.                     }
  746.  
  747.                     fseek( fp, last_start, SEEK_SET );
  748.                     putc('~',fp);
  749.                     fflush (fp);
  750.                     rewind(fp);
  751.                     fseek( fp, current, SEEK_SET );
  752.  
  753.                     if (i == TRUNC_AFTER) {
  754.                         i = cshopen(sptr,O_TRUNC,S_IWRITE);
  755.                         close(i);
  756.                     }
  757.                     else if (i == DELETE_AFTER)
  758.                         unlink (sptr);
  759.                 }
  760.             }
  761.  
  762.             fclose(fp);
  763.             unlink(fname);
  764.         }
  765.     }
  766.  
  767.     if (remote_point) {
  768.         *ext_flags  = 'F';
  769.         for (c = 0; c < NUM_FLAGS; c++) {
  770.             if (caller && (ext_flags[c] == 'H'))
  771.                 continue;
  772.  
  773.             sprintf (fname, "%s%04x%04x.PNT\\%08x.%cLO", HoldName, remote_net, remote_node, remote_point, ext_flags[c]);
  774.  
  775.             if (!stat(fname,&buf)) {
  776.                 fp = fopen( fname, "rb+" );
  777.                 if (fp == NULL)
  778.                     continue;
  779.  
  780.                 current  = 0L;
  781.                 while(!feof(fp)) {
  782.                     s[0] = 0;
  783.                     last_start = current;
  784.                     fgets(s,79,fp);
  785.  
  786.                     sptr = s;
  787.                     password = NULL;
  788.  
  789.                     for(i=0; sptr[i]; i++)
  790.                         if (sptr[i]=='!')
  791.                             password = sptr+i+1;
  792.  
  793.                     if (password) {
  794.                         password = sptr+i+1;
  795.                         for(i=0; password[i]; i++)
  796.                             if (password[i]<=' ')
  797.                                 password[i]=0;
  798.                         if (strcmp(strupr(password),strupr(remote_password))) {
  799.                             status_line("!RemotePwdErr %s %s",password,remote_password);
  800.                             continue;
  801.                         }
  802.                     }
  803.  
  804.                     for(i=0; sptr[i]; i++)
  805.                         if (sptr[i]<=' ')
  806.                             sptr[i]=0;
  807.  
  808.                     current = ftell(fp);
  809.  
  810.                     if (sptr[0]=='#') {
  811.                         sptr++;
  812.                         i = TRUNC_AFTER;
  813.                     }
  814.                     else if (sptr[0] == '^') {
  815.                         sptr++;
  816.                         i = DELETE_AFTER;
  817.                     }
  818.                     else
  819.                         i = NOTHING_AFTER;
  820.  
  821.                     if (!sptr[0])
  822.                         continue;
  823.  
  824.                     if (sptr[0] != '~') {
  825.                         if (stat(sptr,&buf))
  826.                             continue;
  827.                         else
  828.                             if (!buf.st_size)
  829.                                 continue;
  830.  
  831.                         j = xfermdm7 (sptr);
  832.  
  833.                         p = 'B';
  834.                         if (j == 0) {
  835.                             net_problems = 1;
  836.                             something_wrong=1;
  837.                             return FALSE;
  838.                         }
  839.                         else if (j == 2)
  840.                             p = 'F';
  841.  
  842.                         if (!fsend (sptr, p)) {
  843.                             fclose(fp);
  844.                             net_problems   = 1;
  845.                             something_wrong=1;
  846.                             return FALSE;
  847.                         }
  848.  
  849.                         fseek( fp, last_start, SEEK_SET );
  850.                         putc('~',fp);
  851.                         fflush (fp);
  852.                         rewind(fp);
  853.                         fseek( fp, current, SEEK_SET );
  854.  
  855.                         if (i == TRUNC_AFTER) {
  856.                             i = cshopen(sptr,O_TRUNC,S_IWRITE);
  857.                             close(i);
  858.                         }
  859.                         else if (i == DELETE_AFTER)
  860.                             unlink (sptr);
  861.                     }
  862.                 }
  863.  
  864.                 fclose(fp);
  865.                 unlink(fname);
  866.             }
  867.         }
  868.     }
  869.  
  870.     *sptr = 0;
  871.     status_line (" End of outbound file attaches");
  872.     t1 = timerset (100);
  873.     while (CARRIER && !timeup(t1)) {
  874.         j = TIMED_READ(0);
  875.         if ((j == 'C') || (j == NAK)) {
  876.             SENDBYTE (EOT);
  877.             t1 = timerset (100);
  878.         }
  879.     }
  880.     return TRUE;
  881. }
  882.  
  883. static int FTSC_recvmail ()
  884. {
  885.     char fname[80], fname1[80], req[120], *p;
  886.     struct _pkthdr2 pkthdr;
  887.     struct _pkthdr22 *pkthdr22;
  888.     FILE *fp;
  889.     char done, i;
  890.     int j;
  891.  
  892.     status_line (msgtxt[M_RECV_MAIL]);
  893.  
  894.     if (!CARRIER) {
  895.         status_line(msgtxt[M_HE_HUNG_UP]);
  896.         something_wrong=1;
  897.         CLEAR_INBOUND();
  898.         return (1);
  899.     }
  900.  
  901.     XON_DISABLE ();
  902.  
  903.     status_line (" Inbound bundle");
  904.     invent_pkt_name (fname1);
  905.  
  906.     CLEAR_INBOUND();
  907.     SENDBYTE ('C');
  908.     SENDBYTE (0x01);
  909.     SENDBYTE (0xfe);
  910.     if ((p = receive (filepath, fname1, 'B')) == NULL)
  911.         return (1);
  912.  
  913.     if (!remote_capabilities) {
  914.         sprintf (fname, "%s%s", filepath, p);
  915.         fp = fopen (fname, "rb");
  916.         if (fp == NULL) {
  917.             status_line (msgtxt[M_PWD_ERR_ASSUMED]);
  918.             something_wrong=1;
  919.             return (1);
  920.         }
  921.         fread (&pkthdr, 1, sizeof (struct _pkthdr2), fp);
  922.         fclose (fp);
  923.  
  924.         if (pkthdr.rate == 2) {
  925.             pkthdr22 = (struct _pkthdr22 *)&pkthdr;
  926.             remote_net = pkthdr22->orig_net;
  927.             remote_node = pkthdr22->orig_node;
  928.             remote_zone = pkthdr22->orig_zone;
  929.             remote_point = pkthdr22->orig_point;
  930.         }
  931.         else {
  932.             swab ((char *)&pkthdr.cwvalidation, (char *)&i, 2);
  933.             pkthdr.cwvalidation = i;
  934.             if (pkthdr.capability != pkthdr.cwvalidation || !(pkthdr.capability & 0x0001)) {
  935.                 remote_net = pkthdr.orig_net;
  936.                 remote_node = pkthdr.orig_node;
  937.                 remote_zone = pkthdr.orig_zone;
  938.                 remote_point = 0;
  939.                 if (!remote_zone) {
  940.                     for (i = 0; i < MAX_ALIAS && config->alias[i].net; i++) {
  941.                         if (config->alias[i].net == remote_net)
  942.                             break;
  943.                     }
  944.  
  945.                     if (i < MAX_ALIAS && config->alias[i].net) {
  946.                         remote_zone = config->alias[i].zone;
  947.                         assumed = i;
  948.                     }
  949.                     else
  950.                         remote_zone = config->alias[0].zone;
  951.                 }
  952.                 else
  953.                     for (i = 0; i < MAX_ALIAS && config->alias[i].net; i++) {
  954.                         if (config->alias[i].zone == remote_zone) {
  955.                             assumed = i;
  956.                             break;
  957.                         }
  958.                     }
  959.             }
  960.             else {
  961.                 remote_net = pkthdr.orig_net;
  962.                 remote_node = pkthdr.orig_node;
  963.                 remote_zone = pkthdr.orig_zone2;
  964.                 remote_point = pkthdr.orig_point;
  965.             }
  966.         }
  967.  
  968.         if (get_bbs_record (remote_zone, remote_net, remote_node, remote_point)) {
  969.             strcpy (remote_password, nodelist.password);
  970.             sprintf (req, "%u:%u/%u.%u, %s, %s, %s", remote_zone, remote_net, remote_node, remote_point, nodelist.sysop, nodelist.name, nodelist.city);
  971.             if (strlen (req) > 78)
  972.                 req[78] = '\0';
  973.             wcenters (0, LGREY|_BLACK, req);
  974.             wcenters (2, LGREY|_BLACK, "AKAs: No aka presented");
  975.             status_line("%s: %s (%u:%u/%u)",msgtxt[M_REMOTE_SYSTEM],nodelist.name,remote_zone,remote_net,remote_node);
  976.             if (config->know_filepath[0])
  977.                 filepath = config->know_filepath;
  978.             if (config->know_okfile[0])
  979.                 request_list = config->know_okfile;
  980.             max_requests = config->know_max_requests;
  981.             max_kbytes = config->know_max_kbytes;
  982.         }
  983.         else {
  984.             remote_password[0] = '\0';
  985.             sprintf (req, "%u:%u/%u.%u, %s", remote_zone, remote_net, remote_node, remote_point, msgtxt[M_UNKNOWN_MAILER]);
  986.             if (strlen (req) > 78)
  987.                 req[78] = '\0';
  988.             wcenters (0, LGREY|_BLACK, req);
  989.             wcenters (2, LGREY|_BLACK, "AKAs: No aka presented");
  990.             status_line("%s: %s (%u:%u/%u)",msgtxt[M_REMOTE_SYSTEM],msgtxt[M_UNKNOWN_MAILER],remote_zone,remote_net,remote_node);
  991.         }
  992.         sprintf (req, "Connected at %lu baud with %s", rate, prodcode[pkthdr.product]);
  993.         wcenters (1, LGREY|_BLACK, req);
  994.         if (remote_password[0] && stricmp (remote_password, pkthdr.password)) {
  995.             status_line ("!Password Error: expected '%s' got '%s'",remote_password, pkthdr.password);
  996.             strcpy (fname1, fname);
  997.             j = strlen (fname) - 3;
  998.             strcpy (&(fname[j]), "Bad");
  999.             if (rename (fname1, fname))
  1000.                 status_line (msgtxt[M_CANT_RENAME_MAIL], fname1);
  1001.             else
  1002.                 status_line (msgtxt[M_MAIL_PACKET_RENAMED], fname);
  1003.             return (1);
  1004.         }
  1005.         else {
  1006.             status_line (msgtxt[M_PROTECTED_SESSION]);
  1007.             if (config->prot_filepath[0])
  1008.                 filepath = config->prot_filepath;
  1009.             if (config->prot_okfile[0])
  1010.                 request_list = config->prot_okfile;
  1011.             max_requests = config->prot_max_requests;
  1012.             max_kbytes = config->prot_max_kbytes;
  1013.         }
  1014.     }
  1015.  
  1016.     called_zone = remote_zone;
  1017.     if (remote_point) {
  1018.         called_net = config->alias[assumed].fakenet;
  1019.         called_node = remote_point;
  1020.     }
  1021.     else {
  1022.         called_net = remote_net;
  1023.         called_node = remote_node;
  1024.     }
  1025.  
  1026.     done = 0;
  1027.     status_line (" Inbound file attaches");
  1028.     do {
  1029.         if ((i = try_sealink ()) == 0) {
  1030.             if (!recvmdm7 (fname))
  1031.                 done = 1;
  1032.             else {
  1033.                 if (!receive (filepath, fname, 'T'))
  1034.                     done = 1;
  1035.                 else
  1036.                     got_arcmail = 1;
  1037.             }
  1038.         }
  1039.         else {
  1040.             if (i == 1) {
  1041.                 if (!receive (filepath, NULL, 'F'))
  1042.                     done = 1;
  1043.                 else
  1044.                     got_arcmail = 1;
  1045.             }
  1046.             else
  1047.                 done = 1;
  1048.         }
  1049.     } while (!done && CARRIER);
  1050.  
  1051.     status_line (" End of inbound file attaches");
  1052.     CLEAR_INBOUND();
  1053.     return (0);
  1054. }
  1055.  
  1056. static int SEA_sendreq ()
  1057. {
  1058.     char fname[80], reqf[80];
  1059.           char *p, *name, *pw, *HoldName;
  1060.     int i, j, done, done1, nfiles;
  1061.     FILE *fp;
  1062.     long t1;
  1063.  
  1064.     t1 = timerset (1000);
  1065.           HoldName = HoldAreaNameMunge (called_zone);
  1066.  
  1067.           sprintf(fname,"%s%04x%04x.REQ",HoldName,called_net,called_node);
  1068.  
  1069.     if (!dexists(fname))
  1070.         status_line (":No outgoing file requests");
  1071.     else {
  1072.                      status_line (msgtxt[M_MAKING_FREQ]);
  1073.         if ((fp = fopen (fname, "r")) == NULL) {
  1074.             SENDBYTE(ETB);
  1075.             return (1);
  1076.         }
  1077.  
  1078.                      while ((fgets (reqf, 79, fp) != NULL) && (CARRIER)) {
  1079.             p = reqf+strlen(reqf)-1;
  1080.             while ((p>=reqf)&&(isspace(*p)))
  1081.                 *p-- = '\0';
  1082.  
  1083.             p = reqf;
  1084.             while ((*p) && (isspace (*p)))
  1085.                 p++;
  1086.             name = p;
  1087.  
  1088.             if (*name == ';')
  1089.                 continue;
  1090.  
  1091.             while ((*p) && (!isspace (*p)))
  1092.                 p++;
  1093.             if (*p) {
  1094.                 *p = '\0';
  1095.                 ++p;
  1096.                 while ((*p) && (*p != '!'))
  1097.                     p++;
  1098.                 if (*p == '!')
  1099.                     *p = ' ';
  1100.                 pw = p;
  1101.             }
  1102.             else
  1103.                 pw = p;
  1104.  
  1105.             if (req_out (name, pw))
  1106.                 continue;
  1107.  
  1108.             t1 = timerset (1000);
  1109.             done = 0;
  1110.                                 while ((!timeup (t1)) && CARRIER && !done) {
  1111.                 j = TIMED_READ(0);
  1112.                 if (j >= 0) {
  1113.                     if (j == ACK) {
  1114.                         nfiles = 0;
  1115.                         done1 = 0;
  1116.                         do {
  1117.                             if ((i = try_sealink ()) == 0) {
  1118.                                 if (!recvmdm7 (reqf))
  1119.                                     done1 = 1;
  1120.                                 else {
  1121.                                                                                                 if (!receive (filepath, reqf, 'T'))
  1122.                                         done1 = 1;
  1123.                                     else
  1124.                                         ++nfiles;
  1125.                                 }
  1126.                             }
  1127.                             else
  1128.                                  if (i == 1) {
  1129.                                                                                      if (!receive (filepath, NULL, 'F'))
  1130.                                     done1 = 1;
  1131.                                 else
  1132.                                     ++nfiles;
  1133.                             }
  1134.                             else
  1135.                                  done1 = 1;
  1136.  
  1137.                         }
  1138.                                                                 while (CARRIER && !done1);
  1139.  
  1140.                         status_line (":Received %d files", nfiles);
  1141.                         done = 1;
  1142.                         t1 = timerset (1000);
  1143.  
  1144.                                                                 while ((TIMED_READ(0) != ENQ) && (!timeup (t1)) && CARRIER);
  1145.                     }
  1146.                     else
  1147.                         if (j == ENQ)
  1148.                             req_out (name, pw);
  1149.                 }
  1150.             }
  1151.         }
  1152.         fclose (fp);
  1153.         unlink (fname);
  1154.         status_line (":End of outbound file requests");
  1155.     }
  1156.  
  1157.     SENDBYTE(ETB);
  1158.     return(0);
  1159. }
  1160.  
  1161. static int SEA_recvreq ()
  1162. {
  1163.     int done, i, j, recno, retval, nfiles, nfiles1, w_event;
  1164.           char p, reqs[64], req[64];
  1165.     long t1;
  1166.  
  1167.     w_event = -1;
  1168.     t1 = timerset (2000);
  1169.  
  1170.     if (no_requests) {
  1171.         SENDBYTE(CAN);
  1172.                      status_line (msgtxt[M_REFUSING_IN_FREQ]);
  1173.         return TRUE;
  1174.     }
  1175.  
  1176.     done = 0;
  1177.     nfiles = 0;
  1178.     status_line (":Inbound file requests");
  1179.           while (CARRIER && !done && (!timeup (t1))) {
  1180.         SENDBYTE(ENQ);
  1181.  
  1182.         j = TIMED_READ(2);
  1183.  
  1184.         switch (j) {
  1185.         case ACK:
  1186.             recno = -1;
  1187.             nfiles1 = 0;
  1188.             if ((retval = get_req_str (reqs, req, &recno)) > 0) {
  1189.                                           if ((w_event == 32000)) { /* || (nfiles > n_requests)) {*/
  1190.                     status_line ("!File Request denied");
  1191.                     SENDBYTE (ACK);
  1192.                     fsend (NULL, 'S');
  1193.                     recno = -1;
  1194.                 }
  1195.                 else {
  1196.                     SENDBYTE(ACK);
  1197.                     do {
  1198.                         if (reqs[0])
  1199.                             i = xfermdm7 (reqs);
  1200.                         else
  1201.                             i = 2;
  1202.  
  1203.                         p = 'T';
  1204.                         if (i == 0) {
  1205.                             something_wrong=1;
  1206.                             net_problems = 1;
  1207.                             continue;
  1208.                         }
  1209.                         else
  1210.                              if (i == 2)
  1211.                             p = 'F';
  1212.  
  1213.                         if (retval == 1) {
  1214.                                      fsend (reqs, p);
  1215.                             ++nfiles;
  1216.                             ++nfiles1;
  1217.                         }
  1218.                                                                 if (nfiles > max_requests && max_requests) {
  1219.                                                                           status_line (msgtxt[M_FREQ_LIMIT]);
  1220.                             recno = -1;
  1221.                         }
  1222.                         else
  1223.                              if (gen_req_name (reqs, req, &recno) == 2)
  1224.                             recno = -1;
  1225.                     }
  1226.                                                      while (CARRIER && (recno >= 0));
  1227.                 }
  1228.  
  1229.                 if (retval != 1)
  1230.                           fsend (NULL, 'S');
  1231.                 status_line (":%d matching files sent", nfiles1);
  1232.             }
  1233.             t1 = timerset (2000);
  1234.             break;
  1235.  
  1236.         case ETB:
  1237.         case ENQ:
  1238.             done = 1;
  1239.             break;
  1240.  
  1241.         case 'C':
  1242.         case NAK:
  1243.             SENDBYTE(EOT);
  1244.             CLEAR_INBOUND();
  1245.             break;
  1246.         }
  1247.     }
  1248.     status_line (":End of inbound file requests");
  1249.     return TRUE;
  1250. }
  1251.  
  1252. static int try_sealink ()
  1253. {
  1254.     int i, j;
  1255.     long t1;
  1256.  
  1257.     for (i = 0; i < 5; i++) {
  1258.         SENDBYTE ('C');
  1259.  
  1260.         t1 = timerset (100);
  1261.                      while (!timeup (t1) && CARRIER) {
  1262.             if ((j = PEEKBYTE()) >= 0) {
  1263.                 if (j == SOH)
  1264.                     return (1);
  1265.                 j = TIMED_READ(0);
  1266.                 if (j == EOT)
  1267.                     return (2);
  1268.                 else
  1269.                      if (j == TSYNC)
  1270.                     return (0);
  1271.             }
  1272.         }
  1273.  
  1274.                      if (!CARRIER)
  1275.             break;
  1276.     }
  1277.  
  1278.     return (0);
  1279. }
  1280.  
  1281. static int req_out (name, pw)
  1282. char *name, *pw;
  1283. {
  1284.           char *p;
  1285.     unsigned int crc;
  1286.  
  1287.     p = name;
  1288.     if (!*p)
  1289.         return (1);
  1290.  
  1291.     status_line ("*Requesting '%s' %s%s", name, (*pw)?"with password":"", pw);
  1292.     SENDBYTE(ACK);
  1293.     crc = 0;
  1294.     while (*p) {
  1295.         SENDBYTE(*p);
  1296.         crc = xcrc(crc,(byte )(*p));
  1297.         ++p;
  1298.     }
  1299.  
  1300.     SENDBYTE(' ');
  1301.     crc = xcrc(crc,(byte )(' '));
  1302.     SENDBYTE('0');
  1303.     crc = xcrc(crc,(byte )('0'));
  1304.     p = pw;
  1305.     while (*p) {
  1306.         SENDBYTE(*p);
  1307.         crc = xcrc(crc,(byte )(*p));
  1308.         ++p;
  1309.     }
  1310.  
  1311.     SENDBYTE(ETX);
  1312.     SENDBYTE( crc&0xff );
  1313.     SENDBYTE( crc>>8   );
  1314.     return (0);
  1315. }
  1316.  
  1317. static int get_req_str (reqs, req, recno)
  1318. char *reqs, *req;
  1319. int *recno;
  1320. {
  1321.     unsigned int crc, crc1, crc2, crc3;
  1322.     int i,j;
  1323.  
  1324.     crc = i = 0;
  1325.           while (CARRIER) {
  1326.         j = TIMED_READ(2);
  1327.         if (j < 0)
  1328.             return (0);
  1329.  
  1330.         if (j == ETX) {
  1331.             crc1 = TIMED_READ(2);
  1332.             crc2 = TIMED_READ(2);
  1333.             crc3 = (crc2<<8)+crc1;
  1334.             if (crc3 != crc) {
  1335.                 status_line("!Bad crc - trying again");
  1336.                 return (0);
  1337.             }
  1338.             req[i] = '\0';
  1339.             return (gen_req_name (reqs, req, recno));
  1340.         }
  1341.         else {
  1342.             req[i++] = j&0xff;
  1343.             crc = xcrc (crc,j&0xff);
  1344.         }
  1345.     }
  1346.     return (0);
  1347. }
  1348.  
  1349. static int gen_req_name(reqs,req,recno)
  1350. char *reqs, *req;
  1351. int *recno;
  1352. {
  1353.     char *q, *q1;
  1354.     struct stat  st;
  1355.     char buf[32];
  1356.           char *rqname;
  1357.     long fsecs;
  1358.     int save_rec;
  1359.  
  1360.     save_rec = *recno;
  1361.     q = req;
  1362.     q1 = buf;
  1363.     while((*q) && (!isspace(*q)))
  1364.         *q1++ = *q++;
  1365.  
  1366.     if(*q) {
  1367.         ++q;
  1368.  
  1369.         fsecs = atol(q);
  1370.  
  1371.         while((*q) && isdigit (*q))
  1372.             ++q;
  1373.  
  1374.         if(*q) {
  1375.             ++q;
  1376.  
  1377.             *q1++ = ' ';
  1378.             *q1++ = '!';
  1379.             while(*q)
  1380.                 *q1++ = *q++;
  1381.             *q1++ = '\0';
  1382.         }
  1383.     }
  1384.  
  1385.     for(;;) {
  1386.                 if ((rqname = n_frproc (buf, recno, (fsecs == 0) ? 0 : 1)) != NULL) {
  1387.             if(!stat(rqname,&st)) {
  1388.                 if(st.st_atime - timezone <= fsecs)
  1389.                     continue;
  1390.             }
  1391.             strcpy(reqs,rqname);
  1392.             return(1);
  1393.         }
  1394.         else {
  1395.             q = buf;
  1396.             while((*q) && !isspace (*q))
  1397.                 ++q;
  1398.             *q = '\0';
  1399.             if(save_rec == -1)
  1400.                 status_line("!No files matched '%s'",buf);
  1401.             reqs[0] = '\0';
  1402.             return(2);
  1403.         }
  1404.     }
  1405. }
  1406.  
  1407. int xfermdm7(fn)
  1408. char *fn;
  1409. {
  1410.     unsigned char checksum;
  1411.    int i, j;
  1412.    unsigned char mdm7_head[13];
  1413.    char num_tries = 0;
  1414.    char *fname;
  1415.    struct ffblk dta;
  1416.  
  1417.    XON_DISABLE();
  1418.    _BRK_DISABLE();
  1419.  
  1420.    findfirst (fn, &dta, 0);
  1421.    fname = dta.ff_name;
  1422.  
  1423.    memset (mdm7_head, ' ', 12);
  1424.    for (i = j = 0; ((fname[i]) && (i < 12) && (j < 12));i ++) {
  1425.       if (fname[i] == '.')
  1426.          j = 8;
  1427.       else
  1428.          mdm7_head[j++] = (char )toupper (fname[i]);
  1429.    }
  1430.  
  1431.    checksum = SUB;
  1432.    for (i = 0; i < 11; i++)
  1433.       checksum += mdm7_head[i];
  1434.  
  1435. top:
  1436.    if (!CARRIER)
  1437.       return 0;
  1438.    else {
  1439.       if (num_tries++ > 10) {
  1440.          send_can ();
  1441.          return (0);
  1442.       }
  1443.       else
  1444.          if (num_tries)
  1445.                 SENDBYTE ('u');
  1446.    }
  1447.  
  1448.    for (i = 0; i < 15; i++) {
  1449.       if (!CARRIER)
  1450.          return (0);
  1451.  
  1452.       j = TIMED_READ (10);
  1453.  
  1454.       switch (j) {
  1455.          case 'C' :
  1456.             SENDBYTE (SOH);
  1457.             return 2;
  1458.          case NAK :
  1459.             i=16;
  1460.             break;
  1461.          case CAN :
  1462.             return (0);
  1463.       }
  1464.    }
  1465.  
  1466.    SENDBYTE (ACK);
  1467.  
  1468.    for (i = 0; i < 11; i++) {
  1469.       SENDBYTE(mdm7_head[i]);
  1470.  
  1471.       switch (j = TIMED_READ(10)) {
  1472.          case ACK :
  1473.             break;
  1474.          case CAN :
  1475.             SENDBYTE (ACK);
  1476.             return (0);
  1477.          default  :
  1478.             goto top;
  1479.       }
  1480.     }
  1481.  
  1482. try_sub:
  1483.    SENDBYTE (SUB);
  1484.    if ((i = TIMED_READ (10)) != checksum)
  1485.       goto top;
  1486.  
  1487.    SENDBYTE (ACK);
  1488.    return (1);
  1489. }
  1490.  
  1491. static int recvmdm7(fname)
  1492. char *fname;
  1493. {
  1494.     register int i, j;
  1495.     int got_dot, retbyte, tries, got_eot;
  1496.     char tempname[30];
  1497.     unsigned char xchksum;
  1498.  
  1499.         _BRK_DISABLE();
  1500.     XON_DISABLE();
  1501.  
  1502.     tries = got_eot = 0;
  1503.  
  1504.     if(PEEKBYTE() == -1)
  1505.         SENDBYTE(NAK);
  1506.  
  1507.  
  1508. top:
  1509.     i = got_dot = 0;
  1510.     tries++;
  1511.  
  1512.     memset(tempname,0,30);
  1513.     memset(fname,0,30);
  1514.  
  1515.         while((CARRIER) && (tries<8)) {
  1516.         switch(retbyte = TIMED_READ(3)) {
  1517.         case SUB :
  1518.             if(!i) {
  1519.                 if(tries<4)
  1520.                     goto top;
  1521.                 else
  1522.                     return(0);
  1523.             }
  1524.  
  1525.             for(xchksum=SUB,i=0;tempname[i];i++)
  1526.                 xchksum += tempname[i];
  1527.             CLEAR_INBOUND();
  1528.             SENDBYTE(xchksum);
  1529.             retbyte = TIMED_READ(5);
  1530.             if(retbyte==ACK) {
  1531.                 for(i=j=got_dot=0;((tempname[i]) && (i<30));i++) {
  1532.                     if(tempname[i]=='.')
  1533.                         got_dot=1;
  1534.                     else
  1535.                         if ((i==8)&&(!got_dot))
  1536.                         fname[j++] = '.';
  1537.                     fname[j++] = tempname[i];
  1538.                 }
  1539.                 return(1);
  1540.             }
  1541.  
  1542.             got_eot = 0;
  1543.             SENDBYTE(NAK);
  1544.             goto top;
  1545.  
  1546.         case 'u' :
  1547.         case ACK :
  1548.             goto top;
  1549.  
  1550.         case EOT :
  1551.             SENDBYTE(ACK);
  1552.             if (got_eot>2)
  1553.                 return(0);
  1554.  
  1555.             got_eot++;
  1556.             goto top;
  1557.  
  1558.         case CAN :
  1559.             goto fubar;
  1560.  
  1561.         default  :
  1562.             if(retbyte<' ') {
  1563.                 if(got_eot>2)
  1564.                     return(0);
  1565.                 else
  1566.                     got_eot++;
  1567.  
  1568.                 CLEAR_INBOUND();
  1569.  
  1570.                 SENDBYTE(NAK);
  1571.                 goto top;
  1572.             }
  1573.             if(i >= 30)
  1574.                 goto fubar;
  1575.             if((retbyte>=' ') && (retbyte<='~'))
  1576.                 tempname[i++]= (char )retbyte;
  1577.             SENDBYTE(ACK);
  1578.             break;
  1579.         }
  1580.     }
  1581.  
  1582. fubar:
  1583.     return(0);
  1584. }
  1585.  
  1586.  
  1587.