home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 276.img / FORUM21S.ZIP / OVERRET1.PAS < prev    next >
Pascal/Delphi Source File  |  1988-02-15  |  18KB  |  742 lines

  1. {$R-,S-,I-,D-,T-,F-,V-,B-,N-,L+ }
  2. {$M 65500,0,0 }
  3.  
  4. unit overret1;
  5.  
  6. interface
  7.  
  8. uses crt,
  9.      gentypes,modem,configrt,gensubs,subs1,subs2,userret,textret,flags,mainr1;
  10.  
  11. procedure help (fn:mstr);
  12. procedure edituser (eunum:integer);
  13. procedure printnews;
  14. procedure sendmodemstr (ss:anystr; endifcarrier:boolean);
  15. function getlastcaller:mstr;
  16. procedure showlastcallers;
  17. procedure infoform;
  18. function selectspecs (var us:userspecsrec):boolean; { True if user aborts }
  19. procedure editoldspecs;
  20.  
  21.  
  22. implementation
  23.  
  24.  
  25. procedure help (fn:mstr);
  26. var tf:text;
  27.     htopic,cnt:integer;
  28. begin
  29.   fn:=textfiledir+fn;
  30.   assign (tf,fn);
  31.   reset (tf);
  32.   if ioresult<>0 then begin
  33.     writestr ('Sorry, no help is availiable!');
  34.     if issysop then begin
  35.       writeln ('Sysop: To make help, create a file called ',fn);
  36.       writeln ('Group the lines into blocks separated by periods.');
  37.       writeln ('The first group is the topic menu; the second is the');
  38.       writeln ('help for topic 1; the third for topic 2; etc.')
  39.     end;
  40.     exit
  41.   end;
  42.   repeat
  43.     textclose (tf);
  44.     assign (tf,fn);
  45.     reset (tf);
  46.     writeln (^M);
  47.     printtexttopoint (tf);
  48.     repeat
  49.       writestr (^M'Topic number [CR quits]:');
  50.       if hungupon or (length(input)=0) then
  51.         begin
  52.           textclose (tf);
  53.           exit
  54.         end;
  55.       htopic:=valu (input)
  56.     until (htopic>0);
  57.     for cnt:=2 to htopic do
  58.       if not eof(tf)
  59.         then skiptopoint (tf);
  60.     if eof(tf)
  61.       then writestr ('Sorry, no help on that topic!')
  62.       else printtexttopoint (tf)
  63.   until 0=1
  64. end;
  65.  
  66. procedure edituser (eunum:integer);
  67. var eurec:userrec;
  68.     ca:integer;
  69.     k:char;
  70. const sysopstr:array [false..true] of string[6]=('Normal','Sysop');
  71.       sectionnames:array [udsysop..databasesysop] of string[20]=
  72.         ('File transfer','Bulletin section','Voting booths',
  73.          'E-mail section','Doors','Main menu','Databases');
  74.  
  75.   procedure truesysops;
  76.   begin
  77.     writeln ('Sorry, you may not do that without true sysop access!');
  78.     writelog (18,17,'')
  79.   end;
  80.  
  81.   function truesysop:boolean;
  82.   begin
  83.     truesysop:=ulvl>=sysoplevel
  84.   end;
  85.  
  86.   procedure eustatus;
  87.   var cnt:integer;
  88.       k:char;
  89.       c:configtype;
  90.   begin
  91.     writehdr ('Status');
  92.     with eurec do begin
  93.       write (^M'Number:    '^S,eunum,
  94.              ^M'Name:      '^S,handle,
  95.              ^M'Phone #:   '^S,phonenum,
  96.              ^M'Pwd:       '^S);
  97.       if truesysop
  98.         then write (password)
  99.         else write ('Classified');
  100.       write (^M'Level:     '^S,level,
  101.              ^M'Last on:   '^S,datestr(laston),', at ',timestr(laston),
  102.              ^M'Posts:     '^S,nbu,
  103.              ^M'Uploads:   '^S,nup,
  104.              ^M'Downloads: '^S,ndn,
  105.              ^M'Wanted:    '^S,yesno(wanted in config),
  106.              ^M'File xfer',
  107.              ^M'  Level:   '^S,udlevel,
  108.              ^M'  Points:  '^S,udpoints,
  109.              ^M'  Uploads: '^S,uploads,
  110.              ^M'  Dnloads: '^S,downloads,
  111.            ^M^M'Time on system:  '^S,totaltime:0:0,
  112.              ^M'Number of calls: '^S,numon,
  113.              ^M'Voting record:   '^S);
  114.       for cnt:=1 to maxtopics do begin
  115.         if cnt<>1 then write (',');
  116.         write (voted[cnt])
  117.       end;
  118.       writeln (^M);
  119.       for c:=udsysop to databasesysop do
  120.         if c in eurec.config
  121.           then writeln (^B'Sysop of the '^S,sectionnames[c]);
  122.       writeln
  123.     end;
  124.     writelog (18,13,'')
  125.   end;
  126.  
  127.   procedure getmstr (t:mstr; var mm);
  128.   var m:mstr absolute mm;
  129.   begin
  130.     writeln ('Old ',t,': '^S,m);
  131.     writestr ('New '+t+'? *');
  132.     if length(input)>0 then m:=input
  133.   end;
  134.  
  135.   procedure getsstr (t:mstr; var s:sstr);
  136.   var m:mstr;
  137.   begin
  138.     m:=s;
  139.     getmstr (t,m);
  140.     s:=m
  141.   end;
  142.  
  143.   procedure getint (t:mstr; var i:integer);
  144.   var m:mstr;
  145.   begin
  146.     m:=strr(i);
  147.     getmstr (t,m);
  148.     i:=valu(m)
  149.   end;
  150.  
  151.   procedure euwanted;
  152.   begin
  153.     writestr ('Wanted status: '^S+yesno(wanted in eurec.config));
  154.     writestr ('New wanted status:');
  155.     if yes
  156.       then eurec.config:=eurec.config+[wanted]
  157.       else eurec.config:=eurec.config-[wanted];
  158.     writelog (18,1,yesno(wanted in eurec.config))
  159.   end;
  160.  
  161.   procedure eudel;
  162.   begin
  163.     writestr ('Delete user --- confirm:');
  164.     if yes then begin
  165.       deleteuser (eunum);
  166.       seek (ufile,eunum);
  167.       read (ufile,eurec);
  168.       writelog (18,9,'')
  169.     end
  170.   end;
  171.  
  172.   procedure euname;
  173.   var m:mstr;
  174.   begin
  175.     m:=eurec.handle;
  176.     getmstr ('name',m);
  177.     if not match (m,eurec.handle) then
  178.       if lookupuser (m)<>0 then begin
  179.         writestr ('Already exists!  Are you sure? *');
  180.         if not yes then exit
  181.       end;
  182.     eurec.handle:=m;
  183.     writelog (18,6,m)
  184.   end;
  185.  
  186.   procedure eupassword;
  187.   begin
  188.     if not truesysop
  189.       then truesysops
  190.       else begin
  191.         getsstr ('password',eurec.password);
  192.         writelog (18,8,'')
  193.       end
  194.   end;
  195.  
  196.   procedure eulevel;
  197.   var n:integer;
  198.   begin
  199.     n:=eurec.level;
  200.     getint ('level',n);
  201.     if (n>=sysoplevel) and (not truesysop)
  202.       then truesysops
  203.       else begin
  204.         eurec.level:=n;
  205.         writelog (18,15,strr(n))
  206.       end
  207.   end;
  208.  
  209.   procedure euphone;
  210.   var m:mstr;
  211.       p:integer;
  212.   begin
  213.     m:=eurec.phonenum;
  214.     buflen:=15;
  215.     getmstr ('phone number',m);
  216.     p:=1;
  217.     while p<=length(m) do
  218.       if (m[p] in ['0'..'9'])
  219.         then p:=p+1
  220.         else delete (m,p,1);
  221.     if length(m)>7 then begin
  222.       eurec.phonenum:=m;
  223.       writelog (18,16,m)
  224.     end
  225.   end;
  226.  
  227.   procedure boardflags;
  228.   var quit:boolean;
  229.  
  230.     procedure listflags;
  231.     var bd:boardrec;
  232.         cnt:integer;
  233.     begin
  234.       seek (bdfile,0);
  235.       for cnt:=0 to filesize(bdfile)-1 do begin
  236.         read (bdfile,bd);
  237.         tab (bd.shortname,9);
  238.         tab (bd.boardname,30);
  239.         writeln (accessstr[getuseraccflag (eurec,cnt)]);
  240.         if break then exit
  241.       end
  242.     end;
  243.  
  244.     procedure changeflag;
  245.     var bn,q:integer;
  246.         bname:mstr;
  247.         ac:accesstype;
  248.     begin
  249.       buflen:=8;
  250.       writestr ('Board to change access:');
  251.       bname:=input;
  252.       bn:=searchboard(input);
  253.       if bn=-1 then begin
  254.         writeln ('Not found!');
  255.         exit
  256.       end;
  257.       writeln (^B^M'Current access: '^S,
  258.                accessstr[getuseraccflag (eurec,bn)]);
  259.       getacflag (ac,input);
  260.       if ac=invalid then exit;
  261.       setuseraccflag (eurec,bn,ac);
  262.       case ac of
  263.         letin:q:=2;
  264.         keepout:q:=3;
  265.         bylevel:q:=4
  266.       end;
  267.       writelog (18,q,bname)
  268.     end;
  269.  
  270.     procedure allflags;
  271.     var ac:accesstype;
  272.     begin
  273.       writehdr ('Set all board access flags');
  274.       getacflag (ac,input);
  275.       if ac=invalid then exit;
  276.       writestr ('Confirm [Y/N]:');
  277.       if not yes then exit;
  278.       setalluserflags (eurec,ac);
  279.       writelog (18,5,accessstr[ac])
  280.     end;
  281.  
  282.   begin
  283.     opentempbdfile;
  284.     quit:=false;
  285.     repeat
  286.       repeat
  287.         writestr (^M'L)ist flags, C)hange one flag, A)ll flags, or Q)uit:');
  288.         if hungupon then exit
  289.       until length(input)<>0;
  290.       case upcase(input[1]) of
  291.         'L':listflags;
  292.         'C':changeflag;
  293.         'A':allflags;
  294.         'Q':quit:=true
  295.       end
  296.     until quit;
  297.     closetempbdfile
  298.   end;
  299.  
  300.   procedure specialsysop;
  301.  
  302.     procedure getsysop (c:configtype);
  303.     begin
  304.       writeln ('Section ',sectionnames[c],': '^S,
  305.                sysopstr[c in eurec.config]);
  306.       writestr ('Grant sysop access? *');
  307.       if length(input)<>0
  308.         then if yes
  309.           then
  310.             begin
  311.               eurec.config:=eurec.config+[c];
  312.               writelog (18,10,sectionnames[c])
  313.             end
  314.           else
  315.             begin
  316.               eurec.config:=eurec.config-[c];
  317.               writelog (18,11,sectionnames[c])
  318.             end
  319.     end;
  320.  
  321.   begin
  322.     if not truesysop then begin
  323.       truesysops;
  324.       exit
  325.     end;
  326.     writestr
  327. ('Section of M)ain, F)ile, B)ulletin, V)oting, E)mail, D)atabase, P)Doors:');
  328.     if length(input)=0 then exit;
  329.     case upcase(input[1]) of
  330.       'M':getsysop (mainsysop);
  331.       'F':getsysop (udsysop);
  332.       'B':getsysop (bulletinsysop);
  333.       'V':getsysop (votingsysop);
  334.       'E':getsysop (emailsysop);
  335.       'D':getsysop (databasesysop);
  336.       'P':getsysop (doorssysop)
  337.     end
  338.   end;
  339.  
  340.   procedure getlogint (prompt:mstr; var i:integer; ln:integer);
  341.   begin
  342.     getint (prompt,i);
  343.     writelog (18,ln,strr(i))
  344.   end;
  345.  
  346. var q:integer;
  347. begin
  348.   writeurec;
  349.   seek (ufile,eunum);
  350.   read (ufile,eurec);
  351.   writelog (2,3,eurec.handle);
  352.   repeat
  353.     q:=menu('User edit','UEDIT','SDHPLOEWTBQYNI');
  354.     case q of
  355.       1:eustatus;
  356.       2:eudel;
  357.       3:euname;
  358.       4:eupassword;
  359.       5:eulevel;
  360.       6:getlogint ('u/d points',eurec.udpoints,7);
  361.       7:getlogint ('u/d level',eurec.udlevel,14);
  362.       8:euwanted;
  363.       9:getlogint ('time for today',eurec.timetoday,12);
  364.       10:boardflags;
  365.       12:specialsysop;
  366.       13:euphone;
  367.       14:showinfoforms(strr(eunum))
  368.     end
  369.   until hungupon or (q=11);
  370.   writeufile (eurec,eunum);
  371.   readurec
  372. end;
  373.  
  374. procedure printnews;
  375. var nfile:file of integer;
  376.     line:integer;
  377. begin
  378.   assign (nfile,'News');
  379.   reset (nfile);
  380.   if ioresult<>0 then exit;
  381.   if filesize (nfile)=0 then begin
  382.     close (nfile);
  383.     exit
  384.   end;
  385.   writehdr ('News: Hit <SPACE> to abort');
  386.   while not (eof(nfile) or break or hungupon) do begin
  387.     read (nfile,line);
  388.     if line>=0 then begin
  389.       writeln;
  390.       printtext (line)
  391.     end
  392.   end;
  393.   close (nfile)
  394. end;
  395.  
  396. procedure sendmodemstr (ss:anystr; endifcarrier:boolean);
  397. var cnt,ptr:integer;
  398.     k:char;
  399. label exit;
  400. begin
  401.   ptr:=0;
  402.   while ptr<length(ss) do
  403.     begin
  404.       if keyhit or (carrier=endifcarrier) then goto exit;
  405.       ptr:=ptr+1;
  406.       k:=ss[ptr];
  407.       case k of
  408.         '|':sendchar (^M);
  409.         '~':delay (500);
  410.         '^':begin
  411.               ptr:=ptr+1;
  412.               if ptr>length(ss)
  413.                 then k:='^'
  414.                 else k:=upcase(ss[ptr]);
  415.               if k in ['A'..'Z']
  416.                 then sendchar (chr(ord(k)-64))
  417.                 else sendchar (k)
  418.             end;
  419.         else sendchar (k)
  420.       end;
  421.       delay (50);
  422.       while numchars>0 do writecon (getchar)
  423.     end;
  424.   cnt:=0;
  425.   repeat
  426.     while numchars>0 do begin
  427.       cnt:=0;
  428.       writecon (getchar)
  429.     end;
  430.     cnt:=cnt+1
  431.   until (cnt=1000) or keyhit or (carrier=endifcarrier);
  432.   exit:
  433.   break:=keyhit
  434. end;
  435.  
  436. function getlastcaller:mstr;
  437. var qf:file of lastrec;
  438.     l:lastrec;
  439. begin
  440.   getlastcaller:='';
  441.   assign (qf,'Callers');
  442.   reset (qf);
  443.   if ioresult=0 then
  444.     if filesize(qf)>0
  445.       then
  446.         begin
  447.           seek (qf,0);
  448.           read (qf,l);
  449.           getlastcaller:=l.name
  450.         end;
  451.   close (qf)
  452. end;
  453.  
  454. procedure showlastcallers;
  455. var qf:file of lastrec;
  456.     cnt:integer;
  457.     l:lastrec;
  458. begin
  459.   assign (qf,'Callers');
  460.   reset (qf);
  461.   if ioresult=0 then begin
  462.     writehdr ('Recent caller list');
  463.     break:=false;
  464.     for cnt:=0 to filesize(qf)-1 do
  465.       if not break then begin
  466.         read (qf,l);
  467.         tab (l.name,33);
  468.         writeln (datestr(l.when)+' '+timestr(l.when))
  469.       end
  470.   end;
  471.   close (qf)
  472. end;
  473.  
  474. procedure infoform;
  475. var ff:text;
  476.     fn:lstr;
  477.     k:char;
  478.     me:message;
  479. begin
  480.   writeln;
  481.   fn:=textfiledir+'InfoForm';
  482.   if not exist (fn) then begin
  483.     writestr ('There isn''t an information form right now.');
  484.     if issysop then
  485.       writeln ('Sysop: To make an information form, create a text file',
  486.              ^M'called ',fn,'.  Use * to indicate a pause for user input.');
  487.     exit
  488.   end;
  489.   if urec.infoform<>-1 then begin
  490.     writestr ('You have an existing information form!  Replace it? *');
  491.     if not yes then exit;
  492.     deletetext (urec.infoform);
  493.     urec.infoform:=-1;
  494.     writeurec
  495.   end;
  496.   assign (ff,fn);
  497.   reset (ff);
  498.   me.numlines:=1;
  499.   me.title:='';
  500.   me.anon:=false;
  501.   me.text[1]:='Filled out on: '+datestr(now)+' at '+timestr(now);
  502.   while not eof(ff) do begin
  503.     if hungupon then begin
  504.       textclose (ff);
  505.       exit
  506.     end;
  507.     read (ff,k);
  508.     if k='*' then begin
  509.       nochain:=true;
  510.       getstr;
  511.       me.numlines:=me.numlines+1;
  512.       me.text[me.numlines]:=input
  513.     end else writechar (k)
  514.   end;
  515.   textclose (ff);
  516.   urec.infoform:=maketext (me);
  517.   writeurec
  518. end;
  519.  
  520. procedure openusfile;
  521. const newusers:userspecsrec=(name:'New users';minlevel:1;maxlevel:1;
  522.          minlaston:-maxint;maxlaston:maxint;minpcr:-maxint;maxpcr:maxint);
  523. begin
  524.   assign (usfile,'userspec');
  525.   reset (usfile);
  526.   if ioresult<>0 then begin
  527.     rewrite (usfile);
  528.     if level2nd<>0 then newusers.maxlevel:=level2nd;
  529.     write (usfile,newusers)
  530.   end
  531. end;
  532.  
  533. procedure editspecs (var us:userspecsrec);
  534.  
  535.   procedure get (tex:string; var value:integer; min:boolean);
  536.   var vstr:sstr;
  537.   begin
  538.     buflen:=6;
  539.     if abs(value)=maxint then vstr:='None' else vstr:=strr(value);
  540.     writestr (tex+' ['+vstr+']:');
  541.     if input[0]<>#0
  542.       then if upcase(input[1])='N'
  543.         then if min
  544.           then value:=-maxint
  545.           else value:=maxint
  546.         else value:=valu(input)
  547.   end;
  548.  
  549.   procedure getreal (tex:string; var value:real; min:boolean);
  550.   var vstr:sstr;
  551.       s:integer;
  552.   begin
  553.     buflen:=10;
  554.     if abs(value)=maxint then vstr:='None' else vstr:=streal(value);
  555.     writestr (tex+' ['+vstr+']:');
  556.     if length(input)<>0
  557.       then if upcase(input[1])='N'
  558.         then if min
  559.           then value:=-maxint
  560.           else value:=maxint
  561.         else begin
  562.           val (input,value,s);
  563.           if s<>0 then value:=0
  564.         end
  565.   end;
  566.  
  567. begin
  568.   writeln (^B^M'Enter specifications; N for none.'^M);
  569.   buflen:=30;
  570.   writestr ('Specification set name ['+us.name+']:');
  571.   if length(input)<>0
  572.     then if match(input,'N')
  573.       then us.name:='Unnamed'
  574.       else us.name:=input;
  575.   get ('Lowest level',us.minlevel,true);
  576.   get ('Highest level',us.maxlevel,true);
  577.   get ('Lowest #days since last call',us.minlaston,true);
  578.   get ('Highest #days since last call',us.maxlaston,true);
  579.   getreal ('Lowest post to call ratio',us.minpcr,true);
  580.   getreal ('Highest post to call ratio',us.maxpcr,true)
  581. end;
  582.  
  583. function getspecs (var us:userspecsrec):integer; { -1:not saved   >0:in file }
  584. begin
  585.   with us do begin
  586.     name:='Unnamed';                     { Assumes USFILE is open !! }
  587.     minlevel:=-maxint;
  588.     maxlevel:=maxint;
  589.     minlaston:=-maxint;
  590.     maxlaston:=maxint;
  591.     minpcr:=-maxint;
  592.     maxpcr:=maxint
  593.   end;
  594.   editspecs (us);
  595.   writestr (^M'Save these specs to disk? *');
  596.   if yes then begin
  597.     seek (usfile,filesize(usfile));
  598.     write (usfile,us);
  599.     getspecs:=filesize(usfile)
  600.   end else getspecs:=-1
  601. end;
  602.  
  603. function searchspecs (var us:userspecsrec; name:mstr):integer;
  604. var v,pos:integer;
  605. begin
  606.   v:=valu(name);
  607.   seek (usfile,0);
  608.   pos:=1;
  609.   while not eof(usfile) do begin
  610.     read (usfile,us);
  611.     if match(us.name,name) or (valu(name)=pos) then begin
  612.       searchspecs:=pos;
  613.       exit
  614.     end;
  615.     pos:=pos+1
  616.   end;
  617.   searchspecs:=0;
  618.   writestr (^M'Not found!')
  619. end;
  620.  
  621. procedure listspecs;
  622. var us:userspecsrec;
  623.     pos:integer;
  624.  
  625.   procedure writeval (n:integer);
  626.   begin
  627.     if abs(n)=maxint then write ('   None') else write(n:7)
  628.   end;
  629.  
  630.   procedure writevalreal (n:real);
  631.   begin
  632.     if abs(n)=maxint then write ('   None') else write(n:7:2)
  633.   end;
  634.  
  635. begin
  636.   writehdr ('User Specification Sets');
  637.   seek (usfile,0);
  638.   pos:=0;
  639.   tab ('',35);
  640.   tab ('    Level    ',14);
  641.   tab ('  Last Call  ',14);
  642.   writeln ('  Post/Call Ratio  ');
  643.   while not (break or eof(usfile)) do begin
  644.     pos:=pos+1;
  645.     read (usfile,us);
  646.     write (pos:3,'. ');
  647.     tab (us.name,30);
  648.     writeval (us.minlevel);
  649.     writeval (us.maxlevel);
  650.     writeval (us.minlaston);
  651.     writeval (us.maxlaston);
  652.     writevalreal (us.minpcr);
  653.     writevalreal (us.maxpcr);
  654.     writeln
  655.   end
  656. end;
  657.  
  658. function selectaspec (var us:userspecsrec):integer; {  0 = none         }
  659. var done:boolean;                                   { -1 = not in file  }
  660.     pos:integer;                                    { -2 = added to end }
  661. begin
  662.   selectaspec:=0;
  663.   openusfile;
  664.   if filesize(usfile)=0
  665.     then selectaspec:=getspecs(us)
  666.     else
  667.       repeat
  668.         if hungupon then exit;
  669.         done:=false;
  670.         writestr (^M'Specification set name (?=list, A=add):');
  671.         if length(input)=0
  672.           then done:=true
  673.           else if match(input,'A')
  674.             then
  675.               begin
  676.                 pos:=getspecs(us);
  677.                 if pos>0
  678.                   then selectaspec:=-2
  679.                   else selectaspec:=-1;
  680.                 done:=true
  681.               end
  682.             else if match(input,'?')
  683.               then listspecs
  684.               else
  685.                 begin
  686.                   pos:=searchspecs (us,input);
  687.                   done:=pos<>0;
  688.                   selectaspec:=pos
  689.                 end
  690.       until done;
  691.   close (usfile)
  692. end;
  693.  
  694. function selectspecs (var us:userspecsrec):boolean;
  695. var dummy:integer;
  696. begin
  697.   dummy:=selectaspec (us);
  698.   selectspecs:=dummy=0
  699. end;
  700.  
  701. procedure deletespecs (pos:integer);
  702. var cnt:integer;
  703.     us:userspecsrec;
  704. begin
  705.   openusfile;
  706.   for cnt:=pos to filesize(usfile)-1 do begin
  707.     seek (usfile,cnt);
  708.     read (usfile,us);
  709.     seek (usfile,cnt-1);
  710.     write (usfile,us)
  711.   end;
  712.   seek (usfile,filesize(usfile)-1);
  713.   truncate (usfile);
  714.   close (usfile)
  715. end;
  716.  
  717. procedure editoldspecs;
  718. var pos:integer;
  719.     us:userspecsrec;
  720. begin
  721.   repeat
  722.     pos:=selectaspec (us);
  723.     if pos>0 then begin
  724.       buflen:=1;
  725.       writestr (^M'E)dit or D)elete? *');
  726.       if length(input)=1 then case upcase(input[1]) of
  727.         'E':begin
  728.               editspecs (us);
  729.               openusfile;
  730.               seek (usfile,pos-1);
  731.               write (usfile,us);
  732.               close (usfile)
  733.             end;
  734.         'D':deletespecs (pos)
  735.       end
  736.     end
  737.   until (pos=0) or hungupon
  738. end;
  739.  
  740. begin
  741. end.
  742.