home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / beehive / bbs / rosuncr.arc / ROSSND.INC < prev    next >
Text File  |  1991-08-11  |  15KB  |  451 lines

  1. { ROSSND.INC - Remote Operating System File Send Routines }
  2.  
  3. { 14dec87 wb - chain to ROSUNCR.CHN for uncrunching files
  4.  
  5.   13nov86 wb - 1k packet vers.
  6. }
  7.  
  8. overlay procedure SendXmodem;
  9. { Send a file using Xmodem protocol }
  10.   const
  11.     STX = #$02;
  12.  
  13.   var
  14.     OK: boolean;
  15.     this: FilePtr;
  16.     XfrName: FileName;
  17.     XfrFile: untype_file;
  18.     Buffer: array[1..1024] of byte;
  19.     TPL: char;
  20.     KPacket: boolean;
  21.     packet_size: integer;
  22.  
  23.    procedure SendFile(var XfrFile: untype_file; remaining: integer);
  24.     const
  25.       maxerr = 10;
  26.     var
  27.       CRCmode, timeout: boolean;
  28.       bt: byte;
  29.       ch: char;
  30.       mm, ss, time_on, time_left, i, vv, block, block2, errcnt: integer;
  31.  
  32.     begin
  33.       timer(time_on, time_left);
  34.       send_time(remaining, mm, ss);
  35.       if mm > time_left
  36.         then
  37.           begin
  38.             writeln(USR, 'Insufficient time remaining for transfer.');
  39.             OK := FALSE
  40.           end
  41.         else
  42.           begin
  43.             errcnt := 0;
  44.             block := 1;
  45.             writeln(USR, XfrName, ' contains ', remaining, ' blocks.');
  46.             writeln(USR, 'Send time: ', mm, ' minutes ',ss, ' seconds at ', rate, ' bps.');
  47.             writeln(USR, 'To cancel, type CTL-X.');
  48.             writeln(USR, 'Ready to send...');
  49.  
  50.             block2 := remaining;
  51.  
  52.             if KPacket then
  53.             begin
  54.               TPL := STX;
  55.               packet_size := 1024;
  56.             end
  57.             else
  58.             begin
  59.               TPL := SOH;
  60.               packet_size := 128;
  61.             end;
  62.  
  63.  
  64.             repeat
  65.               bt := GetByte(10, timeout);
  66.               CRCmode := (bt = ord('C'));
  67.               if CRCmode
  68.                 then
  69.                   begin
  70.                     writeln('CRC mode requested.');
  71.                     errcnt := 0
  72.                   end
  73.               else if bt = ord(NAK)
  74.                 then
  75.                   begin
  76.                     writeln('Checksum mode requested.');
  77.                     errcnt := 0
  78.                   end
  79.               else if bt = ord(CAN)
  80.                 then errcnt := maxerr
  81.                 else errcnt := succ(errcnt)
  82.             until (errcnt = 0) or (errcnt >= maxerr);
  83.             while (remaining > 0) and (errcnt < maxerr) do
  84.               begin
  85.                 if remaining < 8 then
  86.                 begin
  87.                   KPacket := False;
  88.                   TPL := SOH;
  89.                   Packet_Size := 128;
  90.                 end;
  91.                 if KPacket then
  92.                   blockread(XfrFile, Buffer, 8)
  93.                 else
  94.                   blockread(XfrFile, Buffer, BufBlocks);
  95.                 if KPacket then
  96.                   remaining := remaining - 8
  97.                 else
  98.                   remaining := pred(remaining);
  99.                 repeat
  100.                   vv := 0;
  101.                   if CRCmode
  102.                     then
  103.                       begin
  104.                         for i := 1 to packet_size do
  105.                           updcrc(vv, Buffer[i]);
  106.                         updcrc(vv, 0);
  107.                         updcrc(vv, 0)
  108.                       end
  109.                     else for i := 1 to packet_size do
  110.                            vv := vv + Buffer[i];
  111.                   writeln('vv= ',vv);
  112.                   PutByte(ord(TPL));
  113.                   PutByte(lo(block));
  114.                   PutByte(not lo(block));
  115.                   for i := 1 to packet_size do
  116.                     PutByte(Buffer[i]);
  117.                   if CRCmode
  118.                     then PutByte(hi(vv));
  119.                   PutByte(lo(vv));
  120.                   repeat
  121.                     bt := GetByte(12, timeout);
  122.                     if bt = ord(ACK)
  123.                       then
  124.                         begin
  125.                           write(CR, 'Block sent: ');  { Local display of what is happening }
  126.                           if KPacket then
  127.                             write(block * 8 - 7,'-',block * 8)
  128.                           else
  129.                             write(block2 - remaining);
  130.                           ClrEol;
  131.                           block := succ(block);
  132.                           errcnt := 0
  133.                         end
  134.                     else if (bt = ord(NAK)) or timeout
  135.                       then
  136.                         begin
  137.                           if bt = ord(NAK)
  138.                             then write('  ++ NAK received')
  139.                           else if timeout
  140.                             then write('  ++ Timeout');
  141.                           errcnt := succ(errcnt);
  142.                           writeln(' - error ', errcnt, ' ++')
  143.                         end
  144.                     else if bt = ord(CAN)
  145.                       then errcnt := maxerr;
  146.                     ch := GetChar           { Monitor local console }
  147.                   until (bt in [ord(ACK), ord(NAK), ord(CAN)]) or timeout
  148.                 until (errcnt = 0) or (errcnt >= maxerr)
  149.               end;
  150.             writeln;
  151.             OK := (errcnt = 0);
  152.             if OK
  153.               then
  154.                 begin
  155.                   repeat
  156.                     PutByte(ord(EOT));
  157.                     if ord(ACK) = GetByte(10, timeout)
  158.                       then errcnt := 0
  159.                       else errcnt := succ(errcnt)
  160.                   until (errcnt = 0) or (errcnt >= maxerr);
  161.                   bt := GetByte(2, timeout);
  162.                   OK := (errcnt = 0);
  163.                   if OK
  164.                     then writeln(USR, 'Transfer complete.')
  165.                     else writeln(USR, 'End of file not acknowledged.')
  166.                 end
  167.               else writeln(USR, 'Transfer cancelled.')
  168.           end;
  169.     end;
  170.  
  171.   begin { SendXmodem }
  172.     XfrName := correct_fn(prompt('File name', 12, 'ES'));
  173.     KPacket := ask('1k Packets');
  174.     if XfrName <> ''
  175.       then
  176.         begin
  177.           if in_library
  178.             then this := LibBase
  179.             else this := DirBase;
  180.           while (this <> nil) and (XfrName <> compress_fn(this^.fname)) do
  181.             this := this^.next;
  182.           if this <> nil
  183.             then
  184.               begin
  185.                 log(5, XfrName);
  186.                 SetSect(SetDrv, SetUsr);
  187.                 if in_library
  188.                   then
  189.                     begin
  190.                       seek(libr_file, this^.index);
  191.                       SendFile(libr_file, this^.fsize)
  192.                     end
  193.                   else
  194.                     begin
  195.                       Assign(XfrFile, XfrName);
  196.                       Reset(XfrFile);
  197.                       SendFile(XfrFile, FileSize(XfrFile));
  198.                       Close(XfrFile)
  199.                     end;
  200.                 SetSect(HomDrv, HomUsr);
  201.                 if OK
  202.                   then
  203.                     begin
  204.                       log(7, '');
  205.                       user_rec.download := succ(user_rec.download)
  206.                     end
  207.                   else log(8, '')
  208.               end
  209.             else writeln(USR, XfrName, ' not found.')
  210.         end
  211.   end;
  212.  
  213. overlay procedure SendText;
  214.   var
  215.     this: FilePtr;
  216.  
  217. { Made these variables global to pass file to ROSUNCR.CHN
  218.     XfrName: FileName;
  219.     XfrFile: untype_file;
  220. }
  221.  
  222.   procedure SendFile(var XfrFile: untype_file; remaining: integer);
  223.   { Send a squeezed, crunched or ASCII file }
  224.     const
  225.       recognize = $FF76;
  226.       DLE       = $90;
  227.     var
  228.       EndOfFile, squeezed, crunched : boolean;
  229.       i, x, BufferPtr, bpos, curin, repct, lastc, NoOfRecs, line_count: integer;
  230.       FileType: String[3];
  231.       ErrMsg: StrPr;
  232.       dnode: array [0..255, 0..1] of integer;
  233.  
  234.     function getc: integer;
  235.     { Get an 8 bit value from the input buffer - read block if necessary }
  236.       begin
  237.         if BufferPtr > BufSize
  238.           then
  239.             begin
  240.               NoOfRecs := min(BufBlocks, remaining);
  241.               EndOfFile := (NoOfRecs = 0);
  242.               if not EndOfFile
  243.                 then
  244.                   begin
  245.                     {$I-} BlockRead(XfrFile, Buffer, NoOfRecs) {$I+};
  246.                     EndOfFile := (IOresult <> 0)
  247.                   end;
  248.               remaining := remaining - NoOfRecs;
  249.               BufferPtr := 1
  250.             end;
  251.         getc := Buffer[BufferPtr];
  252.         BufferPtr := succ(BufferPtr)
  253.       end;
  254.  
  255.     function getw: integer;
  256.     { Get a 16 bit value from the input buffer }
  257.       begin
  258.         getw := getc + Swap(getc)
  259.       end;
  260.  
  261.     procedure BuildTree;
  262.     { Build decode tree }
  263.       var
  264.         i, CheckSum, numnodes: integer;
  265.       begin
  266.         ErrMsg := '';
  267.         if recognize = getw                 { Is it really a squeezed file? }
  268.           then
  269.             begin
  270.               CheckSum := getw;             { Get checksum }
  271.               XfrName := '';
  272.               i := getc;                    { Build original file name }
  273.               while i <> 0 do
  274.                 begin
  275.                   XfrName := XfrName + UpCase(chr(i));
  276.                   i := getc
  277.                 end;
  278.               numnodes := getw;             { Get the number of nodes in tree }
  279.               if (0 < numnodes) and (numnodes <= 256)
  280.                 then for i := 0 to pred(numnodes) do
  281.                   begin
  282.                     dnode[i, 0] := getw;
  283.                     dnode[i, 1] := getw;
  284.                   end
  285.                 else
  286.                   begin
  287.                     ErrMsg := 'Invalid decode tree size.';
  288.                     squeezed := FALSE
  289.                   end
  290.             end
  291.           else squeezed := FALSE
  292.       end;
  293.  
  294.     function gethuff: integer;
  295.     { Get character coding }
  296.       var
  297.         i: integer;
  298.       begin
  299.         i := 0;
  300.         repeat
  301.           bpos := succ(bpos);
  302.           if bpos > 7
  303.             then
  304.               begin
  305.                 curin := getc;
  306.                 bpos := 0
  307.               end
  308.             else curin := curin shr 1;
  309.           i := dnode[i, curin and $0001]
  310.         until i < 0;
  311.         i := -succ(i);
  312.         if i = 0
  313.           then gethuff := 26
  314.           else gethuff := i
  315.       end;
  316.  
  317.     function getcr: integer;
  318.       var
  319.         c: integer;
  320.       begin
  321.         if repct > 0
  322.           then
  323.             begin
  324.               repct := pred(repct);
  325.               getcr := lastc
  326.             end
  327.           else
  328.             begin
  329.               c := gethuff;
  330.               if c = DLE
  331.                 then
  332.                   begin
  333.                     repct := gethuff;
  334.                     if repct = 0
  335.                       then getcr := DLE
  336.                       else
  337.                         begin
  338.                           repct := repct - 2;
  339.                           getcr := lastc
  340.                         end
  341.                   end
  342.                 else
  343.                   begin
  344.                     getcr := c;
  345.                     lastc := c
  346.                   end
  347.             end
  348.       end;
  349.  
  350.     begin { SendFile }
  351.       i := pos('.', XfrName);
  352.       if i = 0
  353.         then FileType := ''
  354.         else FileType := copy(XfrName, succ(i), length(XfrName));
  355.       squeezed := ('Q' = FileType[2]);
  356.       crunched := ('Z' = FileType[2]);
  357.       repct := 0;
  358.       bpos := 8;
  359.       ErrMsg := '';
  360.       BufferPtr := MaxInt;                  { Force a read the first time }
  361.       EndOfFile := FALSE;
  362.       if remaining > 0
  363.         then
  364.           begin
  365.             if squeezed
  366.               then BuildTree;
  367.             i := pos('.', XfrName);
  368.             if 0 = i
  369.               then FileType := ''
  370.               else FileType := copy(XfrName, succ(i), length(XfrName));
  371.             if (FileType = 'COM') or (FileType = 'OBJ') or
  372.                (FileType = 'EXE') or (FileType = 'LBR')
  373.               then ErrMsg := 'Xmodem protocol required for ".' + FileType + '" files.';
  374.             if ErrMsg = ''
  375.               then
  376.                 begin
  377.                   line_count := 0;
  378.                   if crunched then
  379.                     begin
  380.                       { Save heap pointers & 1st 128 bytes of heap }
  381.                       heap_ptr:=HeapPtr;
  382.                       heap_fre:=HeapFre;
  383.                       setsect(HomDrv,HomUsr);
  384.                       assign(chain_file,'ROSUNCR.CHN');
  385.                       chain(chain_file);
  386.                     end;
  387.                   if squeezed
  388.                     then
  389.                       begin
  390.                         writeln(USR, '      ---> ', XfrName);
  391.                         x := getcr
  392.                       end
  393.                     else x := getc;
  394.                   while (not brk) and (not EndOfFile) and (x <> 26) do
  395.                     begin
  396.                       write(USR, chr(x));
  397.                       if (user_rec.lines <> 99) and (chr(x) = LF)
  398.                         then
  399.                           begin
  400.                             line_count := succ(line_count);
  401.                             if line_count mod user_rec.lines = 0
  402.                               then pause
  403.                           end;
  404.                       if squeezed
  405.                         then x := getcr
  406.                         else x := getc
  407.                     end
  408.                 end
  409.           end
  410.         else ErrMsg := 'Missing or empty input file.';
  411.       if ErrMsg <> ''
  412.         then writeln(USR, ErrMsg)
  413.     end;
  414.  
  415.   begin { SendText }
  416.     XfrName := correct_fn(prompt('File name', 12, 'ES'));
  417.     if XfrName <> ''
  418.       then
  419.         begin
  420.           if in_library
  421.             then this := LibBase
  422.             else this := DirBase;
  423.           while (this <> nil) and (XfrName <> compress_fn(this^.fname)) do
  424.             this := this^.next;
  425.           if this <> nil
  426.             then
  427.               begin
  428.                 log(6, XfrName);
  429.                 SetSect(SetDrv, SetUsr);
  430.                 if in_library
  431.                   then
  432.                     begin
  433.                       {$I-} seek(libr_file, this^.index) {$I+};
  434.                       if IOresult = 0
  435.                         then SendFile(libr_file, this^.fsize)
  436.                     end
  437.                   else
  438.                     begin
  439.                       Assign(XfrFile, XfrName);
  440.                       Reset(XfrFile);
  441.                       SendFile(XfrFile, FileSize(XfrFile));
  442.                       Close(XfrFile)
  443.                     end;
  444.                 SetSect(HomDrv, HomUsr);
  445.                 log(7, '')
  446.               end
  447.             else writeln(USR, XfrName, ' not found.')
  448.         end
  449.   end;
  450.  
  451.