telegard/mail0.pas

413 lines
9.5 KiB
ObjectPascal

{$A+,B+,E+,F+,I+,L+,N-,O+,R-,S+,V-}
unit mail0;
interface
uses
crt, dos,
{rcg11172000 no overlay under Linux.}
{overlay,}
common, timejunk;
const
_brd_opened:boolean=FALSE; { has brdf been opened yet? }
oldnummsgs:integer=0; { old number of messages }
gotlastmheader:boolean=FALSE;
type
pinforec=record
xbrdfnopen:string[160];
xbread,xmintabloaded:longint;
xopen:boolean;
end;
var
brdfnopen:string; { what *.BRD filename is open }
lastmheader:mheaderrec;
wasyourmsg:boolean;
procedure blockwritestr2(var f:file; s:string);
procedure blockreadstr2(var f:file; var s:string);
function getmixnum(x:word):word;
function getmintab(x:word):word;
procedure loadmintab(x:word);
procedure ensureloaded(x:word);
procedure loadmhead1(var brdf:file; x:word; var mhead:mheaderrec);
procedure savemhead1(var brdf:file; mhead:mheaderrec);
procedure loadmhead(x:word; var mhead:mheaderrec);
procedure savemhead(mhead:mheaderrec);
procedure savemix(mixr:msgindexrec; x:word);
procedure newmix(mixr:msgindexrec);
procedure outmessagetext(fn:string; var mhead:mheaderrec; eraseit:boolean);
procedure findhimsg;
procedure initbrd(x:integer);
procedure closebrd;
function forwardm(n:integer):integer;
function moremail(u:userrec; un,what:word):boolean;
procedure savepinfo(var x:pinforec);
procedure loadpinfo(x:pinforec);
procedure delmail(x:integer);
function rmail(x:integer):string; { bread must = -1 }
implementation
procedure blockwritestr2(var f:file; s:string);
var bb:byte;
begin
bb:=$FF;
blockwrite(f,bb,1);
blockwrite(f,s[0],1);
blockwrite(f,s[1],ord(s[0]));
end;
procedure blockreadstr2(var f:file; var s:string);
begin
blockread(f,s[0],1); { filler-chr }
if (ord(s[0])<>$FF) then exit;
blockread(f,s[0],1);
blockread(f,s[1],ord(s[0]));
end;
function getmixnum(x:word):word;
begin
getmixnum:=x mod 100;
end;
function getmintab(x:word):word;
begin
getmintab:=x div 100;
end;
procedure loadmintab(x:word);
var lng:longint;
numread:word;
i,j:integer;
begin
lng:=x*100; (* stupid *#@$(@($#*($ TP typecasting... *)
while ((lng>=filesize(mixf)) and (x>0)) do begin
dec(x);
lng:=x*100;
end;
mintaboffset:=x*100;
seek(mixf,mintaboffset);
blockread(mixf,mintab,100,numread);
if (numread<>100) then begin
for i:=numread to 99 do begin
mintab[i].messagenum:=0;
mintab[i].hdrptr:=-1;
mintab[i].msgid:=memboard.lastmsgid;
mintab[i].isreplytoid:=0;
for j:=1 to 6 do mintab[i].msgdate[i]:=0;
mintab[i].msgdowk:=0;
mintab[i].msgindexstat:=[];
mintab[i].isreplyto:=65535;
mintab[i].numreplys:=0;
end;
seek(mixf,mintaboffset);
blockwrite(mixf,mintab,100); { fill remainder with garbage .. }
end;
mintabloaded:=x;
end;
procedure ensureloaded(x:word);
var i:word;
begin
i:=getmintab(x);
if (i<>mintabloaded) then loadmintab(i);
end;
procedure loadmhead1(var brdf:file; x:word; var mhead:mheaderrec);
begin
blockread(brdf,mhead,sizeof(mheaderrec));
end;
{ caller must postition to correct place in brdf .... }
procedure savemhead1(var brdf:file; mhead:mheaderrec);
begin
blockwrite(brdf,mhead,sizeof(mheaderrec));
end;
procedure loadmhead(x:word; var mhead:mheaderrec);
begin
ensureloaded(x);
seek(brdf,mintab[getmixnum(x)].hdrptr);
loadmhead1(brdf,x,mhead);
end;
procedure savemhead(mhead:mheaderrec);
begin
savemhead1(brdf,mhead);
end;
procedure savemix(mixr:msgindexrec; x:word);
begin
loadmintab(getmintab(x));
seek(mixf,mintaboffset+getmixnum(x));
blockwrite(mixf,mixr,1);
loadmintab(getmintab(x));
end;
procedure newmix(mixr:msgindexrec);
var lng:longint;
i,j:integer;
begin
if ((getmixnum(himsg+1)=0) and (himsg>-1)) then begin
for i:=0 to 99 do begin
mintab[i].messagenum:=0;
mintab[i].hdrptr:=-1;
mintab[i].msgid:=memboard.lastmsgid;
mintab[i].isreplytoid:=0;
for j:=1 to 6 do mintab[i].msgdate[i]:=0;
mintab[i].msgdowk:=0;
mintab[i].msgindexstat:=[];
mintab[i].isreplyto:=65535;
mintab[i].numreplys:=0;
end;
inc(himintab);
seek(mixf,himintab*100); blockwrite(mixf,mintab[0],100);
end;
inc(himsg); savemix(mixr,himsg);
end;
procedure outmessagetext(fn:string; var mhead:mheaderrec; eraseit:boolean);
var t:text;
f:file;
s:string;
lng:longint;
begin
assign(t,fn);
{$I-} reset(t); {$I+}
if (ioresult<>0) then exit;
lng:=filesize(brdf);
seek(brdf,lng);
mhead.msgptr:=lng+sizeof(mheaderrec);
savemhead(mhead);
while (not eof(t)) do begin
readln(t,s);
blockwritestr2(brdf,s);
end;
close(t);
if (eraseit) then erase(t);
end;
procedure findhimsg;
var mixr:msgindexrec;
lng:longint;
numread:word;
begin
himintab:=(filesize(mixf)-1) div 100;
himsg:=himintab*100-1;
seek(mixf,himsg+1);
repeat
lng:=himsg;
blockread(mixf,mixr,1,numread);
if ((numread=1) and (mixr.hdrptr<>-1)) then inc(himsg);
until (lng=himsg);
end;
procedure initbrd(x:integer); { x=-1 = e-mail }
var mixr:msgindexrec;
fn:string;
lng:longint;
numread:word;
i,j:integer;
begin
closebrd;
bread:=x;
{rcg11272000 filename case.}
{if (x=-1) then fn:='EMAIL' else begin}
if (x=-1) then fn:='email' else begin
loadboard(x);
fn:=memboard.filename;
end;
{rcg11272000 filename case.}
{fn:=allcaps(fn);}
brdfnopen:=fn;
{rcg11272000 filename case.}
{assign(mixf,systat.msgpath+fn+'.MIX');}
assign(mixf,systat.msgpath+fn+'.mix');
{$I-} reset(mixf,sizeof(mixr)); {$I+}
if (ioresult<>0) then begin
rewrite(mixf,sizeof(mixr));
for i:=0 to 99 do begin
mintab[i].messagenum:=0;
mintab[i].hdrptr:=-1;
mintab[i].msgid:=memboard.lastmsgid;
mintab[i].isreplytoid:=0;
for j:=1 to 6 do mintab[i].msgdate[i]:=0;
mintab[i].msgdowk:=0;
mintab[i].msgindexstat:=[];
mintab[i].isreplyto:=65535;
mintab[i].numreplys:=0;
end;
blockwrite(mixf,mintab[0],100);
end;
{rcg11272000 filename case.}
{assign(brdf,systat.msgpath+fn+'.BRD');}
assign(brdf,systat.msgpath+fn+'.brd');
{$I-} reset(brdf,1); {$I+}
if (ioresult<>0) then rewrite(brdf,1);
findhimsg;
loadmintab(himintab);
_brd_opened:=TRUE;
gotlastmheader:=FALSE;
end;
procedure closebrd;
begin
if (_brd_opened) then begin
if (filerec(brdf).mode<>fmclosed) then close(brdf);
if (filerec(mixf).mode<>fmclosed) then close(mixf);
end;
filerec(brdf).mode:=fmclosed;
filerec(mixf).mode:=fmclosed;
end;
{ this routine will find the user that user n is forwarding their mail to.
it will also check to get around "circular forwarding", such as:
5 -> 10 -> 15 -> 5 ... }
function forwardm(n:integer):integer;
var chk:array[1..1250] of byte; { 1250 * 8 = 10000 users max }
cur:integer;
u:userrec;
done:boolean;
function chkval(i:integer):boolean;
begin
dec(i);
chkval:=((chk[i div 8] and (1 shl (i mod 8)))<>0);
end;
procedure chkset(i:integer);
var bb,bc:byte;
begin
dec(i);
bb:=chk[i div 8]; bc:=(1 shl(i mod 8));
if ((bb and bc)=0) then chk[i div 8]:=chk[i div 8]+bc;
end;
begin
for cur:=1 to 1250 do
chk[cur]:=0;
cur:=n;
done:=FALSE;
while not done do
if (chkval(cur)) then begin
done:=TRUE;
cur:=0;
end else
if (cur<filesize(uf)) and (cur>0) then begin
seek(uf,cur); read(uf,u);
if (u.deleted) then begin
done:=TRUE;
cur:=0;
end else begin
if (u.forusr=0) then begin
done:=TRUE;
end else begin
chkset(cur);
cur:=u.forusr;
end;
end;
end else begin
done:=TRUE;
cur:=0;
end;
forwardm:=cur;
end;
{
1: user has too much mail waiting already
2: user mailbox is closed
3: user is deleted
4: can't send mail to yourself! <idiot!>
}
function moremail(u:userrec; un,what:word):boolean;
begin
moremail:=TRUE;
case what of
1:moremail:=(not (((aacs1(u,un,systat.csop)) and
(u.waiting>=systat.csmaxwaiting)) or
((not aacs1(u,un,systat.csop)) and (u.waiting>=systat.maxwaiting))));
2:moremail:=(not (nomail in u.ac));
3:moremail:=(not (u.deleted));
4:moremail:=(not ((un=usernum) and (not cso)));
end;
end;
procedure savepinfo(var x:pinforec);
begin
with x do begin
xbread:=bread;
xbrdfnopen:=brdfnopen;
xopen:=FALSE;
if (not _brd_opened) then xopen:=FALSE
else if (filerec(mixf).mode<>fmclosed) then xopen:=TRUE;
end;
end;
procedure loadpinfo(x:pinforec);
begin
closebrd;
with x do begin
brdfnopen:=xbrdfnopen;
if (xopen) then begin
initbrd(xbread);
loadmintab(0);
end;
end;
end;
{ toggles "existance" flag. If normal, deletes it -- otherwise, undeletes }
procedure delmail(x:integer);
var mixr:msgindexrec;
begin
ensureloaded(x);
mixr:=mintab[getmixnum(x)];
if (miexist in mixr.msgindexstat) then
mixr.msgindexstat:=mixr.msgindexstat-[miexist]
else
mixr.msgindexstat:=mixr.msgindexstat+[miexist];
savemix(mixr,x);
ensureloaded(x);
end;
function rmail(x:integer):string; { bread must = -1 }
var u:userrec;
mheader:mheaderrec;
i:integer;
ufo:boolean;
begin
loadmhead(x,mheader);
with mheader do begin
rmail:=caps(fromi.alias)+' #'+cstr(fromi.usernum);
ufo:=(filerec(uf).mode<>fmclosed);
if (not ufo) then reset(uf);
if ((toi.usernum>=1) and (toi.usernum<=filesize(uf)-1)) then begin
if (toi.usernum=usernum) then dec(thisuser.waiting);
seek(uf,toi.usernum);
read(uf,u);
dec(u.waiting);
seek(uf,toi.usernum);
write(uf,u);
end;
if (not ufo) then close(uf);
end;
delmail(x);
mailread:=TRUE;
end;
end.