home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 189.img / TCS120S.ZIP / PROTOCOL.PAS < prev    next >
Pascal/Delphi Source File  |  1989-04-06  |  54KB  |  1,888 lines

  1. {$R-,S-,I-,D-,F+,V-,B-,N-,L+ }
  2. {$M 65500,0,0 }
  3.  
  4. unit protocol;
  5.  
  6. interface
  7.  
  8. uses dos,crt,
  9.      configrt,gentypes,modem,statret,windows,gensubs,subs1,subs2,mainr2,
  10.      userret;
  11.  
  12. var totaltime:sstr;
  13.     b:string;
  14.     totalxferpoints,mins:integer;
  15.     totalxfersize:longint;
  16.  
  17. function protocolxfer (send,crcmode,ymodem:boolean; fn:lstr):integer;
  18. procedure runext (var ret_code:integer; var commandline,switchz:lstr);
  19. function doext (mode,proto:char; uddir,fn:lstr; baud,comm:integer):integer;
  20. procedure beepbeep (ok:integer);
  21. function checkdszlog (fnxfered:anystr):char;
  22. function sponsoron:boolean;
  23. procedure seekudfile (n:integer);
  24. procedure requestfile;
  25. function getfname (path:lstr; name:mstr):lstr;
  26. procedure possiblelzm (points:integer);
  27. function checkok (ud:udrec):boolean;
  28. function searchforfile (f:sstr):integer;
  29. procedure listfile (n:integer; extended:boolean);
  30. procedure listfiles (extended:boolean);
  31. function allowxfer:boolean;
  32. function numuds:integer;
  33. function nofiles:boolean;
  34. function getfilenum (t:mstr):integer;
  35. procedure addtobatch (auto:integer);
  36. procedure downbatch;
  37. procedure upbatch;
  38. procedure listbatch;
  39. procedure clearbatch;
  40. procedure batchmenu;
  41.  
  42. implementation
  43.  
  44. function protocolxfer (send,crcmode,ymodem:boolean; fn:lstr):integer;
  45. { Return codes:  0=OK, 1=Cancelled within last three blocks, 2=Aborted }
  46.  
  47. {% ENDIF}
  48.  
  49.   const can=^X; ack=^F; nak=^U; soh=^A; stx=^B; eot=^D; crcstart='C';
  50.  
  51.   var timedout:boolean;
  52.  
  53.   function tenthseconds:integer;
  54.   var r:registers;
  55.   begin
  56.     r.ah:=$2c;
  57.     intr ($21,r);
  58.     tenthseconds:=(r.dh*10)+(r.dl div 10)
  59.   end;
  60.  
  61.   function fromnow (tenths:integer):integer;
  62.   begin
  63.     tenths:=tenthseconds+tenths;
  64.     if tenths>599 then tenths:=tenths-600;
  65.     fromnow:=tenths
  66.   end;
  67.  
  68.   function timeout (en:integer):boolean;
  69.   begin
  70.     timeout:=(en=tenthseconds) or hungupon
  71.   end;
  72.  
  73.   procedure clearmodemahead;
  74.   var k:char;
  75.   begin
  76.     while numchars>0 do k:=getchar
  77.   end;
  78.  
  79.   procedure wait (tenths:integer);
  80.   begin
  81.     tenths:=fromnow (tenths);
  82.     repeat until timeout (tenths) or hungupon
  83.   end;
  84.  
  85.   function waitchar (tenths:integer):char;
  86.   begin
  87.     waitchar:=#0;
  88.     tenths:=fromnow (tenths);
  89.     repeat
  90.       if numchars>0 then begin
  91.         waitchar:=getchar;
  92.         timedout:=false;
  93.         exit
  94.       end
  95.     until timeout (tenths) or hungupon;
  96.     timedout:=true
  97.   end;
  98.  
  99.   procedure computecrc (var block; blocksize:integer; var outcrc:word);
  100.   var cnt,c2:integer;
  101.       crc,b:word;
  102.       blk:array[1..1030] of byte absolute block;
  103.       willbecarry:boolean;
  104.   begin
  105.     crc:=0;
  106.     for cnt:=1 to blocksize do begin
  107.       b:=blk[cnt];
  108.       for c2:=1 to 8 do begin
  109.         willbecarry:=(crc and $8000)=$8000;
  110.         crc:=(crc shl 1) or (b shr 7);
  111.         b:=(b shl 1) and 255;
  112.         if willbecarry then crc:=crc xor $1021
  113.       end
  114.     end;
  115.     outcrc:=crc
  116.   end;
  117.  
  118. (****
  119.     inline (
  120.              $1E/                    {           PUSH  DS               }
  121.              $C5/$B6/block/          {           LDS   SI,[BP+block]    }
  122.              $8B/$96/blocksize/      {           MOV   DX,[BP+blocksize]}
  123.              $31/$DB/                {           XOR   BX,BX            }
  124.              $FC/                    {           CLD                    }
  125.              $AC/                    { Mainloop: LODSB                  }
  126.              $B9/$08/$00/            {           MOV   CX,0008          }
  127.              $D0/$E0/                { Byteloop: SHL   AL,1             }
  128.              $D1/$D3/                {           RCL   BX,1             }
  129.              $73/$04/                {           JNC   No_xor           }
  130.              $81/$F3/$21/$10/        {           XOR   BX,1021          }
  131.              $E2/$F4/                { No_xor:   LOOP  Byteloop         }
  132.              $4A/                    {           DEC   DX               }
  133.              $75/$ED/                {           JNZ   Mainloop         }
  134.              $89/$9E/crc/            {           MOV   [BP+crc],BX      }
  135.              $1F                     {           POP   DS               }
  136.            );
  137. ****)
  138.  
  139.   procedure computecksum (var data; blocksize:integer; var outcksum:byte);
  140.   var t:array [1..1024] of byte absolute data;
  141.       cnt,q:integer;
  142.   begin
  143.     q:=0;
  144.     for cnt:=1 to blocksize do q:=q+t[cnt];
  145.     outcksum:=q and 255
  146.   end;
  147.  
  148.   procedure showerrorstats (curblk,totalerrs,consec:integer);
  149.   var x:integer;
  150.       r:real;
  151.   begin
  152.     x:=wherex;
  153.     write (usr,totalerrs);
  154.     gotoxy (x,wherey+1);
  155.     write (usr,consec,' ');
  156.     gotoxy (x,wherey+1);
  157.     if curblk+totalerrs<>0 then begin
  158.       r:=round(10000.0*totalerrs/(curblk+totalerrs))/100.0;
  159.       write (usr,r:0:2,'%    ')
  160.     end
  161.   end;
  162.  
  163.   function xymodemsend (ymodem:boolean):integer;
  164.   var f:file;
  165.       b:array [1..1026] of byte;
  166.       blocksize:integer;
  167.       fsize,curblk,totalerrs,consec,blocksatatime:integer;
  168.       k:char;
  169.       firstblock:boolean;
  170.  
  171.     function getctrlchar:char;   { Gets ACK/NAK/CAN }
  172.     var k,k2:char;
  173.         cnt:integer;
  174.     begin
  175.       getctrlchar:=can;
  176.       repeat
  177.         cnt:=0;
  178.         repeat
  179.           k:=waitchar (10);
  180.           cnt:=cnt+1;
  181.           if keyhit then begin
  182.             k2:=bioskey;
  183.             if k2=^X then exit;
  184.             timedout:=true
  185.           end
  186.         until (not timedout) or (cnt=60);
  187.         if timedout or hungupon then exit;
  188.         if (k in [ack,nak,crcstart,can]) then begin
  189.           getctrlchar:=k;
  190.           if k=can then sendchar (can);
  191.           exit
  192.         end
  193.       until hungupon;
  194.       timedout:=true
  195.     end;
  196.  
  197.     procedure sendendoffile;
  198.     var k:char;
  199.         tries:integer;
  200.     begin
  201.       tries:=0;
  202.       repeat
  203.         tries:=tries+1;
  204.         sendchar(eot);
  205.         k:=waitchar (20);
  206.       until (k=ack) or (k=can) or (tries=3);
  207.       sendchar(eot)
  208.     end;
  209.  
  210.     procedure getblockfromfile;
  211.     begin
  212.       fillchar (b,sizeof(b),26);
  213.       blockread (f,b,blocksatatime);
  214.       blocksize:=blocksatatime shl 7
  215.     end;
  216.  
  217.     procedure buildfirstblock;
  218.     var cnt,p:integer;
  219.     begin
  220.       blocksize:=128;
  221.       fillchar(b,128,0);
  222.       p:=length(fn);
  223.       repeat
  224.         p:=p-1
  225.       until (p=0) or (fn[p]='\');
  226.       for cnt:=1 to length(fn)-p do b[cnt]:=ord(fn[cnt+p])
  227.     end;
  228.  
  229.     procedure sendblock (num:integer);
  230.     var cnt,bksize:integer;
  231.         crc:word;
  232.         n:byte;
  233.         k:char;
  234.     begin
  235.       clearmodemahead;
  236.       n:=num and 255;
  237.       if blocksize=1024
  238.         then k:=stx
  239.         else k:=soh;
  240.       if crcmode
  241.         then
  242.           begin
  243.             b[blocksize+1]:=0;
  244.             b[blocksize+2]:=0;
  245.             computecrc (b,blocksize+2,crc);
  246.             b[blocksize+1]:=hi(crc);
  247.             b[blocksize+2]:=lo(crc);
  248.             bksize:=blocksize+2;
  249.           end
  250.         else
  251.           begin
  252.             b[blocksize+1]:=0;
  253.             computecksum (b,blocksize,b[blocksize+1]);
  254.             bksize:=blocksize+1
  255.           end;
  256.       sendchar (k);
  257.       sendchar (chr(n));
  258.       sendchar (chr(255-n));
  259.       for cnt:=1 to bksize do sendchar(chr(b[cnt]))
  260.     end;
  261.  
  262.     procedure updatestatus;
  263.     begin
  264.       gotoxy (16,3);
  265.       write (usr,curblk,' of ',fsize);
  266.       gotoxy (16,4);
  267.       write (usr,minstr((fsize-curblk)*blocksatatime),' of ',totaltime,' ');
  268.       gotoxy (16,5);
  269.       showerrorstats (curblk,totalerrs,consec)
  270.     end;
  271.  
  272.     procedure initxfer;
  273.     begin
  274.       starttimer (numminsxfer);
  275.       if ymodem then blocksatatime:=8 else blocksatatime:=1;
  276.       fsize:=(filesize(f)+blocksatatime-1) div blocksatatime;
  277.       totaltime:=minstr(fsize*blocksatatime);
  278.       totalerrs:=0;
  279.       consec:=0;
  280.       firstblock:=true;
  281.       if ymodem
  282.         then
  283.           begin
  284.             curblk:=0;
  285.             buildfirstblock
  286.           end
  287.         else
  288.           begin
  289.             curblk:=1;
  290.             getblockfromfile
  291.           end;
  292.       splitscreen (8);
  293.       top;
  294.       write (usr,'Waiting for NAK')
  295.     end;
  296.  
  297.     procedure setupscreen;
  298.     begin
  299.       gotoxy (1,1);
  300.       if ymodem then write (usr,'Y') else write (usr,'X');
  301.       write (usr,'modem');
  302.       if crcmode then write (usr,'-CRC');
  303.       writeln (usr,' send in progress.  Press [Ctrl-X] to Abort.');
  304.       clreol;
  305.       gotoxy (1,3);
  306.       writeln (usr,'Current block:');
  307.       writeln (usr,'Time left:');
  308.       writeln (usr,'Total errors:');
  309.       writeln (usr,'  Consecutive:');
  310.       write (usr,'Error rate:')
  311.     end;
  312.  
  313.   label abort,done;
  314.   begin
  315.     xymodemsend:=2;
  316.     assign (f,fn);
  317.     reset (f);
  318.     iocode:=ioresult;
  319.     if iocode<>0 then exit;
  320.     initxfer;
  321.     repeat
  322.       k:=getctrlchar;
  323.       if k=can then begin
  324.         if (curblk>(fsize*3/4)) and (curblk>2)
  325.           then xymodemsend:=1; { Cheater! }
  326.         goto abort
  327.       end;
  328.       if firstblock then begin
  329.         if (k=nak) or (k=crcstart) then firstblock:=false;
  330.         crcmode:=k=crcstart;
  331.         setupscreen;
  332.         k:=#0
  333.       end;
  334.       if k=ack then begin
  335.         curblk:=curblk+1;
  336.         if eof(f) then goto done;
  337.         getblockfromfile
  338.       end;
  339.       if k<>nak then consec:=0 else begin
  340.         totalerrs:=totalerrs+1;
  341.         consec:=consec+1
  342.       end;
  343.       sendblock(curblk);
  344.       updatestatus
  345.     until 0=1;
  346.     done:
  347.     sendendoffile;
  348.     xymodemsend:=0;
  349.     abort:
  350.     close (f);
  351.     unsplit;
  352.     stoptimer (numminsxfer)
  353.   end;
  354.  
  355.   function xymodemreceive(ymodem:boolean):integer;
  356.   var f:file;
  357.       block:array [1..1026] of byte;
  358.       blkl,blkh,xblkl,nblkl,nblk1:byte;
  359.       curblk:integer;
  360.       ctrl,k,k2:char;
  361.       timeul,consec,totalerrs,blocksize:integer;
  362.       canceled,timeout:boolean;
  363.  
  364.     procedure cancel;
  365.     begin
  366.       wait (10);
  367.       clearmodemahead;
  368.       sendchar (can);
  369.       wait (10);
  370.       clearmodemahead;
  371.       sendchar (can);
  372.       canceled:=true
  373.     end;
  374.  
  375.     function writeblock:boolean;
  376.     var wb:boolean;
  377.     begin
  378.       blockwrite (f,block,blocksize div 128);
  379.       wb:=ioresult=0;
  380.       writeblock:=wb;
  381.       if not wb then begin
  382.         gotoxy (1,1);
  383.         write (usr,'I/O ERROR ',iocode,' WRITING BLOCK');
  384.         clreol;
  385.         sendchar (can);
  386.         wait (10);
  387.         sendchar (can);
  388.         clearmodemahead
  389.       end
  390.     end;
  391.  
  392.     procedure updatestatus;
  393.     begin
  394.       curblk:=blkl+(blkh shl 8);
  395.       gotoxy (16,3);
  396.       write (usr,curblk);
  397.       gotoxy (16,4);
  398.       showerrorstats (curblk,totalerrs,consec)
  399.     end;
  400.  
  401.     function sendctrl:char;
  402.     var cnt,consec:integer;
  403.         k:char;
  404.     begin
  405.       cnt:=0;
  406.       consec:=0;
  407.       timeout:=false;
  408.       updatestatus;
  409.       sendctrl:=can;
  410.       repeat
  411.         if keyhit then begin
  412.           k:=bioskey;
  413.           if k=^X then begin
  414.             timeout:=true;
  415.             cancel;
  416.             exit
  417.           end
  418.         end;
  419.         sendctrl:=waitchar (50);
  420.         if not timedout then exit;
  421.         sendchar (ctrl);
  422.         cnt:=0;
  423.         consec:=consec+1
  424.       until (consec=10) or hungupon;
  425.       timeout:=true
  426.     end;
  427.  
  428.     function getachar:char;
  429.     var cnt:integer;
  430.         k:char;
  431.     begin
  432.       getachar:=#0;
  433.       timeout:=timeout or hungupon;
  434.       if timeout then exit;
  435.       timeout:=false;
  436.       if keyhit then begin
  437.         k:=bioskey;
  438.         if k=^X then begin
  439.           getachar:=#0;
  440.           timeout:=true;
  441.           cancel;
  442.           exit
  443.         end
  444.       end;
  445.       getachar:=waitchar (10);
  446.       timeout:=timeout or timedout
  447.     end;
  448.  
  449.     procedure xfererror (txt:lstr);
  450.     begin
  451.       gotoxy (16,7);
  452.       write (usr,txt,' in block ',curblk);
  453.       clreol
  454.     end;
  455.  
  456.     procedure initxfer;
  457.     var k:char;
  458.     begin
  459.       timeul:=timer;
  460.       timeout:=false;
  461.       consec:=0;
  462.       blkl:=1;
  463.       blkh:=0;
  464.       xblkl:=1;
  465.       curblk:=1;
  466.       totalerrs:=0;
  467.       if crcmode
  468.         then ctrl:=crcstart
  469.         else ctrl:=nak;
  470.       canceled:=false;
  471.       starttimer (numminsxfer);
  472.       splitscreen (8);
  473.       top;
  474.       gotoxy (1,1);
  475.       if ymodem then write (usr,'Y') else write (usr,'X');
  476.       write (usr,'modem');
  477.       if crcmode then write (usr,'-CRC');
  478.       write (usr,' receive in progress.  Press [Ctrl-X] to Abort.'^M^J^J,
  479.              'Current block:'^M^J,
  480.              'Total errors:'^M^J,
  481.              '  Consecutive:'^M^J,
  482.              'Error rate:'^M^J,
  483.              'Error type:');
  484.       while numchars>0 do k:=getchar
  485.     end;
  486.  
  487.     procedure endoffile;
  488.     begin
  489.       xymodemreceive:=0;
  490.       sendchar (ack);
  491.       wait (10);
  492.       sendchar (ack);
  493.       clearmodemahead
  494.     end;
  495.  
  496.     function block0:boolean;
  497.     var b0:boolean;
  498.         cnt:integer;
  499.     begin
  500.       b0:=(nblkl=0) and (nblk1=255) and (blkh=0) and (blkl<>255);
  501.       if b0 then begin
  502.         xfererror ('(Receiving block 0...)');
  503.         for cnt:=1 to blocksize do block[cnt]:=ord(getachar);
  504.         ctrl:=ack;
  505.         sendchar (ack)
  506.       end;
  507.       block0:=b0
  508.     end;
  509.  
  510.     function blocknumerror:boolean;
  511.     var bne:boolean;
  512.     begin
  513.       bne:=(nblkl<>(255-nblk1)) or ((nblkl<>xblkl) and (nblkl<>blkl));
  514.       if bne then xfererror ('Block # '+strr(nblkl)+' not '+strr(255-nblk1)+
  515.                              ' and '+strr(xblkl)+' or '+strr(blkl));
  516.       blocknumerror:=bne
  517.     end;
  518.  
  519.     function resentnoreason:boolean;
  520.     var rnr:boolean;
  521.         cnt:integer;
  522.     begin
  523.       rnr:=(nblkl<>xblkl) and (nblkl=blkl);
  524.       if rnr then begin
  525.         xfererror ('Block re-sent for no reason');
  526.         for cnt:=1 to blocksize do block[cnt]:=ord(getachar);
  527.         ctrl:=ack;
  528.         sendchar (ack)
  529.       end;
  530.       resentnoreason:=rnr
  531.     end;
  532.  
  533.     procedure getblockfrommodem;
  534.     var cnt:integer;
  535.     begin
  536.       for cnt:=1 to blocksize do begin
  537.         block[cnt]:=ord(getachar);
  538.         if timeout then exit
  539.       end
  540.     end;
  541.  
  542.     function badblock:boolean;
  543.     var crc:word;
  544.         cksum,reccksum:byte;
  545.     begin
  546.       badblock:=false;
  547.       if crcmode
  548.         then
  549.           begin
  550.             computecrc(block,blocksize,crc);
  551.             if crc<>0 then begin
  552.               xfererror ('CRC error');
  553.               badblock:=true
  554.             end
  555.           end
  556.         else
  557.           begin
  558.             reccksum:=block[129];
  559.             block[129]:=0;
  560.             computecksum(block,blocksize,cksum);
  561.             if cksum<>reccksum then begin
  562.               xfererror ('Checksum error');
  563.               badblock:=true
  564.             end
  565.           end
  566.     end;
  567.  
  568.   label nakit,abort,done;
  569.   begin
  570.     xymodemreceive:=2;
  571.     assign (f,fn);
  572.     rewrite (f);
  573.     iocode:=ioresult;
  574.     if iocode<>0 then begin
  575.       fileerror ('XYMODEMRECEIVE',fn);
  576.       exit
  577.     end;
  578.     initxfer;
  579.     repeat
  580.       k:=sendctrl;
  581.       ctrl:=nak;
  582.       if timeout or (k=can) then goto abort;
  583.       if k=eot then begin
  584.         endoffile;
  585.         goto done
  586.       end;
  587.       case k of
  588.         soh:blocksize:=128;
  589.         stx:blocksize:=1024
  590.         else begin
  591.           xfererror ('SOH error: '+strr(ord(k)));
  592.           goto nakit
  593.         end
  594.       end;
  595.       if crcmode
  596.         then blocksize:=blocksize+2
  597.         else blocksize:=blocksize+1;
  598.       nblkl:=ord(getachar);
  599.       nblk1:=ord(getachar);
  600.       if timeout then goto nakit;
  601.       if block0 then goto nakit;
  602.       if blocknumerror then goto nakit;
  603.       if resentnoreason then goto nakit;
  604.       if (nblkl=0) and (blkl=255) then blkh:=blkh+1;
  605.       blkl:=nblkl;
  606.       getblockfrommodem;
  607.       if timeout then goto nakit;
  608.       if badblock then goto nakit;
  609.       ctrl:=ack;
  610.       xblkl:=blkl+1;
  611.       sendchar (ack);
  612.       updatestatus;
  613.       if not writeblock then goto abort;
  614.       consec:=0;
  615.       nakit:
  616.       if hungupon then goto abort;
  617.       if timeout then xfererror ('Time out (short block)');
  618.       if ctrl<>ack then begin
  619.         totalerrs:=totalerrs+1;
  620.         consec:=consec+1;
  621.         repeat
  622.           k:=waitchar (10)
  623.         until timedout;
  624.         if consec>=15 then begin
  625.           sendchar (can);
  626.           goto abort
  627.         end;
  628.         sendchar (ctrl)
  629.       end
  630.     until 0=1;
  631.     abort:
  632.     cancel;
  633.     done:
  634.     close (f); consec:=ioresult;
  635.     if canceled then begin
  636.       erase (f); consec:=ioresult
  637.     end;
  638.     timeul:=timer-timeul;
  639.     if timeul<0 then timeul:=timeul+1440;
  640.     settimeleft (timeleft+timeul*2);
  641.     unsplit;
  642.     stoptimer (numminsxfer)
  643.   end;
  644.  
  645. begin
  646.   totaltime:='';
  647.   if send
  648.     then protocolxfer:=xymodemsend(ymodem)
  649.     else protocolxfer:=xymodemreceive(ymodem)
  650. end;
  651.  
  652.   function cmdline (f:lstr):lstr;
  653.   var a,b,c:string;
  654.       x:integer;
  655.   begin
  656.    x:=0;
  657.    a:='';
  658.    b:='';
  659.    c:='';
  660.    repeat
  661.     x:=x+1;
  662.     a:=a+f[x];
  663.    until f[x]=' ';
  664.    delete (a,length(a),1);
  665.    c:=forumdir;
  666.    if c[length(c)]<>'\' then
  667.    c:=c+'\';
  668.    c:=c+a;
  669.    cmdline:=c;
  670.   end;
  671.  
  672.   function switches (c,fn:lstr):lstr;
  673.   var x,y,z,w:string;
  674.       a,s:integer;
  675.       monolith:boolean;
  676.   begin
  677.    a:=0;
  678.    s:=0;
  679.    x:='';
  680.    y:='';
  681.    z:='';
  682.    w:='';
  683.    repeat
  684.     s:=s+1;
  685.     w:=w+c[s];
  686.    until c[s]=' ';
  687.    delete (c,1,s);
  688.    for a:=1 to length(c) do begin
  689.     monolith:=false;
  690.     x:=copy (c,a,1);
  691.     if x='%' then begin
  692.      y:=copy (c,a+1,1);
  693.      if (y='1') or (y='2') or (y='3') then
  694.      begin
  695.       monolith:=true;
  696.       case valu(y) of
  697.        1:z:=z+strr(usecom);
  698.        2:z:=z+strr(baudrate);
  699.        3:z:=z+fn;
  700.       end;
  701.       delete (c,a+1,1);
  702.      end
  703.     end
  704.     else z:=z+x;
  705.    end;
  706.    switches:=z;
  707.   end;
  708.  
  709.   procedure runext (var ret_code:integer; var commandline,switchz:lstr);
  710.   begin
  711.    exec (commandline,switchz);
  712.    if doserror<>0 then
  713.       begin
  714.       writeln;
  715.       writeln (^G^G);
  716.       writeln ('DOS Error #',doserror);
  717.       writeln ('Please report the error number to the Sysop!');
  718.       writeln;
  719.       writestr ('Press [Enter] to continue.*');
  720.     end
  721.    else ret_code:=dosexitcode;
  722.   end;
  723.  
  724.   function doext (mode,proto:char; uddir,fn:lstr; baud,comm:integer):integer;
  725.   var cline,switchz,dirsave,cddir,wildcatsucks:lstr;
  726.       baudst,commst:mstr;
  727.       retcd:integer;
  728.       foofur:text;
  729.       h1,h2,m1,m2,s1,s2,ss1,ss2:word;
  730.   begin
  731.   { getdir (0,dirsave); }{ drive: 0 = cur. 1 = A: etc. - save cur. dir. }
  732.     dirsave:=forumdir;
  733.     if dirsave[length(dirsave)]='\' then
  734.     dirsave:=copy (dirsave,1,length(dirsave)-1);
  735.     if uddir[length(uddir)]='\'
  736.     then cddir:=copy(uddir,1,length(uddir)-1)
  737.     else cddir:=uddir;
  738.     writeln (usr,^M'[Changing Directories to '+cddir+']'^M);
  739.     chdir (cddir);
  740.     str (baud:3,baudst);
  741.     str (comm:1,commst);
  742.     if mode='R' then begin
  743.       case proto of
  744.         'Z':cline:=cmdline(zmodemr);
  745.         'J':cline:=cmdline(jmodemr);
  746.         'L':cline:=cmdline(lynxr);
  747.         'G':cline:=cmdline(ymodemgr);
  748.         'O':cline:=cmdline(xovrr);
  749.         '1':cline:=cmdline(yovrr);
  750.         'S':cline:=cmdline(superkr);
  751.         'K':cline:=cmdline(k9xr);
  752.         'R':cline:=cmdline(zcrashr);
  753.         'P':cline:=cmdline(zpcpr);
  754.         'E':cline:=cmdline(lynxcrashr);
  755.         'W':cline:=cmdline(wxmodemr);
  756.       end
  757.     end;
  758.     if mode='R' then begin
  759.       case proto of
  760.         'Z':switchz:=switches(zmodemr,fn);
  761.         'J':switchz:=switches(jmodemr,fn);
  762.         'L':switchz:=switches(lynxr,fn);
  763.         'G':switchz:=switches(ymodemgr,fn);
  764.         'O':switchz:=switches(xovrr,fn);
  765.         '1':switchz:=switches(yovrr,fn);
  766.         'S':switchz:=switches(superkr,fn);
  767.         'K':switchz:=switches(k9xr,fn);
  768.         'R':switchz:=switches(zcrashr,fn);
  769.         'P':switchz:=switches(zpcpr,fn);
  770.         'E':switchz:=switches(lynxcrashr,fn);
  771.         'W':switchz:=switches(wxmodemr,fn);
  772.       end
  773.     end;
  774.     if mode='S' then begin
  775.       case proto of
  776.         'Z':cline:=cmdline(zmodems);
  777.         'J':cline:=cmdline(jmodems);
  778.         'L':cline:=cmdline(lynxs);
  779.         'G':cline:=cmdline(ymodemgs);
  780.         'O':cline:=cmdline(xovrs);
  781.         '1':cline:=cmdline(yovrs);
  782.         'S':cline:=cmdline(superks);
  783.         'K':cline:=cmdline(k9xs);
  784.         'R':cline:=cmdline(zcrashs);
  785.         'P':cline:=cmdline(zpcps);
  786.         'W':cline:=cmdline(wxmodems);
  787.         '^':cline:=cmdline(zrles);
  788.       end
  789.     end;
  790.     if mode='S' then begin
  791.       case proto of
  792.         'Z':switchz:=switches(zmodems,fn);
  793.         'J':switchz:=switches(jmodems,fn);
  794.         'L':switchz:=switches(lynxs,fn);
  795.         'G':switchz:=switches(ymodemgs,fn);
  796.         'O':switchz:=switches(xovrs,fn);
  797.         '1':switchz:=switches(yovrs,fn);
  798.         'S':switchz:=switches(superks,fn);
  799.         'K':switchz:=switches(k9xs,fn);
  800.         'R':switchz:=switches(zcrashs,fn);
  801.         'P':switchz:=switches(zpcps,fn);
  802.         'W':switchz:=switches(wxmodems,fn);
  803.         '^':switchz:=switches(zrles,fn);
  804.       end;
  805.     end;
  806.     write (^B);
  807. {   if (proto='Z') or (proto='G') or (proto='O') or (proto='1') or (proto='R')
  808.     or (proto='P') then
  809.     begin
  810.      if (not exist (forumdir+'\DSZ.COM')) and (not exist (forumdir+'\DSZ.EXE'))
  811.      then begin
  812.       writeln;
  813.       writeln (^G^R'DSZ Protocols are not available at the moment!');
  814.       writeln ('Sysop does not have DSZ.COM or DSZ.EXE in the TCS directory.');
  815.       writeln ('Please notify him!');
  816.       writeln;
  817.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  818.       chdir (dirsave);
  819.       exit;
  820.      end;
  821.     end;
  822.     if (proto='J') then begin
  823.      if not exist (forumdir+'\JMODEM.COM') then
  824.      begin
  825.       writeln;
  826.       writeln (^G^R'Jmodem Protocol is not available at the moment!');
  827.       writeln ('Sysop does not have JMODEM.COM in the TCS directory.');
  828.       writeln ('Please notify him!');
  829.       writeln;
  830.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  831.       chdir (dirsave);
  832.       exit;
  833.      end;
  834.     end;
  835.     if (proto='L') or (proto='E') then begin
  836.      if not exist (forumdir+'\LYNX.EXE') then
  837.      begin
  838.       writeln;
  839.       writeln (^G^R'Lynx Protocols is not available at the moment!');
  840.       writeln ('Sysop does not have LYNX.EXE in the TCS directory.');
  841.       writeln ('Please notify him!');
  842.       writeln;
  843.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  844.       chdir (dirsave);
  845.       exit;
  846.      end;
  847.     end;
  848.     if (proto='K') or (proto='S') or (proto='W') then begin
  849.      if not exist (forumdir+'\SUPERK.COM') then
  850.      begin
  851.       writeln;
  852.       writeln (^G^R'Super8k/K9Xmodem Protocol is not available at the moment!');
  853.       writeln ('Sysop does not have SUPERK.COM in the TCS directory.');
  854.       writeln ('Please notify him!');
  855.       writeln;
  856.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  857.       chdir (dirsave);
  858.       exit;
  859.       end;
  860.      end; }
  861.     assign (foofur,dszlog);
  862.     if exist (dszlog) then erase (foofur);
  863.     starttimer (numminsxfer);
  864.     gettime (h1,m2,s1,ss1);
  865.     runext (retcd,cline,switchz);
  866.     gettime (h2,m2,s2,ss2);
  867.     stoptimer (numminsxfer);
  868.     writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  869.     chdir (dirsave);
  870.     doext:=retcd;
  871.     setparam (usecom,baudrate,parity);
  872.   end;
  873.  
  874.   procedure beepbeep (ok:integer);
  875.   begin
  876.     delay (500);
  877.     write (^B^M);
  878.     case ok of
  879.       0:write ('Xfer completed!');
  880.       1:write ('Xfer Aborted just before EOF!');
  881.       2:write ('Xfer Aborted!')
  882.     end;
  883.     writeln (^G^M)
  884.   end;
  885.  
  886.   function checkdszlog (fnxfered:anystr):char;
  887.   var f:text;
  888.       l,sn,code,bytes,xferfile,cps,bps,errors,blocksize,flowstops:anystr;
  889.       c:string[1];
  890.       done:boolean;
  891.       x:integer;
  892.  
  893.   function parsespaces (s:anystr):anystr;
  894.   var p,pee,xy:integer;
  895.       k,j:char;
  896.       r:anystr;
  897.   begin
  898.    parsespaces:=s;
  899.    r:=s;
  900.    repeat
  901.    p:=pos (' ',r);
  902.    if p>0 then begin
  903.     delete (r,p,1);
  904.    end;
  905.    until p=0;
  906.    parsespaces:=r;
  907.   end;
  908.  
  909.   begin
  910.    checkdszlog:=' ';
  911.    if not exist (dszlog) then begin
  912.     writeln (^G^G);
  913.     writeln ('DSZLOG error.');
  914.   { ansicolor (12);
  915.     writeln ('*********************************************');
  916.     writeln ('** DSZLOG Error!! Please notify Sysop NOW! **');
  917.     writeln ('*********************************************'); }
  918.     ansicolor (urec.regularcolor);
  919.     exit;
  920.    end;
  921.    assign (f,dszlog);
  922.    reset (f);
  923.    l:='';
  924.    sn:=''; code:=''; bytes:=''; xferfile:='';
  925.    cps:=''; bps:=''; errors:=''; blocksize:='';
  926.    readln (f,l);
  927.    code:=copy (l,1,1);
  928.    bytes:=copy (l,2,7);
  929.    bps:=copy (l,10,6);
  930.    cps:=copy (l,19,5);
  931.    errors:=copy (l,28,12);
  932.    flowstops:=copy (l,40,6);
  933.    blocksize:=copy (l,45,5);
  934.    c:='';
  935.    x:=50;
  936.    repeat
  937.     x:=x+1;
  938.     if c='/' then c:='\';
  939.     xferfile:=xferfile+c;
  940.     c:=copy (l,x,1);
  941.    until c=' ';
  942.    sn:=copy (l,x+1,10);
  943.    textclose (f);
  944.    bps:=parsespaces (bps);
  945.    cps:=parsespaces (cps);
  946.    errors:=parsespaces (errors);
  947.    bytes:=parsespaces (bytes);
  948.    flowstops:=parsespaces (flowstops);
  949.    blocksize:=parsespaces (blocksize);
  950.    xferfile:=parsespaces (xferfile);
  951.    sn:=parsespaces (sn);
  952.    checkdszlog:=code[1];
  953.    writeln (^R^B'Code-> '+code+'  Filename: '+xferfile);
  954.    writeln ('Bytes sent: ',bytes,'  (',cps,' cps at ',bps,' bps)');
  955.    writeln ('SN#: ',sn,'  Packet Length: ',blocksize,' bytes');
  956.    writeln;
  957.   end;
  958.  
  959.   function sponsoron:boolean;
  960.   begin
  961.     sponsoron:=match(area.sponsor,unam) or issysop
  962.   end;
  963.  
  964.   procedure seekudfile (n:integer);
  965.   begin
  966.     seek (udfile,n-1)
  967.   end;
  968.  
  969.   procedure requestfile;
  970.   var t:text;
  971.       me:message;
  972.       m:mailrec;
  973.   begin
  974.     if hungupon then exit;
  975.     writestr (^M^J+'Filename to Request: *');
  976.     if length(input)=0 then exit;
  977.     writeln (^M^J+'Enter a Message regarding the File Request:');
  978.     delay (1000);
  979.     titlestr:='File Request: '+input;
  980.     sendstr:='Sysop';
  981.     m.line:=editor (me,false,'File Request: '+input);
  982.     sendstr:='';
  983.     if m.line<0 then exit;
  984.     m.anon:=false;
  985.     m.title:=titlestr;
  986.     m.sentby:=unam;
  987.     m.when:=now;
  988.     addfeedback (m);
  989.   end;
  990.  
  991.   function getfname (path:lstr; name:mstr):lstr;
  992.   var l:lstr;
  993.   begin
  994.     l:=path;
  995.     if length(l)<>0
  996.       then if not (l[length(l)] in [':','\'])
  997.         then l:=l+'\';
  998.     l:=l+name;
  999.     getfname:=l
  1000.   end;
  1001.  
  1002.   procedure possiblelzm (points:integer);
  1003.   var n:text;
  1004.   begin
  1005.       writeln;
  1006.       writeln (^R'** Possible LEECH-ZMODEM User!');
  1007.       writeln (^R'** Notifying Sysop...');
  1008.       assign (n,forumdir+'System.Not');
  1009.       if exist (forumdir+'System.Not') then append (n)
  1010.       else begin
  1011.        writeln (n,'─────────────────────────────────────────────────');
  1012.        writeln (n,'[ TCS '+ver+' System Notifications Routed to Sysop ]');
  1013.        writeln (n,'─────────────────────────────────────────────────');
  1014.        writeln (n,'');
  1015.        rewrite (n);
  1016.       end;
  1017.       writeln (n,'────────────────────────────────────────────────────────────────────────────');
  1018.       writeln (n,'This is a possible notification of a LEECH-ZMODEM user.');
  1019.       writeln (n,'Leech-Zmodem allows the user to download a file via Zmodem FREE');
  1020.       writeln (n,'of cost by aborting the transfer near the end of the file, or');
  1021.       writeln (n,'by rewinding the file pointer to a random value. TCS reports that');
  1022.       writeln (n,'this may have been attempted by a user; namely:');
  1023.       writeln (n,'"'+unam+'".');
  1024.       writeln (n,'He was trying to download a file (or a batch of files).');
  1025.       writeln (n,'The cost point of this file was subtracted from that user''s points');
  1026.       writeln (n,'as a result of the possible violation.');
  1027.       writeln (n,' ');
  1028.       writeln (n,'[System Notification auto-sent at '+timestr(now)+' on '+datestr(now)+']');
  1029.       writeln (n,'────────────────────────────────────────────────────────────────────────────');
  1030.       textclose (n);
  1031.       urec.udpoints:=urec.udpoints-points;
  1032.       writeurec;
  1033.       writeln ('** Sysop notified & file cost accounted for.');
  1034.       writeln;
  1035.       writeln ('If you were not using Leech-Zmodem and were honestly aborting the Transfer,');
  1036.       writeln ('Then send some [F]eedback to the Sysop telling him you were not using LZM!');
  1037.       writeln ('These precautions are taken to protect against UNWANTED Leech-Zmodem');
  1038.       writeln ('users.');
  1039.       ansicolor (urec.regularcolor);
  1040.   end;
  1041.  
  1042.   function allowxfer:boolean;
  1043.   var cnt:baudratetype;
  1044.       k:char;
  1045.   begin
  1046.     allowxfer:=false;
  1047.    { if not carrier then begin
  1048.       writeln ('You may only transfer from remote!');
  1049.       exit
  1050.     end; }
  1051.     for cnt:=firstbaud to lastbaud do
  1052.       if baudrate=baudarray[cnt]
  1053.         then if not (cnt in downloadrates)
  1054.           then begin
  1055.             writeln ('Sorry, File Transfer is not allowed at ',baudrate,' Baud!');
  1056.             exit
  1057.           end;
  1058.     if parity then begin
  1059.       writeln ('Please select NO parity and press [Return]:');
  1060.       parity:=false;
  1061.       setparam (usecom,baudrate,parity);
  1062.       repeat
  1063.         k:=getchar;
  1064.         if hungupon then exit
  1065.       until k in [#13,#141];
  1066.       if k=#141 then begin
  1067.         parity:=true;
  1068.         setparam (usecom,baudrate,parity);
  1069.         writeln ('You did not turn off parity.  Transfer aborted.');
  1070.         exit
  1071.       end
  1072.     end;
  1073.     allowxfer:=true
  1074.   end;
  1075.  
  1076.   function numuds:integer;
  1077.   begin
  1078.     numuds:=filesize (udfile)
  1079.   end;
  1080.  
  1081.   function nofiles:boolean;
  1082.   begin
  1083.     if numuds=0 then begin
  1084.       nofiles:=true;
  1085.       writestr (^M'Sorry, no files!')
  1086.     end else nofiles:=false
  1087.   end;
  1088.  
  1089.   function checkok (ud:udrec):boolean;
  1090.   var m:string;
  1091.   begin
  1092.    checkok:=true;
  1093.    if (not sponsoron) and (ud.points>urec.udpoints) then begin
  1094.       if not allowloan then begin
  1095.        writeln (^R'Sorry, that file requires '^S,ud.points,^R' points.');
  1096.        writeln;
  1097.        checkok:=false;
  1098.        exit;
  1099.       end;
  1100.        if allowloan then begin
  1101.        if ulvl<lvltoloan then begin
  1102.         writeln (^R'Sorry, that file requires '^S,ud.points,^R' points.');
  1103.         checkok:=false;
  1104.         exit;
  1105.        end;
  1106.        if ud.points>maxloan then begin
  1107.         writeln (^R'Sorry, that file requires '^S,ud.points,^R' points.');
  1108.         writeln ('You have exceeded the File Point Loan limit.');
  1109.         writeln ('Better upload something before the sysop removes your type of scum.');
  1110.         checkok:=false;
  1111.         exit;
  1112.        end;
  1113.         writeln (^R'That file requires '^S,ud.points,^R' file points.');
  1114.         writeln (^R'You have '^S,urec.udpoints,^R' file points.');
  1115.         writestr ('Take a Point Loan [y/n]? *');
  1116.          m:=input;
  1117.          if yes then urec.udpoints:=urec.udpoints-ud.points;
  1118.           end;
  1119.      end;
  1120.     if (ud.newfile) and (not sponsoron) then begin
  1121.       writeln ('Sorry, that is a new file and must be validated.');
  1122.       checkok:=false;
  1123.       exit
  1124.     end;
  1125.     if (ud.specialfile) and (not sponsoron) then begin
  1126.       writeln ('Sorry, downloading that file requires special permission.');
  1127.       checkok:=false;
  1128.       exit
  1129.     end;
  1130.     if not exist (getfname(ud.path,ud.filename)) then begin
  1131.       checkok:=false;
  1132.       writeln ('That file is [Offline].');
  1133.       writestr ('Would you like to request that it be put online [y/n]? *');
  1134.       if length(input)=0 then exit;
  1135.       if (input[1]='y') or (input[1]='Y') then requestfile;
  1136.       exit;
  1137.     end;
  1138.     if (length(ud.dlpw)>0) then begin
  1139.      writeln;
  1140.      dots:=true;
  1141.      writestr ('[Enter Download Password]:');
  1142.      dots:=false;
  1143.      checkok:=false;
  1144.      if length(input)=0 then exit else
  1145.      if not match(input,ud.dlpw) then exit else
  1146.      checkok:=true;
  1147.     end;
  1148.     if tempsysop then begin
  1149.       ulvl:=regularlevel;
  1150.       tempsysop:=false;
  1151.       writeurec;
  1152.       bottomline
  1153.     end;
  1154.   end;
  1155.  
  1156.   function searchforfile (f:sstr):integer;
  1157.   var ud:udrec;
  1158.       cnt:integer;
  1159.   begin
  1160.     for cnt:=1 to numuds do begin
  1161.       seek (udfile,cnt-1);
  1162.       read (udfile,ud);
  1163.       if match(ud.filename,f) then begin
  1164.         searchforfile:=cnt;
  1165.         exit
  1166.       end
  1167.     end;
  1168.     searchforfile:=0
  1169.   end;
  1170.  
  1171.   procedure listfile (n:integer; extended:boolean);
  1172.   var ud:udrec;
  1173.       q:sstr;
  1174.       a,b,c,ed:string;
  1175.   begin
  1176.     seekudfile (n);
  1177.     read (udfile,ud);
  1178.     ansicolor (urec.statcolor);
  1179.     tab (strr(n)+'.',4);
  1180.     ansicolor (urec.promptcolor);
  1181.     tab (ud.filename,14);
  1182.     ansicolor (urec.inputcolor);
  1183.     if ud.newfile
  1184.       then write ('[New]  ')
  1185.       else if ud.specialfile
  1186.         then write ('[Ask]  ')
  1187.         else if ud.points>0
  1188.           then tab (strr(ud.points),7)
  1189.           else write ('[Free] ');
  1190.     ansicolor (urec.regularcolor);
  1191.     if exist (getfname(ud.path,ud.filename)) then tab (strlong(ud.filesize),10) else
  1192.      write ('[Offline] ');
  1193.     ansicolor (urec.statcolor);
  1194.     writeln (ud.descrip);
  1195.     ansicolor (urec.regularcolor);
  1196.     if break or (not extended) then exit;
  1197.     write (^R'    ');
  1198.     tab (datestr(ud.when),19);
  1199.     ansicolor (urec.promptcolor);
  1200.     tab (strr(ud.downloaded)+' D/L''s',13);
  1201.     ansicolor (urec.inputcolor);
  1202.     writeln (ud.sentby);
  1203.     a:=copy (ud.extdesc,1,80);
  1204.     ansicolor (urec.statcolor);
  1205.     writeln (a);
  1206.     if length(ud.extdesc)>80 then begin
  1207.      b:=copy (ud.extdesc,81,80);
  1208.      ansicolor (urec.statcolor);
  1209.      writeln (b);
  1210.     end;
  1211.     if length(ud.extdesc)>160 then begin
  1212.      c:=copy (ud.extdesc,161,80);
  1213.      ansicolor (urec.statcolor);
  1214.      writeln (c);
  1215.     end;
  1216.     ansicolor (urec.regularcolor);
  1217.   end;
  1218.  
  1219.   procedure listfiles (extended:boolean);
  1220.   var cnt,max,r1,r2:integer;
  1221.   const extendedstr:array[false..true] of string[9]=('','Extended ');
  1222.   begin
  1223.     if nofiles then exit;
  1224.     writehdr (extendedstr[extended]+'File List');
  1225.     max:=numuds;
  1226.     thereare (max,'File','Files');
  1227.     parserange (max,r1,r2);
  1228.     if r1=0 then exit;
  1229.     writeln (^S'#.'^P'  Filename'^U'      Points '^R'Size      '^S'Description'^R);
  1230.     if (asciigraphics in urec.config) then
  1231.      writeln ('───────────────────────────────────────────────────────────────────────────────')
  1232.     else
  1233.      writeln ('-------------------------------------------------------------------------------');
  1234.     for cnt:=r1 to r2 do begin
  1235.       listfile (cnt,extended);
  1236.       if break then exit
  1237.     end
  1238.   end;
  1239.  
  1240.   function getfilenum (t:mstr):integer;
  1241.   var n,s:integer;
  1242.   begin
  1243.     getfilenum:=0;
  1244.     if length(input)>1 then input:=copy(input,2,255) else
  1245.       repeat
  1246.         writestr ('File Name/Number to '+t+' [?/List]:');
  1247.         if hungupon or (length(input)=0) then exit;
  1248.         if input='?' then begin
  1249.           listfiles (false);
  1250.           input:=''
  1251.         end
  1252.       until input<>'';
  1253.     val (input,n,s);
  1254.     if s<>0 then begin
  1255.       n:=searchforfile(input);
  1256.       if n=0 then begin
  1257.         writeln ('File not found.');
  1258.         exit
  1259.       end
  1260.     end;
  1261.     if (n<1) or (n>numuds)
  1262.       then writeln ('File number out of range!')
  1263.       else getfilenum:=n
  1264.   end;
  1265.  
  1266.   function numbatches:integer;
  1267.   var x,n:integer;
  1268.   begin
  1269.    n:=0;
  1270.    for x:=1 to maxb do begin
  1271.     if (length (bbuffer[x].fn)>0) and (length (bbuffer[x].path)>0) and
  1272.     (bbuffer[x].filesize>0)
  1273.     then n:=n+1;
  1274.    end;
  1275.    numbatches:=n;
  1276.   end;
  1277.  
  1278.   function minutes (m:longint):integer;
  1279.   var mins,secs,realtime,x:integer;
  1280.       tyme,y:string;
  1281.   begin
  1282.    minutes:=-1;
  1283.    mins:=0;
  1284.    tyme:=minstr(m);
  1285.    x:=pos (':',tyme)-1;
  1286.    y:=copy(tyme,1,x);
  1287.    if valu(y)<1 then
  1288.    begin
  1289.     realtime:=1;
  1290.     minutes:=realtime;
  1291.     exit;
  1292.    end;
  1293.  { case baudrate of
  1294.     300:mins:=valu(y) * 4;
  1295.     1200:mins:=valu(y);
  1296.     2400:mins:=valu(y) div 2;
  1297.     9600:mins:=valu(y) div 8;
  1298.    end; }
  1299.    mins:=valu(y);
  1300.    secs:=valu(copy(tyme,x+1,2));
  1301.    if mins=0 then mins:=1;
  1302.    if secs<>0 then realtime:=mins+(secs div 60) else
  1303.    realtime:=mins;
  1304.    minutes:=realtime;
  1305.   end;
  1306.  
  1307.   function minutestring (m:longint):string;
  1308.   var anarky,y,mins,secs,it:string;
  1309.       x:integer;
  1310.   begin
  1311.    minutestring:='-1:-1';
  1312.    anarky:=minstr(m);
  1313.    x:=pos(':',anarky)-1;
  1314.    y:=copy(anarky,1,x);
  1315.  { case baudrate of
  1316.     300:mins:=strr(valu(y) * 4);
  1317.     1200:mins:=strr(valu(y));
  1318.     2400:mins:=strr(valu(y) div 2);
  1319.     9600:mins:=strr(valu(y) div 8);
  1320.    end; }
  1321.    mins:=y;
  1322.    secs:=copy(anarky,x+1,2);
  1323.    it:=mins+':'+secs;
  1324.    minutestring:=it;
  1325.   end;
  1326.  
  1327.   function totalxfertime (size:longint):integer;
  1328.   var silpheed,urlame:string;
  1329.       sq3,min:integer;
  1330.       rsec:real;
  1331.   begin
  1332.    rsec:=1.38*size*(1200/baudrate);
  1333.    min:=trunc (rsec/60.0);
  1334.    totalxfertime:=min;
  1335.   {
  1336.    silpheed:=minstr(size);
  1337.    sq3:=pos(':',silpheed)-1;
  1338.    urlame:=copy(silpheed,1,sq3);
  1339.    totalxfertime:=valu(urlame);
  1340.   }
  1341.   end;
  1342.  
  1343.   procedure listbatch;
  1344.   var x,gayger,firm:integer;
  1345.       freeworld,kopy:string;
  1346.       f:file;
  1347.   begin
  1348.    gayger:=0;
  1349.    for x:=1 to maxb do begin
  1350.     if (length(bbuffer[x].fn)>0) and (length(bbuffer[x].path)>0) and
  1351.        (bbuffer[x].filesize>0) then
  1352.     begin
  1353.      gayger:=gayger+1;
  1354.      if gayger=1 then begin
  1355.      writehdr ('Batch Download File List');
  1356.      writeln ('Num Filename       Cost  Bytes       Time');
  1357.      if (asciigraphics in urec.config) then
  1358.      writeln ('───────────────────────────────────────────') else
  1359.      writeln ('-------------------------------------------');
  1360.      end;
  1361.      tab (strr(x)+'.',4);
  1362.      tab (bbuffer[x].fn,15);
  1363.      tab (strr(bbuffer[x].points),6);
  1364.      tab (strlong(bbuffer[x].filesize),12);
  1365.      assign (f,getfname(bbuffer[x].path,bbuffer[x].fn));
  1366.      reset (f);
  1367.      writeln (minstr(filesize(f)));
  1368.      close (f);
  1369.     end;
  1370.    end;
  1371.    if gayger>0 then begin
  1372.     if (asciigraphics in urec.config) then
  1373.     writeln  ('───────────────────────────────────────────') else
  1374.     writeln  ('-------------------------------------------');
  1375.     writeln;
  1376.     write (^R'Total Size:   '^S);
  1377.     write (strlong(totalxfersize));
  1378.     writeln (^S' bytes'^R);
  1379.     write (^R'Total Time:   '^S);
  1380.     writeln (minstr(totalxfersize),^R);
  1381.     write (^R'Total Points: '^S);
  1382.     writeln (strr(totalxferpoints));
  1383.     ansireset;
  1384.    end;
  1385.   end;
  1386.  
  1387.   procedure addtobatch (auto:integer);
  1388.   var x,num,y:integer;
  1389.       ud:udrec;
  1390.       m:string;
  1391.       floyd:boolean;
  1392.       t:text;
  1393.       fff,ffff:file;
  1394.       playdoland:longint;
  1395.   begin
  1396.     if numbatches<1 then begin
  1397.      totalxfersize:=0;
  1398.      totalxferpoints:=0;
  1399.     end;
  1400.     assign (t,b);
  1401.     if not allowxfer then exit;
  1402.     if nofiles then exit;
  1403.     if useqr then begin
  1404.      calcqr;
  1405.      if (qr<qrlimit) and (ulvl<qrexempt) then begin
  1406.       writeln ('Your Quality Rating is '^S+strr(qr)+^R'.');
  1407.       writeln ('That exceeds the limit of '^S+strr(qrlimit)+^R'!');
  1408.       writeln ('You must get a better QR before you can download.');
  1409.       exit;
  1410.      end;
  1411.      end;
  1412.     if (area.download=false) then begin
  1413.      writeln;
  1414.      writeln ('Sorry, downloading is not allowed from this area!');
  1415.      writeln;
  1416.      exit;
  1417.     end;
  1418.     num:=getfilenum ('Add to Batch Buffer');
  1419.     if num=0 then exit;
  1420.     writeln;
  1421.     seek (udfile,num-1);
  1422.     read (udfile,ud);
  1423.     assign (ffff,getfname(ud.path,ud.filename));
  1424.     floyd:=checkok (ud);
  1425.     reset (ffff);
  1426.     playdoland:=filesize (ffff);
  1427.     close (ffff);
  1428.     if not floyd then exit else
  1429.     if (totalxfertime(totalxfersize)+minutes(playdoland))>timeleft then
  1430.      begin
  1431.       writeln ('You don''t have enough time left!');
  1432.       exit;
  1433.     end else
  1434.     if totalxfertime(totalxfersize)-5>timeleft then begin
  1435.      writeln ('The system event is coming up to soon to do the transfer!');
  1436.      exit;
  1437.     end else
  1438.     if (totalxferpoints+ud.points)>urec.udpoints then begin
  1439.      writeln ('You don''t have enough points left!');
  1440.      exit;
  1441.     end else
  1442.     begin
  1443.      if not exist (b) then rewrite (t) else reset (t);
  1444.      y:=numbatches+1;
  1445.      bbuffer[y].num:=num;
  1446.      bbuffer[y].fn:=ud.filename;
  1447.      bbuffer[y].path:=ud.path;
  1448.      bbuffer[y].descrip:=ud.descrip;
  1449.      bbuffer[y].dlpw:=ud.dlpw;
  1450.      bbuffer[y].extdesc:=ud.extdesc;
  1451.      bbuffer[y].points:=ud.points;
  1452.      bbuffer[y].filesize:=ud.filesize;
  1453.      bbuffer[y].downloaded:=ud.downloaded;
  1454.      bbuffer[y].sent:=false;
  1455.      close (t);
  1456.      totalxfersize:=totalxfersize+bbuffer[y].filesize;
  1457.      assign (fff,getfname(bbuffer[y].path,bbuffer[y].fn));
  1458.      reset (fff);
  1459.      totalxferpoints:=totalxferpoints+bbuffer[y].points;
  1460.      close (fff);
  1461.      writeln (^R'File added to Batch Download Buffer as #',numbatches,'.');
  1462.     end;
  1463.   end;
  1464.  
  1465.   function batchdownload (proto:char; fl:lstr; baud,comm:integer):integer;
  1466.   var cline,switchz,dirsave,cddir,wildcatsucks:lstr;
  1467.       baudst,commst:mstr;
  1468.       retcd:integer;
  1469.       foofur:text;
  1470.   begin
  1471.     dirsave:=forumdir;
  1472.     if dirsave[length(dirsave)]='\' then
  1473.     dirsave:=copy (dirsave,1,length(dirsave)-1);
  1474.     str (baud:3,baudst);
  1475.     str (comm:1,commst);
  1476.       case proto of
  1477.         'Z':cline:=cmdline(zmodems);
  1478.         'J':cline:=cmdline(jmodems);
  1479.         'L':cline:=cmdline(lynxs);
  1480.         'G':cline:=cmdline(ymodemgs);
  1481.         'S':cline:=cmdline(superks);
  1482.         'K':cline:=cmdline(k9xs);
  1483.         'P':cline:=cmdline(zpcps);
  1484.         'W':cline:=cmdline(wxmodems);
  1485.         'Y':cline:=cmdline(ybatchs);
  1486.       end;
  1487.       case proto of
  1488.        'Z':switchz:=' port '+commst+' speed '+baudst+' sz -s @'+fl;
  1489.        'J':switchz:=' p'+commst+' s'+baudst+' sjb f @'+fl;
  1490.        'L':switchz:=' S /'+commst+' /'+baudst+' @'+fl;
  1491.        'G':switchz:=' port '+commst+' speed '+baudst+' sb -g @'+fl;
  1492.        'S':switchz:=' p'+commst+' s'+baudst+' ssb f @'+fl;
  1493.        'K':switchz:=' p'+commst+' s'+baudst+' skb f @'+fl;
  1494.        'P':switchz:=' port '+commst+' speed '+baudst+' sz -w -s @'+fl;
  1495.        'Y':switchz:=' port '+commst+' speed '+baudst+' sb -s @'+fl;
  1496.        'W':switchz:=' p'+commst+' s'+baudst+' swb f @'+fl;
  1497.       {'X':switchz:=' p'+commst+' s'+baudst+' scb -s @'+fl;}
  1498.       end;
  1499.     write (^B);
  1500.     if (proto='Z') or (proto='G') or (proto='O') or (proto='1') or (proto='R')
  1501.     or (proto='P') then
  1502.     begin
  1503.      if (not exist (forumdir+'\DSZ.COM')) and (not exist (forumdir+'\DSZ.EXE'))
  1504.      then begin
  1505.       writeln;
  1506.       writeln (^G^R'DSZ Protocols are not available at the moment!');
  1507.       writeln ('Sysop does not have DSZ.COM or DSZ.EXE in the TCS directory.');
  1508.       writeln ('Please notify him!');
  1509.       writeln;
  1510.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  1511.       chdir (dirsave);
  1512.       exit;
  1513.      end;
  1514.     end;
  1515.     if (proto='J') then begin
  1516.      if not exist (forumdir+'\JMODEM.COM') then
  1517.      begin
  1518.       writeln;
  1519.       writeln (^G^R'Jmodem Protocol is not available at the moment!');
  1520.       writeln ('Sysop does not have JMODEM.COM in the TCS directory.');
  1521.       writeln ('Please notify him!');
  1522.       writeln;
  1523.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  1524.       chdir (dirsave);
  1525.       exit;
  1526.      end;
  1527.     end;
  1528.     if (proto='L') or (proto='E') then begin
  1529.      if not exist (forumdir+'\LYNX.EXE') then
  1530.      begin
  1531.       writeln;
  1532.       writeln (^G^R'Lynx Protocols is not available at the moment!');
  1533.       writeln ('Sysop does not have LYNX.EXE in the TCS directory.');
  1534.       writeln ('Please notify him!');
  1535.       writeln;
  1536.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  1537.       chdir (dirsave);
  1538.       exit;
  1539.      end;
  1540.     end;
  1541.     if (proto='K') or (proto='S') or (proto='W') or (proto='X') then begin
  1542.      if not exist (forumdir+'\SUPERK.COM') then
  1543.      begin
  1544.       writeln;
  1545.       writeln (^G^R'Super8k/K9Xmodem Protocol is not available at the moment!');
  1546.       writeln ('Sysop does not have SUPERK.COM in the TCS directory.');
  1547.       writeln ('Please notify him!');
  1548.       writeln;
  1549.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  1550.       chdir (dirsave);
  1551.       exit;
  1552.       end;
  1553.      end;
  1554.     assign (foofur,dszlog);
  1555.     if exist (dszlog) then erase (foofur);
  1556.     starttimer (numminsxfer);
  1557.     runext (retcd,cline,switchz);
  1558.     stoptimer (numminsxfer);
  1559.     chdir (dirsave);
  1560.     batchdownload:=retcd;
  1561.     setparam (usecom,baudrate,parity);
  1562.   end;
  1563.  
  1564.   function batchupload (proto:char; dir:lstr; baud,comm:integer):integer;
  1565.   var cline,switchz,dirsave,cddir,wildcatsucks:lstr;
  1566.       baudst,commst:mstr;
  1567.       retcd:integer;
  1568.       foofur:text;
  1569.  
  1570.   begin
  1571.     dirsave:=forumdir;
  1572.     if dirsave[length(dirsave)]='\' then
  1573.     dirsave:=copy (dirsave,1,length(dirsave)-1);
  1574.     str (baud:3,baudst);
  1575.     str (comm:1,commst);
  1576.       case proto of
  1577.         'Z':cline:=cmdline(zmodemr);
  1578.         'J':cline:=cmdline(jmodemr);
  1579.         'L':cline:=cmdline(lynxr);
  1580.         'G':cline:=cmdline(ymodemgr);
  1581.         'O':cline:=cmdline(xovrr);
  1582.         '1':cline:=cmdline(yovrr);
  1583.         'S':cline:=cmdline(superkr);
  1584.         'K':cline:=cmdline(k9xr);
  1585.         'R':cline:=cmdline(zcrashr);
  1586.         'P':cline:=cmdline(zpcpr);
  1587.         'E':cline:=cmdline(lynxcrashr);
  1588.         'W':cline:=cmdline(wxmodemr);
  1589.       end;
  1590.       case proto of
  1591.         'Z':switchz:=' port '+commst+' speed '+baudst+' rz '+dir;
  1592.         'J':switchz:=' p'+commst+' s'+baudst+' rjb f '+dir;
  1593.         'L':switchz:=' R /'+commst+' /'+baudst+' '+dir;
  1594.         'G':switchz:=' port '+commst+' speed '+baudst+' rb -g '+dir;
  1595.         'S':switchz:=' p'+commst+' s'+baudst+' rsb f '+dir;
  1596.         'K':switchz:=' p'+commst+' s'+baudst+' rkb f '+dir;
  1597.         'P':switchz:=' port '+commst+' speed '+baudst+' rz -w '+dir;
  1598.         'Y':switchz:=' port '+commst+' speed '+baudst+' rb '+dir;
  1599.         'W':switchz:=' p'+commst+' s'+baudst+' rw f '+dir;
  1600.         'X':switchz:=' p'+commst+' s'+baudst+' rcb '+dir;
  1601.     end;
  1602.     write (^B);
  1603.     if (proto='Z') or (proto='G') or (proto='O') or (proto='1') or (proto='R')
  1604.     or (proto='P') then
  1605.     begin
  1606.      if (not exist (forumdir+'\DSZ.COM')) and (not exist (forumdir+'\DSZ.EXE'))
  1607.      then begin
  1608.       writeln;
  1609.       writeln (^G^R'DSZ Protocols are not available at the moment!');
  1610.       writeln ('Sysop does not have DSZ.COM or DSZ.EXE in the TCS directory.');
  1611.       writeln ('Please notify him!');
  1612.       writeln;
  1613.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  1614.       chdir (dirsave);
  1615.       exit;
  1616.      end;
  1617.     end;
  1618.     if (proto='J') then begin
  1619.      if not exist (forumdir+'\JMODEM.COM') then
  1620.      begin
  1621.       writeln;
  1622.       writeln (^G^R'Jmodem Protocol is not available at the moment!');
  1623.       writeln ('Sysop does not have JMODEM.COM in the TCS directory.');
  1624.       writeln ('Please notify him!');
  1625.       writeln;
  1626.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  1627.       chdir (dirsave);
  1628.       exit;
  1629.      end;
  1630.     end;
  1631.     if (proto='L') or (proto='E') then begin
  1632.      if not exist (forumdir+'\LYNX.EXE') then
  1633.      begin
  1634.       writeln;
  1635.       writeln (^G^R'Lynx Protocols is not available at the moment!');
  1636.       writeln ('Sysop does not have LYNX.EXE in the TCS directory.');
  1637.       writeln ('Please notify him!');
  1638.       writeln;
  1639.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  1640.       chdir (dirsave);
  1641.       exit;
  1642.      end;
  1643.     end;
  1644.     if (proto='K') or (proto='S') or (proto='W') or (proto='X') then begin
  1645.      if not exist (forumdir+'\SUPERK.COM') then
  1646.      begin
  1647.       writeln;
  1648.       writeln (^G^R'Super8k/K9Xmodem Protocol is not available at the moment!');
  1649.       writeln ('Sysop does not have SUPERK.COM in the TCS directory.');
  1650.       writeln ('Please notify him!');
  1651.       writeln;
  1652.       writeln (usr,^M'[Changing Directories back to '+dirsave+']');
  1653.       chdir (dirsave);
  1654.       exit;
  1655.       end;
  1656.      end;
  1657.     assign (foofur,dszlog);
  1658.     if exist (dszlog) then erase (foofur);
  1659.     starttimer (numminsxfer);
  1660.     runext (retcd,cline,switchz);
  1661.     stoptimer (numminsxfer);
  1662.     chdir (dirsave);
  1663.     batchupload:=retcd;
  1664.     setparam (usecom,baudrate,parity);
  1665.   end;
  1666.  
  1667.   function checkbatchlogs:char;
  1668.   var f:text;
  1669.       l,sn,code,bytes,xferfile,cps,bps,errors,blocksize,flowstops:anystr;
  1670.       c:string[1];
  1671.       done:boolean;
  1672.       x:integer;
  1673.  
  1674.   function parsespaces (s:anystr):anystr;
  1675.   var p,pee,xy:integer;
  1676.       k,j:char;
  1677.       r:anystr;
  1678.   begin
  1679.    parsespaces:=s;
  1680.    r:=s;
  1681.    repeat
  1682.    p:=pos (' ',r);
  1683.    if p>0 then begin
  1684.     delete (r,p,1);
  1685.    end;
  1686.    until p=0;
  1687.    parsespaces:=r;
  1688.   end;
  1689.  
  1690.   begin
  1691.    checkbatchlogs:=' ';
  1692.    if not exist (dszlog) then begin
  1693.     writeln (^G^G);
  1694.     ansicolor (12);
  1695.     writeln ('*********************************************');
  1696.     writeln ('** DSZLOG Error!! Please notify Sysop NOW! **');
  1697.     writeln ('*********************************************');
  1698.     ansicolor (urec.regularcolor);
  1699.     exit;
  1700.    end;
  1701.    assign (f,dszlog);
  1702.    reset (f);
  1703.    l:='';
  1704.    sn:=''; code:=''; bytes:=''; xferfile:='';
  1705.    cps:=''; bps:=''; errors:=''; blocksize:='';
  1706.    readln (f,l);
  1707.    code:=copy (l,1,1);
  1708.    bytes:=copy (l,2,7);
  1709.    bps:=copy (l,10,6);
  1710.    cps:=copy (l,19,5);
  1711.    errors:=copy (l,28,12);
  1712.    flowstops:=copy (l,40,6);
  1713.    blocksize:=copy (l,45,5);
  1714.    c:='';
  1715.    x:=50;
  1716.    repeat
  1717.     x:=x+1;
  1718.     if c='/' then c:='\';
  1719.     xferfile:=xferfile+c;
  1720.     c:=copy (l,x,1);
  1721.    until c=' ';
  1722.    sn:=copy (l,x+1,10);
  1723.    textclose (f);
  1724.    bps:=parsespaces (bps);
  1725.    cps:=parsespaces (cps);
  1726.    errors:=parsespaces (errors);
  1727.    bytes:=parsespaces (bytes);
  1728.    flowstops:=parsespaces (flowstops);
  1729.    blocksize:=parsespaces (blocksize);
  1730.    xferfile:=parsespaces (xferfile);
  1731.    sn:=parsespaces (sn);
  1732.    checkbatchlogs:=code[1];
  1733.    writeln (^R^B'Code-> '+code+'  Filename: '+xferfile);
  1734.    writeln ('Bytes sent: ',bytes,'  (',cps,' cps at ',bps,' bps)');
  1735.    writeln ('SN#: ',sn,'  Packet Length: ',blocksize,' bytes');
  1736.   end;
  1737.  
  1738.   procedure downbatch;
  1739.   var t:text;
  1740.       x,xferdood,cnt:integer;
  1741.       genesis,pro,thecode:char;
  1742.       mastermind:minuterec;
  1743.       tcs:udrec;
  1744.  
  1745.   begin
  1746.    assign (t,b);
  1747.    if totalxfertime(totalxfersize)>timeleft then begin
  1748.     writeln (^M'You don''t have enough time left!'^M);
  1749.     exit;
  1750.    end;
  1751.    if (totalxfertime(totalxfersize)-5>timetillevent) then begin
  1752.     writeln (^M'Sorry, the timed event is coming up to soon to do the xfer!'^M);
  1753.     exit;
  1754.    end;
  1755.    ansicls;
  1756.    if exist (b) then reset (t) else rewrite (t);
  1757.    for x:=1 to numbatches do
  1758.    begin
  1759.     writeln (t,bbuffer[x].fn);
  1760.     writeln (^R'Processing -> '^S,bbuffer[x].fn,^R);
  1761.    end;
  1762.    textclose (t);
  1763.    writeln;
  1764.    writeln (^S'        - Batch Protocols -'^R);
  1765.    writeln (^R' ['^S'Z'^R']-Zmodem            ['^S'Y'^R']-Ymodem ');
  1766.    writeln (^S'*'^R'['^S'G'^R']-Ymodem-G          ['^S'P'^R']-PCPursuit Zmodem');
  1767.  { writeln (^R' ['^S'J'^R']-Jmodem            ['^S'L'^R']-Lynx');
  1768.    writeln (^R' ['^S'S'^R']-Super8k           ['^S'K'^R']-K9Xmodem');
  1769.    writeln (^R' ['^S'W'^R']-Wxmodem           ['^S'X'^R']-Xmodem-CRC'); }
  1770.    writeln (^R' ['^S'Q'^R']-Quit/Abort');
  1771.    writeln (^S' * = '^R'Registered DSZ required');
  1772.    writeln;
  1773.    writestr ('Protocol: &');
  1774.    if length(input)=0 then exit;
  1775.    genesis:=upcase(input[1]);
  1776.    case genesis of
  1777.     'Y':pro:='Y';
  1778.     'Z':pro:='Z';
  1779.   { 'J':pro:='J';
  1780.     'L':pro:='L';
  1781.     'S':pro:='S'; }
  1782.     'G':pro:='G';
  1783.   { 'K':pro:='K'; }
  1784.     'P':pro:='P';
  1785.   { 'W':pro:='W'; }
  1786.     'X':pro:='X';
  1787.     'Q':pro:='N';
  1788.    end;
  1789.    if pro='N' then exit;
  1790.    write (^B^M);
  1791.    listbatch;
  1792.    if ascii then write ('■') else write ('*');
  1793.    writeln (' Batch Send Ready.');
  1794.    if tempsysop then begin
  1795.      ulvl:=regularlevel;
  1796.      tempsysop:=false;
  1797.      writeurec;
  1798.      bottomline
  1799.     end;
  1800.     {}{}{}
  1801.     if pro<>'N' then begin
  1802.      starttimer (mastermind);
  1803.      xferdood:=batchdownload (pro,b,baudrate,usecom);
  1804.      if xferdood<>0 then xferdood:=2;
  1805.      modeminlock:=false;
  1806.      beepbeep (xferdood);
  1807.      stoptimer (mastermind);
  1808.     end;
  1809.     thecode:=checkbatchlogs;
  1810.   { if (leechzmodem) and ((xferdood=1) or (xferdood=0)) then
  1811.     possiblelzm (totalxferpoints); }
  1812.     if (xferdood=0) or (xferdood=1) then begin
  1813.      for cnt:=1 to numbatches do
  1814.      begin
  1815.       seekudfile (bbuffer[cnt].num);
  1816.       read (udfile,tcs);
  1817.       tcs.downloaded:=tcs.downloaded+1;
  1818.       seekudfile (bbuffer[cnt].num);
  1819.       write (udfile,tcs);
  1820.       urec.udpoints:=urec.udpoints-bbuffer[cnt].points;
  1821.      end;
  1822.      urec.downloads:=urec.downloads+numbatches;
  1823.      urec.downk:=urec.downk+totalxfersize;
  1824.    { urec.timetoday:=urec.timetoday-elapsedtime(mastermind); }
  1825.      writeurec;
  1826.      settimeleft (urec.timetoday);
  1827.     end;
  1828.     {}{}{}
  1829.   end;
  1830.  
  1831.   procedure upbatch;
  1832.   begin
  1833.  
  1834.   end;
  1835.  
  1836.   procedure clearbatch;
  1837.   var x:integer;
  1838.       kaos:text;
  1839.   begin
  1840.    writestr ('Clear Batch Download Buffer [y/n]? *');
  1841.    if yes then begin
  1842.    totalxfersize:=0;
  1843.    totalxferpoints:=0;
  1844.    assign (kaos,b);
  1845.    for x:=1 to maxb do begin
  1846.     bbuffer[x].num:=-1;
  1847.     bbuffer[x].fn:='';
  1848.     bbuffer[x].path:='';
  1849.     bbuffer[x].descrip:='';
  1850.     bbuffer[x].dlpw:='';
  1851.     bbuffer[x].extdesc:='';
  1852.     bbuffer[x].points:=0;
  1853.     bbuffer[x].filesize:=0;
  1854.     bbuffer[x].downloaded:=0;
  1855.     bbuffer[x].sent:=false;
  1856.    end;
  1857.    if exist (b) then erase (kaos);
  1858.   end;
  1859.   end;
  1860.  
  1861.   procedure batchmenu;
  1862.   var i:integer;
  1863.   begin
  1864.    {}{}{}{}{}{
  1865.    BETA!!!!!!!!!!!!!!!!!!!!!!
  1866.    }{
  1867.    EXIT;
  1868.    }{}{}{}{}{}{
  1869.    BETA!!!!!!!!!!!!!!!!!!!!!!
  1870.    }
  1871.    ansicls;
  1872.    b:=forumdir+'Xferlist.TCS';
  1873.    writehdr ('Batch Xfer Menu');
  1874.    writeln (^R'Have filled '^S,numbatches,^R' spots in the Batch Buffer so far.');
  1875.    writeln (^R'Type '^S'[L]'^R' to list the Buffer.');
  1876.    repeat
  1877.       i:=menu('Batch Xfer Menu','BATCH','DULCQ');
  1878.       case i of
  1879.        1:downbatch;
  1880.        2:upbatch;
  1881.        3:listbatch;
  1882.        4:clearbatch;
  1883.       end
  1884.     until hungupon or (i=5)
  1885.   end;
  1886.  
  1887. end.
  1888.