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;