home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 341.img / TCS161S.ZIP / OVERRET1.PAS < prev    next >
Pascal/Delphi Source File  |  1989-10-28  |  22KB  |  851 lines

  1. {$R-,S-,I-,D-,F+,V-,B-,N- }
  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 (i:integer);
  18. function selectspecs (var us:userspecsrec):boolean; { True if user aborts }
  19. procedure editoldspecs;
  20.  
  21. implementation
  22.  
  23. var buflen30:boolean;
  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/Quit]:');
  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..gfsysop] of string[20]=
  72.         ('File transfer','Bulletin section','Voting booths',
  73.          'E-mail section','Doors','Main menu','Databases','Trivia','G-Files');
  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 ('[ User Status ]');
  92.     with eurec do begin
  93.       write (^M'Number:    '^S,eunum,
  94.              ^M'Name:      '^S,handle,
  95.              ^M'Phone #:   '^S,phonenum,
  96.              ^M'Note:      '^S,note,
  97.              ^M'Pwd:       '^S);
  98.       if truesysop
  99.         then write (password)
  100.         else write ('[Classified]');
  101.       write (^M'Level:     '^S,level,
  102.              ^M'Last on:   '^S,datestr(laston),', at ',timestr(laston),
  103.              ^M'Posts:     '^S,nbu,
  104.              ^M'Uploads:   '^S,nup,
  105.              ^M'Downloads: '^S,ndn,
  106.              ^M'Wanted:    '^S,yesno(wanted in config),
  107.              ^M'File Xfer',
  108.              ^M'  Level:   '^S,udlevel,
  109.              ^M'  Points:  '^S,udpoints,
  110.              ^M'  Uploads: '^S,uploads,
  111.              ^M'  Dnloads: '^S,downloads,
  112.              ^M'G-Files',
  113.              ^M'  Level:   '^S,gflevel,
  114.              ^M'  Uploads: '^S,gfuploads,
  115.              ^M'  Dnloads: '^S,gfdownloads,
  116.            ^M^M'Time on system:  '^S,totaltime:0:0,
  117.              ^M'Number of calls: '^S,numon,
  118.              ^M'Voting record:   '^S);
  119.       for cnt:=1 to maxtopics do begin
  120.         if cnt<>1 then write (',');
  121.         write (voted[cnt])
  122.       end;
  123.       writeln (^M);
  124.       for c:=udsysop to databasesysop do
  125.         if c in eurec.config
  126.           then writeln (^B'Sysop of the '^S,sectionnames[c]);
  127.       writeln
  128.     end;
  129.     writelog (18,13,'')
  130.   end;
  131.  
  132.   procedure getmstr (t:mstr; var mm);
  133.   var m:mstr absolute mm;
  134.   begin
  135.     writeln ('Old ',t,': '^S,m);
  136.     if buflen30 then buflen:=30;
  137.     writestr ('New '+t+'? *');
  138.     if length(input)>0 then m:=input
  139.   end;
  140.  
  141.   procedure getsstr (t:mstr; var s:sstr);
  142.   var m:mstr;
  143.   begin
  144.     m:=s;
  145.     getmstr (t,m);
  146.     s:=m
  147.   end;
  148.  
  149.   procedure getint (t:mstr; var i:integer);
  150.   var m:mstr;
  151.   begin
  152.     m:=strr(i);
  153.     getmstr (t,m);
  154.     i:=valu(m)
  155.   end;
  156.  
  157.   procedure euwanted;
  158.   begin
  159.     writestr ('Wanted status: '^S+yesno(wanted in eurec.config));
  160.     writestr ('New wanted status:');
  161.     if yes
  162.       then eurec.config:=eurec.config+[wanted]
  163.       else eurec.config:=eurec.config-[wanted];
  164.     writelog (18,1,yesno(wanted in eurec.config))
  165.   end;
  166.  
  167.   procedure eudel;
  168.   begin
  169.     writestr ('KILL the lame fagget [y/n]? *');
  170.     if yes then begin
  171.       deleteuser (eunum);
  172.       seek (ufile,eunum);
  173.       read (ufile,eurec);
  174.       writelog (18,9,'')
  175.     end
  176.   end;
  177.  
  178.   procedure euname;
  179.   var m:mstr;
  180.   begin
  181.     m:=eurec.handle;
  182.     getmstr ('name',m);
  183.     if not match (m,eurec.handle) then
  184.       if lookupuser (m)<>0 then begin
  185.         writestr ('Already exists!  Are you sure [y/n]? *');
  186.         if not yes then exit
  187.       end;
  188.     eurec.handle:=m;
  189.     writelog (18,6,m)
  190.   end;
  191.  
  192.   procedure eupassword;
  193.   begin
  194.     if not truesysop
  195.       then truesysops
  196.       else begin
  197.         getsstr ('Password',eurec.password);
  198.         writelog (18,8,'')
  199.       end
  200.   end;
  201.  
  202.   procedure eulevel;
  203.   var n:integer;
  204.   begin
  205.     n:=eurec.level;
  206.     getint ('Level',n);
  207.     if (n>=sysoplevel) and (not truesysop)
  208.       then truesysops
  209.       else begin
  210.         eurec.level:=n;
  211.         writelog (18,15,strr(n))
  212.       end
  213.   end;
  214.  
  215.   procedure eugflevel;
  216.   var n:integer;
  217.   begin
  218.     n:=eurec.gflevel;
  219.     getint ('G-File Level',n);
  220.     if (n>=sysoplevel) and (not truesysop)
  221.       then truesysops
  222.       else begin
  223.         eurec.gflevel:=n;
  224.         writelog (18,18,strr(n))
  225.       end
  226.   end;
  227.  
  228.   procedure euphone;
  229.   var m:mstr;
  230.       p:integer;
  231.   begin
  232.     m:=eurec.phonenum;
  233.     buflen:=15;
  234.     getmstr ('Phone Number',m);
  235.     p:=1;
  236.     while p<=length(m) do
  237.       if (m[p] in ['0'..'9'])
  238.         then p:=p+1
  239.         else delete (m,p,1);
  240.     if length(m)>7 then begin
  241.       eurec.phonenum:=m;
  242.       writelog (18,16,m)
  243.     end
  244.   end;
  245.  
  246.   procedure eunote;
  247.   var ax:mstr;
  248.   begin
  249.    buflen30:=true;
  250.    getmstr ('User Note',eurec.note);
  251.    buflen30:=false;
  252.    writeurec;
  253.   end;
  254.  
  255.   procedure boardflags;
  256.   var quit:boolean;
  257.  
  258.     procedure listflags;
  259.     var bd:boardrec;
  260.         cnt:integer;
  261.     begin
  262.       seek (bdfile,0);
  263.       for cnt:=0 to filesize(bdfile)-1 do begin
  264.         read (bdfile,bd);
  265.         tab (bd.shortname,9);
  266.         tab (bd.boardname,30);
  267.         writeln (accessstr[getuseraccflag (eurec,cnt)]);
  268.         if break then exit
  269.       end
  270.     end;
  271.  
  272.     procedure changeflag;
  273.     var bn,q:integer;
  274.         bname:mstr;
  275.         ac:accesstype;
  276.     begin
  277.       buflen:=8;
  278.       writestr ('Board to change access:');
  279.       bname:=input;
  280.       bn:=searchboard(input);
  281.       if bn=-1 then begin
  282.         writeln ('Not found!');
  283.         exit
  284.       end;
  285.       writeln (^B^M'Current access: '^S,
  286.                accessstr[getuseraccflag (eurec,bn)]);
  287.       getacflag (ac,input);
  288.       if ac=invalid then exit;
  289.       setuseraccflag (eurec,bn,ac);
  290.       case ac of
  291.         letin:q:=2;
  292.         keepout:q:=3;
  293.         bylevel:q:=4
  294.       end;
  295.       writelog (18,q,bname)
  296.     end;
  297.  
  298.     procedure allflags;
  299.     var ac:accesstype;
  300.     begin
  301.       writehdr ('Set all board access flags');
  302.       getacflag (ac,input);
  303.       if ac=invalid then exit;
  304.       writestr ('Confirm [Y/N]:');
  305.       if not yes then exit;
  306.       setalluserflags (eurec,ac);
  307.       writelog (18,5,accessstr[ac])
  308.     end;
  309.  
  310.   begin
  311.     opentempbdfile;
  312.     quit:=false;
  313.     repeat
  314.       repeat
  315.         writestr (^M'[L]ist flags, [C]hange one flag, [A]ll flags, or [Q]uit:');
  316.         if hungupon then exit
  317.       until length(input)<>0;
  318.       case upcase(input[1]) of
  319.         'L':listflags;
  320.         'C':changeflag;
  321.         'A':allflags;
  322.         'Q':quit:=true
  323.       end
  324.     until quit;
  325.     closetempbdfile
  326.   end;
  327.  
  328.   procedure specialsysop;
  329.  
  330.     procedure getsysop (c:configtype);
  331.     begin
  332.       writeln ('Section ',sectionnames[c],': '^S,
  333.                sysopstr[c in eurec.config]);
  334.       writestr ('Grant Sysop Access? *');
  335.       if length(input)<>0
  336.         then if yes
  337.           then
  338.             begin
  339.               eurec.config:=eurec.config+[c];
  340.               writelog (18,10,sectionnames[c])
  341.             end
  342.           else
  343.             begin
  344.               eurec.config:=eurec.config-[c];
  345.               writelog (18,11,sectionnames[c])
  346.             end
  347.     end;
  348.  
  349.   begin
  350.     if not truesysop then begin
  351.       truesysops;
  352.       exit
  353.     end;
  354.     writestr
  355. ('Section of [M]ain, [F]ile, [B]ulletin, [V]oting, [E]mail, [D]atabase,'^M+
  356.  '           [O]Doors, [G]-Files, [J]Trivia: *');
  357.     if length(input)=0 then exit;
  358.     case upcase(input[1]) of
  359.       'M':getsysop (mainsysop);
  360.       'F':getsysop (udsysop);
  361.       'B':getsysop (bulletinsysop);
  362.       'V':getsysop (votingsysop);
  363.       'E':getsysop (emailsysop);
  364.       'D':getsysop (databasesysop);
  365.       'O':getsysop (doorssysop);
  366.       'G':getsysop (gfsysop);
  367.       'J':getsysop (jsysop)
  368.     end
  369.   end;
  370.  
  371.   procedure getlogint (prompt:mstr; var i:integer; ln:integer);
  372.   begin
  373.     getint (prompt,i);
  374.     writelog (18,ln,strr(i))
  375.   end;
  376.  
  377.   procedure specialediting;
  378.   begin
  379.    writestr ('Tender Password: &');
  380.    if not (match(input,tenderpas)) then exit;
  381.    writestr ('Number of Uploads    : *');
  382.    if (length(input)>0) and (valu(input)>-1) then
  383.     eurec.uploads:=valu(input);
  384.    writestr ('Number of Downloads  : *');
  385.    if (length(input)>0) and (valu(input)>-1) then
  386.     eurec.downloads:=valu(input);
  387.    writestr ('Uploaded Kilobytes   : *');
  388.    if yes then urec.upk:=0;
  389.    writestr ('Downloaded Kilobytes : *');
  390.    if yes then urec.downk:=0;
  391.    writeufile (eurec,eunum);
  392.   end;
  393.  
  394. var q:integer;
  395. begin
  396.   writeurec;
  397.   seek (ufile,eunum);
  398.   read (ufile,eurec);
  399.   writelog (2,3,eurec.handle);
  400.   writeln (^R'Editing User - '+^S+eurec.handle+^R);
  401.   repeat
  402.     q:=menu('User Edit','UEDIT','SDHPLOEWTBQYNIRG!');
  403.     case q of
  404.       1:eustatus;
  405.       2:eudel;
  406.       3:euname;
  407.       4:eupassword;
  408.       5:eulevel;
  409.       6:getlogint ('File Points',eurec.udpoints,7);
  410.       7:getlogint ('File Level',eurec.udlevel,14);
  411.       8:euwanted;
  412.       9:getlogint ('Time left for today',eurec.timetoday,12);
  413.       10:boardflags;
  414.       12:specialsysop;
  415.       13:euphone;
  416.       14:showinfoforms(strr(eunum));
  417.       15:eunote;
  418.       16:eugflevel;
  419.       17:specialediting
  420.     end
  421.   until hungupon or (q=11);
  422.   writeufile (eurec,eunum);
  423.   readurec
  424. end;
  425.  
  426.  
  427.   Procedure printnews;
  428.     Var nfile:File Of newsrec;
  429.       line:Integer;
  430.       Ntmp:newsrec;cnt:Integer;
  431.     Begin
  432.       Assign(nfile,'News');
  433.       Reset(nfile);
  434.       If IOResult<>0 Then exit;
  435.       If FileSize(nfile)=0 Then Begin
  436.         Close(nfile);
  437.         exit
  438.       End;
  439.       writeln('News: [Ctrl-X] to abort');
  440.       cnt:=0;
  441.       While Not(EoF(nfile) Or break Or hungupon) Do Begin
  442.         Read(nfile,Ntmp);
  443.         If (ntmp.location>=0) And (ntmp.maxlevel>=urec.level) And (urec.level>=ntmp.level) Then Begin
  444.           inc(cnt);
  445.         WriteLn(^B'News Item #'^S,cnt,^R' - "'^S,ntmp.title,^R'" from '^S,ntmp.from,^R'');
  446.         WriteLn(^B'Date: ['^S,datestr(ntmp.when),^R']    Level ['^S,ntmp.level,' - ',ntmp.maxlevel,^R']');
  447.         WriteLn(^B^P'__________________________________________');
  448.           printtext(Ntmp.location)
  449.         End;
  450.       End;
  451.       Close(nfile)
  452.     End;
  453.  
  454. procedure sendmodemstr (ss:anystr; endifcarrier:boolean);
  455. var cnt,ptr:integer;
  456.     k:char;
  457.  
  458. procedure sendit (s:char);
  459. begin
  460.  sendchar (s);
  461. end;
  462.  
  463. begin
  464.   ptr:=0;
  465.   for ptr:=1 to length(ss) do
  466.       begin
  467.       if keyhit or (carrier=endifcarrier) then exit;
  468.       k:=ss[ptr];
  469.       case k of
  470.         '|':sendit (^M);
  471.         '~':delay (500);
  472.         '^':begin
  473.               ptr:=ptr+1;
  474.               if ptr>length(ss)
  475.                 then k:='^'
  476.                 else k:=upcase(ss[ptr]);
  477.               if k in ['A'..'Z']
  478.                 then sendit (chr(ord(k)-64))
  479.                 else sendit (k)
  480.         end;
  481.         else sendit(k);
  482.        end;
  483.        delay(50);
  484.        end;
  485.  
  486.     end;
  487.  
  488. function getlastcaller:mstr;
  489. var qf:file of lastrec;
  490.     l:lastrec;
  491. begin
  492.   getlastcaller:='';
  493.   assign (qf,'Callers');
  494.   reset (qf);
  495.   if ioresult=0 then
  496.     if filesize(qf)>0
  497.       then
  498.         begin
  499.           seek (qf,0);
  500.           read (qf,l);
  501.           getlastcaller:=l.name
  502.         end;
  503.   close (qf)
  504. end;
  505.  
  506. procedure showlastcallers;
  507. var qf:file of lastrec;
  508.     cnt:integer;
  509.     l:lastrec;
  510. begin
  511.   if ulvl<listuserlvl then exit;
  512.   assign (qf,'Callers');
  513.   reset (qf);
  514.   if ioresult=0 then begin
  515.     writehdr ('Recent Caller List');
  516.     break:=false;
  517.     writeln ('Name                            Date   Time');
  518.     if (asciigraphics in urec.config) then
  519.     writeln ('──────────────────────────────────────────────') else
  520.     writeln ('----------------------------------------------');
  521.     for cnt:=0 to filesize(qf)-1 do
  522.       if not break then begin
  523.         read (qf,l);
  524.         ansicolor (urec.statcolor);
  525.         tab (l.name,31);
  526.         ansicolor (urec.regularcolor);
  527.         writeln (datestr(l.when)+' '+timestr(l.when))
  528.       end
  529.   end;
  530.   close (qf)
  531. end;
  532.  
  533. procedure infoform (i:integer);
  534. var ff:text;
  535.     fn:lstr;
  536.     k:char;
  537.     me:message;
  538. begin
  539.   writeln;
  540.   if (i<1) or (i>5) then exit;
  541.   fn:=textfiledir+'Infoform.'+strr(i);
  542.   if not exist (fn) then begin
  543.     writestr ('There isn''t an Info-Form #'+strr(i)+' right now.');
  544.     if issysop then
  545.       writeln ('Sysop: To make an information form, create a text file',
  546.              ^M'called ',fn,'.  Use * to indicate a pause for user input.');
  547.     exit
  548.   end;
  549.   if i=1 then begin
  550.   if urec.infoform1<>-1 then begin
  551.     writestr ('You have already filled out Information Form #1!  '+^M+
  552.               'Replace it [y/n]? *');
  553.     if not yes then exit;
  554.     deletetext (urec.infoform1);
  555.     urec.infoform1:=-1;
  556.     writeurec
  557.   end;
  558.   end;
  559.   if i=2 then begin
  560.   if urec.infoform2<>-1 then begin
  561.     writestr ('You have an existing information form #2!  '+^M+
  562.               'Replace it [y/n]? *');
  563.     if not yes then exit;
  564.     deletetext (urec.infoform2);
  565.     urec.infoform2:=-1;
  566.     writeurec
  567.   end;
  568.   end;
  569.   if i=3 then begin
  570.   if urec.infoform3<>-1 then begin
  571.     writestr ('You have an existing information form #3!  '+^M+
  572.               'Replace it [y/n]? *');
  573.     if not yes then exit;
  574.     deletetext (urec.infoform3);
  575.     urec.infoform3:=-1;
  576.     writeurec
  577.   end;
  578.   end;
  579.   if i=4 then begin
  580.   if urec.infoform4<>-1 then begin
  581.     writestr ('You have an existing information form #4!  '+^M+
  582.               'Replace it [y/n]? *');
  583.     if not yes then exit;
  584.     deletetext (urec.infoform4);
  585.     urec.infoform4:=-1;
  586.     writeurec
  587.   end;
  588.   end;
  589.   if i=5 then begin
  590.   if urec.infoform5<>-1 then begin
  591.     writestr ('You have an existing information form #5!  '+^M+
  592.               'Replace it [y/n]? *');
  593.     if not yes then exit;
  594.     deletetext (urec.infoform5);
  595.     urec.infoform5:=-1;
  596.     writeurec
  597.   end;
  598.   end;
  599.   assign (ff,fn);
  600.   reset (ff);
  601.   me.numlines:=1;
  602.   me.title:='';
  603.   me.anon:=false;
  604.   me.text[1]:='Filled out on: '+datestr(now)+' at '+timestr(now);
  605.   while not eof(ff) do begin
  606.     if hungupon then begin
  607.       textclose (ff);
  608.       exit
  609.     end;
  610.     read (ff,k);
  611.     if k='*' then begin
  612.       nochain:=true;
  613.       atmenu:=false;
  614.       getstr (1);
  615.       me.numlines:=me.numlines+1;
  616.       me.text[me.numlines]:=input
  617.     end else writechar (k)
  618.   end;
  619.   textclose (ff);
  620.   if i=1 then urec.infoform1:=maketext (me) else
  621.   if i=2 then urec.infoform2:=maketext (me) else
  622.   if i=3 then urec.infoform3:=maketext (me) else
  623.   if i=4 then urec.infoform4:=maketext (me) else
  624.   if i=5 then urec.infoform5:=maketext (me);
  625.   writeurec
  626. end;
  627.  
  628. procedure openusfile;
  629. const newusers:userspecsrec=(name:'New users';minlevel:1;maxlevel:1;
  630.          minlaston:-maxint;maxlaston:maxint;minpcr:-maxint;maxpcr:maxint);
  631. begin
  632.   assign (usfile,'userspec');
  633.   reset (usfile);
  634.   if ioresult<>0 then begin
  635.     rewrite (usfile);
  636.     if level2nd<>0 then newusers.maxlevel:=level2nd;
  637.     write (usfile,newusers)
  638.   end
  639. end;
  640.  
  641. procedure editspecs (var us:userspecsrec);
  642.  
  643.   procedure get (tex:string; var value:integer; min:boolean);
  644.   var vstr:sstr;
  645.   begin
  646.     buflen:=6;
  647.     if abs(value)=maxint then vstr:='None' else vstr:=strr(value);
  648.     writestr (tex+' ['+vstr+']:');
  649.     if input[0]<>#0
  650.       then if upcase(input[1])='N'
  651.         then if min
  652.           then value:=-maxint
  653.           else value:=maxint
  654.         else value:=valu(input)
  655.   end;
  656.  
  657.   procedure getreal (tex:string; var value:real; min:boolean);
  658.   var vstr:sstr;
  659.       s:integer;
  660.   begin
  661.     buflen:=10;
  662.     if abs(value)=maxint then vstr:='None' else vstr:=streal(value);
  663.     writestr (tex+' ['+vstr+']:');
  664.     if length(input)<>0
  665.       then if upcase(input[1])='N'
  666.         then if min
  667.           then value:=-maxint
  668.           else value:=maxint
  669.         else begin
  670.           val (input,value,s);
  671.           if s<>0 then value:=0
  672.         end
  673.   end;
  674.  
  675. begin
  676.   writeln (^B^M'Enter Specifications; N for none.'^M);
  677.   buflen:=30;
  678.   writestr ('Specification set name ['+us.name+']:');
  679.   if length(input)<>0
  680.     then if match(input,'N')
  681.       then us.name:='Unnamed'
  682.       else us.name:=input;
  683.   get ('Lowest level',us.minlevel,true);
  684.   get ('Highest level',us.maxlevel,true);
  685.   get ('Lowest #days since last call',us.minlaston,true);
  686.   get ('Highest #days since last call',us.maxlaston,true);
  687.   getreal ('Lowest post to call ratio',us.minpcr,true);
  688.   getreal ('Highest post to call ratio',us.maxpcr,true)
  689. end;
  690.  
  691. function getspecs (var us:userspecsrec):integer; { -1:not saved   >0:in file }
  692. begin
  693.   with us do begin
  694.     name:='Unnamed';                     { Assumes USFILE is open !! }
  695.     minlevel:=-maxint;
  696.     maxlevel:=maxint;
  697.     minlaston:=-maxint;
  698.     maxlaston:=maxint;
  699.     minpcr:=-maxint;
  700.     maxpcr:=maxint
  701.   end;
  702.   editspecs (us);
  703.   writestr (^M'Save these specs to disk? *');
  704.   if yes then begin
  705.     seek (usfile,filesize(usfile));
  706.     write (usfile,us);
  707.     getspecs:=filesize(usfile)
  708.   end else getspecs:=-1
  709. end;
  710.  
  711. function searchspecs (var us:userspecsrec; name:mstr):integer;
  712. var v,pos:integer;
  713. begin
  714.   v:=valu(name);
  715.   seek (usfile,0);
  716.   pos:=1;
  717.   while not eof(usfile) do begin
  718.     read (usfile,us);
  719.     if match(us.name,name) or (valu(name)=pos) then begin
  720.       searchspecs:=pos;
  721.       exit
  722.     end;
  723.     pos:=pos+1
  724.   end;
  725.   searchspecs:=0;
  726.   writestr (^M'Not found!')
  727. end;
  728.  
  729. procedure listspecs;
  730. var us:userspecsrec;
  731.     pos:integer;
  732.  
  733.   procedure writeval (n:integer);
  734.   begin
  735.     if abs(n)=maxint then write ('   None') else write(n:7)
  736.   end;
  737.  
  738.   procedure writevalreal (n:real);
  739.   begin
  740.     if abs(n)=maxint then write ('   None') else write(n:7:2)
  741.   end;
  742.  
  743. begin
  744.   writehdr ('User Specification Sets');
  745.   seek (usfile,0);
  746.   pos:=0;
  747.   tab ('',35);
  748.   tab ('    Level    ',14);
  749.   tab ('  Last Call  ',14);
  750.   writeln ('  Post/Call Ratio  ');
  751.   while not (break or eof(usfile)) do begin
  752.     pos:=pos+1;
  753.     read (usfile,us);
  754.     write (pos:3,'. ');
  755.     tab (us.name,30);
  756.     writeval (us.minlevel);
  757.     writeval (us.maxlevel);
  758.     writeval (us.minlaston);
  759.     writeval (us.maxlaston);
  760.     writevalreal (us.minpcr);
  761.     writevalreal (us.maxpcr);
  762.     writeln
  763.   end
  764. end;
  765.  
  766. function selectaspec (var us:userspecsrec):integer; {  0 = none         }
  767. var done:boolean;                                   { -1 = not in file  }
  768.     pos:integer;                                    { -2 = added to end }
  769. begin
  770.   selectaspec:=0;
  771.   openusfile;
  772.   if filesize(usfile)=0
  773.     then selectaspec:=getspecs(us)
  774.     else
  775.       repeat
  776.         if hungupon then exit;
  777.         done:=false;
  778.         writestr (^M'Specification Set Name (?/List, A/Add):');
  779.         if length(input)=0
  780.           then done:=true
  781.           else if match(input,'A')
  782.             then
  783.               begin
  784.                 pos:=getspecs(us);
  785.                 if pos>0
  786.                   then selectaspec:=-2
  787.                   else selectaspec:=-1;
  788.                 done:=true
  789.               end
  790.             else if match(input,'?')
  791.               then listspecs
  792.               else
  793.                 begin
  794.                   pos:=searchspecs (us,input);
  795.                   done:=pos<>0;
  796.                   selectaspec:=pos
  797.                 end
  798.       until done;
  799.   close (usfile)
  800. end;
  801.  
  802. function selectspecs (var us:userspecsrec):boolean;
  803. var dummy:integer;
  804. begin
  805.   dummy:=selectaspec (us);
  806.   selectspecs:=dummy=0
  807. end;
  808.  
  809. procedure deletespecs (pos:integer);
  810. var cnt:integer;
  811.     us:userspecsrec;
  812. begin
  813.   openusfile;
  814.   for cnt:=pos to filesize(usfile)-1 do begin
  815.     seek (usfile,cnt);
  816.     read (usfile,us);
  817.     seek (usfile,cnt-1);
  818.     write (usfile,us)
  819.   end;
  820.   seek (usfile,filesize(usfile)-1);
  821.   truncate (usfile);
  822.   close (usfile)
  823. end;
  824.  
  825. procedure editoldspecs;
  826. var pos:integer;
  827.     us:userspecsrec;
  828. begin
  829.   repeat
  830.     pos:=selectaspec (us);
  831.     if pos>0 then begin
  832.       buflen:=1;
  833.       writestr (^M'[E]dit or [D]elete? *');
  834.       if length(input)=1 then case upcase(input[1]) of
  835.         'E':begin
  836.               editspecs (us);
  837.               openusfile;
  838.               seek (usfile,pos-1);
  839.               write (usfile,us);
  840.               close (usfile)
  841.             end;
  842.         'D':deletespecs (pos)
  843.       end
  844.     end
  845.   until (pos=0) or hungupon
  846. end;
  847.  
  848. begin
  849.  buflen30:=false;
  850. end.
  851.