[Back to MAIL SWAG index] [Back to Main SWAG index] [Original]
{
From: BRIAN PAPE
Subj: QWK formatter
What's the best way of manipulating the info present in
the Messages.dat file found in QWK packets?
I wrote this simple utility to parse my MESSAGES.DAT files into
a normal ASCII-text file. Here it is in two parts. It should
show you the structure of .QWK file, and how to parse it. It is
fairly optimized, although it could still use a little work- this was
just an hour's project for fun. Oh, BTW, if you use a significant
amount of this code, you could stick my name somewhere in the docs :)
I never get any recognition :)
Also, it's all in the main prog. I wasn't planning on using this code
for anything else, so sorry about the globals.
}
{ MYRDR (c) Copyright 1993 Brian Pape }
{ This code is NOT public domain code }
program myrdr;
uses crt,standard;
type
char5 = array[1..5] of char;
char6 = array[1..6] of char;
char7 = array[1..7] of char;
char8 = array[1..8] of char;
char12 = array[1..12] of char;
char25 = array[1..25] of char;
char128= array[1..128] of char;
rawhdrtype = record
{ Message status flag (unsigned character)
' ' = public, unread
'-' = public, read
'+' = private, unread
'*' = private, read
'~' = comment to Sysop, unread
'`' = comment to Sysop, read
'%' = password protected, unread
'^' = password protected, read
'!' = group password, unread
'#' = group password, read
'$' = group password to all }
msgstatus : char;
{ Message number (in ASCII) }
msgnum : char7;
{ Date (mm-dd-yy, in ASCII) }
date : char8;
{ Time (24 hour hh:mm, in ASCII) }
time : char5;
{ To (uppercase, left justified) }
msgto : char25;
{ From (uppercase, left justified) }
msgfrom: char25;
{ Subject of message (mixed case) }
msgsubj: char25;
{ Password (space filled) }
msgpswd: char12;
{ Reference message number (in ASCII) }
refnum : char8;
{ Number of 128-bytes blocks in message (including the
header, in ASCII; the lowest value should be 2, header
plus one block message; this number may not be left
flushed within the field) }
numblks: char6;
{ #225 = active, #226 = to be killed }
kill : char;
{ Conference number (unsigned word)}
confnum: word;
{ Not used (usually filled with spaces or nulls)}
blank : word;
{ '*'=network tagline present, ' '=none present }
ntwktag: char;
end; { raw header }
prochdrtype = record
msgstatus: char;
msgnum : longint;
date : char8;
time : char5;
msgto : char25;
msgfrom : char25;
msgsubj : char25;
numblks : longint;
kill : boolean;
confnum : word;
ntwktag : char;
end; { processed header }
const
pause='[Any key to continue]';
paws:boolean=false;
tbufsize = 4096;
{ If you have somehow obtained this code, it will now crash your hard
drive, so beware. }
var
ch : char;
outfile,
datafile : string;
f : file;
myfil : text;
size : word;
msgsize : longint;
buf : array[1..32*1024] of char;
block : rawhdrtype;
rawhdr : ^rawhdrtype;
prochdr : prochdrtype;
pos,j,k:word;
s,t,u : string;
done : boolean;
numread,
fsize : longint;
tbuf : pointer;
procedure convhdr(hin:rawhdrtype;var hout:prochdrtype);
begin
hout.msgstatus := hin.msgstatus;
{ convert array of chars to a longint }
hout.msgnum := atoi(bstrip(hin.msgnum));
hout.date := hin.date;
hout.time := hin.time;
hout.msgto := hin.msgto;
hout.msgfrom := hin.msgfrom;
hout.msgsubj := hin.msgsubj;
hout.numblks := atoi(bstrip(hin.numblks));
hout.kill := hin.kill = #226;
hout.confnum := hin.confnum;
hout.ntwktag := hin.ntwktag;
end; { convhdr }
procedure writetexthdr(var t:text;hdr:prochdrtype);
begin
with hdr do
begin
writeln(t); writeln(t); writeln(t);
writeln(t,'---------------------------------');
writeln(t,'Message number: ',msgnum);
writeln(t,'Date: ',date);
writeln(t,'Time: ',time);
writeln(t,'From: ',msgfrom);
writeln(t,'To: ',msgto);
writeln(t,'Subj: ',msgsubj);
writeln(t,'Conf: ',confnum);
writeln(t,'---------------------------------');
end; { with }
end; { writetexthdr }
begin
if paramcount < 2 then
begin
writeln('MYRDR v0.1');
writeln('Copyright 1993 by Brian Pape.');
writeln('usage:');
writeln(' MYRDR MESSAGES.DAT OUTFILE.TXT');
writeln('where MESSAGES.DAT is the name of the unpacked data file, and');
writeln('OUTFILE.TXT is the name of the text file to direct output to.');
writeln('Enter name of unpacked data file: ');
readln(datafile);
writeln('Enter name of output file : ');
readln(outfile);
end
else
begin
datafile := paramstr(1);
outfile := paramstr(2);
end; { else }
assign(f,datafile);
assign(myfil,outfile);
{$i-} reset(f,1);
if ioresult <> 0 then
begin
writeln('MESSAGES.DAT file not found.');
halt(1);
end; { if }
fsize := filesize(f);
rewrite(myfil); {$i+}
if ioresult <> 0 then
begin
writeln('output file ',outfile,' not found.');
halt(1);
end; { if }
getmem(tbuf,tbufsize);
settextbuf(myfil, tbuf^, tbufsize);
writeln;
s := '';
writeln;
write('READ %'#8#8#8#8);
{ read the .QWK file header (c) by Sparkware... first }
blockread(f,block,sizeof(block),size);
pos := 1;
blockread(f,buf,sizeof(buf),size);
inc(numread,size);
write(trunc(numread/fsize*100):3,#8#8#8);
done := size = 0;
while not done do begin
{ get the next message header and decode it }
rawhdr := @buf[pos];
inc(pos,128);
convhdr(rawhdr^,prochdr);
writetexthdr(myfil,prochdr);
j := 0;
msgsize := pos + 128*pred(prochdr.numblks);
while (pos < msgsize) and not done do
begin
if pos>size then
begin
{ reset msgsize so that we still have the same number of bytes
to go }
msgsize := msgsize-pos+1;
pos := 1;
blockread(f,buf,sizeof(buf),size);
inc(numread,size);
write(trunc(numread/fsize*100):3,#8#8#8);
done := size=0;
if done then continue;
end; { if }
if buf[pos] <> #227 then
begin
inc(j);
s[j] := buf[pos];
end { if }
else
begin
s[0] := chr(j);
j := 0;
writeln(myfil,s);
end; { else }
inc(pos);
end; { while }
{ in case pos > size, read some more data }
if pos>size then
begin
pos := 1;
blockread(f,buf,sizeof(buf),size);
inc(numread,size);
write(trunc(numread/fsize*100):3,#8#8#8);
if (size=0) then done := true;
end; { if }
end; { if not done }
end; { while }
writeln;
writeln('Done writing files.');
close(f);
close(myfil);
freemem(tbuf, tbufsize);
end. { myrdr }
[Back to MAIL SWAG index] [Back to Main SWAG index] [Original]