{DAT2TXT v0.90- Free DOS utility: Converts .QWK MESSAGES.DAT to text.} {$V-,S-} program DAT2TXT ; uses dos ; const Seperator = '---------------------------------------------------------------------------' ; herald = '===========================================================================' ; type CharArray = array[1..6] of char ; { to read in chunks } MSGDATHdr = record { ALSO the format for SWAG files !!! } Status : char ; MSGNum : array [1..7] of char ; Date : array [1..8] of char ; Time : array [1..5] of char ; UpTO : array [1..25] of char ; UpFROM : array [1..25] of char ; Subject : array [1..25] of char ; PassWord : array [1..12] of char ; ReferNum : array [1..8] of char ; NumChunk : CharArray ; Alive : byte ; LeastSig : byte ; MostSig : byte ; Reserved : array [1..3] of char ; end ; var F : file ; txtfile : text ; procedure showhelp(problem:byte); {if any *foreseen* errors arise, we are sent} { here to give a little help and exit peacefully } const progdata = 'DAT2TXT v0.90- Free DOS utility: Converts .QWK MESSAGES.DAT to text.'; progdat2 = '(By SWAG contributors.)'; usage = 'Usage: DAT2TXT infile(s) [/o]'; usag2 = 'The "/o" causes DAT2TXT to overwrite (not append to) existing messages.txt.'; note = 'DOS * and ? wildcards ok with "infile(s)". Output is always to MESSAGES.TXT.'; var message : string[80]; begin writeln(progdata); { just tell user what this program } writeln(progdat2); { is and who wrote it } writeln; writeln(usage); writeln(usag2); writeln(note); writeln; writeln('Error encountered:'); case problem of 1 : message := 'Incorrect number of parameters.'; { plenty of room for other errors! } else message := 'Unknown error.'; end; writeln(message); halt(problem); end; function converttoupper(w : string) : string; var cp : integer; {the position of the character to change.} begin for cp := 1 to length(w) do w[cp] := upcase(w[cp]); converttoupper := w; end; function ArrayTOInteger ( B : CharArray ; Len : byte ) : longint ; var I : byte ; S : string ; E : integer ; T : integer ; begin S := '' ; for I := 1 to Len do if B[i] <> #32 then S := S + B[i] ; Val ( S, T, E ); if E = 0 then ArrayToInteger := T else ArrayToInteger := 0 ; end ; procedure ReadWriteHdr ( var HDR : MSGDatHdr ); begin BlockRead ( F, Hdr, 1 ); if ArrayToInteger ( Hdr.NumChunk, 6 ) <> 0 then with Hdr do begin writeln ( txtfile, herald ); write ( txtfile, 'Date: ', Date, ' (', Time, ')' ); writeln ( txtfile, '' : 23, 'Number: ', MSGNum ); write ( txtfile, 'From: ', UpFROM ); writeln ( txtfile, '' : 14, 'Refer#: ', ReferNum ); write ( txtfile, ' To: ', UpTO ); write ( txtfile, '' : 15, 'Recvd: ' ); if Status in ['-', '`', '^', '#'] then writeln ( txtfile, 'YES' ) else writeln ( txtfile, 'NO' ); write ( txtfile, 'Subj: ', Subject ); writeln ( txtfile, '' : 16, 'Conf: ', '(', (MostSig * 256) + LeastSig, ')' ); writeln ( txtfile, Seperator ); end ; end ; procedure ReadMSG ( NumChunks : integer ); var Buff : array [1..128] of char ; J : integer ; I : byte ; begin for J := 1 to PRED ( NumChunks ) do begin BlockRead ( F, Buff, 1 ); for I := 1 to 128 do if Buff [I] = #$E3 then writeln ( txtfile ) else write ( txtfile, Buff [I] ); end ; end ; procedure ReadMessage ( HDR : MSGDatHdr ; RelNum : longint ; var Chunks : integer ); begin Seek ( F, RelNum - 1 ); ReadWriteHdr ( HDR ); Chunks := ArrayToInteger ( HDR.NumChunk, 6 ); if Chunks <> 0 then begin ReadMsg ( Chunks ); writeln ( txtfile ); end else Chunks := 1 ; end ; var MSGHdr : MSGDatHdr ; repordat : boolean ; ch : char ; count : integer ; chunks : integer ; defsavefile : string ; fileinfo : searchrec ; fdt : longint ; ps1,ps2 : string [2] ; fileexists, overwrite : boolean ; response : char ; dpath, tpath : pathstr ; {epath & dpath are fully qualified pathnames of .dat & .txt files} ddir, tdir : dirstr ; dname, tname : namestr ; d_ext, t_ext : extstr ; txtfileinfo : searchrec ; begin if ( paramcount < 1) or ( paramcount > 2) then showhelp(1); ps1 := converttoupper ( paramstr (1)); if (ps1 = '/H') or (ps1 = '/?') or (ps1 = '-H') or (ps1 = '-?') then showhelp(0); DefSaveFile := '' ; ps2 := '/A' ; if paramcount > 1 then ps2 := paramstr ( 2 ); overwrite := (upcase ( ps2[2] ) = 'O'); dpath := fexpand ( paramstr ( 1 ) ); fsplit ( dpath, ddir, dname, d_ext ); { break up path into components } findfirst ( dpath, anyfile, fileinfo ); while doserror = 0 do begin fsplit ( fexpand ( fileinfo.name ), tdir, tname, t_ext ); dpath := ddir + fileinfo.name ; tpath := ddir + tname + '.TXT' ; Assign ( F, dpath ); { whatever file .. ( MESSAGES.DAT for .QWK ) } Reset ( F, SizeOf ( MsgHdr ) ); assign ( txtfile, tpath ); {$i-} reset ( txtfile ); {$i+} fileexists := (ioresult = 0); if fileexists then close ( txtfile ); if fileexists and ( not overwrite ) then append ( txtfile ) else rewrite ( txtfile ); write ( 'DAT2TXT: ', dpath, ' to: ', tpath ); Count := 2 ; { start at RECORD #2 } while Count < FileSize ( F ) do begin ReadMessage ( MSGHdr, Count, Chunks ); INC ( Count, Chunks ); end ; getftime ( F, fdt ); close ( F ); close ( txtfile ); reset ( txtfile ); setftime ( txtfile , fdt ); close ( txtfile ); writeln ( ', done!' ); findnext ( fileinfo ); end ; end.