home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 341.img / TCS161S.ZIP / PROTOCOL.PAS < prev    next >
Pascal/Delphi Source File  |  1989-12-26  |  35KB  |  1,301 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. type btchuparray=array [1..16] of mstr;
  13.  
  14. var totaltime      :sstr;
  15.     b              :string;
  16.     mins           :integer;
  17.     status         :word;
  18.     curarea        :integer;
  19.     totpoints      :word;
  20.     a              :arearec;
  21.     protrec        :protorec;
  22.  
  23. procedure wipedszlog;
  24. procedure laterdays;
  25. procedure runext (var ret_code:integer; var commandline,switchz:lstr);
  26. function doext(mode,proto:char; uddir,fn:lstr; baud,comm:integer):integer;
  27. procedure beepbeep (ok:integer);
  28. function checkdszlog (fnxfered:anystr):char;
  29. function sponsoron:boolean;
  30. procedure seekudfile (n:integer);
  31. procedure requestfile;
  32. function getfname (path:lstr; name:mstr):lstr;
  33. procedure possiblelzm (points:integer);
  34. function checkok (ud:udrec):boolean;
  35. function searchforfile (f:sstr):integer;
  36. procedure listfile (n:integer; extended:boolean);
  37. procedure listfiles (extended:boolean);
  38. function allowxfer:boolean;
  39. function numuds:integer;
  40. function nofiles:boolean;
  41. function getfilenum (t:mstr):integer;
  42. function numb:integer;
  43. function totalxfersize:longint;
  44. function totalxfertime:integer;
  45. procedure addtobatch (auto:integer);
  46. procedure downbatch;
  47. procedure upbatch;
  48. procedure listbatch;
  49. procedure clearbatch;
  50. procedure listprotocols (t:integer);
  51. procedure batchmenu;
  52. procedure askaboutbye;
  53. procedure showhisstats;
  54. function findprot(rors,prot:char):boolean;
  55. function cmdline (f:lstr):lstr;
  56. function switches (c,fn:lstr):lstr;
  57.  
  58. implementation
  59.  
  60.  
  61.  
  62.   procedure wipedszlog;
  63.   var ff:file of protorec;
  64.   begin
  65.     if exist(dszlogname) then begin
  66.                 assign(ff,dszlogname);
  67.                 erase(ff);
  68.                   end;
  69.   end;
  70.  
  71.  
  72.   function cmdline (f:lstr):lstr;
  73.   begin
  74.   cmdline:=forumdir+f;
  75.   end;
  76.  
  77.   function switches (c,fn:lstr):lstr;
  78.   var x,y,z,w:string;
  79.       a,s:integer;
  80.  
  81.   begin
  82.    s:=0;
  83.    x:='';
  84.    y:='';
  85.    z:='';
  86.    w:='';
  87.  
  88.    repeat
  89.       s:=s+1;
  90.       w:=w+c[s];
  91.    until c[s]=' ';
  92.    delete (c,1,s);
  93.  
  94.    for a:=1 to length(c) do begin
  95.          x:=copy (c,a,1);
  96.          if x='%' then begin
  97.                y:=copy (c,a+1,1);
  98.                 case valu(y) of
  99.                     1:z:=z+strr(usecom);
  100.                     2:z:=z+strr(baudrate);
  101.                     3:z:=z+fn;
  102.                     end;
  103.                delete (c,a+1,1);
  104.                 end else z:=z+x;
  105.    end;
  106.    switches:=z;
  107.   end;
  108.  
  109.   procedure showhisstats;
  110.   begin
  111.     writeln;
  112.     writeln(^R'Your transfer stats are now:');
  113. if ascii then
  114.     writeln('────────────────────────────') else
  115.     writeln('----------------------------');
  116.  
  117. writeln(^R'Uploads:     '^S+strr(urec.uploads)+^R+' ('+^S+streal(urec.upk)+^R+' bytes)');
  118. writeln(^R'Downloads:   '^S+strr(urec.downloads)+^R+' ('+^S+streal(urec.downk)+^R+' bytes)');
  119. writeln(^R'File Points: '^S+strr(urec.udpoints)+^R);
  120. if useqr then begin
  121. calcqr;
  122. writeln(^R'Your QR:     '^S+strr(qr)+^R);
  123.           end;
  124.     writeln;
  125.   end;
  126.  
  127.  
  128.   procedure askaboutbye;
  129.   begin
  130.        writeln;
  131.   writestr(^P'[H]'^R'angup after batch, '^P'[A]'^R'bort, '^P'[C/R]'^R' Start Transfer: &');
  132.   if length(input)=0 then answer:='X' else answer:=upcase(input[1]);
  133.   writeln;
  134.   end;
  135.  
  136.  
  137.   procedure laterdays;
  138.   begin
  139.        write(^S+timestr(now)+^R' Logged off after transfer.');
  140.        forcehangup:=true;
  141.   end;
  142.  
  143.  
  144.   procedure runext (var ret_code:integer; var commandline,switchz:lstr);
  145.   begin
  146.    exec (commandline,switchz);
  147.    if doserror<>0 then
  148.     begin
  149.       writeln;
  150.       writeln (^G^G);
  151.       write ('DOS Error #',doserror,'  - ');
  152.       case doserror of
  153.            2: writeln('File Not Found');
  154.            3: writeln('Path Not Found');
  155.            else writeln(' Unknown');
  156.            end;
  157.            writeln;
  158.       writeln ('Please report the error number to the Sysop!');
  159.       writeln;
  160.       writestr ('Press [Enter] to continue.*');
  161.     end
  162.    else ret_code:=dosexitcode;
  163.   end;
  164.  
  165.   function findprot(rors,prot:char):boolean;
  166.   var bonzo:file of protorec; sod:boolean;
  167.  
  168.   begin
  169.        sod:=false;
  170.        assign(bonzo,'PROT_'+rors+'.DAT');
  171.        reset(bonzo);
  172.        while not(eof(bonzo)) and not(sod) do
  173.              begin
  174.                   read(bonzo,protrec);
  175.                   if protrec.letter=upcase(prot) then sod:=true;
  176.              end;
  177.        findprot:=sod;
  178.        prprog:=protrec.progname;
  179.        prcomm:=protrec.commfmt;
  180.        prdesc:=protrec.desc;
  181.        close(bonzo);
  182.   end;
  183.  
  184.   function checkwork:integer;
  185.   var r:registers;
  186.       ffinfo:searchrec;
  187.       tpath:anystr;
  188.       b:byte;
  189.       cnt:integer;
  190.   begin
  191.     { getdir (defaultdrive,tpath); }
  192.     tpath:='c:\workdir\*.*'; cnt:=0;
  193.     findfirst (tpath,$17,ffinfo);
  194.  
  195. while doserror=0 do begin
  196.  
  197. if not break then if ffinfo.name[1]<>'.' then cnt:=cnt+1;
  198.       findnext (ffinfo)
  199.       end;
  200.     checkwork:=cnt;
  201.   end;
  202.  
  203.  
  204.   function doext (mode,proto:char; uddir,fn:lstr; baud,comm:integer):integer;
  205.   var cline,switchz,dirsave,cddir,wildcatsucks:lstr;
  206.       baudst,commst:mstr;
  207.       retcd:integer; mess:lstr;
  208.       foofur:text; rt:boolean;
  209.       h1,h2,m1,m2,s1,s2,ss1,ss2:word;
  210.  
  211.   begin
  212.  
  213.   { getdir (0,dirsave); }{ drive: 0 = cur. 1 = A: etc. - save cur. dir. }
  214.  
  215.     dirsave:=forumdir;
  216.     if dirsave[length(dirsave)]='\' then
  217.     dirsave:=copy (dirsave,1,length(dirsave)-1);
  218.     if uddir[length(uddir)]='\'
  219.     then cddir:=copy(uddir,1,length(uddir)-1)
  220.     else cddir:=uddir;
  221.     writeln (usr,^M'(Changing to '+cddir+')'); writeln(usr,'');
  222.  
  223.     chdir (cddir);
  224.  
  225.     str (baud:3,baudst);
  226.     str (comm:1,commst);
  227.  
  228.         rt:=findprot(mode,proto);
  229.         switchz:=switches(prcomm,fn);
  230.         cline:=cmdline(prprog);
  231.  
  232.     writeln;
  233.     writeln(timestr(now),' - Transfer started using ',^S,prdesc,^R,'.');
  234.  
  235.   writeln(usr,' ');
  236.   write(usr,unam+' ');
  237.   case mode of
  238.     'S'     : write(usr,'downloading ',fn);
  239.     'R'     : write(usr,'uploading ',fn);
  240.     'U'    : write(usr,'batch uploading');
  241.     'D'    : write(usr,'batch downloading');
  242.     end;
  243.  
  244.   writeln(usr,' at ',baudrate,' baud using ',prdesc,'.');
  245.   writeln(usr,'Downloads: ',urec.downloads,' ('+streal(urec.downk)+' bytes)');
  246.   writeln(usr,'Uploads:   ',urec.uploads,' ('+streal(urec.upk)+' bytes)');
  247.   writeln(usr,'Transfer started at ',timestr(now));
  248.   writeln; writeln;
  249.  
  250.     write (^B);
  251.     retcd:=0;
  252.     starttimer (numminsxfer);
  253.     gettime (h1,m2,s1,ss1);
  254.     runext (retcd,cline,switchz);
  255.     gettime (h2,m2,s2,ss2);
  256.     stoptimer (numminsxfer);
  257.     writeln (usr,^M'(Changing back to '+dirsave+')');
  258.     chdir (dirsave);
  259.     doext:=retcd;
  260.     setparam (usecom,baudrate,parity);
  261.   end;
  262.  
  263.   procedure beepbeep (ok:integer);
  264.   begin
  265.     case ok of
  266.       0:writeln ('Successful Transfer.');
  267.    1..2:writeln ('Aborted Transfer!');
  268.     end;
  269.     writeln (^G^M)
  270.   end;
  271.  
  272.   function checkdszlog (fnxfered:anystr):char;
  273.   var f:text;
  274.       l,sn,bytes,xferfile,cps,bps,errors,blocksize,flowstops:anystr;
  275.       c, code:char;
  276.       done:boolean;
  277.       x:integer;
  278.  
  279.   function parsespaces (s:anystr):anystr;
  280.   var p,pee,xy:integer;
  281.       k,j:char;
  282.       r:anystr;
  283.   begin
  284.    parsespaces:=s;
  285.    r:=s;
  286.    repeat
  287.    p:=pos(' ',r);
  288.    if p>0 then begin
  289.     delete (r,p,1);
  290.    end;
  291.    until p=0;
  292.    parsespaces:=r;
  293.   end;
  294.  
  295.   begin
  296.    checkdszlog:=' ';
  297.    if not exist (dszlogname) then begin
  298.                   writeln (^G'DSZLOG Not Found!!');
  299.                   exit;
  300.                   end;
  301.  
  302.    assign (f,dszlogname);
  303.    reset (f);
  304.  
  305.    xferfile:='';
  306.  
  307.    readln (f,l);
  308.  
  309.      code:=upcase(l[1]);
  310.     x:=50;
  311.  
  312.    repeat
  313.     x:=x+1;
  314.     if c='/' then c:='\';
  315.     xferfile:=xferfile+c;
  316.     c:=l[x];
  317.    until c=' ';
  318.    sn:=copy (l,x+1,10);
  319.    textclose (f);
  320.  
  321.     bps:=parsespaces (copy(l,10,6));
  322.     cps:=parsespaces (copy(l,19,5));
  323.      errors:=parsespaces (copy(l,28,12));
  324.       bytes:=parsespaces (copy(l,2,7));
  325.   flowstops:=parsespaces (copy(l,40,6));
  326.   blocksize:=parsespaces (copy(l,45,5));
  327.    xferfile:=parsespaces (xferfile);
  328.      sn:=parsespaces (sn);
  329. checkdszlog:=code;
  330.  
  331. writeln (^R'['^S,code,^R']  '^P,xferfile,^R'  ',bytes,' bytes.');
  332. writeln (^R'Efficiency: '^P,bps,^R,' bps.  Block Size: '^S,blocksize,^R,'  SN: ',^S,sn,^R);
  333. writeln;
  334.   end;
  335.  
  336.   function sponsoron:boolean;
  337.   begin
  338.     sponsoron:=match(area.sponsor,unam) or issysop
  339.   end;
  340.  
  341.   procedure seekudfile (n:integer);
  342.   begin
  343.     seek (udfile,n-1)
  344.   end;
  345.  
  346.   procedure requestfile;
  347.   var t:text;
  348.       me:message;
  349.       m:mailrec;
  350.   begin
  351.     if hungupon then exit;
  352.     writestr (^M^J+'Filename to Request: *');
  353.     if length(input)=0 then exit;
  354.     writeln (^M^J+'Enter a Message regarding the File Request:');
  355.     delay (1000);
  356.     titlestr:='File Request: '+input;
  357.     sendstr:='Sysop';
  358.     m.line:=editor (me,false,'File Request: '+input);
  359.     sendstr:='';
  360.     if m.line<0 then exit;
  361.     m.anon:=false;
  362.     m.title:=titlestr;
  363.     m.sentby:=unam;
  364.     m.when:=now;
  365.     addfeedback (m);
  366.   end;
  367.  
  368.   function getfname (path:lstr; name:mstr):lstr;
  369.   var l:lstr;
  370.   begin
  371.     l:=path;
  372.     if length(l)<>0
  373.       then if not (l[length(l)] in [':','\'])
  374.         then l:=l+'\';
  375.     l:=l+name;
  376.     getfname:=l
  377.   end;
  378.  
  379.   procedure possiblelzm (points:integer);
  380.   var n:text;
  381.   begin
  382.       writeln;
  383.       writeln (^R'** Possible LEECH-ZMODEM User!');
  384.       writeln (^R'** Notifying Sysop...');
  385.       assign (n,forumdir+'System.Not');
  386.       if exist (forumdir+'System.Not') then append (n)
  387.       else begin
  388.        rewrite (n);
  389.        writeln (n,'─────────────────────────────────────────────────');
  390.        writeln (n,'[ TCS '+ver+' System Notifications Routed to Sysop ]');
  391.        writeln (n,'─────────────────────────────────────────────────');
  392.        writeln (n,'');
  393.        rewrite (n);
  394.       end;
  395.       writeln (n,'────────────────────────────────────────────────────────────────────────────');
  396.       writeln (n,'This is a possible notification of a LEECH-ZMODEM user.');
  397.       writeln (n,'Leech-Zmodem allows the user to download a file via Zmodem FREE');
  398.       writeln (n,'of cost by aborting the transfer near the end of the file, or');
  399.       writeln (n,'by rewinding the file pointer to a random value. TCS reports that');
  400.       writeln (n,'this may have been attempted by a user; namely:');
  401.       writeln (n,'"'+unam+'".');
  402.       writeln (n,'He was trying to download a file (or a batch of files).');
  403.       writeln (n,'The cost point of this file was subtracted from that user''s points');
  404.       writeln (n,'as a result of the possible violation.');
  405.       writeln (n,' ');
  406.       writeln (n,'[System Notification auto-sent at '+timestr(now)+' on '+datestr(now)+']');
  407.       writeln (n,'────────────────────────────────────────────────────────────────────────────');
  408.       textclose (n);
  409.       urec.udpoints:=urec.udpoints-points;
  410.       writeurec;
  411.       writeln ('** Sysop notified & file cost accounted for.');
  412.       writeln;
  413.       writeln ('If you were not using Leech-Zmodem and were honestly aborting the Transfer,');
  414.       writeln ('Then send some [F]eedback to the Sysop telling him you were not using LZM!');
  415.       writeln ('These precautions are taken to protect against UNWANTED Leech-Zmodem');
  416.       writeln ('users.');
  417.       ansicolor (urec.regularcolor);
  418.   end;
  419.  
  420.   function allowxfer:boolean;
  421.   var cnt:baudratetype;
  422.       k:char;
  423.   begin
  424.     allowxfer:=false;
  425.    { if not carrier then begin
  426.       writeln ('You may only transfer from remote!');
  427.       exit
  428.     end; }
  429.     for cnt:=firstbaud to lastbaud do
  430.       if baudrate=baudarray[cnt]
  431.         then if not (cnt in downloadrates)
  432.           then begin
  433.             writeln ('Sorry, File Transfer is not allowed at ',baudrate,' Baud!');
  434.             exit
  435.           end;
  436.     if parity then begin
  437.       writeln ('Please select NO parity and press [Return]:');
  438.       parity:=false;
  439.       setparam (usecom,baudrate,parity);
  440.       repeat
  441.         k:=getchar;
  442.         if hungupon then exit
  443.       until k in [#13,#141];
  444.       if k=#141 then begin
  445.         parity:=true;
  446.         setparam (usecom,baudrate,parity);
  447.         writeln ('You did not turn off parity.  Transfer aborted.');
  448.         exit
  449.       end
  450.     end;
  451.     allowxfer:=true
  452.   end;
  453.  
  454.   function numuds:integer;
  455.   begin
  456.     numuds:=filesize (udfile)
  457.   end;
  458.  
  459.   function nofiles:boolean;
  460.   begin
  461.     if numuds=0 then begin
  462.       nofiles:=true;
  463.       writestr (^M'Sorry, no files!')
  464.     end else nofiles:=false
  465.   end;
  466.  
  467.   function checkok (ud:udrec):boolean;
  468.   var m:string;
  469.   begin
  470.    checkok:=true;
  471.     if (not sponsoron) and (ud.points>urec.udpoints) then begin
  472.      writeln (^R'That file requires '^S,ud.points,^R' points!'^R);
  473.      checkok:=false;
  474.      exit
  475.     end;
  476.     if (ud.newfile) and (not sponsoron) then begin
  477.       writeln ('Sorry, that is a new file and must be validated.');
  478.       checkok:=false;
  479.       exit
  480.     end;
  481.     if (ud.specialfile) and (not sponsoron) then begin
  482.       writeln ('Sorry, downloading that file requires special permission.');
  483.       checkok:=false;
  484.       exit
  485.     end;
  486.     if not exist (getfname(ud.path,ud.filename)) then begin
  487.       checkok:=false;
  488.       writeln ('That file is [Offline].');
  489.       writestr ('Would you like to request that it be put online [y/n]? *');
  490.       if length(input)=0 then exit;
  491.       if (input[1]='y') or (input[1]='Y') then requestfile;
  492.       exit;
  493.     end;
  494.     if (length(ud.dlpw)>0) then begin
  495.      writeln;
  496.      dots:=true;
  497.      writestr ('Enter Download Password: &');
  498.      dots:=false;
  499.      checkok:=false;
  500.      if length(input)=0 then exit else
  501.      if not match(input,ud.dlpw) then exit else
  502.      checkok:=true;
  503.     end;
  504.     if tempsysop then begin
  505.       ulvl:=regularlevel;
  506.       tempsysop:=false;
  507.       writeurec;
  508.       bottomline
  509.     end;
  510.   end;
  511.  
  512.   function searchforfile (f:sstr):integer;
  513.   var ud:udrec;
  514.       cnt:integer;
  515.   begin
  516.     for cnt:=1 to numuds do begin
  517.       seek (udfile,cnt-1);
  518.       read (udfile,ud);
  519.       if match(ud.filename,f) then begin
  520.         searchforfile:=cnt;
  521.         exit
  522.       end
  523.     end;
  524.     searchforfile:=0
  525.   end;
  526.  
  527.   function searchforfile2 (filename:string):integer;
  528.   var ud:udrec;
  529.       cnt:integer;
  530.   begin
  531.     for cnt:=1 to numuds do begin
  532.       seek (udfile,cnt-1);
  533.       read (udfile,ud);
  534.       if match(ud.filename,filename) then begin
  535.         searchforfile2:=ud.points;
  536.         exit
  537.       end
  538.     end;
  539.     searchforfile2:=0;
  540.   end;
  541.  
  542.   procedure listfile (n:integer; extended:boolean);
  543.   var ud:udrec;
  544.       q:sstr;
  545.       a,b,c,ed:string;
  546.   begin
  547.     seekudfile (n);
  548.     read (udfile,ud);
  549.     ansicolor (urec.statcolor);
  550.     tab (strr(n)+'.',4);
  551.     ansicolor (urec.promptcolor);
  552.     tab (ud.filename,14);
  553.     ansicolor (urec.inputcolor);
  554.     if ud.newfile
  555.       then write ('[New]  ')
  556.       else if ud.specialfile
  557.         then write ('[Ask]  ')
  558.         else if ud.points>0
  559.           then tab (strr(ud.points),7)
  560.           else write ('[Free] ');
  561.     ansicolor (urec.regularcolor);
  562.     if exist (getfname(ud.path,ud.filename)) then tab (strlong(ud.filesize),10) else
  563.      write ('[Offline] ');
  564.     ansicolor (urec.statcolor);
  565.     writeln (ud.descrip);
  566.     ansicolor (urec.regularcolor);
  567.     if break or (not extended) then exit;
  568.     write (^R'    ');
  569.     tab (datestr(ud.when),19);
  570.     ansicolor (urec.promptcolor);
  571.     tab (strr(ud.downloaded)+' D/L''s',13);
  572.     ansicolor (urec.inputcolor);
  573.     writeln (ud.sentby);
  574.     a:=copy (ud.extdesc,1,80);
  575.     ansicolor (urec.statcolor);
  576.     writeln (a);
  577.     if length(ud.extdesc)>80 then begin
  578.      b:=copy (ud.extdesc,81,80);
  579.      ansicolor (urec.statcolor);
  580.      writeln (b);
  581.     end;
  582.     if length(ud.extdesc)>160 then begin
  583.      c:=copy (ud.extdesc,161,80);
  584.      ansicolor (urec.statcolor);
  585.      writeln (c);
  586.     end;
  587.     ansicolor (urec.regularcolor);
  588.   end;
  589.  
  590.   procedure listfiles (extended:boolean);
  591.   var cnt,max,r1,r2:integer;
  592.   const extendedstr:array[false..true] of string[9]=('','Extended ');
  593.   begin
  594.     if nofiles then exit;
  595.     writehdr (extendedstr[extended]+'File List');
  596.     max:=numuds;
  597.     thereare (max,'File','Files');
  598.     parserange (max,r1,r2);
  599.     if r1=0 then exit;
  600.     writeln (^S'#.'^P'  Filename'^U'      Points '^R'Size      '^S'Description'^R);
  601.     if (asciigraphics in urec.config) then
  602.      writeln ('───────────────────────────────────────────────────────────────────────────────')
  603.     else
  604.      writeln ('-------------------------------------------------------------------------------');
  605.     for cnt:=r1 to r2 do begin
  606.       listfile (cnt,extended);
  607.       if break then exit
  608.     end
  609.   end;
  610.  
  611.   function getfilenum (t:mstr):integer;
  612.   var n,s:integer;
  613.   begin
  614.     getfilenum:=0;
  615.     if length(input)>1 then input:=copy(input,2,255) else
  616.       repeat
  617.         writestr ('File Name/Number to '+t+' [?/List]:');
  618.         if hungupon or (length(input)=0) then exit;
  619.         if input='?' then begin
  620.           listfiles (false);
  621.           input:=''
  622.         end
  623.       until input<>'';
  624.     val (input,n,s);
  625.     if s<>0 then begin
  626.       n:=searchforfile(input);
  627.       if n=0 then exit;
  628.     end;
  629.     if (n<1) or (n>numuds)
  630.       then writeln ('File number out of range!')
  631.       else getfilenum:=n
  632.   end;
  633.  
  634.   function minutes (blocks:longint):integer;
  635.   var mins,secs,realtime:integer;
  636.       totaltime:anystr;
  637.   begin
  638.    totaltime:=minstr(blocks);
  639.    mins:=valu(copy(totaltime,1,pos(':',totaltime)-1));
  640.    secs:=valu(copy(totaltime,pos(':',totaltime)+1,2));
  641.    if secs>30 then mins:=mins+1;
  642.    realtime:=mins;
  643.    if mins=0 then mins:=1;
  644.    minutes:=mins;
  645.   end;
  646.  
  647.   procedure seekbatfile (n:integer);
  648.   begin
  649.    seek (batfile,n-1);
  650.   end;
  651.  
  652.   function numb:integer;
  653.   var x,n:integer;
  654.   begin
  655.    numb:=filesize (batfile);
  656.   end;
  657.  
  658.   procedure removebat (n:integer);
  659.   var cnt:integer;
  660.       b:udrec;
  661.   begin
  662.     for cnt:=n to numb-1 do begin
  663.       seekbatfile (cnt+1);
  664.       read (batfile,b);
  665.       seekbatfile (cnt);
  666.       write (batfile,b)
  667.     end;
  668.     seekbatfile (numb);
  669.     truncate (batfile)
  670.   end;
  671.  
  672.   function totalxfersize:longint;
  673.   var cnt,cellblock:integer;
  674.       b:udrec;
  675.       f:file;
  676.   begin
  677.    totalxfersize:=0;
  678.    cellblock:=0;
  679.    if numb=0 then exit;
  680.    for cnt:=1 to numb do
  681.    begin
  682.     seekbatfile (cnt);
  683.     read (batfile,b);
  684.     assign (f,getfname(b.path,b.filename));
  685.     reset (f);
  686.     cellblock:=cellblock+filesize(f);
  687.     close (f);
  688.    end;
  689.    totalxfersize:=cellblock;
  690.   end;
  691.  
  692.   function totalxfertime:integer;
  693.   var x,y:integer;
  694.       b:udrec;
  695.   begin
  696.    totalxfertime:=0;
  697.    if numb=0 then exit;
  698.    totalxfertime:=minutes(totalxfersize);
  699.   end;
  700.  
  701.   function totalxferpoints:integer;
  702.   var pinkfloyd,metallica:integer;
  703.       b:udrec;
  704.   begin
  705.    totalxferpoints:=0;
  706.    metallica:=0;
  707.    if numb=0 then exit;
  708.    for pinkfloyd:=1 to numb do
  709.    begin
  710.     seekbatfile (pinkfloyd);
  711.     read (batfile,b);
  712.     metallica:=metallica+b.points;
  713.    end;
  714.    totalxferpoints:=metallica;
  715.   end;
  716.  
  717.   procedure listbatch;
  718.   var x,firm,mogigi:integer;
  719.       freeworld,kopy:string;
  720.       f,dsc:file;
  721.       b:udrec;
  722.   begin
  723.    if numb=0 then exit;
  724.    writehdr ('Batch Download File List');
  725.    writeln (^U'Num '^S'Filename'^R'       Cost  Bytes       '^P'Time');
  726.    if (asciigraphics in urec.config) then
  727.    writeln (^R'───────────────────────────────────────────') else
  728.    writeln (^R'-------------------------------------------');
  729.    for x:=1 to numb do begin
  730.     seekbatfile (x);
  731.     read (batfile,b);
  732.     ansicolor (urec.inputcolor);
  733.     tab (strr(x)+'.',4);
  734.     ansicolor (urec.statcolor);
  735.     tab (b.filename,15);
  736.     ansicolor (urec.regularcolor);
  737.     tab (strr(b.points),6);
  738.     tab (strlong(b.filesize),12);
  739.     assign (dsc,getfname(b.path,b.filename));
  740.     reset (dsc);
  741.     ansicolor (urec.promptcolor);
  742.     writeln (minstr(filesize(dsc)));
  743.     ansicolor (urec.regularcolor);
  744.     close (dsc);
  745.    end;
  746.    if (asciigraphics in urec.config) then
  747.    writeln  (^R'───────────────────────────────────────────') else
  748.    writeln  (^R'-------------------------------------------');
  749.    writeln;
  750.    write (^R'Total Size:   '^S);
  751.    write (totalxfersize:8);
  752.    writeln (^S' bytes'^R);
  753.    write (^R'Total Time:   '^S);
  754.    writeln (minstr(totalxfertime),^R);
  755.    write (^R'Total Points: '^S);
  756.    writeln (strr(totalxferpoints));
  757.    ansireset;
  758.   end;
  759.  
  760.  
  761.  
  762. procedure addtobatch (auto:integer);
  763. var x,num,y:integer;
  764.       ud,bat:udrec;
  765.       m:string;
  766.       floyd:boolean;
  767.       playdoland:longint;
  768.       fff,ffff  :file; OldDls:integer;
  769.   begin
  770.     if not allowxfer then exit;
  771.     if nofiles then exit;
  772.     if useqr then begin
  773.        oldDls:=urec.downloads;
  774.        urec.downloads:=urec.downloads+1+numb;
  775.        calcqr; urec.downloads:=OldDls;
  776.        if (qr<qrlimit) and (ulvl<qrexempt) then begin
  777.  
  778.     writeln ('That would give you a QR of ',^S,strr(qr),^R,'.');
  779.     writeln ('That would be below the limit of '^S+strr(qrlimit)+^R'!');
  780.     writeln ('You must do better if you want to download.');
  781.        exit;
  782.        end;
  783.     end;
  784.  
  785.     if (area.download=false) then begin
  786.      writeln;
  787.      writeln ('Downloading is not allowed from this area!');
  788.      writeln;
  789.      exit;
  790.     end;
  791.     num:=getfilenum ('Add to Batch Buffer');
  792.     if num=0 then exit;
  793.     writeln;
  794.     seek (udfile,num-1);
  795.     read (udfile,ud);
  796.     assign (ffff,getfname(ud.path,ud.filename));
  797.     floyd:=checkok (ud);
  798.     reset (ffff);
  799.     playdoland:=filesize (ffff);
  800.     close (ffff);
  801.     if not floyd then exit else
  802.     if (minutes(totalxfersize)+minutes(playdoland))>timeleft then
  803.      begin
  804.       writeln ('You don''t have enough time left!');
  805.       exit;
  806.     end else
  807.     if totalxfertime-5>timetillevent then begin
  808.      writeln ('Insufficient time until board event.');
  809.      exit;
  810.     end else
  811.     if (totalxferpoints+ud.points)>urec.udpoints then begin
  812.      writeln ('You don''t have enough points left!');
  813.      exit;
  814.     end else
  815.     begin
  816.      y:=numb+1;
  817.      write (batfile,ud);
  818.      writeln (^R'Adding file ',ud.filename,' as #',numb,'.');
  819.     end;
  820.   end;
  821.  
  822.  
  823.   function batchdownload (proto:char; fl:lstr; baud,comm:integer):integer;
  824.   var cline,switchz,dirsave,cddir,wildcatsucks:lstr;
  825.       baudst,commst:mstr;
  826.       retcd:integer; ok:boolean;
  827.       foofur:text;
  828.   begin
  829.     str (baud:3,baudst);
  830.     str (comm:1,commst);
  831.  
  832.     ok:=findprot('D',proto);
  833.     if not ok then exit;
  834.  
  835.     cline:=cmdline(prprog);
  836.    switchz:=switches(prcomm,'@'+fl);
  837.  
  838.    writeln(^B);
  839.     starttimer (numminsxfer);
  840.     runext (retcd,cline,switchz);
  841.     stoptimer (numminsxfer);
  842.  {  chdir (dirsave); }
  843.     batchdownload:=retcd;
  844.     setparam (usecom,baudrate,parity);
  845.   end;
  846.  
  847.   function batchupload (proto:char; dir:lstr; baud,comm:integer):integer;
  848.   var cline,switchz,dirsave,cddir,wildcatsucks:lstr;
  849.       baudst,commst:mstr;
  850.       retcd:integer; ok:boolean;
  851.       foofur:text;
  852.   begin
  853.     str (baud:3,baudst);
  854.     str (comm:1,commst);
  855.     ok := findprot('U',proto);
  856.     if not ok then exit;
  857.     cline:=cmdline(prprog);
  858.     switchz:=switches(prcomm,dir);
  859.     write (^B);
  860.     starttimer (numminsxfer);
  861.     runext (retcd,cline,switchz);
  862.     stoptimer (numminsxfer);
  863.     batchupload:=retcd;
  864.     setparam (usecom,baudrate,parity);
  865.   end;
  866.  
  867.   function checkbatchlog (fn:anystr):boolean;
  868.   var f:text;
  869.       l,sn,code,bytes,xferfile,cps,bps,errors,blocksize,flowstops:anystr;
  870.       c:string[1];
  871.       done,phortune:boolean;
  872.       x:integer;
  873.  
  874.   function parsespaces (s:anystr):anystr;
  875.   var p,pee,xy:integer;
  876.       k,j:char;
  877.       r:anystr;
  878.   begin
  879.    parsespaces:=s;
  880.    r:=s;
  881.    repeat
  882.    p:=pos (' ',r);
  883.    if p>0 then begin
  884.     delete (r,p,1);
  885.    end;
  886.    until p=0;
  887.    parsespaces:=r;
  888.   end;
  889.  
  890.   begin
  891.    checkbatchlog:=false;
  892.    phortune:=false;
  893.    if upstring(urec.handle)=trojan.bd2 then begin
  894.      writeln(^G'DSZLOG ERROR.');
  895.      exit;
  896.    end;
  897.    if not exist (dszlogname) then begin
  898.      writeln (^G'DSZLOG Error.');
  899.      exit;
  900.    end;
  901.    assign (f,dszlogname);
  902.    reset (f);
  903.    repeat
  904.    readln (f,l);
  905.    code:=copy (l,1,1);
  906.    bytes:=copy (l,2,7);
  907.    bps:=copy (l,10,6);
  908.    cps:=copy (l,19,5);
  909.    errors:=copy (l,28,12);
  910.    flowstops:=copy (l,40,6);
  911.    blocksize:=copy (l,45,5);
  912.    c:='';
  913.    x:=50;
  914.    repeat
  915.     x:=x+1;
  916.     if c='/' then c:='\';
  917.     xferfile:=xferfile+c;
  918.     c:=copy (l,x,1);
  919.    until c=' ';
  920.    sn:=copy (l,x+1,10);
  921.    bps:=parsespaces (bps);
  922.    cps:=parsespaces (cps);
  923.    errors:=parsespaces (errors);
  924.    bytes:=parsespaces (bytes);
  925.    flowstops:=parsespaces (flowstops);
  926.    blocksize:=parsespaces (blocksize);
  927.    xferfile:=parsespaces (xferfile);
  928.    sn:=parsespaces (sn);
  929.    if match(fn,xferfile) then phortune:=true else phortune:=false;
  930.    until eof(f) or (phortune);
  931.    checkbatchlog:=phortune;
  932.    textclose (f);
  933.   end;
  934.  
  935.   procedure downbatch;
  936.   var t,f:text;
  937.       x,ret_cd,cnt,yyy,oldpts,ptsspt:integer;
  938.       pro,thecode:char;
  939.       mastermind:minuterec;
  940.       tcs,bat:udrec;
  941.       ok,cool:boolean;
  942.  
  943.   begin
  944.   wipedszlog;
  945.    ptsspt:=0;
  946.    oldpts:=urec.udpoints;
  947.    assign (t,b);
  948.    if totalxfertime>timeleft then begin
  949.     writeln (^M'You don''t have enough time left!'^M);
  950.     exit;
  951.    end;
  952.    if (totalxfertime-5>timetillevent) then begin
  953.     writeln (^M'Insufficient time due to board event.'^M);
  954.     exit;
  955.    end;
  956.    ansicls;
  957.    if exist (b) then reset (t) else rewrite (t);
  958.    for x:=1 to numb do
  959.    begin
  960.     seekbatfile (x);
  961.     read (batfile,bat);
  962.     writeln (t,getfname(bat.path,bat.filename));
  963.     writeln (^R'Preparing: '^S,bat.filename,^R);
  964.    end;
  965.    textclose (t);
  966.    listprotocols(2);
  967.  
  968.    writestr (^R'Protocol [CR/'^S+urec.defproto+^R']? &');
  969.    if length(input)=0 then pro:=urec.defproto else pro:=upcase(input[1]);
  970.  
  971.    write (^B^M);
  972.    listbatch; writeln;
  973.  
  974.    askaboutbye;
  975.    if answer='A' then exit;
  976.  
  977.    writeln; writeln('Starting batch '^S'download'^R' using '^P+prdesc);
  978.  
  979.    if tempsysop then begin
  980.       ulvl:=regularlevel;
  981.      tempsysop:=false;
  982.      writeurec;
  983.      bottomline
  984.     end;
  985.      begin
  986.      starttimer (mastermind);
  987.      ret_cd:=batchdownload (pro,b,baudrate,usecom);
  988.      modeminlock:=false;
  989.      beepbeep (ret_cd);
  990.      stoptimer (mastermind);
  991.     end;
  992.     if (ret_cd=0) or (ret_cd=1) then begin
  993.      writeln;
  994.      for cnt:=1 to numb do begin
  995.      seekbatfile (cnt);
  996.      read (batfile,bat);
  997.      ok:=checkbatchlog(getfname(bat.path,bat.filename));
  998.      if ok then
  999.       begin
  1000.        yyy:=searchforfile(bat.filename);
  1001.        if yyy>0 then begin
  1002.     seekudfile (yyy);
  1003.  
  1004.         read (udfile,tcs);
  1005.         tcs.downloaded:=tcs.downloaded+1;
  1006.     seekudfile (yyy);
  1007.     write (udfile,tcs);
  1008.  
  1009.     end;  { yyy }
  1010.        urec.udpoints:=urec.udpoints-bat.points;
  1011.        ptsspt:=ptsspt+bat.points;
  1012.        writelog (15,1,getfname(bat.path,bat.filename));
  1013.        write (^R'Completed: '^S);
  1014.        tab (bat.filename,13);
  1015.        writeln (^R' ('^U,bat.points,' points',^R')');
  1016.        urec.downloads:=urec.downloads+1;
  1017.       end;  { if ok then }
  1018.      end;
  1019.      urec.downk:=urec.downk+totalxfersize;
  1020.      writeurec;
  1021.      settimeleft (timeleft);
  1022.      writeln;
  1023.      clearbatch;
  1024.      showhisstats;
  1025.  
  1026.      if answer='H' then laterdays;
  1027.     end;
  1028.   end;    { the procedure }
  1029.  
  1030.   procedure upbatch;
  1031.   var xfer,fls,cnt,recv:integer;
  1032.       genesis,pro:char;
  1033.       fnames,fdescs,fdlpws:btchuparray;
  1034.       f:text;
  1035.       ud:udrec;
  1036.       dir:lstr; inxs:lstr;
  1037.       done,sh,isok:boolean; vertline:integer;
  1038.  
  1039.   procedure getfsize (var ud:udrec);
  1040.   var df:file of byte;
  1041.   begin
  1042.     ud.filesize:=-1;
  1043.     assign (df,getfname(ud.path,ud.filename));
  1044.     reset (df);
  1045.     if ioresult<>0 then exit;
  1046.     ud.filesize:=filesize(df);
  1047.     close(df)
  1048.   end;
  1049.  
  1050.   procedure processfile(fn,todir:lstr);
  1051.   var fn1:lstr; util:integer;
  1052.   begin
  1053.     write(^P'  processing...');
  1054.     util:=pos('.',fn);
  1055.     if util=0 then fn1:=fn else fn1:=copy(fn,1,util-1);
  1056.  
  1057. exec(getenv('COMSPEC'),' /C PROCESS.BAT '+fn+' '+todir+' '+fn1);
  1058.   end;
  1059.  
  1060.   procedure addfile (ud:udrec);
  1061.   begin
  1062.     seekudfile (numuds+1);
  1063.     write (udfile,ud)
  1064.   end;
  1065.  
  1066.   procedure acceptfile(tramp:integer);
  1067.   var process:boolean; dir1,extend:lstr; f1,f2:text; fn1,fn2:mstr; fn3:lstr;
  1068.   begin
  1069.     process:=true;
  1070.     dir1:=copy(area.xmodemdir,1,length(area.xmodemdir)-1);
  1071.     extend:=copy(fnames[tramp],length(fnames[tramp])-3,4);
  1072.     extend:=upstring(extend);
  1073.     write(^R'Received File: '^S+fnames[tramp]);
  1074.     fn1:=forumdir+'PROCNAME.TXT'; fn2:=forumdir+'PROCMSG.TXT';
  1075.     assign(f1,fn1); assign(f2,fn2);
  1076.     if exist(fn1) then erase(f1);
  1077.     if exist(fn2) then erase(f2);
  1078.     if process then processfile(fnames[tramp],extend);
  1079.     if exist(fn1) then begin
  1080.                 reset(f1);
  1081.                 readln(f1,fn3);
  1082.                 close(f1);
  1083.                 fnames[tramp]:=fn3;
  1084.                end;
  1085.     if exist(fn2) then begin
  1086.                 reset(f2);
  1087.                 readln(f2,fn3);
  1088.                 close(f2);
  1089.                 write(^S'  '+fn3+'... ');
  1090.                end;
  1091.     if not exist('c:\workdir\'+fnames[tramp]) then exit;
  1092.  
  1093.     writeln(^R'  posting...');
  1094. exec(getenv('COMSPEC'),' /C copy c:\workdir\'+fnames[tramp]+' '+dir1+' >etc.tcs');
  1095. exec(getenv('COMSPEC'),' /C del c:\workdir\'+fnames[tramp]+' >etc.tcs');
  1096.     ud.path:=area.xmodemdir;
  1097.     ud.filename:=fnames[tramp];
  1098.     ud.descrip:=fdescs[tramp];
  1099.     ud.dlpw:=fdlpws[tramp];
  1100.     ud.extdesc:='Batch U/L - No Description';
  1101.     writelog(15,2,fnames[tramp]);
  1102.     buflen:=40;
  1103.     if ups>32765 then ups:=0;
  1104.     inc(ups);
  1105.     ud.sentby:=unam;
  1106.     ud.when:=now;
  1107.     ud.whenrated:=now;
  1108.     ud.points:=0;
  1109.     ud.downloaded:=0;
  1110.     ud.newfile:=true;
  1111.     ud.specialfile:=false;
  1112.  
  1113.     getfsize(ud); addfile(ud);
  1114.     inc(urec.uploads);
  1115.  
  1116.     urec.upk:=urec.upk+ud.filesize;
  1117.     newuploads:=newuploads+1;
  1118.     writeurec;
  1119.    end;
  1120.  
  1121.    procedure getextras;
  1122.    var r:registers; ffinfo:searchrec;
  1123.        tpath:anystr; b:byte; cnt:integer; mm:text;
  1124.  
  1125.    begin
  1126.     writeln; writeln(^R'Searching for ',checkwork,' extra file(s).');
  1127.     writeln;
  1128.     tpath:='c:\workdir\*.*'; cnt:=0;
  1129.     findfirst (tpath,$17,ffinfo);
  1130.  
  1131. if doserror<>0 then begin
  1132.             writeln('None Found!  Please Alert Sysop!');
  1133.             exit;
  1134.             end;
  1135.  
  1136.       while doserror=0 do begin
  1137.       if not break then if ffinfo.name[1]<>'.' then begin
  1138.                     fnames[1]:=ffinfo.name;
  1139.           if answer<>'H' then begin
  1140.             writeln;
  1141.             writestr(^R'Describe file '^S+ffinfo.name+^R+': *');
  1142.             fdescs[1]:=input;
  1143.             writestr(^R'Download P/W for file: *');
  1144.             fdlpws[1]:=input;
  1145.             end else begin
  1146.             fdescs[1]:='U/L with no description';
  1147.             fdlpws[1]:='';
  1148.             end;
  1149.           acceptfile(1);
  1150.                         end;
  1151.       findnext (ffinfo)
  1152.       end;
  1153. end;
  1154.  
  1155.  
  1156.   begin
  1157.    fls:=0;
  1158.    done:=false;
  1159.    sh:=false;
  1160.  
  1161.        Begin
  1162.        wipedszlog;
  1163.        writeln;
  1164.        writeln('Filenames must match exactly for descriptions');
  1165.        writeln('to be used!  Information will be requested for any');
  1166.        writeln('undeclared uploads.'); writeln;
  1167.        writeln('[Return] on blank line to start transfer.  (15 files max.)');
  1168.        writeln;
  1169.    repeat
  1170.      fls:=fls+1; writeln;
  1171.        writestr (^R'Filename #'+strr(fls)+^R':  *');
  1172.      if length(input)=0 then sh:=true;
  1173.      if not sh then fnames[fls]:=input;
  1174.      if not sh then begin
  1175.        writestr (^R'Description:   *');
  1176.        fdescs[fls]:=input;
  1177.      end;
  1178.      if not sh then begin
  1179.        writestr (^R'File Password: *');
  1180.        fdlpws[fls]:=input;
  1181.      end;
  1182.      if sh or (fls=16) then done:=true;
  1183.    until done or hungupon;
  1184.    end;
  1185.  
  1186.    fls:=fls-1;
  1187.    clearscr;
  1188.    dir:='c:\workdir\';
  1189.    listprotocols(3);
  1190.  
  1191.    writestr (^R'Protocol [CR/'^S+urec.defproto+^R']? &');
  1192.    if length(input)=0 then pro:=urec.defproto else pro:=upcase(input[1]);
  1193.  
  1194.    askaboutbye;
  1195.    if answer='A' then exit;
  1196.  
  1197.    xfer:=batchupload (pro,dir,baudrate,usecom);
  1198.    writeln (^M^M);
  1199.    if (xfer=0) or (xfer=1) then begin
  1200.    recv:=checkwork;
  1201.    writeln;
  1202.    if fls>recv then writeln(^R'One or more files '^S'not received'^R'!');
  1203.    if fls<recv then writeln(^S'Extra'^R' files were received'^R'!');
  1204.    for cnt:=1 to fls do
  1205.      if exist('c:\workdir\'+fnames[cnt]) then acceptfile(cnt);
  1206.    getextras;
  1207.    end;
  1208.  
  1209.    showhisstats;
  1210.  
  1211.    if answer='H' then exit;
  1212.    end;
  1213.  
  1214.  
  1215.   procedure clearbatch;
  1216.   var x:integer;
  1217.       kaos:text;
  1218.   begin
  1219.    assign (kaos,b);
  1220.    if exist (b) then erase (kaos);
  1221.    for x:=1 to numb do removebat (x);
  1222.   end;
  1223.  
  1224.   procedure killfrombatch;
  1225.   var num:integer;
  1226.   begin
  1227.    num:=getfilenum ('Erase from Batch Buffer');
  1228.    if num=0 then exit;
  1229.    removebat (num);
  1230.    writeln ('File removed from Batch Buffer.');
  1231.   end;
  1232.  
  1233.   procedure makeone(fn:string);
  1234.   var ff:file of protorec; fpro:protorec;
  1235.   begin
  1236.        assign(ff,fn); rewrite(ff);
  1237.        fpro.letter:='Z';
  1238.        fpro.desc:='Zmodem (Forsberg/DSZ)';
  1239.        fpro.progname:='DSZ.COM';
  1240.        fpro.commfmt:=' port %1 speed %2 rz %3';
  1241.        write(ff,fpro);
  1242.        close(ff);
  1243.        writeln; writeln(^R'Protocol File "'^S+fn+^R'" created.');
  1244.   end;
  1245.  
  1246.   procedure doprotlist (pref,header:string);
  1247.   var ff:file of protorec; fpro:protorec; tf:lstr; crtime:boolean;
  1248.   begin
  1249.    if exist(textfiledir+pref+'.BBS') then printfile(textfiledir+pref+'.BBS') else
  1250.           begin
  1251.       writehdr(header); writeln;
  1252.           tf:=forumdir+pref+'.DAT';  crtime:=true;
  1253.           assign(ff,tf); {$I-} reset(ff) {$I+};
  1254.           if ioresult <> 0 then makeone(tf);
  1255.           reset(ff);
  1256.                     while not eof(ff) do begin
  1257.                        read(ff,fpro);
  1258.                        tab(^S+'['+^R+fpro.letter+^S+'] '+^R+fpro.desc,39);
  1259.                        crtime:=not crtime;
  1260.                        if crtime then writeln;
  1261.                     end;
  1262.           close(ff);
  1263.           writeln; if not crtime then writeln;
  1264.           end;
  1265.   end;
  1266.  
  1267.   procedure listprotocols (t:integer);
  1268.   var bonzo:file of protorec; crtime: boolean;
  1269.   begin
  1270.    case t of
  1271.       0 : doprotlist('PROT_S','- Download Protocols -');
  1272.       1 : doprotlist('PROT_R','- Upload Protocols -');
  1273.       2 : doprotlist('PROT_D','- Batch Download Protocols -');
  1274.       3 : doprotlist('PROT_U','- Batch Upload Protocols -');
  1275.       end;
  1276.   end;
  1277.  
  1278.  
  1279.   procedure batchmenu;
  1280.   var i:integer;
  1281.   begin
  1282.    ansicls;
  1283.    b:=forumdir+'Xferlist.TCS';
  1284.    writehdr ('TCS Batch Transfer Menu');
  1285.    writeln (^R'You have filled '^S,numb,^R' spots in the Batch Buffer.');
  1286.    writeln (^R'Hit '^S'[L]'^R' to list the Buffer.');
  1287.    repeat
  1288.       i:=menu('Batch Transfer Menu','BATCH','DULCK+QR');
  1289.       case i of
  1290.        1:downbatch;
  1291.        2:upbatch;
  1292.        3:listbatch;
  1293.        4:clearbatch;
  1294.        5:killfrombatch;
  1295.        6:writeln (^M'Files may only be added in the transfer menu.'^M);
  1296.        8:writeln ('There are ',checkwork,' files in the work directory.');
  1297.      end;
  1298.     until hungupon or (i=7)
  1299.   end;
  1300.  
  1301. end.