home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 276.img / FORUM21S.ZIP / FILEXFER.PAS < prev    next >
Pascal/Delphi Source File  |  1988-03-27  |  38KB  |  1,515 lines

  1. {$R-,S-,I-,D-,T-,F-,V-,B-,N-,L+ }
  2. {$M 65500,0,0 }
  3.  
  4. unit filexfer;
  5.  
  6. interface
  7.  
  8. uses crt,dos,
  9.      gentypes,configrt,modem,statret,gensubs,subs1,subs2,windows,
  10.      userret,mainr1,mainr2,overret1,protocol;
  11.  
  12. procedure udsection;
  13.  
  14. implementation
  15.  
  16. procedure udsection;
  17.  
  18. var ud:udrec;
  19.     area:arearec;
  20.     curarea:integer;
  21.  
  22.   procedure beepbeep (ok:integer);
  23.   begin
  24.     delay (500);
  25.     write (^B^M);
  26.     case ok of
  27.       0:write ('Done');
  28.       1:write ('Aborted just before EOF');
  29.       2:write ('Aborted')
  30.     end;
  31.     writeln ('!'^G^G^M)
  32.   end;
  33.  
  34.   function unsigned (i:integer):real;
  35.   begin
  36.     if i>=0
  37.       then unsigned:=i
  38.       else unsigned:=65536.0+i
  39.   end;
  40.  
  41.   procedure writefreespace (path:lstr);
  42.   var drive:byte;
  43.       r:registers;
  44.       csize,free,total:real;
  45.   begin
  46.     r.ah:=$36;
  47.     r.dl:=ord(upcase(path[1]))-64;
  48.     intr ($21,r);
  49.     if r.ax=-1 then begin
  50.       writeln ('Invalid drive');
  51.       exit
  52.     end;
  53.     csize:=unsigned(r.ax)*unsigned(r.cx);
  54.     free:=csize*unsigned(r.bx);
  55.     total:=csize*unsigned(r.dx);
  56.     free:=free/1024;
  57.     total:=total/1024;
  58.     writeln (free:0:0,'k out of ',total:0:0,'k')
  59.   end;
  60.  
  61.   procedure seekafile (n:integer);
  62.   begin
  63.     seek (afile,n-1)
  64.   end;
  65.  
  66.   function numareas:integer;
  67.   begin
  68.     numareas:=filesize (afile)
  69.   end;
  70.  
  71.   procedure seekudfile (n:integer);
  72.   begin
  73.     seek (udfile,n-1)
  74.   end;
  75.  
  76.   function numuds:integer;
  77.   begin
  78.     numuds:=filesize (udfile)
  79.   end;
  80.  
  81.   procedure assignud;
  82.   begin
  83.     close (udfile);
  84.     assign (udfile,'AREA'+strr(curarea))
  85.   end;
  86.  
  87.   function sponsoron:boolean;
  88.   begin
  89.     sponsoron:=match(area.sponsor,unam) or issysop
  90.   end;
  91.  
  92.   function getapath:lstr;
  93.   var q,r:integer;
  94.       f:file;
  95.       b:boolean;
  96.       p:lstr;
  97.   begin
  98.     getapath:=area.xmodemdir;
  99.     if ulvl<sysoplevel then exit;
  100.     repeat
  101.       writestr ('Upload path [CR for '+area.xmodemdir+']:');
  102.       if hungupon then exit;
  103.       if length(input)=0 then input:=area.xmodemdir;
  104.       p:=input;
  105.       if input[length(p)]<>'\' then p:=p+'\';
  106.       b:=true;
  107.       assign (f,p+'CON');
  108.       reset (f);
  109.       q:=ioresult;
  110.       close (f);
  111.       r:=ioresult;
  112.       if q<>0 then begin
  113.         writestr ('  Path doesn''t exist!  Create it? *');
  114.         b:=yes;
  115.         if b then begin
  116.           mkdir (copy(p,1,length(p)-1));
  117.           q:=ioresult;
  118.           b:=q=0;
  119.           if b
  120.             then writestr ('Directory created')
  121.             else writestr ('Unable to create directory')
  122.         end
  123.       end
  124.     until b;
  125.     getapath:=p
  126.   end;
  127.  
  128.   function makearea:boolean;
  129.   var num,n:integer;
  130.       a:arearec;
  131.   begin
  132.     makearea:=false;
  133.     num:=numareas+1;
  134.     n:=numareas;
  135.     writestr ('Create area '+strr(num)+' [Y/N]? *');
  136.     if yes then begin
  137.       writestr ('Area name:');
  138.       if length(input)=0 then exit;
  139.       a.name:=input;
  140.       writestr ('Access level:');
  141.       if length(input)=0 then exit;
  142.       a.level:=valu(input);
  143.       writestr ('Sponsor [CR for '+unam+']:');
  144.       if length(input)=0 then input:=unam;
  145.       a.sponsor:=input;
  146.       a.xmodemdir:=getapath;
  147.       seekafile (num);
  148.       write (afile,a);
  149.       area:=a;
  150.       curarea:=num;
  151.       assignud;
  152.       rewrite (udfile);
  153.       writeln ('Area created');
  154.       makearea:=true;
  155.       writelog (15,4,a.name)
  156.     end
  157.   end;
  158.  
  159.   procedure setarea (n:integer);
  160.  
  161.     procedure nosucharea;
  162.     begin
  163.       writeln (^B'No such area: ',n,'!')
  164.     end;
  165.  
  166.   begin
  167.     curarea:=n;
  168.     if (n>numareas) or (n<1) then begin
  169.       nosucharea;
  170.       if issysop
  171.         then if makearea
  172.           then setarea (curarea)
  173.           else setarea (1)
  174.         else setarea (1);
  175.       exit
  176.     end;
  177.     seekafile (n);
  178.     read (afile,area);
  179.     if (urec.udlevel<area.level) and (not issysop)
  180.       then if curarea=1
  181.         then error ('User can''t access first area','','')
  182.         else
  183.           begin
  184.             nosucharea;
  185.             setarea (1);
  186.             exit
  187.           end;
  188.     assignud;
  189.     close (udfile);
  190.     reset (udfile);
  191.     if ioresult<>0 then rewrite (udfile);
  192.     writeln (^B^M'Active: '^S,area.name,' [',curarea,']');
  193.     if sponsoron then writeln ('%: Sponsor commands');
  194.     writeln
  195.   end;
  196.  
  197.   procedure listareas;
  198.   var a:arearec;
  199.       cnt:integer;
  200.   begin
  201.     writehdr ('Area List');
  202.     seekafile (1);
  203.     for cnt:=1 to numareas do begin
  204.       read (afile,a);
  205.       if a.level<=urec.udlevel
  206.         then writeln (cnt:2,'. (',a.level,') ',a.name);
  207.       if break then exit
  208.     end
  209.   end;
  210.  
  211.   function getareanum:integer;
  212.   var areastr:sstr;
  213.       areanum:integer;
  214.   begin
  215.     getareanum:=0;
  216.     if length(input)>1
  217.       then areastr:=copy(input,2,255)
  218.       else
  219.         repeat
  220.           writestr (^M'Area # [?=list]:');
  221.           if input='?' then listareas else areastr:=input
  222.         until (input<>'?') or hungupon;
  223.     if length(areastr)=0 then exit;
  224.     areanum:=valu(areastr);
  225.     if (areanum>0) and (areanum<=numareas)
  226.       then getareanum:=areanum
  227.       else begin
  228.         writestr ('No such area!');
  229.         if issysop then if makearea then getareanum:=numareas
  230.       end
  231.   end;
  232.  
  233.   procedure getarea;
  234.   var areanum:integer;
  235.   begin
  236.     areanum:=getareanum;
  237.     if areanum<>0 then setarea (areanum)
  238.   end;
  239.  
  240.   function getfname (path:lstr; name:mstr):lstr;
  241.   var l:lstr;
  242.   begin
  243.     l:=path;
  244.     if length(l)<>0
  245.       then if not (l[length(l)] in [':','\'])
  246.         then l:=l+'\';
  247.     l:=l+name;
  248.     getfname:=l
  249.   end;
  250.  
  251.   procedure getpathname (fname:lstr; var path:lstr; var name:sstr);
  252.   var p:integer;
  253.   begin
  254.     path:='';
  255.     repeat
  256.       p:=pos('\',fname);
  257.       if p<>0 then begin
  258.         path:=path+copy(fname,1,p);
  259.         fname:=copy(fname,p+1,255)
  260.       end
  261.     until p=0;
  262.     name:=fname
  263.   end;
  264.  
  265.   procedure listfile (n:integer; extended:boolean);
  266.   var ud:udrec;
  267.       q:sstr;
  268.   begin
  269.     seekudfile (n);
  270.     read (udfile,ud);
  271.     tab (strr(n)+'.',4);
  272.     tab (ud.filename,14);
  273.     if ud.newfile
  274.       then write ('New  ')
  275.       else if ud.specialfile
  276.         then write ('Ask  ')
  277.         else if ud.points>0
  278.           then tab (strr(ud.points),5)
  279.           else write ('     ');
  280.     tab (strlong(ud.filesize),10);
  281.     writeln (ud.descrip);
  282.     if break or (not extended) then exit;
  283.     write ('    ');
  284.     tab (datestr(ud.when),19);
  285.     tab (strr(ud.downloaded),10);
  286.     writeln (ud.sentby)
  287.   end;
  288.  
  289.   function nofiles:boolean;
  290.   begin
  291.     if numuds=0 then begin
  292.       nofiles:=true;
  293.       writestr (^M'Sorry, no files!')
  294.     end else nofiles:=false
  295.   end;
  296.  
  297.   procedure listfiles (extended:boolean);
  298.   var cnt,max,r1,r2:integer;
  299.   const extendedstr:array[false..true] of string[9]=('','Extended ');
  300.   begin
  301.     if nofiles then exit;
  302.     writehdr (extendedstr[extended]+'File List'^M);
  303.     max:=numuds;
  304.     thereare (max,'file','files');
  305.     parserange (max,r1,r2);
  306.     if r1=0 then exit;
  307.     for cnt:=r1 to r2 do begin
  308.       listfile (cnt,extended);
  309.       if break then exit
  310.     end
  311.   end;
  312.  
  313.   function searchforfile (f:sstr):integer;
  314.   var ud:udrec;
  315.       cnt:integer;
  316.   begin
  317.     for cnt:=1 to numuds do begin
  318.       seekudfile (cnt);
  319.       read (udfile,ud);
  320.       if match(ud.filename,f) then begin
  321.         searchforfile:=cnt;
  322.         exit
  323.       end
  324.     end;
  325.     searchforfile:=0
  326.   end;
  327.  
  328.   function getfilenum (t:mstr):integer;
  329.   var n,s:integer;
  330.   begin
  331.     getfilenum:=0;
  332.     if length(input)>1 then input:=copy(input,2,255) else
  333.       repeat
  334.         writestr ('File name/number to '+t+' [?=List]:');
  335.         if hungupon or (length(input)=0) then exit;
  336.         if input='?' then begin
  337.           listfiles (false);
  338.           input:=''
  339.         end
  340.       until input<>'';
  341.     val (input,n,s);
  342.     if s<>0 then begin
  343.       n:=searchforfile(input);
  344.       if n=0 then begin
  345.         writeln ('File not found.');
  346.         exit
  347.       end
  348.     end;
  349.     if (n<1) or (n>numuds)
  350.       then writeln ('File number out of range!')
  351.       else getfilenum:=n
  352.   end;
  353.  
  354.   function allowxfer:boolean;
  355.   var cnt:baudratetype;
  356.       k:char;
  357.   begin
  358.     allowxfer:=false;
  359.     if not carrier then begin
  360.       writeln ('You may only transfer from remote!');
  361.       exit
  362.     end;
  363.     for cnt:=firstbaud to lastbaud do
  364.       if baudrate=baudarray[cnt]
  365.         then if not (cnt in downloadrates)
  366.           then begin
  367.             writeln ('You may not transfer at ',baudrate,' baud.');
  368.             exit
  369.           end;
  370.     if parity then begin
  371.       writeln ('Please select NO parity and press return...');
  372.       parity:=false;
  373.       setparam (usecom,baudrate,parity);
  374.       repeat
  375.         k:=getchar;
  376.         if hungupon then exit
  377.       until k in [#13,#141];
  378.       if k=#141 then begin
  379.         parity:=true;
  380.         setparam (usecom,baudrate,parity);
  381.         writeln ('You did not turn off parity.  Transfer aborted.');
  382.         exit
  383.       end
  384.     end;
  385.     allowxfer:=true
  386.   end;
  387.  
  388.   procedure addfile (ud:udrec);
  389.   begin
  390.     seekudfile (numuds+1);
  391.     write (udfile,ud)
  392.   end;
  393.  
  394.   procedure getfsize (var ud:udrec);
  395.   var df:file of byte;
  396.   begin
  397.     ud.filesize:=-1;
  398.     assign (df,getfname(ud.path,ud.filename));
  399.     reset (df);
  400.     if ioresult<>0 then exit;
  401.     ud.filesize:=filesize(df);
  402.     close(df)
  403.   end;
  404.  
  405.   function wildcardmatch (w,f:sstr):boolean;
  406.   var a,b:sstr;
  407.  
  408.     procedure transform (t:sstr; var q:sstr);
  409.     var p:integer;
  410.  
  411.       procedure filluntil (k:char; n:integer);
  412.       begin
  413.         while length(q)<n do q:=q+k
  414.       end;
  415.  
  416.       procedure dopart (mx:integer);
  417.       var k:char;
  418.       begin
  419.         repeat
  420.           if p>length(t)
  421.             then k:='.'
  422.             else k:=t[p];
  423.           p:=p+1;
  424.           case k of
  425.             '.':begin
  426.                   filluntil (' ',mx);
  427.                   exit
  428.                 end;
  429.             '*':filluntil ('?',mx);
  430.             else if length(q)<mx then q:=q+k
  431.           end
  432.         until 0=1
  433.       end;
  434.  
  435.     begin
  436.       p:=1;
  437.       q:='';
  438.       dopart (8);
  439.       dopart (11)
  440.     end;
  441.  
  442.     function theymatch:boolean;
  443.     var cnt:integer;
  444.     begin
  445.       theymatch:=false;
  446.       for cnt:=1 to 11 do
  447.         if (a[cnt]<>'?') and (b[cnt]<>'?') and
  448.            (upcase(a[cnt])<>upcase(b[cnt])) then exit;
  449.       theymatch:=true
  450.     end;
  451.  
  452.   begin
  453.     transform (w,a);
  454.     transform (f,b);
  455.     wildcardmatch:=theymatch
  456.   end;
  457.  
  458.   const beenaborted:boolean=false;
  459.  
  460.   function aborted:boolean;
  461.   begin
  462.     if beenaborted then begin
  463.       aborted:=true;
  464.       exit
  465.     end;
  466.     aborted:=xpressed or hungupon;
  467.     if xpressed then begin
  468.       beenaborted:=true;
  469.       writeln (^B'Newscan aborted!')
  470.     end
  471.   end;
  472.  
  473.   procedure newscan;
  474.   var cnt:integer;
  475.       u:udrec;
  476.   begin
  477.     beenaborted:=false;
  478.     for cnt:=1 to filesize(udfile) do begin
  479.       if aborted then exit;
  480.       seekudfile (cnt);
  481.       read (udfile,u);
  482.       if (u.whenrated>laston) or (u.when>laston)
  483.         then listfile (cnt,false)
  484.     end
  485.   end;
  486.  
  487.   procedure getstring (t:lstr; var m);
  488.   var q:lstr absolute m;
  489.       mm:lstr;
  490.   begin
  491.     writeln ('Old ',t,': ',q);
  492.     writestr ('Enter new '+t+' [CR for no change]:');
  493.     mm:=input;
  494.     if length(mm)<>0 then q:=mm;
  495.     writeln
  496.   end;
  497.  
  498.   procedure getint (t:lstr; var i:integer);
  499.   var s:sstr;
  500.   begin
  501.     s:=strr(i);
  502.     getstring (t,s);
  503.     i:=valu(s)
  504.   end;
  505.  
  506.   procedure getboo (t:lstr; var b:boolean);
  507.   var s:sstr;
  508.   begin
  509.     s:=yesno (b);
  510.     getstring (t,s);
  511.     b:=upcase(s[1])='Y'
  512.   end;
  513.  
  514.   procedure removefile (n:integer);
  515.   var cnt:integer;
  516.   begin
  517.     for cnt:=n to numuds-1 do begin
  518.       seekudfile (cnt+1);
  519.       read (udfile,ud);
  520.       seekudfile (cnt);
  521.       write (udfile,ud)
  522.     end;
  523.     seekudfile (numuds);
  524.     truncate (udfile)
  525.   end;
  526.  
  527.   procedure displayfile (var ffinfo:searchrec);
  528.   var a:integer;
  529.   begin
  530.     a:=ffinfo.attr;
  531.     if (a and 8)=8 then exit;
  532.     tab (ffinfo.name,13);
  533.     if (a and 16)=16
  534.       then write ('Directory')
  535.       else write (ffinfo.size);
  536.     if (a and 1)=1 then write (' <read-only>');
  537.     if (a and 2)=2 then write (' <hidden>');
  538.     if (a and 4)=4 then write (' <system>');
  539.     writeln
  540.   end;
  541.  
  542.   function defaultdrive:byte;
  543.   var r:registers;
  544.   begin
  545.     r.ah:=$19;
  546.     intr ($21,r);
  547.     defaultdrive:=r.al+1
  548.   end;
  549.  
  550.   procedure directory;
  551.   var r:registers;
  552.       ffinfo:searchrec;
  553.       tpath:anystr;
  554.       b:byte;
  555.       cnt:integer;
  556.   begin
  557.     getdir (defaultdrive,tpath);
  558.     if tpath[length(tpath)]<>'\' then tpath:=tpath+'\';
  559.     tpath:=tpath+'*.*';
  560.     writestr ('Path/wildcard [CR for '+tpath+']:');
  561.     writeln (^M);
  562.     if length(input)<>0 then tpath:=input;
  563.     writelog (16,10,tpath);
  564.     findfirst (chr(defaultdrive+64)+':\*.*',8,ffinfo);
  565.     if doserror<>0
  566.       then writeln ('No volume label'^M)
  567.       else writeln ('Volume label: ',ffinfo.name,^M);
  568.     findfirst (tpath,$17,ffinfo);
  569.     if doserror<>0 then writeln ('No files found.') else begin
  570.       cnt:=0;
  571.       while doserror=0 do begin
  572.         cnt:=cnt+1;
  573.         if not break then displayfile (ffinfo);
  574.         findnext (ffinfo)
  575.       end;
  576.       writeln (^B^M'Total files: ',cnt)
  577.     end;
  578.     write ('Free disk space: ');
  579.     writefreespace (tpath)
  580.   end;
  581.  
  582.   procedure listarchive;
  583.   var n:integer;
  584.       ud:udrec;
  585.       f:file of byte;
  586.       fname:lstr;
  587.       b:byte;
  588.       sg:boolean;
  589.       size:longint;
  590.  
  591.     function getsize:longint;
  592.     var x:longint;
  593.         b:array [1..4] of byte absolute x;
  594.         cnt:integer;
  595.     begin
  596.       for cnt:=1 to 4 do read (f,b[cnt]);
  597.       getsize:=x
  598.     end;
  599.  
  600.     procedure badarchive;
  601.     begin
  602.       writeln (^M'That file isn''t an archive!');
  603.       close (f);
  604.       exit
  605.     end;
  606.  
  607.   begin
  608.     if nofiles then exit;
  609.     n:=getfilenum('list');
  610.     if n=0 then exit;
  611.     seekudfile (n);
  612.     read (udfile,ud);
  613.     fname:=getfname(ud.path,ud.filename);
  614.     assign (f,fname);
  615.     reset (f);
  616.     iocode:=ioresult;
  617.     if iocode<>0 then begin
  618.       fileerror ('LISTARCHIVE',fname);
  619.       exit
  620.     end;
  621.     if filesize(f)<32 then begin
  622.       badarchive;
  623.       exit
  624.     end;
  625.     writehdr ('Archive File List');
  626.     repeat
  627.       read (f,b);
  628.       if b<>26 then begin
  629.         badarchive;
  630.         exit
  631.       end;
  632.       read (f,b);
  633.       if b=0 then begin
  634.         close (f);
  635.         exit
  636.       end;
  637.       sg:=false;
  638.       for n:=1 to 13 do begin
  639.         read (f,b);
  640.         if b=0 then sg:=true;
  641.         if sg then b:=32;
  642.         write (chr(b))
  643.       end;
  644.       size:=getsize;
  645.       for n:=1 to 6 do read (f,b);
  646.       writeln ('   ',getsize);
  647.       seek (f,filepos(f)+size)
  648.     until break or hungupon
  649.   end;
  650.  
  651.   procedure download (autoselect:integer);
  652.   var totaltime:sstr;
  653.       num,fsize,mins:integer;
  654.       ud:udrec;
  655.       fname:lstr;
  656.       ymodem:boolean;
  657.       b:integer;
  658.       f:file;
  659.   begin
  660.     if not allowxfer then exit;
  661.     if nofiles then exit;
  662.     if autoselect=0
  663.       then num:=getfilenum('download')
  664.       else num:=autoselect;
  665.     if num=0 then exit;
  666.     writeln;
  667.     seekudfile (num);
  668.     read (udfile,ud);
  669.     if (not sponsoron) and (ud.points>urec.udpoints) then begin
  670.       writeln ('Sorry, that file requires ',ud.points,' points.');
  671.       exit
  672.     end;
  673.     if (ud.newfile) and (not sponsoron) then begin
  674.       writeln ('Sorry, that is a new file and must be validated.');
  675.       exit
  676.     end;
  677.     if (ud.specialfile) and (not sponsoron) then begin
  678.       writeln ('Sorry, downloading that file requires special permission.');
  679.       exit
  680.     end;
  681.     if tempsysop then begin
  682.       ulvl:=regularlevel;
  683.       tempsysop:=false;
  684.       writeurec;
  685.       bottomline
  686.     end;
  687.     ymodem:=false;
  688.     writestr ('X)modem or Y)modem? *');
  689.     if length(input)>0 then ymodem:=upcase(input[1])='Y';
  690.     fname:=getfname(ud.path,ud.filename);
  691.     assign (f,fname);
  692.     reset (f);
  693.     iocode:=ioresult;
  694.     if iocode<>0 then
  695.       begin
  696.         fileerror ('DOWNLOAD',fname);
  697.         exit
  698.       end;
  699.     fsize:=filesize(f);
  700.     close (f);
  701.     totaltime:=minstr(fsize);
  702.     mins:=valu(copy(totaltime,1,pos(':',totaltime)-1));
  703.     if ((mins>timeleft) and (not sponsoron)) then begin
  704.       writestr ('Sorry, you don''t have enough time left!');
  705.       exit
  706.     end;
  707.     if (mins-5>timetillevent) then begin
  708.       writestr ('Sorry, the timed event is coming up too soon!');
  709.       exit
  710.     end;
  711.     writeln (^B^M'Filename:       '^S,ud.filename);
  712.     writeln ('Uploaded by:    '^S,ud.sentby);
  713.     write ('Downloaded:     '^S,ud.downloaded,' time');
  714.     if ud.downloaded=1 then writeln else writeln ('s');
  715.     if ymodem then fsize:=(fsize+7) div 8;
  716.     writeln ('Blocks to send: '^S,fsize);
  717.     writeln ('Transfer time:  '^S,totaltime);
  718.     writeln (^M'CRC use will be automatically selected');
  719.     writeln (^B'Press [Ctrl-X] to abort the transfer'^B);
  720.     b:=protocolxfer (true,false,ymodem,fname);
  721.     beepbeep (b);
  722.     if (b=0) or (b=1) then begin
  723.       writelog (15,1,fname);
  724.       ud.downloaded:=ud.downloaded+1;
  725.       urec.downloads:=urec.downloads+1;
  726.       seekudfile (num);
  727.       write (udfile,ud);
  728.       if (ud.points>0) and (not sponsoron) then begin
  729.         urec.udpoints:=urec.udpoints-ud.points;
  730.         writeln (^B'You now have ',
  731.                  numthings (urec.udpoints,'point','points'),'.')
  732.       end;
  733.       writeurec
  734.     end
  735.   end;
  736.  
  737.   procedure typefile;
  738.   var num:integer;
  739.       ud:udrec;
  740.       fname:lstr;
  741.       f:text;
  742.       k:char;
  743.   begin
  744.     if nofiles then exit;
  745.     num:=getfilenum('type');
  746.     if num=0 then exit;
  747.     writeln;
  748.     seekudfile (num);
  749.     read (udfile,ud);
  750.     if (not sponsoron) and (ud.points>urec.udpoints) then begin
  751.       writeln ('Sorry, that file requires ',ud.points,' points.');
  752.       exit
  753.     end;
  754.     if (ud.newfile) and (not sponsoron) then begin
  755.       writeln ('Sorry, that is a new file and must be validated.');
  756.       exit
  757.     end;
  758.     if (ud.specialfile) and (not sponsoron) then begin
  759.       writeln ('Sorry, downloading that file requires special permission.');
  760.       exit
  761.     end;
  762.     if tempsysop then begin
  763.       ulvl:=regularlevel;
  764.       tempsysop:=false;
  765.       writeurec;
  766.       bottomline
  767.     end;
  768.     fname:=getfname(ud.path,ud.filename);
  769.     assign (f,fname);
  770.     reset (f);
  771.     iocode:=ioresult;
  772.     if iocode<>0 then
  773.       begin
  774.         fileerror ('TYPEFILE',fname);
  775.         exit
  776.       end;
  777.     writeln (^B^M'Filename:       '^S,ud.filename);
  778.     writeln ('Uploaded by:    '^S,ud.sentby);
  779.     if (ud.points>0) and (not sponsoron) then begin
  780.       write (^B^M'NOTE: When the transfer begins, you ',
  781.                ^M'      will be charged ',ud.points,' point');
  782.       if ud.points<>1 then write ('s');
  783.       writeln ('!')
  784.     end;
  785.     writeln (^B^M'Press any key to begin the transfer,',
  786.                ^M'or [Ctrl-X] to abort...'^M);
  787.     k:=waitforchar;
  788.     if (k=^X) or (upcase(k)='X') then begin
  789.       textclose (f);
  790.       writeln (^B^M'Aborted!');
  791.       exit
  792.     end;
  793.     while not (eof(f) or break) do begin
  794.       read (f,k);
  795.       if k=^M then writeln else if k<>^J then write (k)
  796.     end;
  797.     textclose (f);
  798.     if (ud.points>0) and (not sponsoron) then begin
  799.       urec.udpoints:=urec.udpoints-ud.points;
  800.       writeln (^B'You now have ',
  801.                numthings (urec.udpoints,'point','points'),'.')
  802.     end;
  803.     writeurec
  804.   end;
  805.  
  806.   procedure upload;
  807.   var ud:udrec;
  808.       ok,crcmode,ymodem:boolean;
  809.       b:integer;
  810.       fn:lstr;
  811.   begin
  812.     if not allowxfer then exit;
  813.     if timetillevent<30 then begin
  814.       writestr (
  815.    'Sorry, uploads are not allowed within one half hour of the timed event!');
  816.       exit
  817.     end;
  818.     ok:=false;
  819.     write ('Free disk space: ');
  820.     writefreespace (area.xmodemdir);
  821.     writeln;
  822.     repeat
  823.       writestr ('Target filename:');
  824.       if length(input)=0 then exit;
  825.       if not validfname(input) then begin
  826.         writeln ('Invalid filename!');
  827.         exit
  828.       end;
  829.       ud.filename:=input;
  830.       ud.path:=area.xmodemdir;
  831.       fn:=getfname(ud.path,ud.filename);
  832.       if hungupon then exit;
  833.       if exist(fn)
  834.         then writeln ('Sorry!  File exists!')
  835.         else ok:=true
  836.     until ok;
  837.     ymodem:=false;
  838.     writestr ('X)modem or Y)modem? *');
  839.     if length(input)>0 then ymodem:=upcase(input[1])='Y';
  840.     if ymodem then crcmode:=true else begin
  841.       writestr ('CRC Mode? *');
  842.       crcmode:=yes
  843.     end;
  844.     write (^B^M);
  845.     if ymodem then write ('Y') else write ('X');
  846.     write ('MODEM');
  847.     if crcmode then write ('-CRC');
  848.     writeln (' receive ready.  [Ctrl-X] Aborts');
  849.     if tempsysop then begin
  850.       ulvl:=regularlevel;
  851.       tempsysop:=false;
  852.       writeurec;
  853.       bottomline
  854.     end;
  855.     b:=protocolxfer(false,crcmode,ymodem,fn);
  856.     beepbeep (b);
  857.     if b=0 then begin
  858.       writelog (15,2,ud.filename);
  859.       buflen:=40;
  860.       writestr ('Description of upload: &');
  861.       ud.descrip:=input;
  862.       ud.sentby:=unam;
  863.       ud.when:=now;
  864.       ud.whenrated:=now;
  865.       ud.points:=0;
  866.       ud.downloaded:=0;
  867.       ud.newfile:=true;
  868.       ud.specialfile:=false;
  869.       ud.downloaded:=0;
  870.       writeln ('Thanks for uploading!');
  871.       getfsize (ud);
  872.       addfile (ud);
  873.       urec.uploads:=urec.uploads+1;
  874.       newuploads:=newuploads+1
  875.     end;
  876.   end;
  877.  
  878.   procedure searchfile;
  879.   var cnt:integer;
  880.       searchall:boolean;
  881.       wildcard:sstr;
  882.       a:arearec;
  883.  
  884.     procedure searcharea;
  885.     var cnt:integer;
  886.         u:udrec;
  887.     begin
  888.       for cnt:=1 to numuds do begin
  889.         seekudfile (cnt);
  890.         read (udfile,u);
  891.         if wildcardmatch (wildcard,u.filename) then listfile (cnt,false);
  892.         if xpressed then exit
  893.       end
  894.     end;
  895.  
  896.   begin
  897.     writestr (^M'Search all areas? *');
  898.     searchall:=yes;
  899.     writestr ('File name (wildcards OK):');
  900.     if length(input)=0 then exit;
  901.     wildcard:=input;
  902.     if not searchall then begin
  903.       searcharea;
  904.       exit
  905.     end;
  906.     for cnt:=1 to numareas do begin
  907.       seekafile (cnt);
  908.       read (afile,a);
  909.       if urec.udlevel>=a.level then begin
  910.         setarea (cnt);
  911.         searcharea;
  912.         if xpressed then exit
  913.       end
  914.     end
  915.   end;
  916.  
  917.   procedure yourudstatus;
  918.   begin
  919.     writeln (^B^M'Access level:    '^S,urec.udlevel,
  920.                ^M'Transfer points: '^S,urec.udpoints,
  921.                ^M'Uploads:         '^S,urec.uploads,
  922.                ^M'Downloads:       '^S,urec.downloads)
  923.   end;
  924.  
  925.   procedure newscanall;
  926.   var cnt:integer;
  927.       a:arearec;
  928.   begin
  929.     writehdr ('Newscanning... press [X] to abort.');
  930.     beenaborted:=false;
  931.     if aborted then exit;
  932.     for cnt:=1 to filesize(afile) do begin
  933.       seekafile (cnt);
  934.       read (afile,a);
  935.       if urec.udlevel>=a.level then begin
  936.         if aborted then exit;
  937.         setarea (cnt);
  938.         if aborted then exit;
  939.         newscan
  940.       end;
  941.       if aborted then exit
  942.     end
  943.   end;
  944.  
  945.   procedure addresidentfile (fname:lstr);
  946.   var ud:udrec;
  947.   begin
  948.     getpathname (fname,ud.path,ud.filename);
  949.     getfsize(ud);
  950.     if ud.filesize=-1 then begin
  951.       writeln ('File can''t be opened!');
  952.       exit
  953.     end;
  954.     writestr ('Point value:');
  955.     if length(input)=0 then input:='0';
  956.     ud.points:=valu(input);
  957.     writestr ('Sent by [CR='+unam+']:');
  958.     if length(input)=0 then input:=unam;
  959.     ud.sentby:=input;
  960.     ud.when:=now;
  961.     ud.whenrated:=now;
  962.     ud.downloaded:=0;
  963.     writestr ('Description: &');
  964.     ud.descrip:=input;
  965.     writestr ('Special request only? *');
  966.     ud.specialfile:=yes;
  967.     ud.newfile:=false;
  968.     addfile (ud);
  969.     writelog (16,8,fname)
  970.   end;
  971.  
  972.   procedure sysopadd;
  973.   var fn:lstr;
  974.   begin
  975.     if ulvl<sysoplevel then begin
  976.       writeln
  977.         ('Sorry, you may not add resident files without true sysop access!');
  978.       exit
  979.     end;
  980.     writehdr ('Add Resident File');
  981.     writestr ('Name/path of file:');
  982.     fn:=input;
  983.     if exist(fn)
  984.       then
  985.         begin
  986.           writestr ('Confirm: '+fn+' (Y/N):');
  987.           if yes then addresidentfile (fn)
  988.         end
  989.       else writeln ('File not found!')
  990.   end;
  991.  
  992.   procedure addmultiplefiles;
  993.   var spath,pathpart:lstr;
  994.       dummy:sstr;
  995.       f:file;
  996.       ffinfo:searchrec;
  997.   begin
  998.     if ulvl<sysoplevel then begin
  999.       writeln (
  1000.         'Sorry, you may not add resident files without true sysop access!');
  1001.       exit
  1002.     end;
  1003.     writehdr ('Add Resident Files By Wildcard');
  1004.     writestr ('Search path/wildcard:');
  1005.     if length(input)=0 then exit;
  1006.     spath:=input;
  1007.     if spath[length(spath)]='\' then dec(spath[0]);
  1008.     assign (f,spath+'\con');
  1009.     reset (f);
  1010.     if ioresult=0 then begin
  1011.       close (f);
  1012.       spath:=spath+'\*.*'
  1013.     end;
  1014.     getpathname (spath,pathpart,dummy);
  1015.     findfirst (spath,$17,ffinfo);
  1016.     if doserror<>0
  1017.       then writeln ('No files found!')
  1018.       else
  1019.         while doserror=0 do begin
  1020.           writeln;
  1021.           displayfile (ffinfo);
  1022.           writestr ('Add this file (Y/N/X)? *');
  1023.           if yes
  1024.             then addresidentfile (getfname(pathpart,ffinfo.name))
  1025.             else if (length(input)>0) and (upcase(input[1])='X')
  1026.               then exit;
  1027.           findnext (ffinfo)
  1028.         end
  1029.   end;
  1030.  
  1031.   procedure changef;
  1032.   var n,q:integer;
  1033.       ud:udrec;
  1034.  
  1035.     procedure showudrec (var ud:udrec);
  1036.     begin
  1037.       with ud do
  1038.         writeln(^M^J'   Filename: '^S,ud.filename,
  1039.                 ^M^J'       Path: '^S,ud.path,
  1040.                 ^M^J'       Size: '^S,ud.filesize,
  1041.                 ^M^J'     Points: '^S,ud.points,
  1042.                 ^M^J'Description: '^S,ud.descrip,
  1043.                 ^M^J'#downloaded: '^S,ud.downloaded,
  1044.                 ^M^J'    Unrated: '^S,yesno(ud.newfile),
  1045.                 ^M^J'Special req: '^S,yesno(ud.specialfile),
  1046.                 ^M^J'    Sent by: '^S,sentby,
  1047.                 ^M^J'    Sent on: '^S,datestr(when),
  1048.                 ^M^J'    Sent at: '^S,timestr(when),^M^J);
  1049.     end;
  1050.  
  1051.   begin
  1052.     n:=getfilenum ('Change');
  1053.     if n=0 then exit;
  1054.     seekudfile (n);
  1055.     read (udfile,ud);
  1056.     writelog (16,4,ud.filename);
  1057.     showudrec (ud);
  1058.     repeat
  1059.       q:=menu ('File change','FCHANGE','QUDSNFPV');
  1060.       case q of
  1061.         2:getstring ('uploader',ud.sentby);
  1062.         3:begin
  1063.             nochain:=true;
  1064.             getstring ('description',ud.descrip)
  1065.           end;
  1066.         4:getboo ('special request only',ud.specialfile);
  1067.         5:getboo ('new file (unrated)',ud.newfile);
  1068.         6:getstring ('filename',ud.filename);
  1069.         7:getstring ('path',ud.path);
  1070.         8:getint ('point value',ud.points)
  1071.       end
  1072.     until (q=1);
  1073.     getfsize(ud);
  1074.     if ud.filesize=-1 then writestr ('Warning:  Can''t open file!');
  1075.     seekudfile (n);
  1076.     write (udfile,ud)
  1077.   end;
  1078.  
  1079.   procedure deletef;
  1080.   var n,cnt:integer;
  1081.       fn:lstr;
  1082.       ud:udrec;
  1083.       f:file;
  1084.   begin
  1085.     n:=getfilenum ('delete');
  1086.     if n=0 then exit;
  1087.     seekudfile (n);
  1088.     read (udfile,ud);
  1089.     fn:=getfname(ud.path,ud.filename);
  1090.     writelog (16,7,fn);
  1091.     writestr ('Confirm: File '+fn+' ('+ud.descrip+') ? *');
  1092.     if not yes then exit;
  1093.     removefile (n);
  1094.     writestr ('Erase disk file '+fn+'? *');
  1095.     if not yes then exit;
  1096.     assign (f,fn);
  1097.     erase (f)
  1098.   end;
  1099.  
  1100.   procedure killarea;
  1101.   var a:arearec;
  1102.       cnt,n:integer;
  1103.       oldname,newname:sstr;
  1104.   begin
  1105.     writestr ('Delete area #'+strr(curarea)+' ('+area.name+')? *');
  1106.     if not yes then exit;
  1107.     writelog (16,2,'');
  1108.     close (udfile);
  1109.     oldname:='Area'+strr(curarea);
  1110.     assign (udfile,oldname);
  1111.     erase (udfile);
  1112.     for cnt:=curarea to numareas-1 do begin
  1113.       newname:=oldname;
  1114.       oldname:='Area'+strr(cnt+1);
  1115.       assign (udfile,oldname);
  1116.       rename (udfile,newname);
  1117.       n:=ioresult;
  1118.       seekafile (cnt+1);
  1119.       read (afile,a);
  1120.       seekafile (cnt);
  1121.       write (afile,a)
  1122.     end;
  1123.     seekafile (numareas);
  1124.     truncate (afile);
  1125.     setarea (1)
  1126.   end;
  1127.  
  1128.   procedure modarea;
  1129.   var a:arearec;
  1130.   begin
  1131.     a:=area;
  1132.     getstring ('area name',a.name);
  1133.     writelog (16,3,a.name);
  1134.     getint ('access level',a.level);
  1135.     writelog (16,11,strr(a.level));
  1136.     getstring ('sponsor',a.sponsor);
  1137.     writelog (16,12,a.sponsor);
  1138.     if issysop then begin
  1139.       a.xmodemdir:=getapath;
  1140.       writelog (16,13,a.xmodemdir)
  1141.     end;
  1142.     seekafile (curarea);
  1143.     write (afile,a);
  1144.     area:=a
  1145.   end;
  1146.  
  1147.   procedure sortarea;
  1148.   var temp,mark,cnt:integer;
  1149.       u1,u2:udrec;
  1150.   begin
  1151.     writehdr ('Sort Area');
  1152.     writestr ('Confirm (Y/N):');
  1153.     if not yes then exit;
  1154.     writelog (16,6,'');
  1155.     mark:=numuds-1;
  1156.     repeat
  1157.       if mark<>0 then begin
  1158.         temp:=mark;
  1159.         mark:=0;
  1160.         for cnt:=1 to temp do begin
  1161.           seekudfile (cnt);
  1162.           read (udfile,u1);
  1163.           read (udfile,u2);
  1164.           if upstring(u1.filename)>upstring(u2.filename) then begin
  1165.             mark:=cnt;
  1166.             seekudfile (cnt);
  1167.             write (udfile,u2);
  1168.             write (udfile,u1)
  1169.           end
  1170.         end
  1171.       end
  1172.     until mark=0
  1173.   end;
  1174.  
  1175.   procedure movefile;
  1176.   var an,fn,oldn:integer;
  1177.       ud:udrec;
  1178.   begin
  1179.     oldn:=curarea;
  1180.     fn:=getfilenum ('move');
  1181.     if fn=0 then exit;
  1182.     input:='';
  1183.     an:=getareanum;
  1184.     if an=0 then exit;
  1185.     writeln ('Moving...');
  1186.     seekudfile (fn);
  1187.     read (udfile,ud);
  1188.     writelog (16,5,ud.filename);
  1189.     removefile (fn);
  1190.     setarea (an);
  1191.     addfile (ud);
  1192.     setarea (oldn);
  1193.     writeln (^B'Done.')
  1194.   end;
  1195.  
  1196.   procedure renamefile;
  1197.   var fn:integer;
  1198.       ud:udrec;
  1199.       f:file;
  1200.   begin
  1201.     fn:=getfilenum ('rename');
  1202.     if fn=0 then exit;
  1203.     seekudfile (fn);
  1204.     read (udfile,ud);
  1205.     writestr ('Enter new filename:');
  1206.     if match(input,ud.filename)
  1207.       then
  1208.         ud.filename:=input
  1209.       else if length(input)>0
  1210.         then if validfname(input)
  1211.           then if exist(getfname(ud.path,input))
  1212.             then
  1213.               writeln ('Name already in use!')
  1214.             else
  1215.               begin
  1216.                 assign (f,getfname(ud.path,ud.filename));
  1217.                 rename (f,getfname(ud.path,input));
  1218.                 if ioresult=0 then begin
  1219.                   ud.filename:=input;
  1220.                   writeln (^B^M'File renamed.')
  1221.                 end else writeln (^B^M'Unable to rename file!')
  1222.               end
  1223.           else writeln ('Invalid filename!');
  1224.     seekudfile (fn);
  1225.     write (udfile,ud)
  1226.   end;
  1227.  
  1228.   procedure listxmodem;
  1229.   var cnt:integer;
  1230.       u:userrec;
  1231.   begin
  1232.     seek (ufile,1);
  1233.     writeln ('Name                          Lvl Pts'^M);
  1234.     for cnt:=1 to numusers do begin
  1235.       read (ufile,u);
  1236.       if u.handle<>'' then
  1237.         if u.udlevel>0 then begin
  1238.           tab (u.handle,30);
  1239.           tab (strr(u.udlevel),4);
  1240.           writeln (u.udpoints);
  1241.           if break then exit
  1242.         end
  1243.     end
  1244.   end;
  1245.  
  1246.   procedure reorderareas;
  1247.   var numa,cura,newa:integer;
  1248.       a1,a2:arearec;
  1249.       f1,f2:file;
  1250.       fn1,fn2:sstr;
  1251.   label exit;
  1252.   begin
  1253.     writelog (16,9,'');
  1254.     writehdr ('Re-order Areas');
  1255.     numa:=filesize (afile);
  1256.     writeln ('Number of areas: ',numa);
  1257.     for cura:=0 to numa-2 do begin
  1258.       repeat
  1259.         writestr ('New area #'+strr(cura+1)+' [?=List, CR to quit]:');
  1260.         if length(input)=0 then goto exit;
  1261.         if input='?'
  1262.           then
  1263.             begin
  1264.               listareas;
  1265.               newa:=-1
  1266.             end
  1267.           else
  1268.             begin
  1269.               newa:=valu(input)-1;
  1270.               if (newa<0) or (newa>numa) then begin
  1271.                 writeln ('Not found!  Please re-enter...');
  1272.                 newa:=-1
  1273.               end
  1274.             end
  1275.       until (newa>=0);
  1276.       seek (afile,cura);
  1277.       read (afile,a1);
  1278.       seek (afile,newa);
  1279.       read (afile,a2);
  1280.       seek (afile,cura);
  1281.       write (afile,a2);
  1282.       seek (afile,newa);
  1283.       write (afile,a1);
  1284.       fn1:='Area';
  1285.       fn2:=fn1+strr(newa+1);
  1286.       fn1:=fn1+strr(cura+1);
  1287.       assign (f1,fn1);
  1288.       assign (f2,fn2);
  1289.       rename (f1,'Temp$$$$');
  1290.       rename (f2,fn1);
  1291.       rename (f1,fn2)
  1292.     end;
  1293.     exit:
  1294.     setarea (1)
  1295.   end;
  1296.  
  1297.   procedure newfiles;
  1298.   var a,fn,un:integer;
  1299.       ud:udrec;
  1300.       u:userrec;
  1301.       flag,aborted:boolean;
  1302.  
  1303.     procedure writeudrec;
  1304.     begin
  1305.       seekudfile (fn);
  1306.       write (udfile,ud)
  1307.     end;
  1308.  
  1309.     procedure ratefile (p:integer);
  1310.     begin
  1311.       ud.points:=p;
  1312.       ud.newfile:=false;
  1313.       ud.whenrated:=now;
  1314.       writeudrec;
  1315.       p:=p*uploadfactor;
  1316.       if p>0 then begin
  1317.         un:=lookupuser (ud.sentby);
  1318.         if un=0
  1319.           then writeln (ud.sentby,' has vanished!')
  1320.           else begin
  1321.             writeln ('Granting ',ud.sentby,' ',p,' points.');
  1322.             if un=unum then writeurec;
  1323.             seek (ufile,un);
  1324.             read (ufile,u);
  1325.             u.udpoints:=u.udpoints+p;
  1326.             seek (ufile,un);
  1327.             write (ufile,u);
  1328.             if un=unum then readurec
  1329.           end
  1330.       end
  1331.     end;
  1332.  
  1333.     procedure doarea;
  1334.     var i,advance:integer;
  1335.         done:boolean;
  1336.     begin
  1337.       fn:=1;
  1338.       advance:=0;
  1339.       while fn+advance<=numuds do begin
  1340.         fn:=fn+advance;
  1341.         advance:=1;
  1342.         seekudfile (fn);
  1343.         read (udfile,ud);
  1344.         if ud.newfile then begin
  1345.           flag:=false;
  1346.           done:=false;
  1347.           repeat
  1348.             writeln (^B^M'Filename:    ',ud.filename,
  1349.                        ^M'Path:        ',ud.path,
  1350.                        ^M'Sent by:     ',ud.sentby,
  1351.                        ^M'File size:   ',ud.filesize,
  1352.                        ^M'Description: ',ud.descrip);
  1353.             i:=menu ('Newscan','NEWSCAN','Q#_CEDRM0');
  1354.             input:=' '+strr(fn);
  1355.             if i<0
  1356.               then
  1357.                 begin
  1358.                   ratefile(-i);
  1359.                   done:=true
  1360.                 end
  1361.               else
  1362.                 case i of
  1363.                   1:begin
  1364.                       aborted:=true;
  1365.                       exit
  1366.                     end;
  1367.                   3:done:=true;
  1368.                   4:begin
  1369.                       writestr ('Enter new description:');
  1370.                       if length(input)>0 then ud.descrip:=input;
  1371.                       writeudrec
  1372.                     end;
  1373.                   5:begin
  1374.                       renamefile;
  1375.                       advance:=0
  1376.                     end;
  1377.                   6:begin
  1378.                       deletef;
  1379.                       advance:=0
  1380.                     end;
  1381.                   7:listarchive;
  1382.                   8:begin
  1383.                       movefile;
  1384.                       advance:=0
  1385.                     end;
  1386.                   9:begin
  1387.                       ratefile (0);
  1388.                       done:=true
  1389.                     end
  1390.                 end
  1391.           until done or (advance=0)
  1392.         end
  1393.       end
  1394.     end;
  1395.  
  1396.   begin
  1397.     flag:=true;
  1398.     writelog (16,1,'');
  1399.     if issysop then begin
  1400.       writestr ('Scan all areas? *');
  1401.       if yes then begin
  1402.         for a:=1 to numareas do begin
  1403.           setarea (a);
  1404.           aborted:=false;
  1405.           doarea;
  1406.           if aborted then exit
  1407.         end
  1408.       end else doarea
  1409.     end else doarea;
  1410.     if flag then writeln (^B'No new files.')
  1411.   end;
  1412.  
  1413.   procedure sysopcommands;
  1414.   var i:integer;
  1415.   begin
  1416.     if not sponsoron then begin
  1417.       reqlevel (sysoplevel);
  1418.       exit
  1419.     end;
  1420.     writelog (15,3,area.name);
  1421.     repeat
  1422.       i:=menu('File sponsor','FSYSOP','A@CDF@G@KRNSMLO@QEW@');
  1423.       case i of
  1424.         1:sysopadd;
  1425.         2:changef;
  1426.         3:deletef;
  1427.         4:directory;
  1428. {        5:generatelist; }
  1429.         6:killarea;
  1430.         7:modarea;
  1431.         8:newfiles;
  1432.         9:sortarea;
  1433.         10:movefile;
  1434.         11:listxmodem;
  1435.         12:reorderareas;
  1436.         14:renamefile;
  1437.         15:addmultiplefiles
  1438.       end
  1439.     until hungupon or (i=13)
  1440.   end;
  1441.  
  1442. var i:integer;
  1443.     a:arearec;
  1444.     ms:boolean;
  1445. label ok,exit;
  1446. begin
  1447.   cursection:=udsysop;
  1448.   ms:=false;
  1449.   writehdr ('The File Transfer Section');
  1450.   input:='';
  1451.   assign (afile,'areadir');
  1452.   if exist ('Areadir')
  1453.     then
  1454.       begin
  1455.         reset (afile);
  1456.         if filesize (afile)>0 then goto ok
  1457.       end
  1458.     else rewrite (afile);
  1459.   writeln ('No areas have been defined!');
  1460.   area.xmodemdir:=forumdir+'XMODEM\';
  1461.   if issysop
  1462.     then if makearea
  1463.       then goto ok;
  1464.   goto exit;
  1465.   ok:
  1466.   seekafile (1);
  1467.   read (afile,a);
  1468.   if urec.udlevel<a.level then begin
  1469.     writeln ('Sorry, you can''t access the first area!');
  1470.     goto exit
  1471.   end;
  1472.   yourudstatus;
  1473.   setarea (1);
  1474.   repeat
  1475.     if withintime (xmodemclosetime,xmodemopentime) then
  1476.       if not issysop then begin
  1477.         writestr (^M^M'Sorry, the XMODEM section is closed now!');
  1478.         writeln ('The time now is: '^S,timestr(now));
  1479.         writeln ('It will open at: '^S,xmodemopentime);
  1480.         goto exit
  1481.       end else if not ms then begin
  1482.         writeln ('(The XMODEM section is closed until ',xmodemopentime,')');
  1483.         ms:=true
  1484.       end;
  1485.     write (^B^M^M,area.name,' [',curarea,']'^B);
  1486.     i:=menu('File','FILE','UDLFYA*SQ%NVHRWXT');
  1487.     if hungupon then goto exit;
  1488.     case i of
  1489.       1:upload;
  1490.       2:download (0);
  1491.       3:listfiles (false);
  1492.       4:sendmailto (area.sponsor,false);
  1493.       5:yourudstatus;
  1494.       6,7:getarea;
  1495.       8:searchfile;
  1496.       10:sysopcommands;
  1497.       11:newscanall;
  1498.       12:newscan;
  1499.       13:help ('Filexfer.hlp');
  1500.       14:listarchive;
  1501.       15,16:listfiles (true);
  1502.       17:typefile
  1503.     end
  1504.   until hungupon or (i=9);
  1505.   exit:
  1506.   close (afile);
  1507.   close (udfile);
  1508.   i:=ioresult
  1509. end;
  1510.  
  1511.  
  1512. begin
  1513. end.
  1514.  
  1515.