home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / FORUM25C.ZIP / MAINMENU.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-02-05  |  29.7 KB  |  1,270 lines

  1. {$R-,S-,I-,D-,V-,B-,N-,L- }
  2. {$O+}
  3.  
  4. unit mainmenu;
  5.  
  6.  
  7. {/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\}
  8.  
  9. interface
  10.  
  11. USES Overlay,
  12.      crt,
  13.      dos,
  14.      gentypes,
  15.      configrt,
  16.      statret,
  17.      textret,
  18.      userret,
  19.      mailret,
  20.      gensubs,
  21.      subs1,
  22.      subs2,
  23.      windows,
  24.      Shell,
  25.      chatstuf,
  26.      mainr1,
  27.      mainr2,
  28.      overret1;
  29.  
  30. {/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\}
  31.  
  32.  
  33. Procedure editusers;
  34. Procedure zapspecifiedusers;
  35. Procedure summonsysop;
  36. Procedure offtheforum;
  37. Procedure listusers;
  38. Procedure transfername;
  39. Procedure editnews;
  40. Procedure yourstatus;
  41. Procedure delerrlog;
  42. Procedure feedback;
  43. Procedure settime;
  44. Procedure changepwd;
  45. Procedure requestraise;
  46. Procedure makeuser;
  47. Procedure infoformhunt;
  48. Procedure donations;
  49. Procedure viewsyslog;
  50. Procedure delsyslog;
  51. Procedure showsystemstatus;
  52. Procedure showallforms;
  53. Procedure showallsysops;
  54. Procedure mainhelp;
  55. Procedure otherbbs;
  56. Procedure readerrlog;
  57. Procedure showad;
  58. Procedure setlastcall;
  59. Procedure removeallforms;
  60. Procedure readfeedback;
  61. Procedure PriorityPage;
  62. Procedure Convert_Mail;
  63.  
  64. {/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\}
  65.  
  66. implementation
  67.  
  68. {/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\}
  69.  
  70.  
  71. {=============================================================================}
  72.  
  73. Procedure PriorityPage;                                {Mon  4 Jan 88}
  74.  
  75.           {This unit allows someone with priority access to page the
  76.            sysop even when normally not available.}
  77.  
  78. CONST MaxPage = 10000;
  79.  
  80.         var
  81.              count     : integer;
  82.              c1        : integer;
  83.              s         : SStr;
  84.              z         : text;
  85.  
  86.         procedure makesound( which : byte );
  87.  
  88.           var
  89.                c1, c2 : integer;
  90.  
  91.           begin
  92.             which:= ( which mod 3 ) + 1;
  93.             case which of
  94.               1:
  95.                   for c2:=1 to 50 do begin
  96.                     if odd(c2) then
  97.                       for c1:=500 to 2000 do Sound(c1)
  98.                     else
  99.                       for c1:=2000 downto 500 do Sound(c1);
  100.                   end;
  101.               2:
  102.                   for c2:=1 to 200 do begin
  103.                     for c1:=100 to 250 do Sound(c1*10);
  104.                     for c1:=50 to 150 do Sound(c1*10);
  105.                   end;
  106.               3:
  107.                   for c2:=1 to 25 do begin
  108.                     Sound(1800); Delay(75);
  109.                     Sound(1500); Delay(75);
  110.                   end;
  111.             end; {case}
  112.             NoSound;
  113.           end; {makesound}
  114.  
  115.         Begin
  116.           Writehdr('Priority Page');
  117.           ChainStr := '';
  118.           Writestr(^M^P'Page Sysop? &');
  119.           if (hungupon) or (not yes) then exit;
  120.           write(^M^M'Paging...');
  121.           count:=1;
  122.           repeat
  123. {            if count mod 10 = 0 then write('.');
  124.             If KeyHit THEN
  125.               Begin
  126.                 NoSound;
  127.                 Exit;
  128.               End;
  129.             if odd(count) then
  130.               for c1:=500 to 2000 do Sound(c1)
  131.             else
  132.               for c1:=2000 downto 500 do Sound(c1);
  133.             count:=count+1;
  134.             if count=MaxPage then count:=0;
  135.             NoSound;
  136.             if count mod 100 = 0 then begin
  137.               ChainStr := '';
  138.               WriteStr(^M^M^S'Continue? &');
  139.               if (hungupon) or (not yes) then exit;
  140.             end;
  141. }
  142.             makesound(Random(3)+1);
  143.             writestr(^M^M^P'Continue? &');
  144.             if (hungupon) or (not yes) then exit;
  145.  
  146.           until hungupon;
  147.         end; {PriorityPage}
  148.  
  149. {=============================================================================}
  150.  
  151. Procedure editusers;
  152. VAR eunum:integer;
  153.     matched:boolean;
  154.  
  155.   Procedure elistusers (getspecs:boolean);
  156.   VAR cnt,f,l:integer;
  157.       u:userrec;
  158.       us:userspecsrec;
  159.  
  160.     Procedure listuser;
  161.     begin
  162.       write (cnt:4,' ');
  163.       tab (u.handle,31);
  164.       write (u.level:6,' ');
  165.       tab (datestr(u.laston),8);
  166.       writeln (u.nbu:6,u.numon:6,postcallratio(u):7:2)
  167.     end;
  168.  
  169.   begin
  170.     if getspecs
  171.       then if selectspecs(us)
  172.         then exit
  173.         else
  174.           begin
  175.             f:=1;
  176.             l:=numusers
  177.           end
  178.       else parserange (numusers,f,l);
  179.     seek (ufile,f);
  180.     matched:=false;
  181.     writeln (^B^M^M' Num Name                            Level ',
  182.              'Last on  Posts Calls PCR');
  183.     for cnt:=f to l do begin
  184.       read (ufile,u);
  185.       if (not getspecs) or fitsspecs(u,us) then begin
  186.         listuser;
  187.         matched:=true
  188.       end;
  189.       handleincoming;
  190.       if break then exit
  191.     end;
  192.     if not matched then
  193.       if getspecs
  194.         then writeln (^B^M'No users match specifications!')
  195.         else writeln (^B^M'No users found in that range!')
  196.   end;
  197.  
  198. begin
  199.   repeat
  200.     writestr (^M'User to edit [?,??=list]:');
  201.     if (length(input)=0) or (match(input,'Q')) then exit;
  202.     if input[1]='?'
  203.       then elistusers (input='??')
  204.       else begin
  205.         eunum:=lookupuser (input);
  206.         if eunum=0
  207.           then writestr ('User not found!')
  208.           else edituser (eunum)
  209.       end
  210.   until hungupon
  211. end;
  212.  
  213. Procedure zapspecifiedusers;
  214. VAR us:userspecsrec;
  215.     confirm:boolean;
  216.     u:userrec;
  217.     cnt:integer;
  218.     done:boolean;
  219. begin
  220.   if selectspecs (us) then exit;
  221.   writestr ('Confirm each deletion individually? *');
  222.   if length(input)=0 then exit;
  223.   confirm:=yes;
  224.   if not confirm then begin
  225.     writestr (^M'Are you SURE you want to mass delete without confirmation? *');
  226.     if not yes then exit
  227.   end;
  228.   for cnt:=1 to numusers do begin
  229.     seek (ufile,cnt);
  230.     read (ufile,u);
  231.     if (length(u.handle)>0) and fitsspecs (u,us) then begin
  232.       if confirm
  233.         then
  234.           begin
  235.             done:=false;
  236.             repeat
  237.               writestr ('Delete '+u.handle+' (Y/N/X/E):');
  238.               if length(input)>0 then case upcase(input[1]) of
  239.                 'Y':begin
  240.                       done:=true;
  241.                       writeln ('Deleting '+u.handle+'...');
  242.                       deleteuser (cnt)
  243.                     end;
  244.                 'N':done:=true;
  245.                 'X':exit;
  246.                 'E':begin
  247.                       edituser(cnt);
  248.                       writeln;
  249.                       writeln
  250.                     end
  251.               end
  252.             until done
  253.           end
  254.         else
  255.           begin
  256.             writeln ('Deleting '+u.handle+'...');
  257.             if break then begin
  258.               writestr ('Aborted!!');
  259.               exit
  260.             end;
  261.             deleteuser (cnt)
  262.           end
  263.     end
  264.   end
  265. end;
  266.  
  267. Procedure summonsysop;
  268. VAR tf:text;
  269.     k:char;
  270. begin
  271.   Writeln;
  272.   chatmode:=not chatmode;
  273.   bottomline;
  274.   if chatmode
  275.     then
  276.       if (sysopisavail) OR (Ulvl >= 90)
  277.         then
  278.           begin
  279.             writestr ('Enter a short reason: &');
  280.             chatreason:=input;
  281.             if length(input)=0 then begin
  282.               chatmode:=false;
  283.               exit
  284.             end;
  285.             writelog (1,3,chatreason);
  286.             splitscreen (4);
  287.             top;
  288.             clrscr;
  289.             writeln (usr,unam,' wants to chat!  His reason:');
  290.             write (usr,chatreason);
  291.             bottom;
  292.             assign (tf,textfiledir+'Summon');
  293.             reset (tf);
  294.             if ioresult=0 then begin
  295.               while (not (eof(tf) or hungupon)) and chatmode do
  296.                 begin
  297.                   read (tf,k);
  298.                   nobreak:=true;
  299.                   if ord(k)=7 then summonbeep else writechar (k);
  300.                   if keyhit then begin
  301.                     k:=bioskey;
  302.                     clearbreak;
  303.                     chat_proc;
  304.                   end
  305.                 end;
  306.               textclose (tf)
  307.             end;
  308.             if chatmode
  309.               then writestr (^M'Use [C] again to turn off page.')
  310.               else unsplit
  311.           end
  312.         else
  313.           begin
  314.             writestr ('Sorry, '+sysopname+
  315.                       ' isn''t available right now!');
  316.             chatmode:=false;
  317.             writelog (1,2,'')
  318.           end
  319.     else writestr ('Page off.  Use [C] to turn it back on.');
  320.   clearbreak
  321. end;
  322.  
  323. Procedure offtheforum;
  324. VAR q,n:integer;
  325.     tn:file of integer;
  326.     m:message;
  327. begin
  328.   writestr ('Hang up now? *');
  329.   if yes then begin
  330.     writestr ('Leave message to next user? *');
  331.     if yes then begin
  332.       q:=editor(m,false);
  333.       if q>=0 then begin
  334.         if tonext>=0 then deletetext (tonext);
  335.         tonext:=q;
  336.         writestatus
  337.       end
  338.     end;
  339.     printfile (textfiledir+'GoodBye');
  340.     disconnect
  341.   end
  342. end;
  343.  
  344. Procedure listusers;
  345. VAR cnt:integer;
  346.     u:userrec;
  347. begin
  348.   writeln (^B'Name                             Level'^M);
  349.   if break then exit;
  350.   for cnt:=1 to numusers do
  351.     begin
  352.       seek (ufile,cnt);
  353.       read (ufile,u); che;
  354.       if length(u.handle)>0 then begin
  355.         tab (u.handle,33);
  356.         if break then exit;
  357.         writestr (strr(u.level));
  358.         if break then exit
  359.       end
  360.     end
  361. end;
  362.  
  363. Procedure transfername;
  364. VAR un,nlvl,ntime,tmp:integer;
  365.     u:userrec;
  366. begin
  367.   if tempsysop then begin
  368.     writestr ('Disabling temporary sysop powers...');
  369.     ulvl:=regularlevel;
  370.     tempsysop:=false
  371.   end;
  372.   writestr ('Transfer to user name:');
  373.   if length(input)=0 then exit;
  374.   un:=lookupuser(input);
  375.   if unum=un then begin
  376.     writestr ('You can''t transfer to yourself!');
  377.     exit
  378.   end;
  379.   if un=0 then begin
  380.     writestr ('No such user.');
  381.     exit
  382.   end;
  383.   seek (ufile,un);
  384.   read (ufile,u);
  385.   if ulvl<sysoplevel then if not checkpassword(u) then begin
  386.     writelog (1,5,u.handle);
  387.     exit
  388.   end;
  389.   writelog (1,4,u.handle);
  390.   updateuserstats (false);
  391.   ntime:=0;
  392.   if datepart(u.laston)<>datepart(now) then begin
  393.     tmp:=ulvl;
  394.     if tmp<1 then tmp:=1;
  395.     if tmp>100 then tmp:=100;
  396.     ntime:=usertime[tmp]
  397.   end;
  398.   if u.timetoday<10
  399.     then if issysop or (u.level>=sysoplevel)
  400.       then
  401.         begin
  402.           writestr ('The user has '+strr(u.timetoday)+' min(s) left!');
  403.           writestr ('New time left:');
  404.           ntime:=valu(input)
  405.         end
  406.       else
  407.         if u.timetoday>0
  408.           then writeln ('Warning: You have ',u.timetoday,' minutes left!')
  409.           else
  410.             begin
  411.               writestr ('Sorry, that user doesn''t have any time left!');
  412.               exit
  413.             end;
  414.   unum:=un;
  415.   readurec;
  416.   if ntime<>0 then begin
  417.     urec.timetoday:=ntime;
  418.     writeurec
  419.   end;
  420. end;
  421.  
  422. Procedure editnews;
  423. VAR nn,numnews:integer;
  424.     nf:file of integer;
  425.  
  426.   Procedure getnn (txt:mstr);
  427.   begin
  428.     writestr ('News number to '+txt+':');
  429.     nn:=valu(input);
  430.     if (nn<1) or (nn>numnews) then nn:=0
  431.   end;
  432.  
  433.   Procedure delnews;
  434.   VAR cnt:integer;
  435.       r:integer;
  436.   begin
  437.     if nn=0 then getnn ('delete');
  438.     if nn<>0 then begin
  439.       seek (nf,nn-1);
  440.       read (nf,r); che;
  441.       deletetext (r);
  442.       numnews:=filesize(nf)-1;
  443.       for cnt:=nn to numnews do
  444.         begin
  445.           seek (nf,cnt);
  446.           read (nf,r);
  447.           seek (nf,cnt-1);
  448.           write (nf,r)
  449.         end;
  450.       seek (nf,numnews);
  451.       truncate (nf)
  452.     end
  453.   end;
  454.  
  455.   Procedure listnews;
  456.   VAR cnt:integer;
  457.       r,sector:integer;
  458.       q:buffer;
  459.       l:anystr;
  460.       k:char;
  461.   begin
  462.     clearbreak;
  463.     for cnt:=1 to numnews do begin
  464.       seek (nf,cnt-1);
  465.       read (nf,r);
  466.       seek (tfile,r);
  467.       read (tfile,q);
  468.       write (strr(cnt)+'. ');
  469.       r:=1;
  470.       k:=' ';
  471.       l:='';
  472.       while (ord(k)<>13) and not hungupon do begin
  473.         k:=q[r];
  474.         r:=r+1;
  475.         if (k=#0) or (r>sectorsize) then k:=chr(13);
  476.         l:=l+k
  477.       end;
  478.       writeln (l);
  479.       if break then exit
  480.     end;
  481.     writeln
  482.   end;
  483.  
  484.   Procedure viewnews;
  485.   VAR r:integer;
  486.   begin
  487.     if nn=0 then getnn ('view');
  488.     if nn<>0 then begin
  489.       seek (nf,nn-1);
  490.       read (nf,r); che;
  491.       printtext (r)
  492.     end
  493.   end;
  494.  
  495.   Procedure adddnews;
  496.   begin
  497.     close (nf);
  498.     addnews;
  499.     assign (nf,'News');
  500.     reset (nf)
  501.   end;
  502.  
  503. VAR q:integer;
  504. begin
  505.   assign (nf,'News');
  506.   reset (nf);
  507.   if ioresult<>0 then writestr ('No news!  Use [A] to add some!') else begin
  508.     repeat
  509.       numnews:=filesize(nf);
  510.       write (^B^M'News entries: ',numnews);
  511.       q:=menu ('News edit','NEWS','ADLVQ');
  512.       nn:=valu(copy(input,2,255));
  513.       if (nn<1) or (nn>numnews) then nn:=0;
  514.       case q of
  515.         1:adddnews;
  516.         2:delnews;
  517.         3:listnews;
  518.         4:viewnews
  519.       end;
  520.       if numnews=0 then begin
  521.         close (nf);
  522.         erase (nf);
  523.         writestr ('No more news!  Use [A] to add some.');
  524.         q:=5
  525.       end
  526.     until (q=5) or hungupon
  527.   end;
  528.   close (nf)
  529. end;
  530.  
  531. Procedure yourstatus;
  532. begin
  533.   writehdr ('Your Status');
  534.   writeln ('Name:   '^S,unam,
  535.          ^M'Level:  '^S,ulvl,
  536.          ^M'Calls:  '^S,urec.numon,
  537.          ^M'Posted: '^S,urec.nbu,
  538.        ^M^M'Ascii',
  539.          ^M'  Uploads:     '^S,urec.nup,
  540.          ^M'  Downloads:   '^S,urec.ndn,
  541.          ^M'XMODEM',
  542.          ^M'  Uploads:     '^S,urec.uploads,
  543.          ^M'  Downloads:   '^S,urec.downloads,
  544.        ^M^M'Total time on: '^S,urec.totaltime:0:0,
  545.          ^M'Time left:     '^S,timeleft)
  546. end;
  547.  
  548. Procedure delerrlog;
  549. VAR e:text;
  550.     i:integer;
  551. begin
  552.   writestr ('Delete error log:  Confirm:');
  553.   if not yes then exit;
  554.   assign (e,'errlog');
  555.   reset (e);
  556.   i:=ioresult;
  557.   if ioresult=1
  558.     then writeln (^M'No error log!')
  559.     else begin
  560.       textclose (e);
  561.       erase (e);
  562.       writestr ('Error log deleted.');
  563.       if ioresult>1
  564.         then writeln ('I/O error ',i,' deleting error log!');
  565.       writelog (2,2,'')
  566.     end
  567. end;
  568.  
  569. Procedure feedback;
  570. VAR m:mailrec;
  571.     me:message;
  572. begin
  573.   writestr ('Leave feedback? *');
  574.   if not yes then exit;
  575.   m.line:=editor(me,true);
  576.   if m.line<0 then exit;
  577.   m.title:=me.title;
  578.   m.sentby:=unum;
  579.   m.anon:=false;
  580.   m.when:=now;
  581.   addfeedback (m);
  582.   writestr ('Feedback sent.')
  583. end;
  584.  
  585. Procedure settime;
  586. VAR t:integer;
  587.     n:longint;
  588.     r:registers;
  589.     d:datetime;
  590. begin
  591.   writestr ('Current time: '+timestr(now));
  592.   writestr ('Current date: '+datestr(now));
  593.   writestr ('Enter new time:');
  594.   if length(input)<>0
  595.     then begin
  596.       t:=timeleft;
  597.       unpacktime (timeval(input),d);
  598.       r.ch:=d.hour;
  599.       r.cl:=d.min;
  600.       r.dh:=0;
  601.       r.dl:=0;
  602.       r.ah:=$2d;
  603.       intr ($21,r);
  604.       if r.al=$ff then writestr ('Invalid time!');
  605.       settimeleft (t)
  606.     end;
  607.   writestr ('Enter new date:');
  608.   if length(input)<>0
  609.     then begin
  610.       unpacktime (dateval(input),d);
  611.       r.dl:=d.day;
  612.       r.dh:=d.month;
  613.       r.cx:=d.year;
  614.       r.ah:=$2b;
  615.       intr ($21,r);
  616.       if r.al=$ff then writestr ('Invalid date!')
  617.     end;
  618.   writelog (2,4,'')
  619. end;
  620.  
  621. Procedure changepwd;
  622. VAR t:sstr;
  623. begin
  624.   writehdr ('Password Change');
  625.   dots:=true;
  626.   buflen:=15;
  627.   write ('Enter new password: ');
  628.   if getpassword
  629.     then begin
  630.       writeurec;
  631.       writestr ('Password changed.');
  632.       writelog (1,1,'')
  633.     end else
  634.       writestr ('No change.')
  635. end;
  636.  
  637. Procedure requestraise;
  638. VAR t:text;
  639.     q:lstr;
  640.     p,l1,l2:integer;
  641.     s1,s2:sstr;
  642.     me:message;
  643.     m:mailrec;
  644. label nope,found;
  645. begin
  646.   assign (t,textfiledir+'RAISEREQ');
  647.   reset (t);
  648.   if ioresult<>0 then goto nope;
  649.   printtexttopoint (t);
  650.   while not eof(t) do begin
  651.     readln (t,q);
  652.     p:=pos('-',q);
  653.     if p>0
  654.       then
  655.         begin
  656.           s1:=copy(q,1,p-1);
  657.           s2:=copy(q,p+1,255)
  658.         end
  659.       else
  660.         begin
  661.           s1:=copy(q,1,15);
  662.           s2:=s1
  663.         end;
  664.     val (s1,l1,p);
  665.     if p=0 then val (s2,l2,p);
  666.     if p<>0 then begin
  667.       textclose (t);
  668.       error ('Invalid range in RAISEREQ: %1','',q);
  669.       exit
  670.     end;
  671.     if (ulvl>=l1) and (ulvl<=l2) then goto found;
  672.     skiptopoint (t)
  673.   end;
  674.   nope:
  675.   error ('No text for level %1','',strr(ulvl));
  676.   textclose (t);
  677.   p:=ioresult;
  678.   exit;
  679.   found:
  680.   printtexttopoint (t);
  681.   textclose (t);
  682.   if hungupon then exit;
  683.   m.line:=editor (me,false);
  684.   if m.line<0 then exit;
  685.   m.anon:=false;
  686.   m.title:='Raise request; now lvl='+strr(ulvl);
  687.   m.sentby:=unum;
  688.   m.when:=now;
  689.   addfeedback (m);
  690. end;
  691.  
  692. Procedure makeuser;
  693. VAR u:userrec;
  694.     un,ln:integer;
  695. begin
  696.   writehdr ('Add a user');
  697.   writestr ('Name:');
  698.   if length(input)=0 then exit;
  699.   if lookupuser(input)<>0 then begin
  700.     writestr ('Sorry!  Already exists!');
  701.     exit
  702.   end;
  703.   u.handle:=input;
  704.   writestr ('Password:');
  705.   u.password:=input;
  706.   writestr ('Level:');
  707.   if length(input)=0 then exit;
  708.   u.level:=valu(input);
  709.   un:=adduser(u);
  710.   if un=-1 then begin
  711.     writestr ('Sorry, no room for new users!');
  712.     exit
  713.   end;
  714.   ln:=u.level;
  715.   if ln<1 then ln:=1;
  716.   if ln>100 then ln:=100;
  717.   u.timetoday:=usertime[ln];
  718.   seek (ufile,un);
  719.   write (ufile,u);
  720.   writestr ('User added as #'+strr(un)+'.');
  721.   writelog (2,8,u.handle)
  722. end;
  723.  
  724. Procedure infoformhunt;
  725. begin
  726.   writestr ('User to search for [CR=all users]:');
  727.   writeln (^M);
  728.   showinfoforms (input)
  729. end;
  730.  
  731. Procedure donations;
  732. VAR fn:lstr;
  733. begin
  734.   fn:=textfiledir+'Donation';
  735.   if exist (fn)
  736.     then printfile (fn)
  737.     else begin
  738.       writestr ('I''m sorry, no information is currently available.');
  739.       if issysop
  740.         then writestr (
  741. 'Sysop:  To create donation information text, make a file called '+fn)
  742.     end
  743. end;
  744.  
  745. Procedure viewsyslog;
  746. VAR n:integer;
  747.     l:logrec;
  748.  
  749.   Function lookupsyslogdat (m,s:integer):integer;
  750.   VAR cnt:integer;
  751.   begin
  752.     for cnt:=1 to numsyslogdat do with syslogdat[cnt] do
  753.       if (menu=m) and (subcommand=s) then begin
  754.         lookupsyslogdat:=cnt;
  755.         exit
  756.       end;
  757.     lookupsyslogdat:=0
  758.   end;
  759.  
  760.   Function firstentry:boolean;
  761.   begin
  762.     firstentry:=(l.menu=0) and (l.subcommand in [1..2])
  763.   end;
  764.  
  765.   Procedure backup;
  766.   begin
  767.     while n<>0 do begin
  768.       n:=n-1;
  769.       seek (logfile,n);
  770.       read (logfile,l);
  771.       if firstentry then exit
  772.     end;
  773.     n:=-1
  774.   end;
  775.  
  776.   Procedure showentry (includedate:boolean);
  777.   VAR q:lstr;
  778.       p:integer;
  779.   begin
  780.     q:=syslogdat[lookupsyslogdat(l.menu,l.subcommand)].text;
  781.     p:=pos('%',q);
  782.     if p<>0 then q:=copy(q,1,p-1)+l.param+copy(q,p+1,255);
  783.     if includedate then q:=q+' on '+datestr(l.when);
  784.     q:=q+' at '+timestr(l.when);
  785.     writeln (q)
  786.   end;
  787.  
  788. VAR b:boolean;
  789. begin
  790.   writehdr ('View system log');
  791.   writeln ('Press space to advance to the previous caller, X to abort.');
  792.   writeln;
  793.   writelog (2,6,'');
  794.   n:=filesize(logfile);
  795.   repeat
  796.     clearbreak;
  797.     writeln (^M);
  798.     backup;
  799.     if n=-1 then exit;
  800.     seek (logfile,n);
  801.     read (logfile,l);
  802.     showentry (true);
  803.     b:=false;
  804.     while not (eof(logfile) or break or xpressed or b) do begin
  805.       read (logfile,l);
  806.       b:=firstentry;
  807.       if not b then showentry (false);
  808.     end
  809.   until xpressed
  810. end;
  811.  
  812. Procedure delsyslog;
  813. begin
  814.   writestr ('Delete system log: Confirm:');
  815.   if not yes then exit;
  816.   close (logfile);
  817.   rewrite (logfile);
  818.   writeln (^M'System log deleted.');
  819.   writelog (2,7,unam)
  820. end;
  821.  
  822. Procedure showsystemstatus;
  823. VAR totalused,totalidle,totalup,totaldown,totalmins,callsday:real;
  824.  
  825.   Procedure percent (prompt:mstr; top,bot:real);
  826.   VAR p:real;
  827.   begin
  828.     write (prompt);
  829.     if bot<1 then begin
  830.       writeln ('N/A');
  831.       exit
  832.     end;
  833.     p:=round(1000*top/bot)/10;
  834.     writeln (p:0:1,'%')
  835.   end;
  836.  
  837. begin
  838.   totalused:=numminsused.total+elapsedtime(numminsused);
  839.   totalidle:=numminsidle.total;
  840.   totalup:=totalidle+numminsused.total;
  841.   totalmins:=1440.0*(numdaysup-1.0)+timer;
  842.   totaldown:=totalmins-totalup;
  843.   callsday:=round(10*numcallers/numdaysup)/10;
  844.   writehdr ('System Status');
  845.   writeln ('Time & date:       '^S,timestr(now),', ',datestr(now),
  846.        ^M^J'Calls today:       '^S,callstoday,
  847.        ^M^J'Total callers:     '^S,numcallers:0:0,
  848.        ^M^J'Total days up:     '^S,numdaysup,
  849.        ^M^J'Calls per day:     '^S,callsday:0:1,
  850.        ^M^J'Total mins in use: '^S,numminsused.total:0:0,
  851.        ^M^J'Total mins idle:   '^S,totalidle:0:0,
  852.        ^M^J'Mins file xfer:    '^S,numminsxfer.total:0:0,
  853.        ^M^J'Total mins up:     '^S,totalup:0:0,
  854.        ^M^J'Total mins down:   '^S,totaldown:0:0);
  855.   percent ('Percent in use:    '^S,totalused,totalmins);
  856.   percent ('Percent idle:      '^S,totalidle,totalmins);
  857.   percent ('Percent up:        '^S,totalup,totalmins);
  858.   percent ('Percent down:      '^S,totaldown,totalmins);
  859. end;
  860.  
  861. Procedure showallforms;
  862. begin
  863.   showinfoforms ('')
  864. end;
  865.  
  866. Procedure showallsysops;
  867. VAR n:integer;
  868.     u:userrec;
  869.     q:set of configtype;
  870.     s:configtype;
  871.  
  872.   Procedure showuser;
  873.   const sectionnames:array [udsysop..databasesysop] of string[20]=
  874.          ('File transfer','Bulletin section','Voting booths',
  875.           'E-mail section','Doors','Main menu','Databases');
  876.   VAR s:configtype;
  877.   begin
  878.     writeln (^B^M'Name:  '^S,u.handle,
  879.                ^M'Level: '^S,u.level,^M);
  880.     for s:=udsysop to databasesysop do
  881.       if s in u.config then
  882.         writeln ('Sysop of the ',sectionnames[s]);
  883.     writestr (^M'Edit user? *');
  884.     if yes then edituser (n)
  885.   end;
  886.  
  887. begin
  888.   q:=[];
  889.   for s:=udsysop to databasesysop do q:=q+[s];
  890.   for n:=1 to numusers do begin
  891.     seek (ufile,n);
  892.     read (ufile,u);
  893.     if (u.level>=sysoplevel) or (q*u.config<>[]) then showuser
  894.   end
  895. end;
  896.  
  897. Procedure mainhelp;
  898. begin
  899.   help ('Mainmenu.hlp')
  900. end;
  901.  
  902. Procedure otherbbs;
  903. begin
  904.   printfile (textfiledir+'Otherbbs')
  905. end;
  906.  
  907. Procedure readerrlog;
  908. begin
  909.   if exist ('Errlog')
  910.     then printfile ('Errlog')
  911.     else writestr ('No error file!')
  912. end;
  913.  
  914. Procedure showad;
  915. VAR fn:lstr;
  916. begin
  917.   fn:=textfiledir+'Forum.AD';
  918.   if exist (fn) then printfile (fn)
  919. end;
  920.  
  921. Procedure setlastcall;
  922.  
  923.   Function digit (k:char):boolean;
  924.   begin
  925.     digit:=ord(k) in [48..57]
  926.   end;
  927.  
  928.   Function validtime (inp:sstr):boolean;
  929.   VAR c,s,l:integer;
  930.       d1,d2,d3,d4:char;
  931.       ap,m:char;
  932.   begin
  933.     validtime:=false;
  934.     l:=length(inp);
  935.     if (l<7) or (l>8) then exit;
  936.     c:=pos(':',inp);
  937.     if c<>l-5 then exit;
  938.     s:=pos(' ',inp);
  939.     if s<>l-2 then exit;
  940.     d2:=inp[c-1];
  941.     if l=7
  942.       then d1:='0'
  943.       else d1:=inp[1];
  944.     d3:=inp[c+1];
  945.     d4:=inp[c+2];
  946.     ap:=upcase(inp[s+1]);
  947.     m:=upcase(inp[s+2]);
  948.     if d1='1' then if d2>'2' then d2:='!';
  949.     if (d1>='0') and (d1<='1') and digit(d2) and (d3>='0') and (d3<='5')
  950.        and digit(d4) and ((ap='A') or (ap='P')) and (m='M')
  951.          then validtime:=true
  952.   end;
  953.  
  954.   Function validdate (inp:sstr):boolean;
  955.   VAR k,l:char;
  956.  
  957.     Function gchar:char;
  958.     begin
  959.       if length(inp)=0 then begin
  960.         gchar:='?';
  961.         exit
  962.       end;
  963.       gchar:=inp[1];
  964.       delete (inp,1,1)
  965.     end;
  966.  
  967.   begin
  968.     validdate:=false;
  969.     k:=gchar;
  970.     l:=gchar;
  971.     if not digit(k) then exit;
  972.     if l='/'
  973.       then if k='0'
  974.         then exit
  975.         else
  976.       else begin
  977.         if k>'1' then exit;
  978.         if not digit(l) then exit;
  979.         if (l>'2') and (k='1') then exit;
  980.         l:=gchar;
  981.         if l<>'/' then exit
  982.       end;
  983.     k:=gchar;
  984.     l:=gchar;
  985.     if l='/'
  986.       then if k='0'
  987.         then exit
  988.         else
  989.       else begin
  990.         if k>'3' then exit;
  991.         if not digit(l) then exit;
  992.         if (k='3') and (l>'1') then exit;
  993.         l:=gchar;
  994.         if l<>'/' then exit
  995.       end;
  996.     if digit(gchar) and digit(gchar) then validdate:=true
  997.   end;
  998.  
  999. begin
  1000.   writeln (^M'Your last call was: '^S,datestr(laston),' at ',timestr(laston));
  1001.   writestr (^M'Enter new date (mm/dd/yy):');
  1002.   if length(input)>0
  1003.     then if validdate (input)
  1004.       then laston:=dateval(input)+timepart(laston)
  1005.       else writestr ('Invalid date!');
  1006.   writestr (^M'Enter new time (hh:mm am/pm):');
  1007.   if length(input)>0
  1008.     then if validtime(input)
  1009.       then laston:=timeval(input)+datepart(laston)
  1010.       else writestr ('Invalid time!')
  1011. end;
  1012.  
  1013. Procedure removeallforms;
  1014. VAR cnt,ndel:integer;
  1015.     u:userrec;
  1016. begin
  1017.   writestr ('Erase ALL info-forms:  Are you sure? *');
  1018.   if not yes then exit;
  1019.   writeurec;
  1020.   writestr (^M'Erasing... please stand by...');
  1021.   ndel:=0;
  1022.   for cnt:=1 to numusers do begin
  1023.     if (cnt mod 10)=0 then write (cnt,', ');
  1024.     seek (ufile,cnt);
  1025.     read (ufile,u);
  1026.     if u.infoform>=0 then begin
  1027.       deletetext (u.infoform);
  1028.       u.infoform:=-1;
  1029.       seek (ufile,cnt);
  1030.       write (ufile,u);
  1031.       ndel:=ndel+1
  1032.     end
  1033.   end;
  1034.   writeln ('done.');
  1035.   writestr (^M'All '+strr(ndel)+' forms erased.');
  1036.   readurec
  1037. end;
  1038.  
  1039. Procedure readfeedback;
  1040. VAR ffile:file of mailrec;
  1041.     m:mailrec;
  1042.     me:message;
  1043.     cur:integer;
  1044.  
  1045.   Function nummessages:integer;
  1046.   begin
  1047.     nummessages:=filesize(ffile)
  1048.   end;
  1049.  
  1050.   Function checkcur:boolean;
  1051.   begin
  1052.     if length(input)>1 then cur:=valu(copy(input,2,255));
  1053.     if (cur<1) or (cur>nummessages) then begin
  1054.       writestr (^M'Message out of range!');
  1055.       cur:=0;
  1056.       checkcur:=true
  1057.     end else begin
  1058.       checkcur:=false;
  1059.       seek (ffile,cur-1);
  1060.       read (ffile,m)
  1061.     end
  1062.   end;
  1063.  
  1064.   Procedure readnum(n:integer);
  1065.   begin
  1066.     cur:=n;
  1067.     input:='';
  1068.     if checkcur then exit;
  1069.     writeln (^B^M'Message: '^S,cur,
  1070.                ^M'Title:   '^S,m.title,
  1071.                ^M'Sent by: '^S,LookUpUName(m.sentby),
  1072.                ^M'Sent on: '^S,datestr(m.when),' at ',timestr(m.when),^M);
  1073.     if break then exit;
  1074.     printtext (m.line)
  1075.   end;
  1076.  
  1077.   Procedure writecurmsg;
  1078.   begin
  1079.     if (cur<1) or (cur>nummessages) then cur:=0;
  1080.     write (^B^M'Current msg: '^S);
  1081.     if cur=0 then write ('None') else begin
  1082.       seek (ffile,cur-1);
  1083.       read (ffile,m);
  1084.       write (m.title,' by ',LookUpuname(m.sentby));
  1085.     end
  1086.   end;
  1087.  
  1088.   Procedure delfeedback;
  1089.   VAR cnt:integer;
  1090.   begin
  1091.     if checkcur then exit;
  1092.     deletetext (m.line);
  1093.     for cnt:=cur to nummessages-1 do begin
  1094.       seek (ffile,cnt);
  1095.       read (ffile,m);
  1096.       seek (ffile,cnt-1);
  1097.       write (ffile,m)
  1098.     end;
  1099.     seek (ffile,nummessages-1);
  1100.     truncate (ffile);
  1101.     cur:=cur-1
  1102.   end;
  1103.  
  1104.   Procedure editusr;
  1105.   VAR n:integer;
  1106.   begin
  1107.     if checkcur then exit;
  1108.     n:=m.sentby;
  1109.     if n=0
  1110.       then writestr ('User disappeared!')
  1111.       else edituser (n)
  1112.   end;
  1113.  
  1114.   Procedure infoform;
  1115.   begin
  1116.     if checkcur then exit;
  1117.     showinfoforms (LookUpUname(m.sentby));
  1118.   end;
  1119.  
  1120.   Procedure nextfeedback;
  1121.   begin
  1122.     cur:=cur+1;
  1123.     if cur>nummessages then begin
  1124.       writestr (^M'Sorry, no more feedback!');
  1125.       cur:=0;
  1126.       exit
  1127.     end;
  1128.     readnum (cur)
  1129.   end;
  1130.  
  1131.   Procedure readagain;
  1132.   begin
  1133.     if checkcur then exit;
  1134.     readnum (cur)
  1135.   end;
  1136.  
  1137.   Procedure replyfeedback;
  1138.   begin
  1139.     if checkcur then exit;
  1140.     sendmailto (m.sentby,false)
  1141.   end;
  1142.  
  1143.   Procedure listfeedback;
  1144.   VAR cnt:integer;
  1145.   begin
  1146.     if nummessages=0 then exit;
  1147.     thereare (nummessages,'piece of feedback','pieces of feedback');
  1148.     if break then exit;
  1149.     writeln (^M'Num Title                          Left by'^M);
  1150.     seek (ffile,0);
  1151.     for cnt:=1 to nummessages do begin
  1152.       read (ffile,m);
  1153.       tab (strr(cnt),4);
  1154.       if break then exit;
  1155.       tab (m.title,31);
  1156.       writeln (LookUpUname(m.sentby));
  1157.       if break then exit
  1158.     end
  1159.   end;
  1160.  
  1161. VAR q:integer;
  1162. label exit;
  1163. begin
  1164.   assign (ffile,'Feedback');
  1165.   reset (ffile);
  1166.   if ioresult<>0 then rewrite (ffile);
  1167.   cur:=0;
  1168.   repeat
  1169.     if nummessages=0 then begin
  1170.       writestr ('Sorry, no feedback!');
  1171.       goto exit
  1172.     end;
  1173.     writecurmsg;
  1174.     q:=menu ('Feedback','FEED','Q#DEIR_AL');
  1175.     if q<0
  1176.       then readnum (-q)
  1177.       else case q of
  1178.         3:delfeedback;
  1179.         4:editusr;
  1180.         5:infoform;
  1181.         6:replyfeedback;
  1182.         7:nextfeedback;
  1183.         8:readagain;
  1184.         9:listfeedback;
  1185.       end
  1186.   until (q=1) or hungupon;
  1187.   exit:
  1188.   close (ffile)
  1189. end;
  1190.  
  1191. TYPE mail_rec = RECORD
  1192.        title,
  1193.        sentby    : mstr;
  1194.        when      : longint;
  1195.        anon,
  1196.        read      : boolean;
  1197.        sentto,
  1198.        line,
  1199.        fileindex : integer;
  1200. {       AnonPost  : BOOLEAN;   }
  1201.      End;
  1202.  
  1203. VAR Mail1 : FILE OF Mail_Rec;
  1204.     Mail2 : FILE Of mailRec;
  1205.     c1    : LONGINT;
  1206.     Inrec : Mail_Rec;
  1207.     OutRec : mailRec;
  1208.  
  1209. Procedure Convert_mail;
  1210. VAR c1 : LONGINT;
  1211. Begin
  1212.   Writeln('Converting mail');
  1213.   Assign(Mail1,'MAIL');
  1214.   Assign(Mail2,'NewMail');
  1215.   Reset(Mail1);
  1216.   Rewrite(Mail2);
  1217.   For c1 := 0 TO FileSize(Mail1)-1 DO
  1218.     Begin
  1219.       Seek(Mail1,c1);
  1220.       Read(Mail1,Inrec);
  1221.       OutRec.title := InRec.Title;
  1222.       OutRec.sentby := LookUpUser(InRec.SentBy);
  1223.       OutRec.when := inRec.When;
  1224.       OutRec.anon := inRec.Anon;
  1225.       Outrec.read := InRec.Read;
  1226.       Outrec.sentto := InRec.SentTo;
  1227.       Outrec.line := InRec.Line;
  1228.       OutRec.fileindex := Inrec.FileIndex;
  1229.       OutRec.AnonPost := FALSE;
  1230.       Seek(Mail2,c1);
  1231.       Write(Mail2,OutRec);
  1232.       Write(c1,'  ');
  1233.     End;
  1234.   Close(Mail2);
  1235.   Close(Mail1);
  1236.   Erase(Mail1);
  1237.   Rename(Mail2,'Mail');
  1238.  
  1239.   Writeln;
  1240.   Writeln('Converting Feedback');
  1241.   Assign(Mail1,'Feedback');
  1242.   Assign(Mail2,'NewFeed');
  1243.   Reset(Mail1);
  1244.   Rewrite(Mail2);
  1245.   For c1 := 0 TO FileSize(Mail1)-1 DO
  1246.     Begin
  1247.       Seek(Mail1,c1);
  1248.       Read(Mail1,Inrec);
  1249.       OutRec.title := InRec.Title;
  1250.       OutRec.sentby := LookUpUser(InRec.SentBy);
  1251.       OutRec.when := inRec.When;
  1252.       OutRec.anon := inRec.Anon;
  1253.       Outrec.read := InRec.Read;
  1254.       Outrec.sentto := InRec.SentTo;
  1255.       Outrec.line := InRec.Line;
  1256.       OutRec.fileindex := Inrec.FileIndex;
  1257.       OutRec.AnonPost := FALSE;
  1258.       Seek(Mail2,c1);
  1259.       Write(Mail2,OutRec);
  1260.       Write(c1,'  ');
  1261.     End;
  1262.   Close(Mail2);
  1263.   Close(Mail1);
  1264.   Erase(Mail1);
  1265.   Rename(Mail2,'FeedBack');
  1266. End;
  1267.  
  1268. Begin
  1269. End.
  1270.