Contributor: WILLIAM MCBRINE 
{
WILLIAM MCBRINE>I have this File here that tells me the format of QWK stuff, and it>says that the messages.dat File is a whole bunch of Strings of length 128...
This is wrong. They aren't Pascal Strings, simply 128-Byte blocks.
Within the Text blocks, each line is terminated by a "pi" Character
($E3).>I dont know if I did this right but what I load the data into is>this: (I have an Array[1..100] of messagedata).>Type> MessageData = Record> Rec : String[128];> end;
For blocks of Text, you want someting like this:
Type
 messagedata = Array[0..127] of Char;
For the message HEADER, you need something more complex. Here's the
structure I use in my QWK door:
}
qwkhead = Record
 status : Char;
 messnum : Array [1..7] of Char;
 date : Record
 month : Array [1..2] of Char;
 dash1 : Char;
 day : Array [1..2] of Char;
 dash2 : Char;
 year : Array [1..2] of Char
 end;
 time : Record
 hour : Array [1..2] of Char;
 colon : Char;
 minute : Array [1..2] of Char
 end;
 toname : Array [1..25] of Char;
 from : Array [1..25] of Char;
 subject : Array [1..25] of Char;
 passwd : Array [1..12] of Char;
 refnum : Array [1..8] of Char;
 length : Array [1..6] of Char;
 killflag : Byte;
 confnum : Word;
 null : Word;
 nettag : Char
end;
{
This is also 128 Bytes.>1). A tiny little thing that's not too important right now, but it's>bugging me. When I try to load the first Record (which is supposed>to be a packet header) from messages.dat, I seem to be not reading in>the first Character... Like, Constantly it'll skip the first>Character... it'll say "roduced by Qmail..." instead of "Produced by>Qmail..."
The first Character is going into the length field of the String.
Position [0] of the String contains the length.
Your "problem 2" is the same thing. 128 Bytes are actually read, but
only the erroneous length's worth of them are printed out.
Here's some pseudocode to read a whole packet:
 Open MESSAGES.DAT
 Skip the first Record (128 Bytes)
 While not EOF do
 begin
 Read a message header
 Get length of Text in blocks from qwkhead.length (in ASCII) -1
 Reserve memory For 128 Bytes*number of blocks
 Read Text blocks
 Parse Text
 Release memory
 end
 Close MESSAGES.DAT, cleanup
"Parse Text" is the hard part. I wrote an Asm routine to convert the
pi-delimited Text into Strings, pointed to by an Array of Pointers.
(This is the format used by the Searchlight Programmer's Library message
routines; pretty easy to work With.) Pointer "a" points to this:
 msgType = Record
 msglen:Word;
 msglin:Array[1..400] of Pointer
 end;
The "raw data" (Pointer b) below starts one Byte before the actual QWK
data. The purpose of this is to hold the first String length after
conversion. "d" should be the maximum number of lines to convert (400,
in this case); "e" should be about 79 (though it can be set all the way
up to 255 if desired).
}
Procedure mangle(a, b : Pointer; c, d, e : Word); Assembler;
Asm
 push ds
 mov ax,c {# of blocks loaded (maximum length)}
 les di,b {raw data; lines terminated With pi Chars}
 lds si,a {msgType: Word:linecount, 1..400:Pointers}
 xor bx,bx {line count=0}
 inc si {to first line Pointer}
 inc si
 mov dx,di
 mov cl,7
 shl ax,cl {blocks * 128 = maximum Bytes in message}
 mov cx,ax
 cld
 @mloop:
 push ax
 inc di
 mov al, $E3 {pi Character; QWK packet line delimiter}
 repnz scasb {find one}
 pop ax {ax = length before search, cx = length left}
 jnz @notfound {if there aren't any, done With message}
 sub ax, cx
 dec ax {length of line}
 cmp ax, e
 jle @placelen
 mov ax, e {limit line length}
 @placelen:
 xchg di, dx {beginning of String in raw data}
 seges mov [di], al {wow, now it's a Pascal String!}
 mov [si], di
 mov [si+2], es
 add si, 4 {set the Pointer to it}
 dec dx {DX was at $E3 + 1}
 mov di, dx
 mov ax, cx
 inc bx
 cmp bx, d {maximum number of lines}
 jle @mloop {start next line/String}
 @notfound:
 lds si, a {line counter in msgType}
 mov [si], bx {store # of lines}
 pop ds {magically a message!}
end;
{then, to print this Text, you'd do something like this: }
Procedure dump;
Var
 i : Word;
begin
 For i := 1 to a^.msglen do
 Writeln(a^.msglin[i]^);
end;
 

AltStyle によって変換されたページ (->オリジナル) /