home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
r
/
rusn-09.zip
/
RUSNEWS.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-11-03
|
58KB
|
2,279 lines
program rusnews; {read news}
{
KNOWN SHORTCOMINGS (but don't let them scare you away)
does not 'f'ollow up to postings or post new ones
works with only Waffle 1.64 password file format (for fullname)
(but can use environment variables or command-line paramaters
as quick fix for newer versions) (but this is a dumb idea)
not tested with Waffle 1.65 directory structure (possibly only seqf changes)
does not handle multiple DEFAULT lines the way waffle does
assumes all mail goes out to smarthost
(cannot mail to local users (without it leaving the site first!))
(does not use paths file information)
cannot 'G'oto an already-read group - must edit join file by hand
at most 600 articles/group selectable (but you can usually go back for more)
online version: 200 articles/group
at most 200 groups in join file (for crossposting detection)
very limited kill files
no regular expressions/substring searches in kill files
kill files restricted to Subject: and From: only
at most 200 killed items/group
online version: 50 killed items/group
doesn't create directories as needed - must already exist
threading doesn't use References: data as much as it could
doesn't log outgoing mail in ~waffle/admin/mail
doesn't guess when daylight savings hits
(you have to change the clock on your pc anyway!)
KNOWN WEIRDNESS
'W'rite not implemented in selection screen
'r'eply makes you be careful with sig (but it works)
needs headers while browsing (3 more, last, 70% through this article, etc.)
'P'revious group needs work (same as 'G'oto)
'U'njoin not there
tabs not expanded (but no one should be using tabs - it's interesting)
lines greater than 80 chars not wrapped (again, no one should use them)
(author uses `e' to pop into auto-wrapping editor when an interesting one
is shown)
(but they are indicated by < on right-hand margin)
ENVIRONMENT VARIABLES
(required) WAFFLE - same as waffle requires it
NET_NAME - users' waffle name
also -u/--user
EDITOR - full path+extension of editor (default: c:\usr\bin\vi.exe)
also -e/--editor - see also -o/--options
TZ - time zone; default: `MST' (if not found in static file)
FULLNAME - full non-computer name of user
also -f/--fullname (underscores changed to spaces)
WAFVERSION - version of waffle; default: `1.64'
CREDITS
Kim Storm, for the `nn' newsreader (a much more powerful newsreader
for Unix, whose keystrokes were used as a model (not Unix, nn))
}
{$define nontiny}
{use tiny for a default-to-fossil-port-0 version, with smaller limits}
{this is usually called rusnews0.exe. use with any __small__}
{fossil-compatible editor, such as trived.exe from same author}
{trived is a trivial editor implementing a small subset of vi on the}
{console _or_ out a fossil - no ANSI.SYS required on console 50k required}
{$ifdef tiny}
{$M 32768,0,80000}
{$else}
{$M 32768,0,200000}
{$endif}
{$define verbose}
{$undef debug}
uses dos,crt;
const
newsreadername='rusnews';
newsreaderversion='v0.9';
{$ifdef tiny}
maxarts=200;
maxkills=50;
lpp=22;
sellpp=19;
{$else}
maxarts=600;
maxkills=200;
lpp=23;
sellpp=20;
{$endif}
headerlines=1;
headerbufsize=2048;
maxjoined=200;
type
subjstringt=string[70];
fnstringt=string[14];
datestringt=string[8];
fromstringt=string[20];
groupstringt=string[40];
fnarray=array[1..maxarts] of fnstringt;
fromarray=array[1..maxarts] of fromstringt;
datearray=array[1..maxarts] of datestringt;
headerbuft=array[1..headerbufsize] of char;
killsarr=array[1..maxkills] of string;
var
basedir: string;
basedirsuf: string;
username: string;
numarts: integer;
numjoined: integer;
indents: array[1..maxarts] of integer;
sizeink: array[1..maxarts] of integer;
basesubjs: array[1..maxarts] of subjstringt;
joinedgroups: array[1..maxjoined] of groupstringt;
filenamesp: ^fnarray;
fromsp: ^fromarray;
datesp: ^datearray;
i: integer;
selected: array[1..maxarts] of boolean;
highestart: integer;
highestread: integer;
wafenv: string;
spooldir,temporarydir,userdir,waffledir: string;
uucpname,node,smarthost,organ,timezone: string;
home: string;
join,kill: string;
joinf,killf: text;
alreadyread: integer;
currgroup: string;
headerinmem: string;
headerbuf: headerbuft;
headerbytesinmem: integer;
currart: integer;
donegroup: boolean;
browsedir: integer;
mainnewsdir: string;
mainnewsdirsuf: string;
alreadyingroup: boolean;
nextwhilereading: boolean;
editor: string;
edoptions: string;
killsubjsp,killfromsp: ^killsarr;
killtextp: ^killsarr;
haskillfile: boolean;
killfileinmem: boolean;
numkills: integer;
numkillss,numkillfs: integer;
fullname: string;
wafversion: string;
console: boolean;
port: integer;
trusted: boolean;
forumset: string;
{$I rusn-io.pas}
procedure usage;
begin
xwritelnsss('usage: ',newsreadername,' [options]');
xwritelns(' -u --user username');
xwritelns(' -n --newsgroup newsgroup (jumps directly to that newsgroup)');
xwritelns(' -p --port port (uses that fossil port)');
xwritelns(' -f --fullname Full_Name (underscores will become spaces)');
xwritelns(' -e --editor d:/path/editor.exe (uses this editor)');
xwritelns(' -o --options !_w:\user\%A (editor non-filename options)');
xwritelns(' -s --forumset usenet (uses this forum set)');
xwritelns(' -t --trusted (allows dialin users to edit articles)');
halt(1);
end;
{$I rusn-fun.pas}
procedure getfullname;
const
passwordblocksize=256;
type
passwordpasswordbuft=array[1..passwordblocksize] of char;
var
passwordbuf: passwordpasswordbuft;
passwordf: file;
function passwordentry(fieldnum: integer): string;
var
i: integer;
lfs: integer;
result: string;
begin
result := '';
lfs := 0;
for i := 1 to passwordblocksize do
begin
if passwordbuf[i]=#10 then
inc(lfs);
if (lfs=fieldnum) and (passwordbuf[i]<>#10) then
result := result+passwordbuf[i];
end;
passwordentry := result;
end;
begin
fullname := '';
assign(passwordf,waffledir+'\admin\'+'password');
reset(passwordf,1);
blockread(passwordf,passwordbuf,passwordblocksize);
while (fullname='') and not eof(passwordf) do
begin
blockread(passwordf,passwordbuf,passwordblocksize);
if passwordentry(0)=username then
fullname := passwordentry(5);
end;
close(passwordf);
end;
procedure updatejoin;
var
s: string;
tempf: text;
begin
if alreadyread<highestread then
begin
xwritelns('Updating join file...');
assign(tempf,temporarydir+'\'+username);
reset(joinf);
rewrite(tempf);
while not eof(joinf) do
begin
readln(joinf,s);
if getgroup(s)=currgroup then
writeln(tempf,currgroup,' ',highestread)
else
writeln(tempf,s);
end;
close(joinf);
close(tempf);
reset(tempf);
rewrite(joinf);
while not eof(tempf) do
begin
readln(tempf,s);
writeln(joinf,s);
end;
close(tempf);
close(joinf);
erase(tempf);
reset(joinf);
end;
end;
procedure addtokill(header,words: string; isglobal: boolean);
var
s: string;
tempf: text;
newkillwritten: boolean;
begin
xwritelns('Updating kill file...');
{}{} killfileinmem := false;
{}{} {must check if out of bounds!}
if header='Subject' then
begin
inc(numkillss);
killsubjsp^[numkillss] := words;
end
else
begin
inc(numkillfs);
killfromsp^[numkillfs] := words;
end;
if haskillfile then
begin
newkillwritten := false;
assign(tempf,temporarydir+'\'+username);
reset(killf);
rewrite(tempf);
if isglobal then
begin
writeln(tempf,header,': ',words);
newkillwritten := true;
end;
while not eof(killf) do
begin
readln(killf,s);
if (parseheadername(s)='Newsgroups') and
(parseheadervalue(s)=currgroup) then
begin
writeln(tempf,s);
writeln(tempf,header,': ',words);
newkillwritten := true;
end
else
writeln(tempf,s);
end;
if not newkillwritten then {that group had no kill information}
begin
writeln(tempf,'Newsgroups:',' ',currgroup);
writeln(tempf,header,': ',words);
newkillwritten := true;
end;
close(killf);
close(tempf);
reset(tempf);
rewrite(killf);
while not eof(tempf) do
begin
readln(tempf,s);
writeln(killf,s);
end;
close(tempf);
close(killf);
erase(tempf);
end
else
begin
haskillfile := true;
assign(killf,kill);
rewrite(killf);
if not isglobal then
writeln(killf,'Newsgroups: ',currgroup);
writeln(killf,header,': ',words);
end;
reset(killf);
end;
procedure backupjoin;
var
s: string;
tempf: text;
createjoined: boolean;
begin
xwritelns('Backing up join file...');
createjoined := (numjoined=0);
assign(tempf,home+'\join.bak');
reset(joinf);
rewrite(tempf);
while not eof(joinf) do
begin
readln(joinf,s);
writeln(tempf,s);
if createjoined and (numjoined<maxjoined) then
begin
inc(numjoined);
joinedgroups[numjoined] := getgroup(s);
end;
end;
close(tempf);
reset(joinf);
end;
procedure backupkill;
var
s: string;
tempf: text;
begin
killfileinmem := true;
numkills := 0;
if haskillfile then
begin
xwritelns('Backing up kill file...');
assign(tempf,home+'\kill.bak');
reset(killf);
rewrite(tempf);
while not eof(killf) do
begin
readln(killf,s);
writeln(tempf,s);
if numkills<maxkills then
begin
inc(numkills);
killtextp^[numkills] := s;
end
else
killfileinmem := false;
end;
close(tempf);
reset(killf);
end;
end;
procedure swapart(a,b: integer);
var
tempsubj: string;
tempfilename: fnstringt;
tempdate: datestringt;
tempindents: integer;
tempsizeink: integer;
tempfrom: fromstringt;
begin
tempsubj := basesubjs[a];
tempfilename := filenamesp^[a];
tempdate := datesp^[a];
tempindents := indents[a];
tempsizeink := sizeink[a];
tempfrom := fromsp^[a];
basesubjs[a] := basesubjs[b];
filenamesp^[a] := filenamesp^[b];
datesp^[a] := datesp^[b];
indents[a] := indents[b];
sizeink[a] := sizeink[b];
fromsp^[a] := fromsp^[b];
basesubjs[b] := tempsubj;
filenamesp^[b] := tempfilename;
datesp^[b] := tempdate;
indents[b] := tempindents;
sizeink[b] := tempsizeink;
fromsp^[b] := tempfrom;
end;
procedure sortitall;
var
i,j: integer;
dateptrs,subjptrs,finalptrs,revfinalptrs: array[1..maxarts] of integer;
tempint: integer;
dateptrsdone: integer;
finalptrsdone: integer;
finalstart: integer;
currsubjptr: integer;
currsubj: string;
begin
for i := 1 to numarts do
dateptrs[i] := i;
for i := 1 to numarts-1 do
for j := i+1 to numarts do
if (datesp^[dateptrs[i]]>datesp^[dateptrs[j]]) or
((datesp^[dateptrs[i]]=datesp^[dateptrs[j]]) and
(basesubjs[dateptrs[i]]>basesubjs[dateptrs[j]])) then
{that dates equal but subjects not test is for comp.sources.* etc. v29i033}
{hopefully will help part 1/6 posts too (eg alt.sources)}
begin
tempint := dateptrs[i];
dateptrs[i] := dateptrs[j];
dateptrs[j] := tempint;
end;
for i := 1 to numarts do
subjptrs[i] := i;
for i := 1 to numarts-1 do
for j := i+1 to numarts do
if basesubjs[subjptrs[i]]>basesubjs[subjptrs[j]] then
begin
tempint := subjptrs[i];
subjptrs[i] := subjptrs[j];
subjptrs[j] := tempint;
end;
dateptrsdone := 0;
finalptrsdone := 0;
while finalptrsdone<numarts do
begin
inc(dateptrsdone);
if dateptrs[dateptrsdone]>0 then
begin
currsubj := basesubjs[dateptrs[dateptrsdone]];
currsubjptr := 1;
while currsubj>basesubjs[subjptrs[currsubjptr]] do
inc(currsubjptr);
finalstart := finalptrsdone+1;
while currsubj=basesubjs[subjptrs[currsubjptr]] do
begin
inc(finalptrsdone);
finalptrs[finalptrsdone] := subjptrs[currsubjptr];
inc(currsubjptr);
end;
for i := finalstart to finalptrsdone-1 do
for j := i+1 to finalptrsdone do
if not firstartfirst(finalptrs[i],finalptrs[j]) then
begin
tempint := finalptrs[i];
finalptrs[i] := finalptrs[j];
finalptrs[j] := tempint;
end;
for i := 1 to numarts do
if basesubjs[dateptrs[i]]=currsubj then
dateptrs[i] := -dateptrs[i];
end;
end;
for i := 1 to numarts do
revfinalptrs[finalptrs[i]] := i;
for i := 1 to numarts-1 do
if finalptrs[i]<>i then
begin
swapart(i,finalptrs[i]);
finalptrs[revfinalptrs[i]] := finalptrs[i];
revfinalptrs[finalptrs[i]] := revfinalptrs[i];
finalptrs[i] := i;
revfinalptrs[i] := i;
end;
end;
procedure browseart(artnum: integer);
var
s: string;
artfn: string;
artf: text;
newlinesshown: integer;
lineon: integer;
newart: boolean;
artsubject: string;
artfrom: string;
numheaderlines: integer;
procedure newbrowsescreen;
begin
xclrscr;
end;
procedure rereadfromline(i: integer);
var
gottoline: integer;
begin
newbrowsescreen;
reset(artf);
gottoline := 0;
lineon := i;
while gottoline<=lineon-lpp do
begin
readln(artf,s);
inc(gottoline);
end;
newlinesshown := 0;
while gottoline<=lineon do
begin
readln(artf,s);
xwritelns(screenline(s));
inc(newlinesshown);
inc(gottoline);
end;
end;
procedure browsehelppage;
var
ch: char;
begin
xclrscr;
writexy(1,1,newsreadername+' '+newsreaderversion+
' - newsreader-under-development');
writexy(1,2,'russell@alpha3.ersys.edmonton.ab.ca (921103)');
writexy(1,4,'space,d,CR - forward 1 page, 1/2 page, 1 line');
writexy(1,5,'u - back 1 page');
writexy(1,6,'^ - top line');
writexy(1,7,'n,p - next, previous article');
writexy(1,8,'r - reply to author (in mail)');
writexy(1,9,'f - followup (in netnews) (not yet)');
writexy(1,10,'k - kill by subject or author (will not display again)');
writexy(1,11,'e - edit article on disk');
writexy(1,12,'w - write article to a file');
writexy(1,20,'? - help');
writexy(1,22,'press any key to return');
ch := xreadkey;
newbrowsescreen;
rereadfromline(0);
end;
procedure morelines(lines: integer);
begin
if eof(artf) then
newart := true
else
begin
dec(newlinesshown,lines);
while not eof(artf) and (newlinesshown<lpp) do
begin
readln(artf,s);
xwritelns(screenline(s));
inc(newlinesshown);
inc(lineon);
end;
end;
end;
procedure writeart;
var
outfilen: string;
outfile: text;
begin
xclreolxy(1,lpp);
xwrites('file name: ');
xreadlns(outfilen);
assign(outfile,unslash(outfilen));
{$I-}
append(outfile);
{$I-}
if ioresult<>0 then
begin
{$I-}
rewrite(outfile);
{$I+}
end;
if ioresult=0 then
begin
reset(artf);
while not eof(artf) do
begin
readln(artf,s);
writeln(outfile,s);
end;
close(outfile);
end;
rereadfromline(0);
end;
procedure mailart;
begin
end;
procedure editart;
var
doserr: integer;
begin
if trusted then
begin
close(artf);
exec(editor,edoptions+' '+artfn);
doserr := doserror;
if doserr<>0 then
begin
xwritesis('edit failed - error number ',doserr,
' - press any key ');
inc(doserr,0*ord(xreadkey));
end;
rereadfromline(0);
end;
end;
procedure followtoart;
var
subject: string;
messageid: string;
replyaddr: string;
newreplyaddr: string;
replyname: string;
ccaddr: string;
mailfn: string;
mailf: text;
maillffn: string;
maillff: text;
sigfn: string;
sigf: text;
foundblank: boolean;
s: string;
sendeditquit: char;
seqstr: string;
outmailfn: string;
outmailf: text;
outmailnum: integer;
gotafile: boolean;
basesite: string;
lineno: integer;
doserr: integer;
begin
{$ifdef followiswritten}
close(artf);
subject := getheaderline(artfn,'subject:');
if copy(subject,1,4)<>'Re: ' then
subject := 'Re: '+subject;
messageid := getheaderline(artfn,'message-id:');
replyaddr := getheaderline(artfn,'reply-to:');
if replyaddr='' then
replyaddr := getheaderline(artfn,'from:');
if replyaddr='' then
begin
end
else
begin
xclreolxy(1,lpp);
xwrites('Reply-To: ');
xreadlns(newreplyaddr);
if newreplyaddr='' then
begin
replyname := getfromname(replyaddr);
replyaddr := getfromaddr(replyaddr);
end
else
begin
replyaddr := newreplyaddr;
replyname := '';
end;
xclreolxy(1,lpp);
{
xwrites('CC: ');
xreadlns(ccaddr);
xclreolxy(1,lpp);
}
mailfn := temporarydir+'\'+username+'.mai';
assign(mailf,mailfn);
rewrite(mailf);
writeln(mailf,'From ',username,' ',copy(cdow,1,3),', ',dayofmonth,' ',
copy(monthname,1,3),' ',year mod 100,' ',time,' ',timezone,' ',
'remote from ',uucpname);
writeln(mailf,'Received: by ',node,' ('+newsreadername+')');
writeln(mailf,' via UUCP; ',copy(cdow,1,3),', ',dayofmonth,' ',
copy(monthname,1,3),' ',year mod 100,' ',time,' ',timezone);
writeln(mailf,' for ',replyaddr);
write(mailf,'To: ',replyaddr);
if replyname='' then
writeln(mailf)
else
writeln(mailf,' (',replyname,')');
writeln(mailf,'Subject: ',subject);
writeln(mailf,'From: ',username,'@',node,' (',fullname,')');
writeln(mailf,'Message-ID: ',newmessageid);
writeln(mailf,'Date: ',copy(cdow,1,3),', ',dayofmonth,' ',
copy(monthname,1,3),' ',year mod 100,' ',time,' ',timezone);
writeln(mailf,'In-Reply-To: ',messageid);
writeln(mailf,'Organization: ',organ);
writeln(mailf,'X-Newsreader: ',newsreadername,' ',newsreaderversion);
writeln(mailf);
writeln(mailf,'In ',currgroup,' you write:');
writeln(mailf);
reset(artf);
foundblank := false;
while not eof(artf) and not foundblank do
begin
readln(artf,s);
if s='' then
foundblank := true;
end;
while not eof(artf) do
begin
readln(artf,s);
writeln(mailf,'> ',s);
end;
close(artf);
sigfn := home+'\mailsig';
assign(sigf,sigfn);
{$I-}
reset(sigf);
{$I+}
if ioresult=0 then
begin
readln(sigf,s);
if s<>'-- ' then
write(mailf,'-- ');
reset(sigf);
while not eof(sigf) do
begin
readln(sigf,s);
writeln(mailf,s);
end;
close(sigf);
end;
close(mailf);
repeat
exec(editor,edoptions+' '+mailfn);
doserr := doserror;
if doserr<>0 then
begin
xwritesis('edit failed - error number ',doserr,
' - press any key ');
inc(doserr,0*ord(xreadkey));
end;
repeat
xclreolxy(1,lpp);
xwrites('<s>end <e>dit <q>uit ');
sendeditquit := xreadkey;
until (sendeditquit='s') or (sendeditquit='e') or (sendeditquit='q');
until (sendeditquit='s') or (sendeditquit='q');
if sendeditquit='q' then
xwritelns('quit');
if sendeditquit='s' then
begin
xwritelns('send');
seqstr := integertozstring(newseqnumber,4);
{ here copy mailf to maillff - strip carriage returns }
maillffn := spooldir+'\'+smarthost+'\'+seqstr+'.xqt';
assign(maillff,maillffn);
rewrite(maillff);
write(maillff,'U ',username,' ',uucpname,#10);
write(maillff,'Z',#10);
write(maillff,'F D.',uucpname,seqstr,#10);
write(maillff,'I D.',uucpname,seqstr,#10);
write(maillff,'C rmail ',replyaddr,#10);
close(maillff);
maillffn := spooldir+'\'+smarthost+'\'+seqstr+'.dat';
assign(maillff,maillffn);
rewrite(maillff);
assign(mailf,mailfn);
reset(mailf);
while not eof(mailf) do
begin
readln(mailf,s);
write(maillff,s,#10);
end;
close(mailf);
close(maillff);
mailfn := spooldir+'\'+smarthost+'\'+seqstr+'.cmd';
assign(mailf,mailfn);
rewrite(mailf);
writeln(mailf,'S ',seqstr,'.DAT D.',uucpname,seqstr,' ',
username,' - ',seqstr,'.DAT 0666');
writeln(mailf,'S ',seqstr,'.XQT X.',uucpname,seqstr,' ',
username,' - ',seqstr,'.XQT 0666');
close(mailf);
basesite := copy(basesitename(replyaddr),1,8);
outmailfn := spooldir+'\outbox\'+basesite;
gotafile := false;
outmailnum := 1;
while not gotafile do
begin
assign(outmailf,outmailfn+'.'+itoa(outmailnum));
{$I-}
reset(outmailf);
{$I+}
if ioresult<>0 then
gotafile := true
else
begin
inc(outmailnum);
close(outmailf);
end;
end;
outmailfn := outmailfn+'.'+itoa(outmailnum);
assign(outmailf,outmailfn);
rewrite(outmailf);
mailfn := temporarydir+'\'+username+'.mai';
assign(mailf,mailfn);
reset(mailf);
lineno := 1;
while not eof(mailf) do
begin
readln(mailf,s);
if lineno=1 then
writeln(outmailf,copy(s,1,length(s)-
length(' remote from '+uucpname)))
else if lineno>4 then
writeln(outmailf,s);
inc(lineno);
end;
close(mailf);
close(outmailf);
end;
end;
reset(artf);
{$endif}
rereadfromline(0);
end;
procedure killart;
var
subjectfromoops: char;
i: integer;
begin
repeat
xclreolxy(1,lpp);
xwrites('this group: <s>ubject <f>rom; always <S>ubject <F>rom; <o>ops');
subjectfromoops := xreadkey;
until
(subjectfromoops='s') or
(subjectfromoops='f') or
(subjectfromoops='S') or
(subjectfromoops='F') or
(subjectfromoops='o');
xclreolxy(1,lpp);
if subjectfromoops<>'o' then
begin
if (subjectfromoops='s') or (subjectfromoops='S') then
begin
addtokill('Subject',basesubjs[artnum],(subjectfromoops='S'));
{}{} {too much checking here}
for i := 1 to numarts do
if subjkilled(basesubjs[i]) then
selected[i] := false;
end
else
begin
addtokill('From',
getfromaddr(fromsp^[artnum]),(subjectfromoops='F'));
{}{} {too much checking here}
for i := 1 to numarts do
if fromkilled(fromsp^[i]) then
selected[i] := false;
end;
newart := true;
end;
end;
procedure replytoart;
var
thisfrom: string;
subject: string;
messageid: string;
replyaddr: string;
newreplyaddr: string;
replyname: string;
defaultreply: boolean;
ccaddr: string;
mailfn: string;
mailf: text;
maillffn: string;
maillff: text;
rereadblankfound: boolean;
sigfn: string;
sigf: text;
foundblank: boolean;
s: string;
sendeditquit: char;
seqstr: string;
outmailfn: string;
outmailf: text;
outmailnum: integer;
gotafile: boolean;
basesite: string;
lineno: integer;
doserr: integer;
begin
thisfrom := username+'@'+node;
close(artf);
subject := getheaderline(artfn,'subject:');
if copy(subject,1,4)<>'Re: ' then
subject := 'Re: '+subject;
messageid := getheaderline(artfn,'message-id:');
replyaddr := getheaderline(artfn,'reply-to:');
if replyaddr='' then
replyaddr := getheaderline(artfn,'from:');
if replyaddr='' then
replyaddr := thisfrom;
thisfrom := thisfrom+' ('+fullname+')';
xclreolxy(1,lpp);
xwrites('Reply-To: ');
xreadlns(newreplyaddr);
defaultreply := (newreplyaddr='');
if defaultreply then
begin
replyname := getfromname(replyaddr);
replyaddr := getfromaddr(replyaddr);
end
else
begin
replyaddr := newreplyaddr;
replyname := '';
end;
{handle one-line user/x/forward files}
mailfn := userdir+'\'+replyaddr+'\forward';
assign(mailf,mailfn);
{$I-}
reset(mailf);
{$I+}
if ioresult=0 then
begin
readln(mailf,replyaddr);
close(mailf);
end;
xclreolxy(1,lpp);
{
xwrites('CC: ');
xreadlns(ccaddr);
xclreolxy(1,lpp);
}
mailfn := temporarydir+'\'+username+'.mai';
assign(mailf,mailfn);
rewrite(mailf);
writeln(mailf,'From ',username,' ',copy(cdow,1,3),', ',dayofmonth,' ',
copy(monthname,1,3),' ',year mod 100,' ',time,' ',timezone,' ',
'remote from ',uucpname);
writeln(mailf,'Received: by ',node,' ('+newsreadername+')');
writeln(mailf,' via UUCP; ',copy(cdow,1,3),', ',dayofmonth,' ',
copy(monthname,1,3),' ',year mod 100,' ',time,' ',timezone);
writeln(mailf,' for ',replyaddr);
write(mailf,'To: ',replyaddr);
if replyname='' then
writeln(mailf)
else
writeln(mailf,' (',replyname,')');
writeln(mailf,'Subject: ',subject);
writeln(mailf,'From: ',thisfrom);
writeln(mailf,'Message-ID: ',newmessageid);
writeln(mailf,'Date: ',copy(cdow,1,3),', ',dayofmonth,' ',
copy(monthname,1,3),' ',year mod 100,' ',time,' ',timezone);
writeln(mailf,'In-Reply-To: ',messageid);
writeln(mailf,'Organization: ',organ);
writeln(mailf,'X-Newsreader: ',newsreadername,' ',newsreaderversion);
writeln(mailf);
if defaultreply then
writeln(mailf,'In ',currgroup,' you write:')
else
writeln(mailf,'In ',currgroup,' it is written:');
writeln(mailf);
reset(artf);
foundblank := false;
while not eof(artf) and not foundblank do
begin
readln(artf,s);
if s='' then
foundblank := true;
end;
while not eof(artf) do
begin
readln(artf,s);
writeln(mailf,'> ',s);
end;
close(artf);
sigfn := home+'\mailsig';
assign(sigf,sigfn);
{$I-}
reset(sigf);
{$I+}
if ioresult=0 then
begin
readln(sigf,s);
if s<>'-- ' then
write(mailf,'-- ');
reset(sigf);
while not eof(sigf) do
begin
readln(sigf,s);
writeln(mailf,s);
end;
close(sigf);
end;
close(mailf);
repeat
exec(editor,edoptions+' '+mailfn);
doserr := doserror;
if doserr<>0 then
begin
xwritesis('edit failed - error number ',doserr,
' - press any key ');
inc(doserr,0*ord(xreadkey));
end;
repeat
xclreolxy(1,lpp);
xwrites('<s>end <e>dit <q>uit ');
sendeditquit := xreadkey;
until (sendeditquit='s') or (sendeditquit='e') or (sendeditquit='q');
until (sendeditquit='s') or (sendeditquit='q');
if sendeditquit='q' then
xwritelns('quit');
if sendeditquit='s' then
begin
xwritelns('send');
seqstr := integertozstring(newseqnumber,4);
{ here copy mailf to maillff - strip carriage returns }
maillffn := spooldir+'\'+smarthost+'\'+seqstr+'.xqt';
assign(maillff,maillffn);
rewrite(maillff);
write(maillff,'U ',username,' ',uucpname,#10);
write(maillff,'Z',#10);
write(maillff,'F D.',uucpname,seqstr,#10);
write(maillff,'I D.',uucpname,seqstr,#10);
write(maillff,'C rmail ',replyaddr,#10);
close(maillff);
maillffn := spooldir+'\'+smarthost+'\'+seqstr+'.dat';
assign(maillff,maillffn);
rewrite(maillff);
assign(mailf,mailfn);
reset(mailf);
{check for changed From: lines on non-trusted users and replace}
rereadblankfound := false;
while not eof(mailf) do
begin
readln(mailf,s);
if not trusted then
begin
if s='' then
rereadblankfound := true
else if not rereadblankfound then
if copy(s,1,6)='From: ' then
if s<>'From: '+thisfrom then
begin
xclreolxy(1,1);
xclreolxy(1,2);
xclreolxy(1,3);
xclreolxy(1,4);
xclreolxy(1,5);
xclreolxy(1,6);
xclreolxy(1,7);
writexy(1,1,'From: line was changed from');
writexy(1,2,s+' to');
writexy(1,3,thisfrom);
writexy(1,4,'and has been changed back. if you need');
writexy(1,5,'to change From:, run as a trusted user.');
writexy(1,6,'adding a Reply-To: is probably better');
s := 'From: '+thisfrom;
end;
end;
write(maillff,s,#10);
end;
close(mailf);
close(maillff);
mailfn := spooldir+'\'+smarthost+'\'+seqstr+'.cmd';
assign(mailf,mailfn);
rewrite(mailf);
writeln(mailf,'S ',seqstr,'.DAT D.',uucpname,seqstr,' ',
username,' - ',seqstr,'.DAT 0666');
writeln(mailf,'S ',seqstr,'.XQT X.',uucpname,seqstr,' ',
username,' - ',seqstr,'.XQT 0666');
close(mailf);
basesite := copy(basesitename(replyaddr),1,8);
outmailfn := spooldir+'\outbox\'+basesite;
{$ifdef oldandsillymethod}
gotafile := false;
outmailnum := 1;
while not gotafile do
begin
assign(outmailf,outmailfn+'.'+itoa(outmailnum));
{$I-}
reset(outmailf);
{$I+}
if ioresult<>0 then
gotafile := true
else
begin
inc(outmailnum);
close(outmailf);
end;
end;
outmailfn := outmailfn+'.'+itoa(outmailnum);
{$endif}
outmailfn := getuniqfile(spooldir+'\outbox\'+basesite);
assign(outmailf,outmailfn);
rewrite(outmailf);
mailfn := temporarydir+'\'+username+'.mai';
assign(mailf,mailfn);
reset(mailf);
rereadblankfound := false;
lineno := 1;
while not eof(mailf) do
begin
readln(mailf,s);
if lineno=1 then
writeln(outmailf,copy(s,1,length(s)-
length(' remote from '+uucpname)))
else if lineno>4 then
begin
if not trusted then
begin
if s='' then
rereadblankfound := true
else if not rereadblankfound then
if copy(s,1,6)='From: ' then
if s<>'From: '+thisfrom then
s := 'From: '+thisfrom;
end;
writeln(outmailf,s);
end;
inc(lineno);
end;
close(mailf);
close(outmailf);
end;
reset(artf);
rereadfromline(0);
end;
procedure geteopkey;
var
ch: char;
begin
ch := xreadkey;
if ch='?' then browsehelppage
else if ch='n' then newart := true
else if ch='p' then begin newart := true; browsedir := -1; end
else if ch='u' then rereadfromline(max(0,lineon-lpp div 2))
else if ch='^' then rereadfromline(0)
else if ch=#13 then morelines(1)
else if ch=' ' then morelines(lpp-2)
else if ch='d' then morelines(lpp div 2)
else if ch='w' then writeart
else if ch='m' then mailart
else if ch='r' then replytoart
else if ch='f' then followtoart
else if ch='k' then killart
else if ch='e' then editart;
end;
begin
newbrowsescreen;
newlinesshown := 0;
lineon := 0;
artfrom := fromsp^[artnum];
artsubject := basesubjs[artnum];
artfn := basedir+basedirsuf+filenamesp^[artnum];
assign(artf,artfn);
reset(artf);
newart := false;
while not newart do
begin
if eof(artf) then
newart := true
else
begin
while (not eof(artf)) and not newart do
begin
readln(artf,s);
xwritelns(screenline(s));
inc(newlinesshown);
inc(lineon);
while (newlinesshown>=lpp) and not newart do
geteopkey;
end;
if (newlinesshown>0) and not newart then
geteopkey;
end;
end;
close(artf);
end;
procedure getindents(filename: string; var numindents: integer);
var
references: string;
i: integer;
begin
references := getheaderline(filename,'references:');
if references<>'' then
begin
if pos('<',references)>0 then
numindents := 0;
while pos('<',references)>0 do
begin
inc(numindents,1);
references := copy(references,pos('<',references)+1,255);
end;
end;
end;
procedure readinarts;
var
fileinfo: searchrec;
subject: string;
from: string;
newsgroups: string;
filename: string;
datestr: string;
ch: char;
i: integer;
workwithit: boolean;
readnomore: boolean;
begin
nextwhilereading := false;
readnomore := false;
highestart := 0;
findfirst(basedir+basedirsuf+'*.*',archive,fileinfo);
while (doserror=0) and (numarts<maxarts) and not nextwhilereading and
not readnomore do
begin
if xkeypressed then
begin
ch := xreadkey;
if ch='N' then
nextwhilereading := true
else if ch='O' then
readnomore := true
else if ch='Q' then
begin
nextwhilereading := true;
alreadyingroup := true;
currgroup := '';
end;
end;
if not nextwhilereading and not readnomore and
(atoi(fileinfo.name)>alreadyread) then
begin
filename := basedir+basedirsuf+fileinfo.name;
subject := getheaderline(filename,'subject:');
from := getheaderline(filename,'from:');
newsgroups := getheaderline(filename,'newsgroups:');
workwithit := (subject<>'') and
not subjkilled(subject) and
not fromkilled(from);
xwrites(fileinfo.name);
if workwithit then
begin
if alreadyseen(newsgroups) then
begin
workwithit := false;
xwrites('s');
end
end
else
xwrites('k');
xwrites(' ');
if workwithit then
begin
inc(numarts);
filenamesp^[numarts] := fileinfo.name;
basesubjs[numarts] := subject;
fromsp^[numarts] := getfromname(from);
if fromsp^[numarts]='' then
fromsp^[numarts] := getfromaddr(from);
sizeink[numarts] :=
longint(fileinfo.size+1023) div longint(1024);
indents[numarts] := 0;
while copy(basesubjs[numarts],1,4)='Re: ' do
begin
inc(indents[numarts]);
basesubjs[numarts] := copy(basesubjs[numarts],5,255);
end;
getindents(filename,indents[numarts]);
datestr := getheaderline(filename,'date:');
datesp^[numarts] := stringtodatestring(datestr);
if atoi(fileinfo.name)>highestart then
highestart := atoi(fileinfo.name);
end;
end;
findnext(fileinfo);
end;
if numarts=0 then
xwritelns('no new articles')
else
xwriteln;
end;
procedure viewarts(lowest,highest: integer; updatehighestread: boolean);
begin
currart := lowest;
donegroup := false;
browsedir := 1;
while not donegroup do
begin
while (currart>=lowest) and (currart<=highest) and
not selected[currart] do
inc(currart,browsedir);
if currart>highest then
donegroup := true;
if currart<lowest then
browsedir := 1;
if (currart>=lowest) and (currart<=highest) then
begin
browsedir := 1;
browseart(currart);
if (atoi(filenamesp^[currart])>highestread) and
updatehighestread then
highestread := atoi(filenamesp^[currart]);
end;
inc(currart,browsedir);
end;
end;
procedure selectarts;
var
i: integer;
donepagesel: boolean;
donegroupsel: boolean;
topline,botline: integer;
selsubjs: array[1..sellpp] of string;
inkey,lastinkey: char;
highestletteronscreen: char;
function issellet(ch: char): boolean;
begin
issellet := islower(ch) and (ch<=highestletteronscreen);
end;
procedure writeselln(lineno: integer);
var
ycoord: integer;
printsubj: string;
i: integer;
begin
if selected[lineno] then
xhighvideo
else
xlowvideo;
ycoord := lineno-topline+1+headerlines+1;
writexy(1,ycoord,chr(ord('a')+lineno-topline));
writexy(3,ycoord,copy(fromsp^[lineno],1,20));
xgotoxy(24,ycoord);
xwriteiw(sizeink[lineno],4);
printsubj := '';
for i := 1 to indents[lineno] do
printsubj := printsubj+'>';
printsubj := printsubj+selsubjs[lineno-topline+1];
if printsubj='' then
writexy(29,ycoord,'-')
else
writexy(29,ycoord,copy(printsubj,1,50));
xlowvideo;
xgotoxy(1,sellpp+headerlines+4);
end;
procedure showselscreen;
var
i: integer;
prevsubj: string;
percent: integer;
begin
prevsubj := '';
xclrscr;
xgotoxy(1,1);
xwritessis(currgroup,' Articles: ',numarts,' ');
botline := topline-1;
for i := topline to min(topline+sellpp-1,numarts) do
begin
if basesubjs[i]=prevsubj then
selsubjs[i-topline+1] := ''
else
selsubjs[i-topline+1] := basesubjs[i];
prevsubj := basesubjs[i];
writeselln(i);
botline := i;
end;
if numarts>100 then
percent := (10*botline) div (numarts div 10)
else
percent := (100*botline) div numarts;
xgotoxy(1,sellpp+headerlines+3);
xwritelnsssisis('?=help ',time,' ',percent,'% through this group ',
numarts-botline,' more on later screen(s)');
xclreol;
xgotoxy(1,sellpp+headerlines+4);
highestletteronscreen := chr(ord('a')+(botline-topline+1)-1);
end;
procedure togglekey(inkey: char);
var
inkeyint: integer;
artnum: integer;
begin
inkeyint := ord(inkey)-ord('a');
artnum := inkeyint+topline;
if artnum<=botline then
begin
selected[artnum] := not selected[artnum];
writeselln(artnum);
end;
end;
procedure selreversepage;
var
artnum: integer;
begin
for artnum := topline to botline do
begin
selected[artnum] := not selected[artnum];
writeselln(artnum);
end;
end;
procedure dostar(inkey: char);
var
inkeyint: integer;
artnum: integer;
currsubj: string;
begin
inkeyint := ord(inkey)-ord('a');
artnum := inkeyint+topline;
currsubj := basesubjs[artnum];
while (artnum<=numarts) and (currsubj=basesubjs[artnum]) do
begin
if not selected[artnum] then
begin
selected[artnum] := true;
if artnum<=botline then
writeselln(artnum);
end;
inc(artnum);
end;
end;
procedure dodash(inkey: char);
var
inkeyint: integer;
artnum: integer;
currsubj: string;
newkey: char;
newkeyint: integer;
begin
inkeyint := ord(inkey)-ord('a');
xclreolxy(1,lpp);
xwritess(inkey,'-');
newkey := xreadkey;
if issellet(newkey) then
begin
newkeyint := ord(newkey)-ord('a');
if (newkeyint<botline-topline+1) and (newkeyint>=inkeyint) then
for artnum := topline+inkeyint to topline+newkeyint do
if not selected[artnum] then
begin
selected[artnum] := true;
writeselln(artnum);
end;
end;
xclreolxy(1,lpp);
end;
procedure backpage;
begin
if topline=1 then
begin
topline := numarts-((numarts-1) mod sellpp);
showselscreen;
end
else
begin
dec(topline,sellpp);
showselscreen;
end;
end;
procedure forwardpage;
begin
if botline=numarts then
begin
topline := 1;
showselscreen;
end
else
begin
inc(topline,sellpp);
showselscreen;
end;
end;
procedure browsehighlightedarts;
var
currart: integer;
begin
viewarts(topline,botline,false);
for currart := topline to botline do
selected[currart] := false;
showselscreen;
end;
procedure writehighlightedarts;
var
currart: integer;
ch: char;
begin
end;
procedure gotonewgroup;
var
possgroup: string;
begin
xclreolxy(1,lpp);
xwrites('New Group: ');
xreadlns(possgroup);
if joinedtogroup(possgroup) then
begin
alreadyingroup := true;
currgroup := possgroup;
donegroupsel := true;
end
else
xclreolxy(1,lpp);
end;
procedure selprevgroup;
var
prevgroup: string;
foundgroup: string;
begin
prevgroup := '..invalid..';
foundgroup := prevgroup;
reset(joinf);
repeat
prevgroup := foundgroup;
readln(joinf,foundgroup);
foundgroup := getgroup(foundgroup);
until foundgroup=currgroup;
{}{should check eof - I guess}
if prevgroup<>'..invalid..' then
begin
currgroup := prevgroup;
donegroupsel := true;
alreadyingroup := true;
end;
{}{need more error checking here...}
{}{also, it just goes back 1 group - not to the one with something to read!}
end;
procedure selcatch;
begin
donegroupsel := true;
highestread := highestart;
end;
procedure selquit;
var
i: integer;
begin
alreadyingroup := true;
currgroup := '';
donegroupsel := true;
for i := 1 to numarts do
selected[i] := false;
end;
procedure selhelppage;
var
ch: char;
begin
xclrscr;
writexy(1,1,newsreadername+' '+newsreaderversion+
' - newsreader-under-development');
writexy(1,2,'russell@alpha3.ersys.edmonton.ab.ca (921103)');
writexy(1,4,'letter - toggle whether or not to read that article');
writexy(1,5,'c-f - highlight c through and including f');
writexy(1,6,'g* - highlight g and all with same subject');
writexy(1,7,'N - go to next group (but browse first)');
writexy(1,8,'X - like N, but mark _all_ articles as read after');
writexy(1,9,'P - go to previous group');
writexy(1,11,'@ - reverse all selections on this page');
writexy(1,14,'< - go back a page');
writexy(1,15,'> - go forward a page');
writexy(1,16,'Z - browse articles on this page (not marked as read)');
writexy(1,17,'W - write selected articles (this or all pages) (not yet)');
writexy(1,20,'? - help');
writexy(1,22,'press any key to return');
ch := xreadkey;
showselscreen;
end;
begin
for i := 1 to numarts do
selected[i] := false;
donegroupsel := (numarts=0);
lastinkey := ' ';
topline := 1;
while not donegroupsel do
begin
donepagesel := false;
showselscreen;
while not donegroupsel and not donepagesel do
begin
inkey := xreadkey;
if inkey='?' then selhelppage
else if issellet(inkey) then togglekey(inkey)
else if inkey='<' then backpage
else if inkey='>' then forwardpage
else if (inkey=' ') or (inkey=#13) then donepagesel := true
else if (inkey='*') and issellet(lastinkey) then dostar(lastinkey)
else if (inkey='-') and issellet(lastinkey) then dodash(lastinkey)
else if inkey='Z' then browsehighlightedarts
else if inkey='W' then writehighlightedarts
else if inkey='G' then gotonewgroup
else if inkey='N' then donegroupsel := true
else if inkey='@' then selreversepage
else if inkey='X' then selcatch
else if inkey='P' then selprevgroup
else if inkey='Q' then selquit;
lastinkey := inkey;
end;
if botline<numarts then
inc(topline,sellpp)
else
donegroupsel := true;
end;
end;
procedure getmainnewsdir;
var
infilen: string;
infile: text;
foundit: boolean;
s: string;
begin
mainnewsdir := '';
infilen := waffledir+'\system\'+forumset;
assign(infile,infilen);
{$I-}
reset(infile);
{$I+}
if ioresult=0 then
begin
foundit := false;
while not eof(infile) and not foundit do
begin
readln(infile,s);
if (copy(ltrim(s),1,length('DEFAULT'))='DEFAULT') and
(pos('/dir=',s)>0) then
begin
foundit := true;
mainnewsdir := trim(ltrim(copy(s,pos('/dir=',s)+5,255)));
mainnewsdir := unquote(unslash(mainnewsdir));
end;
end;
close(infile);
end
else
begin
xwritelnss('could not open forum set file ',infilen);
halt(1);
end;
end;
procedure groupinit;
procedure groupinitkills;
var
s: string;
killgroup: string;
killline: integer;
function killeof: boolean;
begin
if killfileinmem then
killeof := (killline>=numkills)
else
killeof := eof(killf);
end;
function nextkillline: string;
var
s: string;
begin
if killfileinmem then
begin
inc(killline);
nextkillline := killtextp^[killline];
end
else
begin
readln(killf,s);
nextkillline := s;
end;
end;
begin
{read in kill file for this group}
numkillss := 0;
numkillfs := 0;
killline := 0;
if haskillfile then
begin
if not killfileinmem then
begin
{} xwritelns('reading in kill file...');
reset(killf);
end;
{allow defaults to come before the first Newsgroups line}
killgroup := currgroup;
while not killeof do
begin
s := nextkillline;
if parseheadername(s)='Newsgroups' then
killgroup := parseheadervalue(s);
if killgroup=currgroup then
begin
{} if parseheadername(s)='Subject' then xwritelnss('kill: ',s);
if parseheadername(s)='Subject' then
begin
if numkillss<maxkills then
begin
inc(numkillss);
killsubjsp^[numkillss] := parseheadervalue(s);
end
else
begin
{too many subject kills - ignore}
end;
end
else if parseheadername(s)='From' then
begin
if numkillss<maxkills then
begin
inc(numkillfs);
killfromsp^[numkillfs] := parseheadervalue(s);
end
else
begin
{too many from kills - ignore}
end;
end
else
begin
{invalid entry in kill file - ignore}
end;
end;
end;
end;
end;
begin
numarts := 0;
basedir := getbasedir(currgroup);
headerinmem := '';
highestread := 0;
if (copy(basedir,length(basedir),1)=':') then
basedirsuf := ''
else
basedirsuf := '\';
{$ifdef verbose}
xwritelnssss('basedir=',basedir,', basedirsuf=',basedirsuf);
{$endif}
groupinitkills;
end;
procedure findhighest;
var
s: string;
begin
reset(joinf);
alreadyread := -1;
while (alreadyread<0) and not eof(joinf) do
begin
readln(joinf,s);
if getgroup(s)=currgroup then
alreadyread := getalreadyread(s);
end;
{ only needed for initial single-group stuff }
if alreadyread<0 then
begin
xwritelnss('not joined to ',currgroup);
halt(1);
end;
{ end of only needed part }
end;
procedure initialize;
var
currparmi: integer;
currparm: string;
nextparm: string;
begin
randomize;
new(filenamesp);
new(fromsp);
new(datesp);
new(killsubjsp);
new(killfromsp);
new(killtextp);
username := '';
currgroup := '';
forumset := '';
{$ifdef tiny}
console := false;
port := 0;
trusted := false;
{$else}
console := true;
port := -1;
trusted := true;
{$endif}
fullname := '';
editor := '';
edoptions := '';
alreadyingroup := false;
currparmi := 1;
while currparmi<=paramcount do
begin
currparm := paramstr(currparmi);
if currparmi<paramcount then
nextparm := paramstr(currparmi+1)
else
nextparm := '';
if (currparm='-u') or (currparm='--user') then
begin
username := nextparm;
inc(currparmi);
end
else if (currparm='-n') or (currparm='--newsgroup') then
begin
currgroup := nextparm;
if currgroup<>'' then
alreadyingroup := true;
inc(currparmi);
end
else if (currparm='-p') or (currparm='--port') then
begin
console := false;
port := atoi(nextparm);
trusted := false;
inc(currparmi);
end
else if (currparm='-f') or (currparm='--fullname') then
begin
fullname := ununderscore(nextparm);
inc(currparmi);
end
else if (currparm='-e') or (currparm='--editor') then
begin
editor := nextparm;
inc(currparmi);
end
else if (currparm='-o') or (currparm='--options') then
begin
edoptions := ununderscore(nextparm);
inc(currparmi);
end
else if (currparm='-s') or (currparm='--forumset') then
begin
forumset := nextparm;
inc(currparmi);
end
else if (currparm='-t') or (currparm='--trusted') then
begin
trusted := true;
end
else
begin
{
compatability switch with earlier releases - now obsolete
xwritelnss('unknown option: ',currparm);
halt(1);
}
username := currparm;
xwritelns('warning: obsolete usage of username');
xwritelns('use -u or --user instead');
end;
inc(currparmi);
end;
if username='' then
username := lower(getenv('NET_NAME'));
if username='' then
usage;
if not console and (port<>0) and (port<>1) then
begin
xwritelns('error: -p or --port specified without valid port number');
xwritelns(' valid numbers are 0 (COM1) and 1 (COM2)');
halt(1);
end;
wafenv := unslash(getenv('WAFFLE'));
if wafenv='' then
begin
xwritelns('must set WAFFLE environment variable');
halt(1);
end;
spooldir := unslash(getstaticvalue('spool'));
temporarydir := unslash(getstaticvalue('temporary'));
userdir := unslash(getstaticvalue('user'));
waffledir := unslash(getstaticvalue('waffle'));
if forumset='' then
begin
forumset := getstaticvalue('forums');
if pos(' ',forumset)<>0 then
begin
if pos(' usenet ',' '+forumset+' ')<>0 then
forumset := 'usenet'
else
forumset := copy(forumset,1,pos(' ',forumset)-1);
end;
end;
xwritelnss('forum set: ',forumset);
if fullname='' then
begin
getfullname;
if fullname='' then
begin
xwritelnsss('user ',username,' has no name in the password file');
xwritelns(' and environment variable FULLNAME not set');
xwritelns(' and options -f and --fullname not used');
halt(1);
end;
end;
if editor='' then
editor := getenv('EDITOR');
if editor='' then
editor := 'c:\usr\bin\vi.exe';
uucpname := getstaticvalue('uucpname');
node := getstaticvalue('node');
smarthost := getstaticvalue('smarthost');
organ := getstaticvalue('organ');
timezone := getenv('TZ');
if timezone='' then
timezone := getstaticvalue('timezone');
if timezone='' then
timezone := 'MST'
else if pos(' ',timezone)>1 then
timezone := copy(timezone,1,pos(' ',timezone)-1);
xwritelnss('time zone: ',timezone);
wafversion := getenv('WAFVERSION');
if wafversion='' then
wafversion := '1.64';
if length(wafversion)<>4 then
begin
xwritelns('WAFVERSION environment variable in wrong format');
xwritelns('should be similar to `1.64'' (without the quotes)');
halt(1);
end;
home := userdir+'\'+username;
join := home+'\join';
assign(joinf,join);
{$I-}
reset(joinf);
{$I+}
if ioresult<>0 then
begin
xwritelnsss('join file ',join,' not found.');
halt(1);
end;
haskillfile := true;
kill := home+'\kill';
assign(killf,kill);
{$I-}
reset(killf);
{$I+}
if ioresult<>0 then
begin
haskillfile := false;
xwritelns('(no kill file found)');
end;
xwritelnss('user: ',username);
mainnewsdirsuf := '';
getmainnewsdir;
if mainnewsdir='' then
begin
xwritelns('could not find main news directory');
{ no longer halts - user may have /dir= on each and every entry - allow it }
end
else
begin
if copy(mainnewsdir,length(mainnewsdir),1)=':' then
begin
xwritelns('invalid main news dir - cannot end in ":"');
mainnewsdir := mainnewsdir+'\';
xwritelnsss('rewritten as ',mainnewsdir,
' for Waffle compatability');
halt(1);
end;
{
it'd be better if it always had the : in it, but it's not... well... wrong
if pos(':',mainnewsdir)=0 then
begin
xwritelns('invalid main news dir - must have ":"');
halt(1);
end;
}
if copy(mainnewsdir,length(mainnewsdir),1)<>'\' then
mainnewsdirsuf := '\';
end;
if currgroup<>'' then
if not joinedtogroup(currgroup) then
begin
xwritelnsss('not joined to ',currgroup,
' - starting at top of join file');
currgroup := '';
alreadyingroup := false;
end;
numjoined := 0;
backupjoin;
backupkill;
end;
procedure shutdown;
begin
close(joinf);
if haskillfile then
close(killf);
xgotoxy(1,lpp);
xwriteln;
end;
begin
initialize;
{$ifdef debug}
exec('c:\usr\bin\freem.exe','');
xwrites('rusnews: freem: doserror=');
xwritei(doserror);
xwriteln;
{$endif}
repeat
if alreadyingroup then
alreadyingroup := false
else
currgroup := getnextgroup;
if currgroup<>'' then
begin
{$ifdef verbose}
xwritelnss('group found=',currgroup);
{$endif}
groupinit;
findhighest;
xwritelns('Reading...');
readinarts;
if not nextwhilereading then
begin
{all these routines handle numarts=0 just fine - but it cuts down on output}
if numarts>0 then
begin
xwritelns('Sorting...');
sortitall;
{
for i := 1 to numarts do
xwritelnsssssss(filenamesp^[i]:14,' ',datesp^[i],' ',
indents[i]:1,' ',copy(basesubjs[i],1,55));
}
selectarts;
viewarts(1,numarts,true);
updatejoin;
end;
end;
end;
until currgroup='';
shutdown;
end.