{ Hi.. Well, this is the "Repaired" Packets.Pas Unit. The Unit uses the Mark May's MKSM106.zip unit plus the Duncan Murdoch Streams unit. I've placed the URL and a Ftp where the readers can obtain the latest version of those units. {PACKETS.PAS : Sort of Objects for Reading-Writing Fidonet PKT type 2+ files and standard QWK and REP files. + Donated to public domain by Best Software Mar del Plata + You can contact me via e-mail to sebastianf@usa.net or bsmdp@usa.net + You can compile this unit under BP 6.0 or 7.0. + Runs perfectly under Protected Mode } UNIT PACKETS; INTERFACE USES OBJECTS,DOS, {PASCAL UNITS} {These units are part of Mark May's Msgbase Objects. You can download the file from www.dnaco.net/~mmay or you can found the Zip file in ftp.pcmicro.com or elsewhere. They are used to write the Pkt or Rep file directly from the Msgbase } MKGLOBT, MKMSGABS, MKSTRING, {This unit is the Duncan Murdoch's Streams Units. Used for simple and fast buffering in XMS-EMS. You can found the unit in ftp.garbo.uwasa.fi} STREAMS; CONST {STATUS CONSTANTS} ERROK = 0; ERRFINPKT =-1; ERRFINQWK =ERRFINPKT; ERRNOPKT2 =-2; ERRNOMEMORY =-3; ERRBADQWKMSG=-4; ERRNOTOSS =-5; ERRMAXAREAS =-6; {PREDEFINDED STRINGS} AREABADMAIL ='BADMAIL'; AREAKLUDGE ='AREA:'; MSGIDKLUDGE =#1'MSGID:'; INTLKLUDGE =#1'INTL'; FMPTKLUDGE =#1'FMPT'; TOPTKLUDGE =#1'TOPT'; REPLYKLUDGE =#1'REPLY:'; BAUDIOSPKT =0; TIPOPKT =2; PRODUCTCODE =$FF; VERSION =$0200; VALORCAPWORD =1; VALORCAPWORDCOPY=256; COSTOMENSAJE =0; ANCHOMENSAJE :BYTE=80; ENDOFMSG :CHAR=#0; ENDOFPACKET :STRING[2]=#0#0; {ATRIBUTOS} ATRPRIVADO = 1; ATRCRASH = 2; ATRRECIBIDO = 4; ATRENVIADO = 8; ATRFILEATTACH = 16; ATRENTRANSITO = 32; ATRORPHAN = 64; ATRBORRARENVIADO = 128; ATRLOCAL = 256; ATRHOLD = 512; ATRDIRECTO = 1024; ATRFILEREQUEST = 2048; ATRPEDIRRECIBIDO = 4096; ATRRETORNARRECIBIDO = 8192; ATREXAMINARPEDIDO =16384; ATRACTUALIZARPEDIDO =32768; TYPE ORIGPKTHDR=RECORD {THIS IS THE ORIGINAL PKT HEADER} ONODE,DNODE, ANO,MES,DIA, HORA,MINUTO,SEGUNDO, BAUDIOS, TIPOPAQUETE:WORD; ONET,DNET:INTEGER; CODPH,REVH:BYTE; PASSWORD:ARRAY[1..8] OF CHAR; OZONE1,DZONE1,AUXNET,CWORD:WORD; CODPL,REVL:BYTE; CWORDCOPY,OZONE2,DZONE2,OPOINT,DPOINT:WORD; SPECDATA:ARRAY[1..4] OF CHAR; END; {MODIFIED PKT HEADER. IT'S FOR PACKETS.PAS ONLY. Used for easy access of PKT Headers} MODPKTHDR=RECORD ODIR,DDIR:ADDRTYPE; CLAVE:STRING[8]; END; FECHATYPE=RECORD DIA, MES, ANO:WORD; END; HORATYPE=RECORD HORA, MINUTO, SEGUNDO:WORD; END; {Modified Message Header Used for writing Pkt messages headers in a very easy way} MODMSGHDR=RECORD ATRIBUTOS:WORD; DIRORIG,DIRDEST:ADDRTYPE; DE,PARA:STRING[36]; FECHA:FECHATYPE; HORA:HORATYPE; SOBRE:STRING[72]; AREA:STRING[40]; END; {Pkt Message Header. Original} ORIGMSGHDR=RECORD MSGID:WORD; ONODE,DNODE,ONET,DNET, ATR, COSTO:WORD; FECHA:ARRAY[1..20] OF CHAR; END; {Qwk Header} QWKHEADER=RECORD STATUS:CHAR; MSGNUM:ARRAY[1..7] OF CHAR; FECHA: ARRAY[1..8] OF CHAR; HORA: ARRAY[1..5] OF CHAR; PARA: ARRAY[1..25] OF CHAR; DE: ARRAY[1..25] OF CHAR; SOBRE: ARRAY[1..25] OF CHAR; PASSWORD:ARRAY[1..12] OF CHAR; REFER: ARRAY[1..8] OF CHAR; NUMBLOCKS:ARRAY[1..6] OF CHAR; ACTIVO:CHAR; AREANUM:WORD; FILL:ARRAY[1..2] OF CHAR; HASTAG:CHAR; END; {} {This Object is for Read the Pkt named PKTFILE. The Message is retrieved from the file to the Pased Text Stream. If the Stream is nil, it's created. The Header Variable is filled with apropiate values, and the ReadPktMessage retruns one of Status Constants } PPACKETREADPROCESS=^TPACKETREADPROCESS; TPACKETREADPROCESS=OBJECT(TOBJECT) PKTHEADER:ORIGPKTHDR; PKTSTREAM:PBUFSTREAM; CONSTRUCTOR INIT(PKTFILE:STRING); PROCEDURE GETPKTORIGADDRESS(VAR DIR:ADDRTYPE); PROCEDURE GETPKTDESTADDRESS(VAR DIR:ADDRTYPE); FUNCTION READPKTMESSAGE(VAR HEADER:MODMSGHDR;VAR TEXT:PSTREAM):INTEGER; DESTRUCTOR DONE;VIRTUAL; PRIVATE FUNCTION GETSTRINGTONULL:STRING; FUNCTION GETMSGHEADER(VAR HDR:MODMSGHDR):INTEGER; END; {This Object Write the Pkt file PKTFILE. Fill's the main Header with HDRDATA and if the PKTFILE already exists the OVERWRITEHDR boolean decides if the object must replace the Header with HDRDATA or must preserve the old header. The Pkt Message is writed from the Current Message in MSGBASE and fill's the area name with AREA. } PPACKETWRITEPROCESS=^TPACKETWRITEPROCESS; TPACKETWRITEPROCESS=OBJECT(TOBJECT) PKTSTREAM:PBUFSTREAM; CONSTRUCTOR INIT(PKTFILE:STRING;HDRDATA:MODPKTHDR;OVERWRITEHDR:BOOLEAN); FUNCTION WRITEPKTMESSAGE(AREA:STRING;MSGBASE:ABSMSGPTR):INTEGER; FUNCTION WRITEPKTFROMBUFFER(HDR:MODMSGHDR;TEXT:PSTREAM):INTEGER; DESTRUCTOR DONE;VIRTUAL; END; {This Object read the Qwkfiles located in the path PATHTOQWKFILES The READQWKMESSAGE read the current qwk message into TEXT stream, and fill the Header with Apropiate values. } PQWKREADPROCESS=^TQWKREADPROCESS; TQWKREADPROCESS=OBJECT(TOBJECT) BBSID,NOMBREBBS,NOMBRESYSOP,NOMBREUSUARIO:STRING; AREALIST:PSTRINGCOLLECTION; QWKSTREAM:PBUFSTREAM; CONSTRUCTOR INIT(PATHTOQWKFILES:STRING); FUNCTION READQWKMESSAGE(VAR HEADER:MODMSGHDR;VAR TEXT:PSTREAM):INTEGER; DESTRUCTOR DONE;VIRTUAL; END; {This Object writes the Messages.dat file, that conforms the Rep file. The Write procedure writes the current MSGBASE message to the File and you must supply the Area Number of the message in the AreaNumb field} PQWKWRITEPROCESS=^TQWKWRITEPROCESS; TQWKWRITEPROCESS=OBJECT(TOBJECT) QWKSTREAM:PBUFSTREAM; CONSTRUCTOR INIT(PATHTOQWKFILES:STRING;BBSID:STRING); FUNCTION WRITEQWKMESSAGE(MSGBASE:ABSMSGPTR;AREANUMB:WORD):INTEGER; DESTRUCTOR DONE;VIRTUAL; END; {} PROCEDURE GETORIGADDRESS(PKT:STRING;VAR ADR:ADDRTYPE);{Que direccion origen tiene el paquete PKT} PROCEDURE GETDESTADDRESS(PKT:STRING;VAR ADR:ADDRTYPE);{Que direccion destino tiene el paquete PKT} IMPLEMENTATION {} FUNCTION SCANBUFFER(VAR BLOCK; SIZE: WORD; STR: STRING): WORD;ASSEMBLER; ASM PUSH DS LES DI,BLOCK LDS SI,STR MOV CX,SIZE JCXZ @@3 CLD LODSB CMP AL,1 JB @@5 JA @@1 LODSB REPNE SCASB JNE @@3 JMP @@5 @@1: XOR AH,AH MOV BX,AX DEC BX MOV DX,CX SUB DX,AX JB @@3 LODSB INC DX INC DX @@2: DEC DX MOV CX,DX REPNE SCASB JNE @@3 MOV DX,CX MOV CX,BX REP CMPSB JE @@4 SUB CX,BX ADD SI,CX ADD DI,CX INC DI OR DX,DX JNE @@2 @@3: XOR AX,AX JMP @@6 @@4: SUB DI,BX @@5: MOV AX,DI SUB AX,WORD PTR BLOCK @@6: DEC AX POP DS END; { SCAN } PROCEDURE INSERTAAD(CAR:CHAR;VAR S:STRING;TAM:WORD); VAR LN:WORD; FILL:STRING; ST:STRING; BEGIN IF LENGTH(S)>=TAM THEN EXIT; FILL[0]:=CHR(TAM-LENGTH(S)); FILLCHAR(FILL[1],TAM-LENGTH(S),CAR); INSERT(FILL,S,1); END; FUNCTION MAYUSMINUS(MN:BOOLEAN;DESTINO:STRING):STRING; FUNCTION LOSTR(CONST S:STRING):STRING; ASSEMBLER; ASM PUSH DS LDS SI,S LES DI,@RESULT LODSB { LOAD AND STORE LENGTH OF STRING } STOSB XOR CH,CH MOV CL,AL JCXZ @EMPTY { FIX FOR NULL STRING } @LOWERLOOP: LODSB CMP AL,'A' JB @CONT CMP AL,'Z' JA @CONT ADD AL,' ' @CONT: STOSB LOOP @LOWERLOOP @EMPTY: POP DS END; { LOSTR } FUNCTION UPSTR(CONST S:STRING):STRING; ASSEMBLER; ASM PUSH DS LDS SI,S LES DI,@RESULT LODSB { LOAD AND STORE LENGTH OF STRING } STOSB XOR CH,CH MOV CL,AL JCXZ @EMPTY { FIX FOR NULL LENGTH STRING } @UPPERLOOP: LODSB CMP AL,'a' JB @CONT CMP AL,'z' JA @CONT SUB AL,' ' @CONT: STOSB LOOP @UPPERLOOP @EMPTY: POP DS END; { UPSTR } BEGIN IF MN THEN MAYUSMINUS:=UPSTR(DESTINO) ELSE MAYUSMINUS:=LOSTR(DESTINO); END; PROCEDURE ACTUALIZAR(VAR M:STRING;L:BYTE); VAR FILL:STRING; BEGIN IF LENGTH(M)>L THEN M[0]:=CHAR(L) ELSE IF LENGTH(M)=P2) THEN BEGIN SUBCAD:=''; EXIT; END; ST1:=''; FOR M:=P1+1 TO P2-1 DO ST1:=ST1+STIN[M]; SUBCAD:=ST1; END; FUNCTION RECORTAFINAL(IND:STRING):STRING; VAR P1:INTEGER; RES:STRING; BEGIN RES:=IND; IF RES<>'' THEN BEGIN FOR P1:=LENGTH(RES) DOWNTO 1 DO IF RES[P1]<>#32 THEN BREAK; IF P1>1 THEN SYSTEM.DELETE(RES,P1+1,LENGTH(RES)); END; RECORTAFINAL:=RES; END; FUNCTION FULLPATH(INP:STRING):STRING; VAR RES:STRING; BEGIN RES:=FEXPAND(INP); IF RES[LENGTH(RES)]<>'\' THEN RES:=RES+'\'; FULLPATH:=RES; END; FUNCTION EXISTE(NOMBRE:STRING):BOOLEAN; VAR SR:SEARCHREC; BEGIN FINDFIRST(NOMBRE,DOS.ARCHIVE,SR); EXISTE:=DOSERROR=0; END; {} FUNCTION FILTER0A(INS:STRING):STRING; VAR CONT:WORD; RES:STRING; BEGIN RES:=''; FILTER0A:=''; IF LENGTH(INS)=0 THEN EXIT; FOR CONT:=1 TO LENGTH(INS) DO IF INS[CONT]<>#$A THEN RES:=RES+INS[CONT]; FILTER0A:=RES; END; FUNCTION CONVERTPITOCRLF(INS:STRING):STRING; VAR CONT:WORD; RES:STRING; BEGIN RES:=''; CONVERTPITOCRLF:=''; IF LENGTH(INS)=0 THEN EXIT; FOR CONT:=1 TO LENGTH(INS) DO IF INS[CONT]<>#227 THEN RES:=RES+INS[CONT] ELSE RES:=RES+#13#10; CONVERTPITOCRLF:=RES; END; FUNCTION CONVERTCRLFTOPI(INS:STRING):STRING; VAR P1:WORD; RES:STRING; BEGIN RES:=INS; WHILE POS(#13,RES)<>0 DO BEGIN P1:=POS(#13,RES); DELETE(RES,P1,2); INSERT(#227,RES,P1); END; CONVERTCRLFTOPI:=RES; END; {} CONSTRUCTOR TQWKREADPROCESS.INIT(PATHTOQWKFILES:STRING); VAR CONT,CANTAREAS:WORD; PATH,CNUM,CNAM,TMPST:STRING; TXT:TEXT; BEGIN INHERITED INIT; PATH:=FULLPATH(PATHTOQWKFILES); ASSIGN(TXT,PATH+'CONTROL.DAT'); {$I-}RESET(TXT);{$I+} IF IORESULT<>0 THEN FAIL; READLN(TXT,NOMBREBBS); READLN(TXT,TMPST);READLN(TXT,TMPST); READLN(TXT,NOMBRESYSOP); READLN(TXT,BBSID);READLN(TXT,TMPST); BBSID:=COPY(BBSID,POS(',',BBSID)+1,LENGTH(BBSID)-POS(',',BBSID)); READLN(TXT,NOMBREUSUARIO); READLN(TXT,TMPST);READLN(TXT,TMPST);READLN(TXT,TMPST); READLN(TXT,TMPST);CANTAREAS:=STR2LONG(TMPST); IF CANTAREAS=0 THEN BEGIN CLOSE(TXT);FAIL;END; AREALIST:=NEW(PSTRINGCOLLECTION,INIT(1,1)); FOR CONT:=0 TO CANTAREAS-1 DO BEGIN READLN(TXT,CNUM); READLN(TXT,CNAM); AREALIST^.INSERT(NEWSTR(#1+CNUM+#2#3+CNAM+#4)); END; CLOSE(TXT); QWKSTREAM:=NEW(PBUFSTREAM,INIT(PATH+'MESSAGES.DAT',STOPEN,1024)); IF QWKSTREAM^.STATUS<>STOK THEN BEGIN DISPOSE(QWKSTREAM,DONE); DISPOSE(AREALIST,DONE); FAIL; END; QWKSTREAM^.SEEK(128);{SALTEA EL COPYRIGHT DEL QWK} END; FUNCTION TQWKREADPROCESS.READQWKMESSAGE(VAR HEADER:MODMSGHDR;VAR TEXT:PSTREAM):INTEGER; VAR QWKHDR:QWKHEADER; TEMPST:STRING; NUMRECS,CONT:WORD; BEGIN QWKSTREAM^.READ(QWKHDR,SIZEOF(QWKHDR)); IF QWKSTREAM^.STATUS<>STOK THEN BEGIN READQWKMESSAGE:=ERRFINPKT; EXIT; END; TEMPST[0]:=#6; MOVE(QWKHDR.NUMBLOCKS,TEMPST[1],6); TEMPST:=RECORTAFINAL(TEMPST); NUMRECS:=STR2LONG(TEMPST); IF NUMRECS<2 THEN BEGIN READQWKMESSAGE:=ERRBADQWKMSG; EXIT; END; WITH HEADER DO BEGIN ATRIBUTOS:=ATRLOCAL; DE[0]:=#25;MOVE(QWKHDR.DE,DE[1],25);SYSTEM.DELETE(DE,POS(#0,DE),LENGTH(DE)-POS(#0,DE)+1); PARA[0]:=#25;MOVE(QWKHDR.PARA,PARA[1],25);SYSTEM.DELETE(PARA,POS(#0,PARA),LENGTH(PARA)-POS(#0,PARA)+1); SOBRE[0]:=#25;MOVE(QWKHDR.SOBRE,SOBRE[1],25);SYSTEM.DELETE(SOBRE,POS(#0,SOBRE),LENGTH(SOBRE)-POS(#0,SOBRE)+1); FECHA.DIA:=STR2LONG(COPY(QWKHDR.FECHA,4,2)); FECHA.MES:=STR2LONG(COPY(QWKHDR.FECHA,1,2)); FECHA.ANO:=STR2LONG(COPY(QWKHDR.FECHA,7,2)); HORA.HORA:=STR2LONG(COPY(QWKHDR.HORA,1,2)); HORA.MINUTO:=STR2LONG(COPY(QWKHDR.HORA,4,2)); HORA.SEGUNDO:=00; AREA:=AREABADMAIL; FOR CONT:=0 TO AREALIST^.COUNT-1 DO BEGIN TEMPST:=PSTRING(AREALIST^.AT(CONT))^; IF SUBCAD(TEMPST,#1,#2)=LONG2STR(QWKHDR.AREANUM) THEN BEGIN AREA:=SUBCAD(TEMPST,#3,#4); BREAK; END; END; END; IF TEXT=NIL THEN BEGIN TEXT:=NEW(PWORKSTREAM,INIT(TEMPSTREAM,1024,16384,FORSIZEINMEM)); IF TEXT^.STATUS<>STOK THEN BEGIN DISPOSE(TEXT,DONE); READQWKMESSAGE:=ERRNOMEMORY; EXIT; END; END; FOR CONT:=1 TO NUMRECS-1 DO BEGIN TEMPST[0]:=#128; QWKSTREAM^.READ(TEMPST[1],128); TEMPST:=CONVERTPITOCRLF(TEMPST); IF CONT=(NUMRECS-1) THEN TEMPST:=RECORTAFINAL(TEMPST); TEXT^.WRITE(TEMPST[1],LENGTH(TEMPST)); END; {POR SER QWK,VA TODO EN 0} FILLCHAR(HEADER.DIRORIG,SIZEOF(HEADER.DIRORIG),0); FILLCHAR(HEADER.DIRDEST,SIZEOF(HEADER.DIRDEST),0); {} READQWKMESSAGE:=ERROK; END; DESTRUCTOR TQWKREADPROCESS.DONE; BEGIN DISPOSE(AREALIST,DONE); DISPOSE(QWKSTREAM,DONE); INHERITED DONE; END; {} CONSTRUCTOR TQWKWRITEPROCESS.INIT(PATHTOQWKFILES:STRING;BBSID:STRING); VAR PATH:STRING; MODO:WORD; BEGIN PATH:=FULLPATH(PATHTOQWKFILES); IF EXISTE(PATH+BBSID+'.MSG') THEN MODO:=STOPEN ELSE MODO:=STCREATE; QWKSTREAM:=NEW(PBUFSTREAM,INIT(PATH+BBSID+'.MSG',MODO,1024)); IF MODO=STOPEN THEN QWKSTREAM^.SEEK(QWKSTREAM^.GETSIZE) ELSE BEGIN ACTUALIZAR(BBSID,128); QWKSTREAM^.WRITE(BBSID[1],128); END; END; FUNCTION TQWKWRITEPROCESS.WRITEQWKMESSAGE(MSGBASE:ABSMSGPTR;AREANUMB:WORD):INTEGER; VAR NUMBLOCKS:WORD; LASTPOS,POSHEADER:LONGINT; QWKHDR:QWKHEADER; TEMPST:STRING; BEGIN MSGBASE^.MSGSTARTUP; WITH QWKHDR DO BEGIN IF MSGBASE^.ISPRIV THEN STATUS:='+' ELSE STATUS:=' '; TEMPST:=LONG2STR(AREANUMB);ACTUALIZAR(TEMPST,7);MOVE(TEMPST[1],MSGNUM,7); TEMPST:=MSGBASE^.GETDATE;ACTUALIZAR(TEMPST,8);MOVE(TEMPST[1],FECHA,8); TEMPST:=MSGBASE^.GETTIME;ACTUALIZAR(TEMPST,5);MOVE(TEMPST[1],HORA,5); TEMPST:=MSGBASE^.GETTO;IF LENGTH(TEMPST)>25 THEN ACTUALIZAR(TEMPST,25);TEMPST:=MAYUSMINUS(TRUE,TEMPST); FILLCHAR(PARA,25,0);MOVE(TEMPST[1],PARA,LENGTH(TEMPST)); TEMPST:=MSGBASE^.GETFROM;IF LENGTH(TEMPST)>25 THEN ACTUALIZAR(TEMPST,25);TEMPST:=MAYUSMINUS(TRUE,TEMPST); FILLCHAR(DE,25,0);MOVE(TEMPST[1],DE,LENGTH(TEMPST)); TEMPST:=MSGBASE^.GETSUBJ;IF LENGTH(TEMPST)>25 THEN ACTUALIZAR(TEMPST,25); FILLCHAR(SOBRE,25,0);MOVE(TEMPST[1],SOBRE,LENGTH(TEMPST)); FILLCHAR(PASSWORD,12,0); FILLCHAR(REFER,8,#32);REFER[1]:='0'; POSHEADER:=QWKSTREAM^.GETPOS; ACTIVO:=#225; AREANUM:=AREANUMB; FILLCHAR(FILL,2,0); HASTAG:=' '; END; QWKSTREAM^.WRITE(QWKHDR,SIZEOF(QWKHDR)); NUMBLOCKS:=SIZEOF(QWKHDR); MSGBASE^.MSGTXTSTARTUP; TEMPST:=MSGBASE^.GETSTRING(ANCHOMENSAJE); WHILE NOT MSGBASE^.EOM DO BEGIN TEMPST:=FILTER0A(TEMPST)+#$D; TEMPST:=CONVERTCRLFTOPI(TEMPST); QWKSTREAM^.WRITE(TEMPST[1],LENGTH(TEMPST)); INC(NUMBLOCKS,LENGTH(TEMPST)); TEMPST:=MSGBASE^.GETSTRING(ANCHOMENSAJE); END; IF ((NUMBLOCKS DIV 128)+1)<2 THEN BEGIN QWKSTREAM^.SEEK(POSHEADER); QWKSTREAM^.TRUNCATE; END ELSE BEGIN IF (NUMBLOCKS MOD 128)>0 THEN BEGIN ACTUALIZAR(TEMPST,128-(NUMBLOCKS MOD 128)); QWKSTREAM^.WRITE(TEMPST[1],LENGTH(TEMPST)); END; TEMPST:=LONG2STR((NUMBLOCKS DIV 128)+1);ACTUALIZAR(TEMPST,6); MOVE(TEMPST[1],QWKHDR.NUMBLOCKS,6); LASTPOS:=QWKSTREAM^.GETPOS; QWKSTREAM^.SEEK(POSHEADER); QWKSTREAM^.WRITE(QWKHDR,SIZEOF(QWKHDR)); QWKSTREAM^.SEEK(LASTPOS); END; WRITEQWKMESSAGE:=ERROK; END; DESTRUCTOR TQWKWRITEPROCESS.DONE; BEGIN DISPOSE(QWKSTREAM,DONE); INHERITED DONE; END; {} CONSTRUCTOR TPACKETWRITEPROCESS.INIT(PKTFILE:STRING;HDRDATA:MODPKTHDR;OVERWRITEHDR:BOOLEAN); VAR H,MI,S,C,D,M,A,DW,MODO:WORD; PKTHDR:ORIGPKTHDR; BEGIN INHERITED INIT; IF NOT EXISTE(PKTFILE) THEN MODO:=STCREATE ELSE MODO:=STOPEN; PKTSTREAM:=NEW(PBUFSTREAM,INIT(PKTFILE,MODO,1024)); GETDATE(A,M,D,DW); GETTIME(H,MI,S,C); WITH PKTHDR DO BEGIN ONODE:=HDRDATA.ODIR.NODE;DNODE:=HDRDATA.DDIR.NODE; ANO:=A;MES:=M;DIA:=D; HORA:=H;MINUTO:=MI;SEGUNDO:=S; BAUDIOS:=BAUDIOSPKT; TIPOPAQUETE:=TIPOPKT; ONET:=HDRDATA.ODIR.NET;DNET:=HDRDATA.DDIR.NET; CODPH:=HI(PRODUCTCODE);REVH:=HI(VERSION); FILLCHAR(PASSWORD,SIZEOF(PASSWORD),0); MOVE(HDRDATA.CLAVE[1],PASSWORD,LENGTH(HDRDATA.CLAVE)); OZONE1:=HDRDATA.ODIR.ZONE;DZONE1:=HDRDATA.DDIR.ZONE; AUXNET:=0; CWORD:=VALORCAPWORD; CODPL:=LO(PRODUCTCODE);REVL:=LO(VERSION); CWORDCOPY:=VALORCAPWORDCOPY; OZONE2:=OZONE1;DZONE2:=DZONE1; OPOINT:=HDRDATA.ODIR.POINT;DPOINT:=HDRDATA.DDIR.POINT; FILLCHAR(SPECDATA,SIZEOF(SPECDATA),0); END; IF ((MODO=STOPEN) AND (OVERWRITEHDR)) OR (MODO=STCREATE) THEN PKTSTREAM^.WRITE(PKTHDR,SIZEOF(PKTHDR)); IF (MODO=STOPEN) THEN PKTSTREAM^.SEEK(PKTSTREAM^.GETSIZE-2); END; FUNCTION TPACKETWRITEPROCESS.WRITEPKTMESSAGE(AREA:STRING;MSGBASE:ABSMSGPTR):INTEGER; VAR MSGHDR:ORIGMSGHDR; DIR:ADDRTYPE; AREASTR,TEMPSTR,MES,RESFECHA,FECHASTR:STRING; BEGIN WITH MSGHDR DO BEGIN MSGBASE^.MSGSTARTUP; MSGID:=TIPOPKT; MSGBASE^.GETORIG(DIR); ONODE:=DIR.NODE;ONET:=DIR.NET; MSGBASE^.GETDEST(DIR); DNODE:=DIR.NODE;DNET:=DIR.NET; ATR:=0; IF MSGBASE^.ISLOCAL THEN ATR:=ATR OR ATRLOCAL; IF MSGBASE^.ISCRASH THEN ATR:=ATR OR ATRCRASH; IF MSGBASE^.ISKILLSENT THEN ATR:=ATR OR ATRBORRARENVIADO; IF MSGBASE^.ISSENT THEN ATR:=ATR OR ATRENVIADO; IF MSGBASE^.ISFATTACH THEN ATR:=ATR OR ATRFILEATTACH; IF MSGBASE^.ISREQRCT THEN ATR:=ATR OR ATRPEDIRRECIBIDO; IF MSGBASE^.ISREQAUD THEN ATR:=ATR OR ATREXAMINARPEDIDO; IF MSGBASE^.ISRETRCT THEN ATR:=ATR OR ATRRETORNARRECIBIDO; IF MSGBASE^.ISFILEREQ THEN ATR:=ATR OR ATRFILEREQUEST; IF MSGBASE^.ISRCVD THEN ATR:=ATR OR ATRRECIBIDO; IF MSGBASE^.ISPRIV THEN ATR:=ATR OR ATRPRIVADO; COSTO:=COSTOMENSAJE; FECHASTR:=MSGBASE^.GETDATE; RESFECHA:=COPY(FECHASTR,4,2); MES:=COPY(FECHASTR,1,2); IF MES='01' THEN RESFECHA:=RESFECHA+' Jan'; IF MES='02' THEN RESFECHA:=RESFECHA+' Feb'; IF MES='03' THEN RESFECHA:=RESFECHA+' Mar'; IF MES='04' THEN RESFECHA:=RESFECHA+' Apr'; IF MES='05' THEN RESFECHA:=RESFECHA+' May'; IF MES='06' THEN RESFECHA:=RESFECHA+' Jun'; IF MES='07' THEN RESFECHA:=RESFECHA+' Jul'; IF MES='08' THEN RESFECHA:=RESFECHA+' Aug'; IF MES='09' THEN RESFECHA:=RESFECHA+' Sep'; IF MES='10' THEN RESFECHA:=RESFECHA+' Oct'; IF MES='11' THEN RESFECHA:=RESFECHA+' Nov'; IF MES='12' THEN RESFECHA:=RESFECHA+' Dec'; RESFECHA:=RESFECHA+' '+COPY(FECHASTR,7,2)+' '+MSGBASE^.GETTIME; FILLCHAR(FECHA,SIZEOF(FECHA),0); MOVE(RESFECHA[1],FECHA,LENGTH(RESFECHA)); END; PKTSTREAM^.WRITE(MSGHDR,SIZEOF(MSGHDR)); TEMPSTR:=MSGBASE^.GETTO+#0;PKTSTREAM^.WRITE(TEMPSTR[1],LENGTH(TEMPSTR)); TEMPSTR:=MSGBASE^.GETFROM+#0;PKTSTREAM^.WRITE(TEMPSTR[1],LENGTH(TEMPSTR)); TEMPSTR:=MSGBASE^.GETSUBJ+#0;PKTSTREAM^.WRITE(TEMPSTR[1],LENGTH(TEMPSTR)); IF AREA<>'' THEN BEGIN AREASTR:=AREAKLUDGE+AREA+#13; PKTSTREAM^.WRITE(AREASTR[1],LENGTH(AREASTR)); END; MSGBASE^.MSGTXTSTARTUP; TEMPSTR:=MSGBASE^.GETSTRING(ANCHOMENSAJE); WHILE NOT MSGBASE^.EOM DO BEGIN TEMPSTR:=FILTER0A(TEMPSTR)+#$D; PKTSTREAM^.WRITE(TEMPSTR[1],LENGTH(TEMPSTR)); TEMPSTR:=MSGBASE^.GETSTRING(ANCHOMENSAJE); END; PKTSTREAM^.WRITE(ENDOFMSG,LENGTH(ENDOFMSG)); END; FUNCTION TPACKETWRITEPROCESS.WRITEPKTFROMBUFFER(HDR:MODMSGHDR;TEXT:PSTREAM):INTEGER; VAR MSGHDR:ORIGMSGHDR; DIR:ADDRTYPE; AREASTR,D,M,A,S,H,TEMPSTR,MES,RESFECHA,FECHASTR:STRING; BEGIN WITH MSGHDR DO BEGIN MSGID:=TIPOPKT; ONODE:=HDR.DIRORIG.NODE;ONET:=HDR.DIRORIG.NET; DNODE:=HDR.DIRDEST.NODE;DNET:=HDR.DIRDEST.NET; ATR:=HDR.ATRIBUTOS; COSTO:=COSTOMENSAJE; D:=LONG2STR(HDR.FECHA.DIA);M:=LONG2STR(HDR.FECHA.MES);A:=LONG2STR(HDR.FECHA.ANO); INSERTAAD('0',D,2);INSERTAAD('0',M,2); FECHASTR:=M+'/'+D+'/'+A; RESFECHA:=COPY(FECHASTR,4,2); MES:=COPY(FECHASTR,1,2); IF MES='01' THEN RESFECHA:=RESFECHA+' Jan'; IF MES='02' THEN RESFECHA:=RESFECHA+' Feb'; IF MES='03' THEN RESFECHA:=RESFECHA+' Mar'; IF MES='04' THEN RESFECHA:=RESFECHA+' Apr'; IF MES='05' THEN RESFECHA:=RESFECHA+' May'; IF MES='06' THEN RESFECHA:=RESFECHA+' Jun'; IF MES='07' THEN RESFECHA:=RESFECHA+' Jul'; IF MES='08' THEN RESFECHA:=RESFECHA+' Aug'; IF MES='09' THEN RESFECHA:=RESFECHA+' Sep'; IF MES='10' THEN RESFECHA:=RESFECHA+' Oct'; IF MES='11' THEN RESFECHA:=RESFECHA+' Nov'; IF MES='12' THEN RESFECHA:=RESFECHA+' Dec'; H:=LONG2STR(HDR.HORA.HORA);M:=LONG2STR(HDR.HORA.MINUTO);S:=LONG2STR(HDR.HORA.SEGUNDO); INSERTAAD('0',H,2);INSERTAAD('0',M,2);INSERTAAD('0',S,2); RESFECHA:=RESFECHA+' '+COPY(FECHASTR,7,2)+' '+H+':'+M+':'+S; FILLCHAR(FECHA,SIZEOF(FECHA),0); MOVE(RESFECHA[1],FECHA,LENGTH(RESFECHA)); END; PKTSTREAM^.WRITE(MSGHDR,SIZEOF(MSGHDR)); TEMPSTR:=HDR.PARA+#0;PKTSTREAM^.WRITE(TEMPSTR[1],LENGTH(TEMPSTR)); TEMPSTR:=HDR.DE+#0;PKTSTREAM^.WRITE(TEMPSTR[1],LENGTH(TEMPSTR)); TEMPSTR:=HDR.SOBRE+#0;PKTSTREAM^.WRITE(TEMPSTR[1],LENGTH(TEMPSTR)); IF HDR.AREA<>'' THEN BEGIN AREASTR:=AREAKLUDGE+HDR.AREA+#13; PKTSTREAM^.WRITE(AREASTR[1],LENGTH(AREASTR)); END; PKTSTREAM^.COPYFROM(TEXT^,TEXT^.GETSIZE-TEXT^.GETPOS); PKTSTREAM^.WRITE(ENDOFMSG,LENGTH(ENDOFMSG)); END; DESTRUCTOR TPACKETWRITEPROCESS.DONE; BEGIN PKTSTREAM^.SEEK(PKTSTREAM^.GETSIZE); PKTSTREAM^.WRITE(ENDOFPACKET,2); DISPOSE(PKTSTREAM,DONE); INHERITED DONE; END; {} CONSTRUCTOR TPACKETREADPROCESS.INIT(PKTFILE:STRING); BEGIN INHERITED INIT; PKTSTREAM:=NEW(PBUFSTREAM,INIT(PKTFILE,STOPEN,1024)); IF PKTSTREAM^.STATUS<>STOK THEN BEGIN DISPOSE(PKTSTREAM,DONE); FAIL; END; PKTSTREAM^.READ(PKTHEADER,SIZEOF(PKTHEADER)); PKTHEADER.CWORDCOPY:=(LO(PKTHEADER.CWORDCOPY) SHL 8) OR HI(PKTHEADER.CWORDCOPY); END; PROCEDURE TPACKETREADPROCESS.GETPKTORIGADDRESS(VAR DIR:ADDRTYPE); BEGIN FILLCHAR(DIR,SIZEOF(DIR),0); WITH PKTHEADER DO BEGIN IF TIPOPAQUETE<>2 THEN EXIT; IF (CWORD=CWORDCOPY) AND (CWORD<>0) AND (CWORD=256) THEN BEGIN IF (OPOINT<>0) AND (ONET=-1) THEN ONET:=AUXNET; DIR.ZONE:=OZONE1; DIR.NET:=ONET; DIR.NODE:=ONODE; DIR.POINT:=OPOINT; END ELSE BEGIN DIR.ZONE:=0; DIR.NET:=ONET; DIR.NODE:=ONODE; DIR.POINT:=OPOINT; END; END; END; PROCEDURE TPACKETREADPROCESS.GETPKTDESTADDRESS(VAR DIR:ADDRTYPE); BEGIN FILLCHAR(DIR,SIZEOF(DIR),0); WITH PKTHEADER DO BEGIN IF TIPOPAQUETE<>2 THEN EXIT; IF (CWORD=CWORDCOPY) AND (CWORD<>0) AND (CWORD=256) THEN BEGIN IF (DPOINT<>0) AND (DNET=-1) THEN DNET:=AUXNET; DIR.ZONE:=DZONE1; DIR.NET:=DNET; DIR.NODE:=DNODE; DIR.POINT:=DPOINT; END ELSE BEGIN DIR.ZONE:=0; DIR.NET:=DNET; DIR.NODE:=DNODE; DIR.POINT:=DPOINT; END; END; END; FUNCTION TPACKETREADPROCESS.READPKTMESSAGE(VAR HEADER:MODMSGHDR;VAR TEXT:PSTREAM):INTEGER; CONST TAMBUF=1023; TYPE TBUFTYPE=ARRAY[0..TAMBUF] OF CHAR; PBUFTYPE=^TBUFTYPE; VAR BUFSIZE:WORD; TEXTSTREAM:PSTREAM; POSCR,POSBUSQ,READSIZE:WORD; FINDMSGID,FIRSTBLOCK,FINTEXTO:BOOLEAN; TEMPBUF:POINTER; RESTSIZE,RESTPOS:LONGINT; BEGIN FILLCHAR(HEADER,SIZEOF(HEADER),0); CASE GETMSGHEADER(HEADER) OF ERRFINPKT:BEGIN READPKTMESSAGE:=ERRFINPKT;EXIT;END; END; IF TEXT=NIL THEN BEGIN TEXT:=NEW(PWORKSTREAM,INIT(TEMPSTREAM,1024,16384,FORSPEED)); IF TEXT^.STATUS<>STOK THEN BEGIN DISPOSE(TEXT,DONE); READPKTMESSAGE:=ERRNOMEMORY; EXIT; END; END; GETMEM(TEMPBUF,TAMBUF); IF TEMPBUF=NIL THEN BEGIN READPKTMESSAGE:=ERRNOMEMORY; EXIT; END; FINTEXTO:=FALSE; FIRSTBLOCK:=TRUE; RESTSIZE:=PKTSTREAM^.GETSIZE-PKTSTREAM^.GETPOS; WHILE NOT FINTEXTO DO BEGIN IF TAMBUF>RESTSIZE THEN BUFSIZE:=RESTSIZE ELSE BUFSIZE:=TAMBUF; PKTSTREAM^.READ(TEMPBUF^,BUFSIZE); DEC(RESTSIZE,BUFSIZE); IF FIRSTBLOCK THEN BEGIN FIRSTBLOCK:=FALSE; POSBUSQ:=SCANBUFFER(TEMPBUF^,BUFSIZE,AREAKLUDGE); IF POSBUSQ<$FFFF THEN BEGIN INC(POSBUSQ,LENGTH(AREAKLUDGE)); POSCR:=SCANBUFFER(TEMPBUF^,BUFSIZE,#13); MOVE(PBUFTYPE(TEMPBUF)^[POSBUSQ],HEADER.AREA[1],POSCR-POSBUSQ); HEADER.AREA[0]:=CHR(POSCR-POSBUSQ); {} DEC(POSBUSQ,LENGTH(AREAKLUDGE)); DEC(BUFSIZE,(POSCR-POSBUSQ)+1); MOVE(PBUFTYPE(TEMPBUF)^[POSCR+POSBUSQ+1],TEMPBUF^,BUFSIZE); {} END; END; POSBUSQ:=SCANBUFFER(TEMPBUF^,BUFSIZE,#0); IF POSBUSQ<$FFFF THEN BEGIN IF POSBUSQ>0 THEN TEXT^.WRITE(TEMPBUF^,POSBUSQ-1); TEXT^.TRUNCATE; RESTPOS:=BUFSIZE-POSBUSQ-1; PKTSTREAM^.SEEK(PKTSTREAM^.GETPOS-RESTPOS); FINTEXTO:=TRUE; END ELSE TEXT^.WRITE(TEMPBUF^,BUFSIZE); END; FREEMEM(TEMPBUF,TAMBUF); HEADER.AREA:=MAYUSMINUS(TRUE,HEADER.AREA); READPKTMESSAGE:=ERROK; END; FUNCTION TPACKETREADPROCESS.GETSTRINGTONULL:STRING; VAR RES:STRING; C:CHAR; BEGIN PKTSTREAM^.READ(C,1); RES:=''; WHILE C<>#0 DO BEGIN RES:=RES+C; PKTSTREAM^.READ(C,1); END; GETSTRINGTONULL:=RES; END; FUNCTION TPACKETREADPROCESS.GETMSGHEADER(VAR HDR:MODMSGHDR):INTEGER; VAR TEMPFECHA:STRING; SD,SM,SA,SFECHA,SHORA:STRING; OHDR:ORIGMSGHDR; BEGIN PKTSTREAM^.READ(OHDR,SIZEOF(OHDR)); IF PKTSTREAM^.STATUS<>STOK THEN BEGIN GETMSGHEADER:=ERRFINPKT;EXIT;END; FILLCHAR(HDR,SIZEOF(HDR),0); HDR.DIRORIG.NODE:=OHDR.ONODE; HDR.DIRORIG.NET:=OHDR.ONET; HDR.DIRDEST.NODE:=OHDR.DNODE; HDR.DIRDEST.NET:=OHDR.DNET; HDR.ATRIBUTOS:=OHDR.ATR; TEMPFECHA[0]:=#20; MOVE(OHDR.FECHA[1],TEMPFECHA[1],20); TEMPFECHA:=RECORTAFINAL(TEMPFECHA); SFECHA:=COPY(TEMPFECHA,1,9); SHORA:=COPY(TEMPFECHA,12,8); SD:=COPY(SFECHA,1,2);HDR.FECHA.DIA:=STR2LONG(SD); SM:=COPY(SFECHA,4,3);SM:=MAYUSMINUS(TRUE,SM); IF SM='JAN' THEN HDR.FECHA.MES:=1; IF SM='FEB' THEN HDR.FECHA.MES:=2; IF SM='MAR' THEN HDR.FECHA.MES:=3; IF SM='APR' THEN HDR.FECHA.MES:=4; IF SM='MAY' THEN HDR.FECHA.MES:=5; IF SM='JUN' THEN HDR.FECHA.MES:=6; IF SM='JUL' THEN HDR.FECHA.MES:=7; IF SM='AUG' THEN HDR.FECHA.MES:=8; IF SM='SEP' THEN HDR.FECHA.MES:=9; IF SM='OCT' THEN HDR.FECHA.MES:=10; IF SM='NOV' THEN HDR.FECHA.MES:=11; IF SM='DEC' THEN HDR.FECHA.MES:=12; SA:=COPY(SFECHA,8,2);HDR.FECHA.ANO:=STR2LONG(SA); HDR.HORA.HORA:=STR2LONG(COPY(SHORA,1,2)); HDR.HORA.MINUTO:=STR2LONG(COPY(SHORA,4,2)); HDR.HORA.SEGUNDO:=STR2LONG(COPY(SHORA,7,2)); HDR.PARA:=GETSTRINGTONULL; HDR.DE:=GETSTRINGTONULL; HDR.SOBRE:=GETSTRINGTONULL; GETMSGHEADER:=ERROK; END; DESTRUCTOR TPACKETREADPROCESS.DONE; BEGIN DISPOSE(PKTSTREAM,DONE); INHERITED DONE; END; {} PROCEDURE GETORIGADDRESS(PKT:STRING;VAR ADR:ADDRTYPE); VAR PKTR:PPACKETREADPROCESS; BEGIN FILLCHAR(ADR,SIZEOF(ADR),0); PKTR:=NEW(PPACKETREADPROCESS,INIT(PKT)); IF PKTR=NIL THEN EXIT; PKTR^.GETPKTORIGADDRESS(ADR); DISPOSE(PKTR,DONE); END; PROCEDURE GETDESTADDRESS(PKT:STRING;VAR ADR:ADDRTYPE); VAR PKTR:PPACKETREADPROCESS; BEGIN FILLCHAR(ADR,SIZEOF(ADR),0); PKTR:=NEW(PPACKETREADPROCESS,INIT(PKT)); IF PKTR=NIL THEN EXIT; PKTR^.GETPKTDESTADDRESS(ADR); DISPOSE(PKTR,DONE); END; END.