home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / vi_si_on / email.pas < prev    next >
Pascal/Delphi Source File  |  1991-04-04  |  29KB  |  1,141 lines

  1. {$R-,S-,I-,D-,F+,V-,B-,N-,L+,O+}
  2.  
  3. unit email;
  4.  
  5. interface
  6.  
  7. uses windows,gentypes,configrt,gensubs,subs1,subs2,textret,flags,
  8.      mailret,userret,overret1,mainr1,mainr2,others;
  9.  
  10. procedure opengfile;
  11. procedure autoreply;
  12. procedure editmailuser;
  13. procedure newmailre;
  14. procedure emailmenu;
  15.  
  16. implementation
  17.  
  18. var lastread:integer;
  19.     m:mailrec;
  20.     incoming,outgoing:catalogrec;
  21.  
  22.  
  23.   procedure addcatalog (var c:catalogrec; var m:mailrec; fpos:integer);
  24.   begin
  25.     m.fileindex:=fpos;
  26.     if c.nummail=maxcatalogsize
  27.       then c.additional:=c.additional+1
  28.       else begin
  29.         c.nummail:=c.nummail+1;
  30.         c.mail[c.nummail]:=m
  31.       end
  32.   end;
  33.  
  34.   procedure writenummail (var c:catalogrec; txt:mstr);
  35.   begin
  36.     writeln (^B^M'You have ',c.nummail+c.additional,' ',txt,
  37.              ' message',s(c.nummail));
  38.     if c.additional>0
  39.       then writeln ('   Note: Of those, ',
  40.                      numthings (c.additional,'is','are'),' uncataloged.')
  41.   end;
  42.  
  43.   procedure readcatalogs;
  44.   var m:mailrec;
  45.       cnt:integer;
  46.   begin
  47.     seek (mfile,1);
  48.     incoming.nummail:=0;
  49.     incoming.additional:=0;
  50.     outgoing.nummail:=0;
  51.     outgoing.additional:=0;
  52.     for cnt:=1 to filesize(mfile)-1 do begin
  53.       read (mfile,m);
  54.       if m.sentto=unum
  55.         then addcatalog (incoming,m,cnt);
  56.       if match(m.sentby,unam)
  57.         then addcatalog (outgoing,m,cnt)
  58.     end
  59.   end;
  60.  
  61.   procedure readit (var m:mailrec);
  62.   begin
  63.   clearscr;
  64.   writeln(^B'[ E-Mail ]');
  65.     write (^B^M'Title:   '^S,m.title,^M'Sent by: '^S);
  66.     if m.anon
  67.       then
  68.         begin
  69.           write (configset.anonymousst);
  70.           if issysop then write (' (',m.sentby,')')
  71.         end
  72.       else write (m.sentby);
  73.     writeln (^M'Sent at: '^S,datestr(m.when),' at ',timestr(m.when));
  74.     writeln;
  75.     ansicolor(urec.regularcolor);
  76.     if not break then printtext (m.line)
  77.   end;
  78.  
  79.   procedure readincoming (n:integer);
  80.   var m:^mailrec;
  81.       cnt:integer;
  82.   begin
  83.     m:=addr(incoming.mail[n]);
  84.     readit (m^);
  85.     if not (m^.read) then begin
  86.       m^.read:=true;
  87.       seek (mfile,m^.fileindex);
  88.       write (mfile,m^)
  89.     end;
  90.     for cnt:=n+1 to incoming.nummail do
  91.       if match(incoming.mail[cnt].sentby,m^.sentby) then begin
  92.         writeln (^B^M'There''s more mail from ',m^.sentby,'!');
  93.         exit
  94.       end
  95.   end;
  96.  
  97.   procedure listmail (var c:catalogrec);
  98.   var n:integer;
  99.       u:userrec;
  100.       cnt:integer;
  101.       m:mailrec;
  102.   begin
  103.     write ('Num  ');
  104.     tab ('Title',30);
  105.     write ('New  Sent ');
  106.     if ofs(c)=ofs(incoming) then writeln ('by'^M) else writeln ('to'^M);
  107.     if break then exit;
  108.     for cnt:=1 to c.nummail do if not break then begin
  109.       m:=c.mail[cnt];
  110.       write (cnt:2,'.  ');
  111.       if not break then tab (m.title,30);
  112.       if not break then if m.read then write ('     ') else write ('New  ');
  113.       if match(m.sentby,unam)
  114.         then writeln (lookupuname (m.sentto))
  115.         else writeln (m.sentby)
  116.     end
  117.   end;
  118.  
  119.   procedure writemail (var c:catalogrec; num:integer);
  120.   begin
  121.     seek (mfile,c.mail[num].fileindex);
  122.     write (mfile,c.mail[num])
  123.   end;
  124.  
  125.   function checklastread:boolean;
  126.   begin
  127.     if (lastread<0) or (lastread>incoming.nummail) then lastread:=0;
  128.     checklastread:=lastread=0
  129.   end;
  130.  
  131.   function getmsgnumber (var c:catalogrec; txt:sstr):integer;
  132.   var n:integer;
  133.       inc:boolean;
  134.   begin
  135.     inc:=ofs(c)=ofs(incoming);
  136.     getmsgnumber:=0;
  137.     if c.nummail=0 then begin
  138.       if c.additional>0 then readcatalogs;
  139.       if c.nummail=0 then writestr (^M'Sorry, no mail!');
  140.       if inc then lastread:=0;
  141.       exit
  142.     end;
  143.     input:=copy(input,2,255);
  144.     if length(input)=0
  145.       then if inc
  146.         then n:=lastread
  147.         else n:=0
  148.       else n:=valu(input);
  149.     if (n<1) or (n>c.nummail) then begin
  150.       repeat
  151.         writestr (^M'Message number to '+txt+' [?=list]:');
  152.         if length(input)=0 then exit;
  153.         if input='?' then listmail (c)
  154.       until input<>'?';
  155.       n:=valu(input);
  156.       if (n<1) or (n>c.nummail) then n:=0
  157.     end;
  158.     getmsgnumber:=n
  159.   end;
  160.  
  161.   procedure deletemail (var c:catalogrec; n:integer);
  162.   begin
  163.     delmail (c.mail[n].fileindex);
  164.     writeln (c.mail[n].title,' by ',c.mail[n].sentby,' deleted.');
  165.     readcatalogs
  166.   end;
  167.  
  168.   procedure nextmail;
  169.   begin
  170.     lastread:=lastread+1;
  171.     if lastread>incoming.nummail
  172.       then
  173.         begin
  174.           lastread:=0;
  175.           if incoming.additional>0
  176.             then writeln ('You must delete some old mail first!')
  177.             else writeln ('Sorry, no more mail!')
  178.         end
  179.       else readincoming (lastread)
  180.   end;
  181.  
  182.   procedure readnum (n:integer);
  183.   begin
  184.     if (n<1) or (n>incoming.nummail) then begin
  185.       lastread:=0;
  186.       exit
  187.     end;
  188.     lastread:=n;
  189.     readincoming (n)
  190.   end;
  191.  
  192.   procedure readmail;
  193.   begin
  194.     readnum (getmsgnumber (incoming,'read'))
  195.   end;
  196.  
  197.   procedure listallmail;
  198.   begin
  199.     if incoming.nummail>0 then begin
  200.       writehdr ('Incoming mail');
  201.       listmail (incoming)
  202.     end;
  203.     if outgoing.nummail>0 then begin
  204.       writehdr ('Outgoing mail');
  205.       listmail (outgoing)
  206.     end
  207.   end;
  208.  
  209.   procedure newmailre;
  210.   begin
  211.   close(gfile);
  212.   opengfile;
  213.   readcatalogs;
  214.     lastread:=0;
  215.     repeat
  216.       lastread:=lastread+1;
  217.       if lastread>incoming.nummail then begin
  218.         lastread:=0;
  219.         close(gfile);
  220.         exit
  221.       end;
  222.       if not incoming.mail[lastread].read then begin
  223.         readincoming (lastread);
  224.         repeat
  225.         write(^M^M^S'[CR/Next] [A/Again] [Q/Quit] [R/Reply] [D/Delete] ');
  226.         if urec.level>=configset.sysopleve then write(^S'[E/Edit Sender] ');
  227.         writestr(^S':*');
  228.         if input='' then input:='N';
  229.         if match(input,'R') then autoreply else if match(input,'A') then readincoming(lastread)
  230.         else if match(input,'D') then begin
  231.         deletemail(incoming,lastread);
  232.         lastread:=lastread-1;
  233.         input:='N';
  234.         end else  if (match(input,'E') and (urec.level>=configset.sysopleve)) then editmailuser else
  235.         if match(input,'Q') then begin close(gfile); exit; end;
  236.         until (match(input,'N')) or hungupon;
  237.       end
  238.     until hungupon;
  239.     close(gfile);
  240.   end;
  241.  
  242.   procedure deleteincoming;
  243.   var n:integer;
  244.   begin
  245.     if checklastread then begin
  246.       n:=getmsgnumber (incoming,'delete');
  247.       if n=0 then exit;
  248.       lastread:=n
  249.     end;
  250.     deletemail (incoming,lastread);
  251.     lastread:=lastread-1
  252.   end;
  253.  
  254.   procedure killoutgoing;
  255.   var n:integer;
  256.   begin
  257.     n:=getmsgnumber (outgoing,'kill');
  258.     if n<>0 then deletemail (outgoing,n)
  259.   end;
  260.  
  261.   procedure autoreply;
  262.   var n:integer;
  263.   begin
  264.     if checklastread then begin
  265.       n:=getmsgnumber (incoming,'reply to');
  266.       if n=0 then exit;
  267.       lastread:=n
  268.     end;
  269.     with incoming.mail[lastread] do
  270.       sendmailto (sentby,anon);
  271.     readcatalogs
  272.   end;
  273.  
  274.   procedure viewoutgoing;
  275.   var n:integer;
  276.   begin
  277.     n:=getmsgnumber (outgoing,'view');
  278.     if n=0 then exit;
  279.     readit (outgoing.mail[n])
  280.   end;
  281.  
  282.   procedure showinfos;
  283.   var n,info:integer;
  284.   begin
  285.     if checklastread then begin
  286.       n:=getmsgnumber (incoming,'delete');
  287.       if n=0 then exit;
  288.       lastread:=n
  289.     end;
  290.     writestr('Which infoform to view [1-5]: [1]:*');
  291.     if input='' then input:='1';
  292.     info:=valu(input);
  293.     if (info>0) and (info<6) then
  294.     showinfoforms (incoming.mail[lastread].sentby,info)
  295.   end;
  296.  
  297.   procedure editmailuser;
  298.   var n:integer;
  299.       m:mstr;
  300.   begin
  301.     if checklastread then begin
  302.       n:=getmsgnumber (incoming,'edit the sender');
  303.       if n=0 then exit;
  304.       lastread:=n
  305.     end;
  306.     m:=incoming.mail[lastread].sentby;
  307.     n:=lookupuser (m);
  308.     if n=0 then begin
  309.       writeln (^B^R'User ',m,' not found!');
  310.       exit
  311.     end;
  312.     edituser (n)
  313.   end;
  314.  
  315.   procedure writecurmsg;
  316.   var b:boolean;
  317.   begin
  318.     b:=checklastread;
  319.     write (^B^M'Current msg: ');
  320.     if lastread=0
  321.       then writeln ('None')
  322.       else with incoming.mail[lastread] do
  323.         writeln ('#',lastread,': ',title,' sent by ',sentby)
  324.   end;
  325.  
  326.   procedure showannouncement (un:integer);
  327.   var u:userrec;
  328.   begin
  329.     seek (ufile,un);
  330.     read (ufile,u);
  331.     if u.emailannounce>0 then begin
  332.       writehdr (u.handle+'''s Announcement');
  333.       printtext (u.emailannounce)
  334.     end
  335.   end;
  336.  
  337.   procedure copymsg (var m:mailrec; un:integer);
  338.   var me:message;
  339.       line:integer;
  340.       b:boolean;
  341.   begin
  342.     me.anon:=m.anon;
  343.     reloadtext (m.line,me);
  344.     me.sendto:='All';
  345.     me.title:='Was from '+m.sentby;
  346.     showannouncement (un);
  347.     writestr ('Add a prologue (A to abort)? *');
  348.     if match(input,'a') then exit;
  349.     if yes then b:=reedit (me,true);
  350.     line:=maketext (me);
  351.     addmail (un,line,me);
  352.     readcatalogs
  353.   end;
  354.  
  355.   procedure copymail;
  356.   var n,un,line:integer;
  357.   begin
  358.     if checklastread then begin
  359.       n:=getmsgnumber (incoming,'copy');
  360.       if n=0 then exit;
  361.       lastread:=n
  362.     end;
  363.     n:=lastread;
  364.     writestr ('User to copy it to:');
  365.     if length(input)=0 then exit;
  366.     un:=lookupuser (input);
  367.     if un=0 then exit;
  368.     copymsg (incoming.mail[n],un)
  369.   end;
  370.  
  371.   procedure forwardmail;
  372.   var n,un:integer;
  373.   begin
  374.     if checklastread then begin
  375.       n:=getmsgnumber (incoming,'forward');
  376.       if n=0 then exit;
  377.       lastread:=n
  378.     end;
  379.     n:=lastread;
  380.     writestr ('User to forward it to:');
  381.     if length(input)=0 then exit;
  382.     un:=lookupuser (input);
  383.     if un=0 then exit;
  384.     copymsg (incoming.mail[n],un);
  385.     deletemail (incoming,n)
  386.   end;
  387.  
  388.   const groupclassstr:array [groupclass] of string[8]=
  389.           ('Public','Private','Personal');
  390.  
  391.   procedure opengfile;
  392.   begin
  393.   close(gfile);
  394.     assign (gfile,'groups');
  395.     reset (gfile);
  396.     if ioresult<>0 then begin
  397.       close (gfile);
  398.       rewrite (gfile)
  399.     end
  400.   end;
  401.  
  402.   procedure seekgfile (n:integer);
  403.   begin
  404.     seek (gfile,n-1)
  405.   end;
  406.  
  407.   function ismember (var g:grouprec; n:integer):boolean;
  408.   var cnt:integer;
  409.   begin
  410.     ismember:=true;
  411.     for cnt:=1 to g.nummembers do
  412.       if g.members[cnt]=n then exit;
  413.     ismember:=false
  414.   end;
  415.  
  416.   function groupaccess (var g:grouprec):boolean;
  417.   begin
  418.     if issysop then begin
  419.       groupaccess:=true;
  420.       exit
  421.     end;
  422.     groupaccess:=false;
  423.     case g.class of
  424.       publicgroup:groupaccess:=true;
  425.       personalgroup:groupaccess:=g.creator=unum;
  426.       privategroup:groupaccess:=ismember (g,unum)
  427.     end
  428.   end;
  429.  
  430.   function lookupgroup (nm:mstr):integer;
  431.   var cnt:integer;
  432.       g:grouprec;
  433.   begin
  434.     lookupgroup:=0;
  435.     seekgfile (1);
  436.     for cnt:=1 to filesize(gfile) do begin
  437.       read (gfile,g);
  438.       if groupaccess(g)
  439.         then if match(g.name,nm)
  440.           then begin
  441.             lookupgroup:=cnt;
  442.             exit
  443.           end
  444.     end
  445.   end;
  446.  
  447.   procedure listgroups;
  448.   var g:grouprec;
  449.       cnt:integer;
  450.   begin
  451.     writestr (^M'Name                          Class'^M);
  452.     if break then exit;
  453.     seekgfile (1);
  454.     for cnt:=1 to filesize(gfile) do begin
  455.       read (gfile,g);
  456.       if groupaccess(g) then begin
  457.         tab (g.name,30);
  458.         writeln (groupclassstr[g.class]);
  459.         if break then exit
  460.       end
  461.     end
  462.   end;
  463.  
  464.   function getgroupclass:groupclass;
  465.   var k:char;
  466.   begin
  467.     repeat
  468.       input[1]:=#0;
  469.       writestr ('Group class p(U)blic, p(R)ivate, p(E)rsonal:');
  470.       k:=upcase(input[1]);
  471.       if k in ['U','R','E'] then begin
  472.         case k of
  473.           'U':getgroupclass:=publicgroup;
  474.           'R':getgroupclass:=privategroup;
  475.           'E':getgroupclass:=personalgroup
  476.         end;
  477.         exit
  478.       end
  479.     until hungupon;
  480.     getgroupclass:=publicgroup
  481.   end;
  482.  
  483.   procedure addmember (var g:grouprec; n:integer);
  484.   begin
  485.     if ismember (g,n) then begin
  486.       writestr ('That person is already a member!');
  487.       exit
  488.     end;
  489.     if g.nummembers=maxgroupsize then begin
  490.       writestr ('Sorry, group is full!');
  491.       exit
  492.     end;
  493.     g.nummembers:=g.nummembers+1;
  494.     g.members[g.nummembers]:=n
  495.   end;
  496.  
  497.   procedure addgroup;
  498.   var g:grouprec;
  499.       un:integer;
  500.   begin
  501.     writestr ('Group name:');
  502.     if (length(input)=0) or (input='?') then exit;
  503.     g.name:=input;
  504.     if lookupgroup (g.name)<>0 then begin
  505.       writestr (^M'Group already exists!');
  506.       exit
  507.     end;
  508.     g.class:=getgroupclass;
  509.     g.creator:=unum;
  510.     g.nummembers:=0;
  511.     writestr ('Include yourself in the group? *');
  512.     if yes then addmember (g,unum);
  513.     writestr (^M'Enter names of members, CR when done'^M);
  514.     repeat
  515.       writestr ('Member:');
  516.       if length(input)>0 then begin
  517.         un:=lookupuser (input);
  518.         if un=0
  519.           then writestr ('User not found!')
  520.           else addmember (g,un)
  521.       end
  522.     until hungupon or (length(input)=0) or (g.nummembers=maxgroupsize);
  523.     seek (gfile,filesize (gfile));
  524.     write (gfile,g);
  525.     writestr (^M'Group created!');
  526.     writelog (13,1,g.name)
  527.   end;
  528.  
  529.   function maybecreategroup (nm:mstr):integer;
  530.   begin
  531.     writestr ('Create group '+nm+'? *');
  532.     if yes then begin
  533.       addtochain (nm);
  534.       addgroup;
  535.       maybecreategroup:=lookupgroup (nm)
  536.     end else maybecreategroup:=0
  537.   end;
  538.  
  539.   function getgroupnum:integer;
  540.   var groupname:mstr;
  541.       gn:integer;
  542.       g:grouprec;
  543.   begin
  544.     getgroupnum:=0;
  545.     groupname:=copy(input,2,255);
  546.     repeat
  547.       if length(groupname)=0 then begin
  548.         writestr (^M'  Group name [?=list]:');
  549.         if length(input)=0 then exit;
  550.         if input[1]='/' then delete (input,1,1);
  551.         if length(input)=0 then exit;
  552.         groupname:=input
  553.       end;
  554.       if groupname='?' then begin
  555.         listgroups;
  556.         groupname:=''
  557.       end
  558.     until length(groupname)>0;
  559.     gn:=lookupgroup (groupname);
  560.     if gn=0 then begin
  561.       writestr ('Group not found!');
  562.       gn:=maybecreategroup (groupname);
  563.       if gn=0 then exit
  564.     end;
  565.     seekgfile (gn);
  566.     read (gfile,g);
  567.     if not groupaccess(g)
  568.       then writestr ('Sorry, you may not access that group!')
  569.       else getgroupnum:=gn
  570.   end;
  571.  
  572.   procedure sendmail;
  573.   var g:grouprec;
  574.  
  575.     procedure sendit (showeach:boolean);
  576.     var un,line,cnt:integer;
  577.         me:message;
  578.  
  579.       procedure addit (n:integer);
  580.       begin
  581.         if n<>unum then begin
  582.           if showeach then writeln (lookupuname(n));
  583.           addmail (n,line,me)
  584.         end else deletetext (line)
  585.       end;
  586.  
  587.     begin
  588.       if g.nummembers<1 then exit;
  589.       writehdr ('Sending mail to '+g.name);
  590.       line:=editor (me,true,true,g.name,'0');
  591.       if line<0 then exit;
  592.       addit (g.members[1]);
  593.       if g.nummembers=1 then exit;
  594.       writeln (^B^M);
  595.       for cnt:=2 to g.nummembers do begin
  596.         un:=g.members[cnt];
  597.         if un<>unum then begin
  598.           line:=maketext (me);
  599.           if line<0 then begin
  600.             writeln (cnt,' of ',g.nummembers,' completed.');
  601.             exit
  602.           end;
  603.           addit (un)
  604.         end
  605.       end;
  606.       readcatalogs
  607.     end;
  608.  
  609.     procedure sendtogroup;
  610.     var gn:integer;
  611.     begin
  612.       gn:=getgroupnum;
  613.       if gn=0 then exit;
  614.       seekgfile (gn);
  615.       read (gfile,g);
  616.       sendit (true)
  617.     end;
  618.  
  619.     procedure sendtousers;
  620.     var cnt,un:integer;
  621.     begin
  622.       g.name:=input;
  623.       un:=lookupuser (g.name);
  624.       if un=0 then begin
  625.         writestr (^M'User not found.');
  626.         exit
  627.       end;
  628.       g.nummembers:=1;
  629.       g.members[1]:=un;
  630.       cnt:=1;
  631.       showannouncement (un);
  632.       repeat
  633.         writestr ('Carbon copy #'+strr(cnt)+' to:');
  634.         if length(input)>0 then begin
  635.           un:=lookupuser (input);
  636.           if un=0
  637.             then writestr (^M'User not found!'^M)
  638.             else if ismember (g,un)
  639.               then writestr (^M'User is already receiving a copy!')
  640.               else begin
  641.                 cnt:=cnt+1;
  642.                 g.nummembers:=cnt;
  643.                 g.members[cnt]:=un;
  644.                 showannouncement (un)
  645.               end
  646.         end
  647.       until (length(input)=0) or (cnt=maxgroupsize);
  648.       sendit (g.nummembers>1)
  649.     end;
  650.  
  651.   begin
  652.     writestr ('User to send mail to [''/'' to send Group Mail ]:');
  653.     if length(input)<>0
  654.       then if input[1]='/'
  655.         then sendtogroup
  656.         else sendtousers
  657.   end;
  658.  
  659.   procedure zippymail;
  660.   var un:integer;
  661.       me:message;
  662.       l:integer;
  663.   begin
  664.     writestr ('Send mail to:');
  665.     if length(input)=0 then exit;
  666.     un:=lookupuser (input);
  667.     if un=0 then begin
  668.       writestr ('No such user!');
  669.       exit
  670.     end;
  671.     l:=editor (me,false,false,input,'0');
  672.     if l<0 then exit;
  673.     me.title:='-----';
  674.     me.anon:=false;
  675.     addmail (un,l,me);
  676.     readcatalogs
  677.   end;
  678.  
  679.   {overlay} procedure sysopmail;
  680.  
  681.     function sysopreadnum (var n:integer):boolean;
  682.     var m:mailrec;
  683.         k:char;
  684.         done:boolean;
  685.  
  686.       procedure showit;
  687.       begin
  688.         clearscr;
  689.         writeln (^B^N^M'Number  '^S,n,
  690.                      ^M'Sent by '^S,m.sentby,
  691.                      ^M'Sent to '^S,lookupuname (m.sentto),
  692.                      ^M'Sent on '^S,datestr(m.when),' at ',timestr(m.when),
  693.                      ^M'Title:  '^S,m.title,^M);
  694.         printtext (m.line);
  695.       end;
  696.  
  697.       procedure changen (m:integer);
  698.       var r2:integer;
  699.       begin
  700.         r2:=filesize(mfile)-1;
  701.         if (m<1) or (m>r2) then begin
  702.           writestr ('Continue scan at [1-'+strr(r2)+']:');
  703.           m:=valu(input)
  704.         end;
  705.         if (m>=1) and (m<=r2) then begin
  706.           n:=m-1;
  707.           done:=true
  708.         end
  709.       end;
  710.  
  711.     var q:integer;
  712.     begin
  713.       sysopreadnum:=false;
  714.       seek (mfile,n);
  715.       read (mfile,m);
  716.       showit;
  717.       repeat
  718.         done:=false;
  719.         q:=menu ('E-Mail Scan','ESCAN','QSERDNAC_#');
  720.         if q<0
  721.           then changen (-q)
  722.           else case q of
  723.             1:sysopreadnum:=true;
  724.             2:sendmail;
  725.             3:edituser(lookupuser(m.sentby));
  726.             4:edituser(m.sentto);
  727.             5:delmail(n);
  728.             6,9:done:=true;
  729.             7:showit;
  730.             8:changen (0);
  731.           end
  732.       until (q=1) or done or hungupon
  733.     end;
  734.  
  735.     procedure someoneelse;
  736.     var t,last:integer;
  737.     begin
  738.       writestr (^M'User name to look at:');
  739.       if (length(input)=0) or hungupon then exit;
  740.       writeln;
  741.       t:=lookupuser (input);
  742.       if t=0 then begin
  743.         writestr ('No such user!');
  744.         exit
  745.       end;
  746.       writelog (14,1,input);
  747.       writestr ('Looking in mailbox...');
  748.       last:=searchmail(0,t);
  749.       if last=0 then writestr ('No mail.');
  750.       while last<>0 do begin
  751.         seek (mfile,last);
  752.         read (mfile,m);
  753.         if sysopreadnum (last) or hungupon then exit;
  754.         last:=searchmail(last,t)
  755.       end;
  756.       writeln (^B^M'No more mail!')
  757.     end;
  758.  
  759.     procedure scanall;
  760.     var r1,r2:integer;
  761.         u:userrec;
  762.         n:mstr;
  763.     begin
  764.       r2:=filesize(mfile)-1;
  765.       writestr ('Start scanning at [1-'+strr(r2)+']:');
  766.       if length(input)=0 then r1:=1 else r1:=valu(input);
  767.       if (r1<1) or (r1>r2) then exit;
  768.       writelog (14,2,'');
  769.       while r1<filesize(mfile) do begin
  770.         seek (mfile,r1);
  771.         read (mfile,m);
  772.         if m.sentto<>0 then
  773.           if sysopreadnum (r1) then exit;
  774.         r1:=r1+1
  775.       end;
  776.       writeln (^B^M'No more mail!')
  777.     end;
  778.  
  779.     procedure groupflags;
  780.     var gn,bn,un,cnt:integer;
  781.         bname:sstr;
  782.         ac:accesstype;
  783.         g:grouprec;
  784.         u:userrec;
  785.     begin
  786.       writestr ('Grant all group members access to a sub-board'^M);
  787.       gn:=getgroupnum;
  788.       if gn=0 then exit;
  789.       writestr ('  Sub-board access name/number:');
  790.       writeln;
  791.       bname:=input;
  792.       opentempbdfile;
  793.       bn:=searchboard(bname);
  794.       closetempbdfile;
  795.       if bn=-1 then begin
  796.         writeln ('No such board!');
  797.         exit
  798.       end;
  799.       writelog (14,3,bname);
  800.       for cnt:=1 to g.nummembers do begin
  801.         un:=g.members[cnt];
  802.         writeln (lookupuname(un));
  803.         seek (ufile,un);
  804.         read (ufile,u);
  805.         setuseraccflag (u,bn,letin);
  806.         seek (ufile,un);
  807.         write (ufile,u)
  808.       end
  809.     end;
  810.  
  811.     procedure deleterange;
  812.     var first,last,num,cnt:integer;
  813.     begin
  814.       writehdr ('Mass Mail Delete');
  815.       parserange (filesize(mfile)-1,first,last);
  816.       if first=0 then exit;
  817.       num:=last-first;
  818.       if num<>1 then begin
  819.         writeln ('Warning! ',num,' pieces of mail will be deleted!');
  820.         writestr ('Are you sure? *');
  821.         if not yes then exit
  822.       end;
  823.       for cnt:=last downto first do begin
  824.         delmail (cnt);
  825.         write (cnt,' ');
  826.         if break then begin
  827.           writestr (^B^M'Aborted!');
  828.           exit
  829.         end
  830.       end;
  831.       writeln
  832.     end;
  833.  
  834.   var q:integer;
  835.   begin
  836.     repeat
  837.       q:=menu ('Sysop E-Mail','ESYSOP','QLSGD');
  838.       case q of
  839.         2:someoneelse;
  840.         3:scanall;
  841.         4:groupflags;
  842.         5:deleterange;
  843.       end
  844.     until (q=1) or hungupon;
  845.     readcatalogs
  846.   end;
  847.  
  848.   {overlay} procedure announcement;
  849.  
  850.     procedure delannouncement;
  851.     begin
  852.       if urec.emailannounce=-1 then begin
  853.         writestr (^M'You don''t HAVE an announcement.');
  854.         exit
  855.       end;
  856.       deletetext (urec.emailannounce);
  857.       urec.emailannounce:=-1;
  858.       writeurec;
  859.       writestr (^M'Deleted.')
  860.     end;
  861.  
  862.     procedure createannouncement;
  863.     var me:message;
  864.     begin
  865.       if urec.emailannounce>=0 then deletetext (urec.emailannounce);
  866.       urec.emailannounce:=editor (me,false,false,'0','EMAIL');
  867.       writeurec
  868.     end;
  869.  
  870.   var k:char;
  871.   begin
  872.     if urec.emailannounce>0
  873.       then showannouncement (unum)
  874.       else writestr ('You don''t have an announcement right now.');
  875.     writestr (^M'C)reate/replace, D)elete, or Q)uit:');
  876.     if length(input)=0 then exit;
  877.     k:=upcase(input[1]);
  878.     case k of
  879.       'D':delannouncement;
  880.       'C':createannouncement
  881.     end
  882.   end;
  883.  
  884.   {overlay} procedure groupediting;
  885.   var curgroup:integer;
  886.       cg:grouprec;
  887.  
  888.     procedure selectgroup;
  889.     var n:integer;
  890.         g:grouprec;
  891.     begin
  892.       delete (input,1,1);
  893.       repeat
  894.         if length(input)=0 then writestr ('Select group [?=list]:');
  895.         if length(input)=0 then exit;
  896.         if input='?' then begin
  897.           listgroups;
  898.           n:=0;
  899.           input[0]:=#0
  900.         end else begin
  901.           n:=lookupgroup (input);
  902.           if n=0 then begin
  903.             writestr ('Group not found!');
  904.             exit
  905.           end
  906.         end
  907.       until n>0;
  908.       seekgfile (n);
  909.       read (gfile,g);
  910.       if groupaccess(g) then begin
  911.         curgroup:=n;
  912.         cg:=g
  913.       end else writestr ('You can''t access that group.')
  914.     end;
  915.  
  916.     function nocurgroup:boolean;
  917.     begin
  918.       nocurgroup:=curgroup=0;
  919.       if curgroup=0 then writestr ('No group as been S)elected!')
  920.     end;
  921.  
  922.     function notcreator:boolean;
  923.     var b:boolean;
  924.     begin
  925.       if nocurgroup then b:=true else begin
  926.         b:=(unum<>cg.creator) and (not issysop);
  927.         if b then writestr ('You aren''t the creator of this group!')
  928.       end;
  929.       notcreator:=b;
  930.     end;
  931.  
  932.     procedure writecurgroup;
  933.     begin
  934.       seekgfile (curgroup);
  935.       write (gfile,cg)
  936.     end;
  937.  
  938.     procedure deletegroup;
  939.     var cnt:integer;
  940.         g:grouprec;
  941.     begin
  942.       if notcreator then exit;
  943.       writestr ('Delete group '+cg.name+': Are you sure? *');
  944.       if not yes then exit;
  945.       writelog (13,2,cg.name);
  946.       for cnt:=curgroup to filesize(gfile)-1 do begin
  947.         seekgfile (cnt+1);
  948.         read (gfile,g);
  949.         seekgfile (cnt);
  950.         write (gfile,g)
  951.       end;
  952.       seek (gfile,filesize(gfile)-1);
  953.       truncate (gfile);
  954.       curgroup:=0
  955.     end;
  956.  
  957.     procedure listmembers;
  958.     var cnt:integer;
  959.     begin
  960.       if nocurgroup then exit;
  961.       writeln ('Creator:           '^S,lookupuname (cg.creator));
  962.       writeln ('Number of members: '^S,cg.nummembers,^M);
  963.       for cnt:=1 to cg.nummembers do begin
  964.         if break then exit;
  965.         writeln (cnt:2,'. ',lookupuname (cg.members[cnt]))
  966.       end
  967.     end;
  968.  
  969.     procedure readdmember;
  970.     var n:integer;
  971.     begin
  972.       if notcreator then exit;
  973.       writestr ('User to add:');
  974.       if length(input)=0 then exit;
  975.       n:=lookupuser (input);
  976.       if n=0
  977.         then writestr ('User not found!')
  978.         else begin
  979.           addmember (cg,n);
  980.           writecurgroup
  981.         end
  982.     end;
  983.  
  984.     procedure removemember;
  985.  
  986.       procedure removemembernum (n:integer);
  987.       var cnt:integer;
  988.       begin
  989.         cg.nummembers:=cg.nummembers-1;
  990.         for cnt:=n to cg.nummembers do cg.members[cnt]:=cg.members[cnt+1];
  991.         writecurgroup;
  992.         writestr ('Member removed.')
  993.       end;
  994.  
  995.     var cnt,n:integer;
  996.     begin
  997.       if notcreator then exit;
  998.       repeat
  999.         writestr ('User to remove [?=list]:');
  1000.         if length(input)=0 then exit;
  1001.         if input='?' then begin
  1002.           input[0]:=#0;
  1003.           listmembers
  1004.         end
  1005.       until length(input)>0;
  1006.       n:=lookupuser (input);
  1007.       if n=0 then begin
  1008.         writestr ('User not found!');
  1009.         exit
  1010.       end;
  1011.       for cnt:=1 to cg.nummembers do if cg.members[cnt]=n then begin
  1012.         removemembernum (cnt);
  1013.         exit
  1014.       end;
  1015.       writestr ('User isn''t in the group!')
  1016.     end;
  1017.  
  1018.     procedure setclass;
  1019.     begin
  1020.       if notcreator then exit;
  1021.       writeln ('Current class: '^S,groupclassstr [cg.class],^M);
  1022.       cg.class:=getgroupclass;
  1023.       writecurgroup
  1024.     end;
  1025.  
  1026.     procedure setcreator;
  1027.     var m:mstr;
  1028.         n:integer;
  1029.     begin
  1030.       if notcreator then exit;
  1031.       writeln ('Current creator: '^S,lookupuname(cg.creator),^M);
  1032.       writestr ('Enter new creator:');
  1033.       if length(input)=0 then exit;
  1034.       n:=lookupuser(input);
  1035.       if n=0 then begin
  1036.         writestr ('User not found!');
  1037.         exit
  1038.       end;
  1039.       cg.creator:=n;
  1040.       writecurgroup;
  1041.       if (n<>unum) and (not issysop) then curgroup:=0
  1042.     end;
  1043.  
  1044.     procedure addbylevel;
  1045.     var n,cnt:integer;
  1046.         u:userrec;
  1047.     begin
  1048.       if notcreator then exit;
  1049.       writestr ('Let in all people over level:');
  1050.       n:=valu(input);
  1051.       if n=0 then exit;
  1052.       seek (ufile,1);
  1053.       for cnt:=1 to numusers do begin
  1054.         read (ufile,u);
  1055.         if (length(u.handle)>0) and (u.level>=n) then begin
  1056.           if cg.nummembers=maxgroupsize then begin
  1057.             writestr ('Sorry, group is full!');
  1058.             exit
  1059.           end;
  1060.           addmember (cg,cnt)
  1061.         end
  1062.       end
  1063.     end;
  1064.  
  1065.  
  1066.   var q:integer;
  1067.   begin
  1068.     curgroup:=0;
  1069.     repeat
  1070.       write (^B^M^M^R'Group selected: '^S);
  1071.       if curgroup=0
  1072.         then writeln ('None')
  1073.         else writeln (cg.name);
  1074.       q:=menu ('Group editing','GROUP','QS*LGDVMRCAE');
  1075.       case q of
  1076.         2,3:selectgroup;
  1077.         4:listgroups;
  1078.         5:addgroup;
  1079.         6:deletegroup;
  1080.         7:listmembers;
  1081.         8:readdmember;
  1082.         9:removemember;
  1083.         10:setcreator;
  1084.         11:setclass;
  1085.         12:addbylevel
  1086.       end
  1087.     until hungupon or (q=1)
  1088.   end;
  1089.  
  1090. procedure emailmenu;
  1091.  
  1092. var q:integer;
  1093. begin
  1094.   cursection:=emailsysop;
  1095.   clearscr;
  1096.   if (ansigraphics in urec.config) then begin;
  1097.      blowup(2,2,22,3);
  1098.      end;
  1099.   printxy(3,4,'The Postal Service');
  1100.   opengfile;
  1101.   readcatalogs;
  1102.   printxy(5,4,'');writenummail (incoming,'incoming');
  1103.   printxy(6,4,'');writenummail (outgoing,'outgoing');
  1104.   if ((incoming.nummail+incoming.additional)>10) and ((outgoing.nummail+outgoing.additional)>10)
  1105.   then writeln(^M'What, are you running a Mail Order business or something?'^M);
  1106.   lastread:=0;
  1107.   repeat
  1108.     writecurmsg;
  1109.     q:=menu ('E-Mail','EMAIL','QRSLN_%@DKAV#E@CFHGI@Z');
  1110.     if q<0
  1111.       then readnum (abs(q))
  1112.       else case q of
  1113.         2:autoreply;
  1114.         3:sendmail;
  1115.         4:listallmail;
  1116.         5:begin
  1117.           newmailre;
  1118.           opengfile;
  1119.           readcatalogs;
  1120.           end;
  1121.         6:nextmail;
  1122.         7:sysopmail;
  1123.         8:deleteincoming;
  1124.         9:killoutgoing;
  1125.         10:announcement;
  1126.         11:viewoutgoing;
  1127.         13:editmailuser;
  1128.         14:copymail;
  1129.         15:forwardmail;
  1130.         16:help ('Email.hlp');
  1131.         17:groupediting;
  1132.         18:showinfos;
  1133.         19:zippymail
  1134.       end
  1135.   until hungupon or (q=1);
  1136.   close (gfile)
  1137. end;
  1138.  
  1139. begin
  1140. end.
  1141.