1 { $O+,F+,I-,S-,R-,V-,X+}
2 Unit MKMsgSqu;
3
4 {$IfDef FPC}
5 {$PackRecords 1}
6 {$EndIf}
7
8 Interface
9
10 Uses MKGlobT, MKMsgAbs, GeneralP;
11
12 { $I FILEMODE.INC}
13 {--- begin FILEMODE.INC ---}
14 {$IfDef SPEED}
15 Uses
16 BseDOS;
17
18 Const
19 fmReadOnly = Open_Access_ReadOnly;
20 fmReadWrite = Open_Access_ReadWrite;
21 fmDenyNone = Open_Share_DenyNone;
22
23 {$Else}
24
25 Const
26 fmReadOnly = 0; {FileMode constants}
27 fmWriteOnly = 1;
28 fmReadWrite = 2;
29 fmDenyAll = 16;
30 fmDenyWrite = 32;
31 fmDenyRead = 48;
32 fmDenyNone = 64;
33 fmNoInherit = 128;
34
35 {$EndIf}
36 {--- end FILEMODE.INC ---}
37
38 Const
39 SqHdrId = $AFAE4453;
40 SqLinkNext = 0;
41 SqLinkPrev = 1;
42 SqNullFrame = 0;
43 SqFrameMsg = 0;
44 SqFrameFree = 1;
45 SqFrameRLE = 2;
46 SqFrameLZW = 3;
47 SqFromSize = 36;
48 SqToSize = 36;
49 SqSubjSize = 72;
50 SqMaxReply = 10;
51
52
53 Type SqBaseType = Record
54 Len: Word; {Length of this record}
55 Rsvd1: Word; {Future use}
56 NumMsg: LongInt; {Number of messages}
57 HighMsg: LongInt; {Highest msg}
58 SkipMsg: LongInt; {# of msgs to keep in beginning of area}
59 HighWater: LongInt; {High water UMsgId}
60 Uid: LongInt; {Next UMsgId}
61 Base: String[79]; {Base name of Squish file}
62 BeginFrame: LongInt; {Offset of first frame in file}
63 LastFrame: LongInt; {Offset of last frame in file}
64 FirstFree: LongInt; {Offset of first free frame in file}
65 LastFree: LongInt; {Offset of last free frame in file}
66 EndFrame: LongInt; {Pointer to end of file}
67 MaxMsg: LongInt; {Maximum number of messages}
68 KeepDays: Word; {Maximum age of messages}
69 SqHdrSize: Word; {Size of frame header}
70 Rsvd2: Array[1..124] of Byte; {Future use}
71 End;
72
73
74 Type SqFrameHdrType = Record
75 Id: LongInt; {Must equal SqHdrId}
76 NextFrame: LongInt; {Next msg frame}
77 PrevFrame: LongInt; {Prior msg frame}
78 FrameLength: LongInt; {Length of this frame not counting header}
79 MsgLength: LongInt; {Length of message}
80 ControlLength: LongInt; {Length of control information}
81 FrameType: Word; {Type of message frame}
82 Rsvd: Word; {Future use}
83 End;
84
85
86 Type SqMsgHdrType = Record
87 Attr: LongInt; {Msg attribute}
88 MsgFrom: String[SqFromSize - 1]; {Nul Term from name}
89 MsgTo: String[SqToSize - 1]; {Nul term to name}
90 Subj: String[SqSubjSize - 1]; {Nul term subject}
91 Orig: OldAddrType; {Origin address}
92 Dest: OldAddrType; {Destination address}
93 DateWritten: LongInt; {Date/Time msg written}
94 DateArrived: LongInt; {Date/Time msg arrived here}
95 UtcOffset: Word; {Minutes offset from UTC}
96 ReplyTo: LongInt; {Original msg}
97 Replies: Array[1..SqMaxReply] of LongInt; {Replies}
98 AzDate: String[19]; {AsciiZ "Fido" style date}
99 End;
100
101
102 Type SqIdxType = Record
103 Ofs: LongInt; {Offset of frame header}
104 UMsgId: LongInt; {Unique message id}
105 Hash: LongInt; {Hash of MsgTo name}
106 End;
107
108
109 Const
110 {$IFDEF OS2}
111 SqIdxArraySize = 16384;
112 {$ELSE}
113 SqIdxArraySize = 5400; {5200}
114 {$ENDIF}
115
116 Type SqIdxArrayType = Array[1..SqIdxArraySize] of SqIdxType;
117
118 Type SqIdxPtrType = ^SqIdxArrayType;
119
120 Type FreeListType = Record
121 FreePos: LongInt;
122 FreeSize: LongInt;
123 End;
124
125 Const MaxFree = 500;
126
127 Type FreeArrayType = Array[1..MaxFree] of FreeListType;
128
129 Const
130 SqBSize: Word = SizeOf(SqBaseType);
131 SqFSize: Word = SizeOf(SqFrameHdrType);
132 SqMSize: Word = SizeOf(SqMsgHdrType);
133 SqISize: Word = SizeOf(SqIdxType);
134
135
136 Const
137 SqTxtBufferSize = 34000; {34000}
138
139 Type SqInfoType = Record
140 FN: String[80];
141 MsgChars: Array[1..SqTxtBufferSize] of Char;
142 Error: Word;
143 FreeLoaded: Boolean;
144 SqdFile: File;
145 SqIFile: File;
146 SqBase: SqBaseType;
147 SqBaseExtra: Array[1..100] of Char;
148 SqdOpened: Boolean;
149 SqiOpened: Boolean;
150 SqiAlloc: Word;
151 Locked: Boolean;
152 HighestFree: Word;
153 Frame: SqFrameHdrType;
154 MsgHdr: SqMsgHdrType;
155 Extra: Array[1..100] of Char;
156 TxtCtr: Word;
157 CurrIdx: Word;
158 StrDate: String[8];
159 StrTime: String[8];
160 CurrentFramePos: LongInt;
161 CurrentUID: LongInt;
162 SName: String[35];
163 SHandle: String[35];
164 HName: LongInt;
165 HHandle: LongInt;
166 End;
167
168
169 Type SqMsgObj = Object(AbsMsgObj)
170 SqInfo: ^SqInfoType;
171 SqIdx: ^SqIdxArrayType;
172 IndexRead: Boolean;
173 FreeArray: ^FreeArrayType;
174 Constructor Init; {Initialize}
175 Destructor Done; Virtual; {Done cleanup and dispose}
GetIDnull176 function GetID: Byte; Virtual;
OpenMsgBasenull177 Function OpenMsgBase: Word; Virtual; {Open message base}
CloseMsgBasenull178 Function CloseMsgBase: Word; Virtual; {Close message base}
CreateMsgBasenull179 Function CreateMsgBase(MaxMsg: Word; MaxDays: Word): Word; Virtual;
MsgBaseExistsnull180 Function MsgBaseExists: Boolean; Virtual;
181 Procedure SetMsgPath(FN: String); Virtual; {Set filepath and name - no extension}
SqdOpennull182 Function SqdOpen: Word; Virtual; {Open squish data file}
SqiOpennull183 Function SqiOpen: Word; Virtual; {Open squish index file}
184 Procedure SqdClose; Virtual; {Close squish data file}
185 Procedure SqiClose; Virtual; {Close squish index file}
LockMsgBasenull186 Function LockMsgBase: Boolean; Virtual; {Lock msg base}
UnLockMsgBasenull187 Function UnLockMsgBase: Boolean; Virtual; {Unlock msg base}
188 Procedure ReadBase; Virtual; {Read base data record}
189 Procedure WriteBase; Virtual; {Write base data record}
GetBeginFramenull190 Function GetBeginFrame: LongInt; Virtual; {Get beginning frame pos}
GetHighWaternull191 Function GetHighWater: LongInt; Virtual; {Get high water umsgid}
GetHighMsgNumnull192 Function GetHighMsgNum: LongInt; Virtual; {Get highest msg number}
193 Procedure ReadFrame(FPos: LongInt); Virtual; {Read frame at FPos}
194 Procedure ReadVarFrame(Var Frame: SqFrameHdrType; FPos: LongInt); Virtual; {Read frame at FPos into Frame}
195 Procedure WriteFrame(FPos: LongInt); Virtual; {Write frame at FPos}
196 Procedure WriteVarFrame(Var Frame: SqFrameHdrType; FPos: LongInt); Virtual;
197 Procedure UnlinkFrame(Var Frame: SqFrameHdrType); Virtual; {Unlink frame from linked list}
198 Procedure LinkFrameNext(Var Frame: SqFrameHdrType; OtherFrame: LongInt;
199 FramePos: LongInt); Virtual; {Link frame after other frame}
200 Procedure KillMsg(MsgNum: LongInt); {Kill msg msgnum}
201 Procedure KillExcess; {Kill msg in excess of limit}
202 Procedure FindFrame(Var FL: LongInt; Var FramePos: LongInt); Virtual;
GetNextFramenull203 Function GetNextFrame: LongInt; Virtual; {Get next frame pos}
204 Procedure ReadMsgHdr(FPos: LongInt); Virtual; {Read msg hdr for frame at FPos}
205 Procedure WriteMsgHdr(FPos: LongInt); Virtual; {Read msg hdr for frame at FPos}
206 Procedure WriteText(FPos: LongInt); Virtual; {Write text buffer for frame at Fpos}
SqHashNamenull207 Function SqHashName(Name: String): LongInt; Virtual; {Convert name to hash value}
208 Procedure StartNewMsg; Virtual; {Initialize msg header}
GetFromnull209 Function GetFrom: String; Virtual; {Get message from}
GetTonull210 Function GetTo: String; Virtual; {Get message to}
GetSubjnull211 Function GetSubj: String; Virtual; {Get message subject}
212 Procedure SetFrom(Str: String); Virtual; {Set message from}
213 Procedure SetTo(Str: String); Virtual; {Set message to}
214 Procedure SetSubj(Str: String); Virtual; {Set message subject}
215 Procedure SetDate(Str: String); Virtual; {Set message date}
216 Procedure SetTime(Str: String); Virtual; {Set message time}
SetReadnull217 function SetRead(RS: Boolean): boolean; virtual;
IsReadnull218 Function IsRead: Boolean; Virtual; {Is current msg received}
GetDatenull219 Function GetDate: String; Virtual; {Get message date mm-dd-yy}
GetTimenull220 Function GetTime: String; Virtual; {Get message time hh:mm}
GetRefernull221 Function GetRefer: LongInt; Virtual; {Get reply to of current msg}
222 Procedure SetRefer(Num: LongInt); Virtual; {Set reply to of current msg}
GetSeeAlsonull223 Function GetSeeAlso: LongInt; Virtual; {Get see also msg}
224 Procedure SetSeeAlso(Num: LongInt); Virtual; {Set see also msg}
225 Procedure ReadText(FPos: LongInt); Virtual;
GetCharnull226 Function GetChar: Char; Virtual;
GetStringnull227 Function GetString: String; Virtual;
228 Procedure GetOrig(Var Addr: AddrType); Virtual;
229 Procedure SetOrig(Var Addr: AddrType); Virtual;
230 Procedure GetDest(Var Addr: AddrType); Virtual;
231 Procedure SetDest(Var Addr: AddrType); Virtual;
232 Procedure InitText; Virtual;
233 Procedure DoString(Str: String); Virtual; {Add string to message text}
234 Procedure DoChar(Ch: Char); Virtual; {Add character to message text}
235 Procedure DoStringLn(Str: String); Virtual; {Add string and newline to msg text}
WriteMsgnull236 Function WriteMsg: Word; Virtual; {Write msg to msg base}
237 Procedure ReadIdx; Virtual;
238 Procedure WriteIdx; Virtual;
239 Procedure SeekFirst(MsgNum: LongInt); Virtual; {Seeks to 1st msg >= MsgNum}
GetMsgNumnull240 Function GetMsgNum: LongInt; Virtual;
241 Procedure SeekNext; Virtual;
242 Procedure SeekPrior; Virtual;
SeekFoundnull243 Function SeekFound: Boolean; Virtual;
GetIdxFramePosnull244 Function GetIdxFramePos: LongInt; Virtual;
GetIdxHashnull245 Function GetIdxHash: LongInt; Virtual;
IsLocalnull246 Function IsLocal: Boolean; Virtual; {Is current msg local}
IsCrashnull247 Function IsCrash: Boolean; Virtual; {Is current msg crash}
IsKillSentnull248 Function IsKillSent: Boolean; Virtual; {Is current msg kill sent}
IsSentnull249 Function IsSent: Boolean; Virtual; {Is current msg sent}
IsFAttachnull250 Function IsFAttach: Boolean; Virtual; {Is current msg file attach}
IsReqRctnull251 Function IsReqRct: Boolean; Virtual; {Is current msg request receipt}
IsReqAudnull252 Function IsReqAud: Boolean; Virtual; {Is current msg request audit}
IsRetRctnull253 Function IsRetRct: Boolean; Virtual; {Is current msg a return receipt}
IsFileReqnull254 Function IsFileReq: Boolean; Virtual; {Is current msg a file request}
IsRcvdnull255 Function IsRcvd: Boolean; Virtual; {Is current msg received}
IsPrivnull256 Function IsPriv: Boolean; Virtual; {Is current msg priviledged/private}
IsHoldnull257 Function IsHold: Boolean; Virtual; {Is current msg hold}
IsDeletednull258 Function IsDeleted: Boolean; Virtual; {Is current msg deleted}
259 Procedure SetAttr(St: Boolean; Mask: LongInt); Virtual; {Set attribute}
260 Procedure SetLocal(St: Boolean); Virtual; {Set local status}
261 Procedure SetRcvd(St: Boolean); Virtual; {Set received status}
262 Procedure SetPriv(St: Boolean); Virtual; {Set priveledge vs public status}
263 Procedure SetCrash(St: Boolean); Virtual; {Set crash netmail status}
264 Procedure SetKillSent(St: Boolean); Virtual; {Set kill/sent netmail status}
265 Procedure SetSent(St: Boolean); Virtual; {Set sent netmail status}
266 Procedure SetFAttach(St: Boolean); Virtual; {Set file attach status}
267 Procedure SetReqRct(St: Boolean); Virtual; {Set request receipt status}
268 Procedure SetReqAud(St: Boolean); Virtual; {Set request audit status}
269 Procedure SetRetRct(St: Boolean); Virtual; {Set return receipt status}
270 Procedure SetFileReq(St: Boolean); Virtual; {Set file request status}
271 procedure setHold(sh : Boolean); virtual; {set hold status}
272 Procedure InitMsgHdr; Virtual; {Set up message}
273 Procedure MsgTxtStartUp; Virtual;
274 Procedure SetMailType(MT: MsgMailType); Virtual; {Set message base type}
GetSubAreanull275 Function GetSubArea: Word; Virtual; {Get sub area number}
276 Procedure ReWriteHdr; Virtual; {Rewrite msg header after changes}
277 Procedure DeleteMsg; Virtual; {Delete current message}
278 Procedure LoadFree; Virtual; {Load freelist into memory}
NumberOfMsgsnull279 Function NumberOfMsgs: LongInt; Virtual; {Number of messages}
280 Procedure SetEcho(ES: Boolean); Virtual; {Set echo status}
IsEchoednull281 Function IsEchoed: Boolean; Virtual; {Is current msg unmoved echomail msg}
GetLastReadnull282 Function GetLastRead: LongInt; Virtual; {Get last read for user num}
283 Procedure SetLastRead(LR: LongInt); Virtual; {Set last read}
GetMsgLocnull284 Function GetMsgLoc: LongInt; Virtual; {To allow reseeking to message}
285 Procedure SetMsgLoc(ML: LongInt); Virtual; {Reseek to message}
IdxHighestnull286 Function IdxHighest: LongInt; Virtual; { *** }
GetMsgDisplayNumnull287 Function GetMsgDisplayNum: LongInt; Virtual; {Get msg number to display}
GetTxtPosnull288 Function GetTxtPos: LongInt; Virtual; {Get indicator of msg text position}
289 Procedure SetTxtPos(TP: LongInt); Virtual; {Set text position}
GetRealMsgNumnull290 Function GetRealMsgNum: LongInt; Virtual;
291 End;
292
293 Type SqMsgPtr = ^SqMsgObj;
294
295 procedure GetSquishInfo(fn: string; var cur, msgs: longint);
296
297 Implementation
298
299 Uses MKFile, MKString, MKDos, Dos {, Global};
300
301 Const
302 SqMsgPriv = $00001;
303 SqMsgCrash = $00002;
304 SqMsgRcvd = $00004;
305 SqMsgSent = $00008;
306 SqMsgFile = $00010;
307 SqMsgFwd = $00020;
308 SqMsgOrphan = $00040;
309 SqMsgKill = $00080;
310 SqMsgLocal = $00100;
311 SqMsgHold = $00200;
312 SqMsgXX2 = $00400;
313 SqMsgFreq = $00800;
314 SqMsgRrq = $01000;
315 SqMsgCpt = $02000;
316 SqMsgArq = $04000;
317 SqMsgUrg = $08000;
318 SqMsgScanned= $10000;
319 SqMsgRead = $80000000;
320
321
322 Constructor SqMsgObj.Init;
323 begin
324 New(SqInfo);
325 New(FreeArray);
326 if (SqInfo = nil) or (FreeArray=nil) then begin
327 if SqInfo <> Nil then Dispose(SqInfo);
328 if FreeArray <> Nil then Dispose(FreeArray);
329 Fail;
330 Exit;
331 end;
332 with SqInfo^ do begin
333 SqdOpened := False;
334 SqiOpened := False;
335 FN := '';
336 Error := 0;
337 Locked := False;
338 FreeLoaded:=false;
339 SqiAlloc := 0;
340 end;
341 End;
342
343
344 Destructor SqMsgObj.Done;
345 Begin
346 If SqInfo^.SqdOpened Then SqdClose;
347 If SqInfo^.SqiOpened Then SqiClose;
348 If SqInfo^.SqIAlloc > 0 Then
349 If SqIdx <> Nil Then
350 FreeMem(SqIdx, SqInfo^.SqiAlloc * SizeOf(SqIdxType));
351 Dispose(FreeArray);
352 Dispose(SqInfo);
353 End;
354
355
SqMsgObj.GetIDnull356 function SqMsgObj.GetID: Byte;
357 begin
358 GetID:=msgSquish;
359 end;
360
361
362 Procedure SqMsgObj.SetMsgPath(FN: String);
363 Begin
364 SqInfo^.FN := FExpand(FN);
365 If Pos('.SQD', UpStr(SqInfo^.FN)) > 0 Then
366 SqInfo^.FN := Copy(SqInfo^.FN,1,Pos('.SQD', UpStr(SqInfo^.FN)) - 1);
367 End;
368
369
SqMsgObj.OpenMsgBasenull370 Function SqMsgObj.OpenMsgBase: Word;
371 Var
372 Error: Word;
373
374 Begin
375 Error := SqiOpen;
376 If Error = 0 Then
377 Begin
378 Error := SqdOpen;
379 If (Error = 0) then
380 Begin
381 ReadIdx;
382 OpenMsgBase := 0;
383 End
384 Else
385 Begin
386 SqiClose;
387 OpenMsgBase := Error;
388 End;
389 End
390 Else
391 OpenMsgBase := Error;
392 End;
393
394
SqMsgObj.SqdOpennull395 Function SqMsgObj.SqdOpen: Word;
396 Var
397 {$IFDEF VirtualPascal}
398 NumRead: LongInt;
399 {$ELSE}
400 NumRead: Word;
401 {$ENDIF}
402
403 Begin
404 If Not SqInfo^.SqdOpened Then
405 Begin
406 Assign(SqInfo^.SqdFile, SqInfo^.FN + '.sqd');
407 FileMode := fmReadWrite + fmDenyNone;
408 If Not shReset(SqInfo^.SqdFile, 1) Then
409 SqdOpen := MKFileError
410 Else
411 Begin
412 SqInfo^.SqdOpened := True;
413 SqdOpen := 0;
414 If Not shRead(SqInfo^.SqdFile, SqInfo^.SqBase, 2, NumRead) Then
415 SqdOpen := MKFileError
416 Else
417 Begin
418 If SqInfo^.SqBase.Len = 0 Then
419 SqInfo^.SqBase.Len := SqBSize;
420 If SqInfo^.SqBase.Len > (SizeOf(SqBaseType) + 100) Then
421 SqdOpen := 1001
422 Else
423 Begin
424 SqBSize := SqInfo^.SqBase.Len;
425 ReadBase;
426 End;
427 End;
428 End;
429 End
430 Else
431 SqdOpen := 0;
432 End;
433
434
SqMsgObj.SqiOpennull435 Function SqMsgObj.SqiOpen: Word;
436 Begin
437 If Not SqInfo^.SqiOpened Then
438 Begin
439 Assign(SqInfo^.SqiFile, SqInfo^.FN + '.sqi');
440 FileMode := fmReadWrite + fmDenyNone;
441 If Not shReset(SqInfo^.SqiFile, SizeOf(SqIdxType)) Then
442 SqiOpen := MKFileError
443 Else
444 Begin
445 SqInfo^.SqiOpened := True;
446 SqiOpen := 0;
447 End;
448 End
449 Else
450 SqiOpen := 0;
451 End;
452
453
SqMsgObj.CloseMsgBasenull454 Function SqMsgObj.CloseMsgBase: Word;
455 Begin
456 SqdClose;
457 SqiClose;
458 CloseMsgBase := 0;
459 End;
460
461
SqMsgObj.CreateMsgBasenull462 Function SqMsgObj.CreateMsgBase(MaxMsg: Word; MaxDays: Word): Word;
463 Var
464 i: Word;
465
466 Begin
467 If Not SqInfo^.SqdOpened Then
468 Begin
469 i := PosLastChar(DirSep, SqInfo^.FN);
470 If i > 0 Then
471 Begin
472 If MakePath(Copy(SqInfo^.FN, 1, i)) Then;
473 End;
474 FillChar(SqInfo^.SqBase, SizeOf(SqInfo^.SqBase), 0);
475 SqInfo^.SqBase.Len := 256;
476 SqInfo^.SqBase.SqHdrSize := SqFSize;
477 SqInfo^.SqBase.UID := 1;
478 SqInfo^.SqBase.NumMsg := 0;
479 SqInfo^.SqBase.Base := SqInfo^.FN;
480 Str2Az(SqInfo^.FN, 78, SqInfo^.SqBase.Base);
481 SqInfo^.SqBase.MaxMsg := MaxMsg;
482 SqInfo^.SqBase.KeepDays := MaxDays;
483 SqInfo^.SqBase.EndFrame := SqInfo^.SqBase.Len;
484 CreateMsgBase := SaveFile(SqInfo^.FN + '.sqd', SqInfo^.SqBase, SqInfo^.SqBase.Len);
485 If SaveFile(SqInfo^.FN + '.sqi', SqInfo^.SqBase, 0) = 0 Then;
486 If SaveFile(SqInfo^.FN + '.sql', SqInfo^.SqBase, 0) = 0 Then;
487 End
488 Else
489 CreateMsgBase := 176;
490 End;
491
492
SqMsgObj.MsgBaseExistsnull493 Function SqMsgObj.MsgBaseExists: Boolean;
494 Begin
495 MsgBaseExists := FileExist(SqInfo^.FN + '.sqd');
496 End;
497
498
499 Procedure SqMsgObj.SqdClose;
500 Begin
501 If SqInfo^.SqdOpened Then
502 Close(SqInfo^.SqdFile);
503 If IOResult <> 0 Then;
504 SqInfo^.SqdOpened := False;
505 End;
506
507
SqMsgObj.LockMsgBasenull508 Function SqMsgObj.LockMsgBase: Boolean; {Lock msg base}
509 Begin
510 If Not SqInfo^.Locked Then Begin
511 SqInfo^.Locked := shLock(SqInfo^.SqdFile, 0, 1) = 0;
512 LockMsgBase := SqInfo^.Locked;
513 ReadBase;
514 ReadIdx;
515 SqInfo^.FreeLoaded:=false;
516 end;
517 end;
518
519
SqMsgObj.UnLockMsgBasenull520 Function SqMsgObj.UnLockMsgBase: Boolean; {Unlock msg base}
521 Begin
522 If SqInfo^.Locked Then
523 Begin
524 WriteBase;
525 WriteIdx;
526 SqInfo^.Locked := Not UnLockFile(SqInfo^.SqdFile, 0, 1) < 2;
527 UnLockMsgBase := Not SqInfo^.Locked;
528 End;
529 End;
530
531
532 Procedure SqMsgObj.SqiClose;
533 Begin
534 If SqInfo^.SqiOpened Then
535 Close(SqInfo^.SqiFile);
536 If IoResult <> 0 Then;
537 SqInfo^.SqiOpened := False;
538 End;
539
540
541 Procedure SqMsgObj.ReadBase;
542 Var
543 {$IFDEF VirtualPascal}
544 NumRead: LongInt;
545 {$ELSE}
546 NumRead: Word;
547 {$ENDIF}
548
549 Begin
550 Seek(SqInfo^.SqdFile, 0);
551 If Not shRead(SqInfo^.SqdFile, SqInfo^.SqBase, SqBSize, NumRead) Then
552 SqInfo^.Error := MKFileError;
553 If SqInfo^.SqBase.SqHdrSize = 0 Then
554 SQInfo^.SqBase.SqHdrSize := SqFSize;
555 SqFSize := SqInfo^.SqBase.SqHdrSize;
556 End;
557
558
559 Procedure SqMsgObj.WriteBase;
560 Begin
561 Seek(SqInfo^.SqdFile, 0);
562 If Not shWrite(SqInfo^.SqdFile, SqInfo^.SqBase, SQBSize) Then
563 SqInfo^.Error := MKFileError;
564 End;
565
566
567 Procedure SqMsgObj.StartNewMsg; {Initialize msg header}
568 Begin
569 FillChar(SqInfo^.MsgHdr, SizeOf(SqInfo^.MsgHdr), 0);
570 FillChar(SqInfo^.Frame, SizeOf(SqInfo^.Frame), 0);
571 SqInfo^.TxtCtr := 0;
572 SqInfo^.StrDate := '';
573 SqInfo^.StrTime := '';
574 End;
575
576
SqMsgObj.GetFromnull577 Function SqMsgObj.GetFrom: String; {Get message from}
578 Var
579 s: String;
580
581 Begin
582 Move(SqInfo^.MsgHdr.MsgFrom, s, SqFromSize);
583 { s := SqInfo^.MsgHdr.MsgFrom;}
584 GetFrom := Az2Str(s, SqFromSize);
585 End;
586
587
SqMsgObj.GetTonull588 Function SqMsgObj.GetTo: String; {Get message to}
589 Var
590 s: String;
591
592 Begin
593 Move(SqInfo^.MsgHdr.MsgTo, s, SqToSize);
594 { s := SqInfo^.MsgHdr.MsgTo;}
595 GetTo := Az2Str(s, SqToSize);
596 End;
597
598
SqMsgObj.GetSubjnull599 Function SqMsgObj.GetSubj: String; {Get message subject}
600 Var
601 s: String;
602
603 Begin
604 Move(SqInfo^.MsgHdr.Subj, s, SqSubjSize);
605 { SqInfo^.MsgHdr.Subj := s;}
606 GetSubj := Az2Str(s, SqSubjSize);
607 End;
608
609
610 Procedure SqMsgObj.SetFrom(Str: String); {Set message from}
611 Begin
612 Str2Az(Str, 35, SqInfo^.MsgHdr.MsgFrom);
613 End;
614
615
616 Procedure SqMsgObj.SetTo(Str: String); {Set message to}
617 Begin
618 Str2Az(Str,35, SqInfo^.MsgHdr.MsgTo);
619 End;
620
621
622 Procedure SqMsgObj.SetSubj(Str: String); {Set message subject}
623 Begin
624 Str2Az(Str,72, SqInfo^.MSgHdr.Subj);
625 End;
626
627
SqMsgObj.GetDatenull628 Function SqMsgObj.GetDate: String; {Get message date mm-dd-yy}
629 Var
630 TmpDate: LongInt;
631
632 Begin
633 TmpDate := (SqInfo^.MsgHdr.DateWritten shr 16) +
634 ((SqInfo^.MsgHdr.DateWritten and $ffff) shl 16);
635 GetDate := DateStr(TmpDate);
636 End;
637
638
SqMsgObj.GetTimenull639 Function SqMsgObj.GetTime: String; {Get message time hh:mm}
640 Var
641 TmpDate: LongInt;
642
643 Begin
644 TmpDate := (SqInfo^.MsgHdr.DateWritten shr 16) +
645 ((SqInfo^.MsgHdr.DateWritten and $ffff) shl 16);
646 GetTime := TimeStr(TmpDate);
647 End;
648
649
650 Procedure SqMsgObj.SetDate(Str: String);
651 Begin
652 SqInfo^.StrDate := Copy(Str,1,8);
653 End;
654
655
656 Procedure SqMsgObj.SetTime(Str: String);
657 Begin
658 SqInfo^.StrTime := Copy(Str,1,8);
659 End;
660
661
662 Procedure SqMsgObj.GetOrig(Var Addr: AddrType);
663 begin
664 move(SqInfo^.MsgHdr.Orig, Addr, sizeof(SqInfo^.MsgHdr.Orig));
665 Addr.domain := '';
666 end;
667
668
669 Procedure SqMsgObj.SetOrig(Var Addr: AddrType);
670 Begin
671 move(Addr, SqInfo^.MsgHdr.Orig, sizeof(SqInfo^.MsgHdr.Orig));
672 End;
673
674
675 Procedure SqMsgObj.GetDest(Var Addr: AddrType);
676 Begin
677 move(SqInfo^.MsgHdr.Dest, Addr, sizeof(SqInfo^.MsgHdr.Dest));
678 addr.domain := '';
679 End;
680
681
682 Procedure SqMsgObj.SetDest(Var Addr: AddrType);
683 Begin
684 move(Addr, SqInfo^.MsgHdr.Dest, sizeof(SqInfo^.MsgHdr.Dest));
685 End;
686
687
SqMsgObj.SqHashNamenull688 Function SqMsgObj.SqHashName(Name: String): LongInt;
689 Var
690 Hash: LongInt;
691 Tmp: LongInt;
692 Counter: Word;
693
694 Begin
695 Hash := 0;
696 Counter := 1;
697 While Counter <= Length(Name) Do
698 Begin
699 Hash := (Hash shl 4) + Ord(LoCase(Name[Counter]));
700 Tmp := Hash and $F0000000;
701 If (Tmp <> 0) Then
702 Hash := (Hash or (Tmp shr 24)) or Tmp;
703 Inc(Counter);
704 End;
705 SqHashName := Hash and $7fffffff;
706 End;
707
708
709 Procedure SqMsgObj.ReadFrame(FPos: LongInt); {Read frame at FPos}
710 Begin
711 ReadVarFrame(SqInfo^.Frame, FPos);
712 End;
713
714
715 Procedure SqMsgObj.ReadVarFrame(Var Frame: SqFrameHdrType; FPos: LongInt); {Read frame at FPos}
716 Var
717 {$IFDEF VirtualPascal}
718 NumRead: LongInt;
719 {$ELSE}
720 NumRead: Word;
721 {$ENDIF}
722
723 Begin
724 Seek(SqInfo^.SqdFile, FPos);
725 SqInfo^.Error := IoResult;
726 If SqInfo^.Error = 0 Then
727 Begin
728 If Not shRead(SqInfo^.SqdFile, Frame, SizeOf(SqFrameHdrType), NumRead) Then
729 SqInfo^.Error := MKFileError;
730 End;
731 End;
732
733
734 Procedure SqMsgObj.WriteFrame(FPos: LongInt); {Read frame at FPos}
735 Begin
736 WriteVarFrame(SqInfo^.Frame, FPos);
737 End;
738
739
740 Procedure SqMsgObj.WriteVarFrame(Var Frame: SqFrameHdrType; FPos: LongInt); {Write frame at FPos}
741 Begin
742 Seek(SqInfo^.SqdFile, FPos);
743 SqInfo^.Error := IoResult;
744 If SqInfo^.Error = 0 Then
745 Begin
746 If Not shWrite(SqInfo^.SqdFile, Frame, SizeOf(SqFrameHdrType)) Then
747 SqInfo^.Error := MKFileError;
748 End;
749 End;
750
751
752
753 Procedure SqMsgObj.UnlinkFrame(Var Frame: SqFrameHdrType);
754 Var
755 TmpFrame: SqFrameHdrType;
756
757 Begin
758 If Frame.PrevFrame <> 0 Then
759 Begin
760 ReadVarFrame(TmpFrame, Frame.PrevFrame);
761 TmpFrame.NextFrame := Frame.NextFrame;
762 WriteVarFrame(TmpFrame, Frame.PrevFrame);
763 End;
764 If Frame.NextFrame <> 0 Then
765 Begin
766 ReadVarFrame(TmpFrame, Frame.NextFrame);
767 TmpFrame.PrevFrame := Frame.PrevFrame;
768 WriteVarFrame(TmpFrame, Frame.NextFrame);
769 End;
770 End;
771
772
773 Procedure SqMsgObj.LoadFree;
774 Var
775 i: Word;
776 TmpFrame: SqFrameHdrType;
777 TmpPos: LongInt;
778
779 Begin
780 SqInfo^.FreeLoaded:=true;
781 FillChar(FreeArray^,Sizeof(FreeArray^),0);
782 i := 0;
783 TmpPos := SqInfo^.SqBase.FirstFree;
784 While ((TmpPos <> 0) and (i < MaxFree)) Do
785 Begin
786 ReadVarFrame(TmpFrame, TmpPos);
787 Inc(i);
788 FreeArray^[i].FreeSize := TmpFrame.FrameLength;
789 FreeArray^[i].FreePos := TmpPos;
790 TmpPos := TmpFrame.NextFrame;
791 End;
792 SqInfo^.HighestFree := i;
793 End;
794
795
796 Procedure SqMsgObj.FindFrame(Var FL: LongInt; Var FramePos: LongInt);
797 Var
798 TmpFrame: SqFrameHdrType;
799 BestFoundPos: LongInt;
800 BestFoundSize: LongInt;
801 BestIdx: Word;
802 i: Word;
803
804 Begin
805 If SqInfo^.FreeLoaded=false Then LoadFree;
806 BestFoundPos := 0;
807 BestFoundSize := 0;
808 For i := 1 to SqInfo^.HighestFree Do
809 Begin
810 If (FreeArray^[i].FreeSize > FL) Then
811 Begin
812 If ((BestFoundSize = 0) or (FreeArray^[i].FreeSize < BestFoundSize)) Then
813 Begin
814 BestFoundSize := FreeArray^[i].FreeSize;
815 BestFoundPos := FreeArray^[i].FreePos;
816 BestIdx := i;
817 End;
818 End
819 End;
820 FramePos := BestFoundPos;
821 If FramePos <> 0 Then
822 Begin
823 ReadVarFrame(TmpFrame, FramePos);
824 FreeArray^[BestIdx].FreePos := 0;
825 FreeArray^[BestIdx].FreeSize := 0;
826 End;
827 If FramePos = 0 Then
828 Begin
829 FL := 0;
830 FramePos := SqInfo^.SqBase.EndFrame;
831 End
832 Else
833 Begin
834 UnLinkFrame(TmpFrame);
835 If TmpFrame.PrevFrame = 0 Then
836 SqInfo^.SqBase.FirstFree := TmpFrame.NextFrame;
837 If TmpFrame.NextFrame = 0 Then
838 SqInfo^.SqBase.LastFree := TmpFrame.PrevFrame;
839 FL := TmpFrame.FrameLength;
840 End;
841 End;
842
843
844 Procedure SqMsgObj.LinkFrameNext(Var Frame: SqFrameHdrType; OtherFrame: LongInt;
845 FramePos: LongInt);
846
847 Var
848 TmpFrame: SqFrameHdrType;
849
850 Begin
851 If OtherFrame <> 0 Then
852 Begin
853 ReadVarFrame(TmpFrame, OtherFrame);
854 TmpFrame.NextFrame := FramePos;
855 Frame.PrevFrame := OtherFrame;
856 WriteVarFrame(TmpFrame, OtherFrame);
857 End;
858 End;
859
860
861 Procedure SqMsgObj.KillMsg(MsgNum: LongInt);
862 Var
863 i: Word;
864 KillPos: LongInt;
865 IndexPos: LongInt;
866 KillFrame: SqFrameHdrType;
867 TmpFrame: SqFrameHdrType;
868 CurrMove: LongInt;
869 AlreadyLocked: Boolean;
870 FreeCtr: Word;
871
872 Begin
873 AlreadyLocked := SqInfo^.Locked;
874 If Not AlreadyLocked Then
875 If LockMsgBase Then;
876 If SqIdx = Nil Then
877 SqInfo^.Error := 999
878 Else
879 Begin
880 i := 1;
881 While ((i <= SqInfo^.SqBase.NumMsg) and (MsgNum <> SqIdx^[i].UMsgId)) Do
882 Inc(i);
883 If MsgNum = SqIdx^[i].UMsgId Then
884 Begin
885 IndexPos := i;
886 KillPos := SqIdx^[i].Ofs;
887 ReadVarFrame(KillFrame, KillPos);
888 If KillFrame.PrevFrame = 0 Then
889 SqInfo^.SqBase.BeginFrame := KillFrame.NextFrame;
890 If KillFrame.NextFrame = 0 Then
891 SqInfo^.SqBase.LastFrame := KillFrame.PrevFrame;
892 KillFrame.FrameType := sqFrameFree;
893 UnLinkFrame(KillFrame);
894 If ((SqInfo^.SqBase.FirstFree = 0) or (SqInfo^.SqBase.LastFree = 0)) Then
895 Begin
896 SqInfo^.SqBase.FirstFree := KillPos;
897 SqInfo^.SqBase.LastFree := KillPos;
898 KillFrame.PrevFrame := 0;
899 KillFrame.NextFrame := 0;
900 End
901 Else
902 Begin
903 KillFrame.NextFrame := 0;
904 KillFrame.PrevFrame := SqInfo^.SqBase.LastFree;
905 ReadVarFrame(TmpFrame, SqInfo^.SqBase.LastFree);
906 TmpFrame.NextFrame := KillPos;
907 WriteVarFrame(TmpFrame, SqInfo^.SqBase.LastFree);
908 SqInfo^.SqBase.LastFree := KillPos;
909 End;
910 WriteVarFrame(KillFrame, KillPos);
911 FreeCtr := 1;
912 While ((FreeCtr < MaxFree) and (FreeArray^[FreeCtr].FreePos <> 0)) Do
913 Inc(FreeCtr);
914 If FreeArray^[FreeCtr].FreePos = 0 Then
915 Begin
916 FreeArray^[FreeCtr].FreePos := KillPos;
917 FreeArray^[FreeCtr].FreeSize := KillFrame.FrameLength;
918 End;
919 If FreeCtr > SqInfo^.HighestFree Then
920 SqInfo^.HighestFree := FreeCtr;
921 Dec(SqInfo^.SqBase.NumMsg);
922 Dec(SqInfo^.SqBase.HighMsg);
923 CurrMove := IndexPos;
924 While CurrMove <= SqInfo^.SqBase.NumMsg Do
925 Begin
926 SqIdx^[CurrMove] := SqIdx^[CurrMove + 1];
927 Inc(CurrMove);
928 End;
929 { NumMove := SqInfo^.SqBase.NumMsg + 1 - IndexPos;
930 NumMove := NumMove * SizeOf(SqIdxType);
931 Move(SqIdx^[IndexPos + 1], SqIdx^[IndexPos], NumMove); }
932 End;
933 End;
934 If Not AlreadyLocked Then
935 If UnlockMsgBase Then;
936 End;
937
938
939 Procedure SqMsgObj.ReadMsgHdr(FPos: LongInt); {Read msg hdr for frame at FPos}
940 Var
941 {$IFDEF VirtualPascal}
942 NumRead: LongInt;
943 {$ELSE}
944 NumRead: Word;
945 {$ENDIF}
946
947 Begin
948 Seek(SqInfo^.SqdFile, FPos + SqFSize);
949 SqInfo^.Error := IoResult;
950 If SqInfo^.Error = 0 Then
951 Begin
952 If Not shRead(SqInfo^.SqdFile, SqInfo^.MsgHdr, SizeOf(SqMsgHdrType), NumRead) Then
953 SqInfo^.Error := MKFileError;
954 End;
955 End;
956
957
958 Procedure SqMsgObj.WriteMsgHdr(FPos: LongInt); {Read msg hdr for frame at FPos}
959 Var
960 NumRead: Word;
961
962 Begin
963 Seek(SqInfo^.SqdFile, FPos + SqFSize);
964 SqInfo^.Error := IoResult;
965 If SqInfo^.Error = 0 Then
966 Begin
967 If Not shWrite(SqInfo^.SqdFile, SqInfo^.MsgHdr, SizeOf(SqMsgHdrType)) Then
968 SqInfo^.Error := MKFileError;
969 End;
970 End;
971
972
973 Procedure SqMsgObj.WriteText(FPos: LongInt); {Write text buffer for frame at Fpos}
974 Begin
975 Seek(SqInfo^.SqdFile, FPos + SqFSize + SqMSize);
976 SqInfo^.Error := IoResult;
977 If SqInfo^.Error = 0 Then
978 Begin
979 If Not shWrite(SqInfo^.SqdFile, SqInfo^.MsgChars, SqInfo^.TxtCtr) Then
980 SqInfo^.Error := MKFileError;
981 End;
982 End;
983
984
SqMsgObj.GetBeginFramenull985 Function SqMsgObj.GetBeginFrame: LongInt; {Get beginning frame pos}
986 Begin
987 GetBeginFrame := SqInfo^.SqBase.BeginFrame;
988 End;
989
990
SqMsgObj.GetNextFramenull991 Function SqMsgObj.GetNextFrame: LongInt; {Get next frame pos}
992 Begin
993 GetNextFrame := SqInfo^.Frame.NextFrame;
994 End;
995
996
997 Procedure SqMsgObj.ReadText(FPos: LongInt);
998 Begin
999 Seek(SqInfo^.SqdFile, FPos + SqFSize + SqMSize);
1000 SqInfo^.Error := IoResult;
1001 if SqInfo^.Error = 0 then begin
1002 If SqInfo^.Frame.MsgLength > SqTxtBufferSize Then
1003 BlockRead(SqInfo^.SqdFile, SqInfo^.MsgChars, SqTxtBufferSize)
1004 Else
1005 BlockRead(SqInfo^.SqdFile, SqInfo^.MsgChars,
1006 SqInfo^.Frame.MsgLength-SizeOf(SqMsgHdrType));
1007 SqInfo^.Error := IoResult;
1008 End;
1009 SqInfo^.TxtCtr := 1;{ + SqInfo^.Frame.ControlLength};
1010 EOM := False;
1011 Wrapped := False;
1012 End;
1013
1014
1015
1016 Procedure SqMsgObj.InitText;
1017 Begin
1018 SqInfo^.TxtCtr := 0;
1019 End;
1020
1021
1022 Procedure SqMsgObj.DoString(Str: String); {Add string to message text}
1023 Var
1024 i: Word;
1025
1026 Begin
1027 i := 1;
1028 While i <= Length(Str) Do
1029 Begin
1030 DoChar(Str[i]);
1031 Inc(i);
1032 End;
1033 End;
1034
1035
1036 Procedure SqMsgObj.DoChar(Ch: Char); {Add character to message text}
1037 Begin
1038 If SqInfo^.TxtCtr < SqTxtBufferSize Then
1039 Begin
1040 Inc(SqInfo^.TxtCtr);
1041 SqInfo^.MsgChars[SqInfo^.TxtCtr] := ch;
1042 End;
1043 End;
1044
1045
1046 Procedure SqMsgObj.DoStringLn(Str: String); {Add string and newline to msg text}
1047 Begin
1048 DoString(Str);
1049 DoChar(#13);
1050 End;
1051
1052
1053
1054 Procedure SqMsgObj.KillExcess;
1055 Var
1056 AlreadyLocked: Boolean;
1057
1058 Begin
1059 AlreadyLocked := SqInfo^.Locked;
1060 If Not AlreadyLocked Then
1061 If LockMsgBase Then;
1062 If SqIdx = Nil Then
1063 SqInfo^.error := 999
1064 Else
1065 Begin
1066 If ((SqInfo^.SqBase.MaxMsg > 0) and
1067 (SqInfo^.SqBase.MaxMsg > SqInfo^.SqBase.SkipMsg)) Then
1068 Begin
1069 While (SqInfo^.SqBase.NumMsg > SqInfo^.SqBase.MaxMsg) Do
1070 KillMsg(SqIdx^[SqInfo^.SqBase.SkipMsg + 1].UMsgId);
1071 End;
1072 End;
1073 If Not AlreadyLocked Then
1074 If UnlockMsgBase Then;
1075 End;
1076
1077
SqMsgObj.WriteMsgnull1078 Function SqMsgObj.WriteMsg: Word; {Write msg to msg base}
1079 Var
1080 MsgSize: LongInt;
1081 FrameSize: LongInt;
1082 FramePos: LongInt;
1083 TmpFrame: SqFrameHdrType;
1084 TmpDate: LongInt;
1085 {$IFDEF WINDOWS}
1086 TmpDT: TDateTime;
1087 {$ELSE}
1088 TmpDT: DateTime;
1089 {$ENDIF}
1090 TmpStr: String;
1091 AlreadyLocked: Boolean;
1092 s : String;
1093
1094 Begin
1095 DoChar(#0);
1096 TmpDT.Year := Str2Long(Copy(SqInfo^.StrDate,7,2));
1097 If TmpDT.Year > 79 Then
1098 Inc(TmpDT.Year, 1900)
1099 Else
1100 Inc(TmpDT.Year, 2000);
1101 TmpDT.Month := Str2Long(Copy(SqInfo^.StrDate,1,2));
1102 TmpDT.Day := Str2Long(Copy(SqInfo^.StrDate,4,2));
1103 TmpDt.Hour := Str2Long(Copy(SqInfo^.StrTime,1,2));
1104 TmpDt.Min := Str2Long(Copy(SqInfo^.StrTime, 4,2));
1105 TmpDt.Sec := 0;
1106 TmpStr := FormattedDate(TmpDT, 'DD NNN YY ') + Copy(SqInfo^.StrTime,1,5) + ':00';
1107 PackTime(TmpDT, TmpDate);
1108 SqInfo^.MsgHdr.DateWritten := (TmpDate shr 16) + ((TmpDate and $ffff) shl 16);
1109 TmpDate := GetDosDate;
1110 SqInfo^.MsgHdr.DateArrived := (TmpDate shr 16) + ((TmpDate and $ffff) shl 16);
1111 Str2AZ(TmpStr, 20, SqInfo^.MsgHdr.AZDate);
1112 AlreadyLocked := SqInfo^.Locked;
1113 If Not AlreadyLocked Then
1114 If LockMsgBase Then;
1115 If SqInfo^.Locked Then
1116 Begin
1117 MsgSize := SqInfo^.TxtCtr + SqMSize;
1118 FrameSize := MsgSize;
1119 FindFrame(FrameSize, FramePos);
1120 If SqInfo^.SqBase.LastFrame <> 0 Then
1121 Begin
1122 ReadVarFrame(TmpFrame, SqInfo^.SqBase.LastFrame);
1123 TmpFrame.NextFrame := FramePos;
1124 WriteVarFrame(TmpFrame, SqInfo^.SqBase.LastFrame);
1125 TmpFrame.PrevFrame := SqInfo^.SqBase.LastFrame;
1126 End
1127 Else
1128 Begin
1129 SqInfo^.SqBase.BeginFrame := FramePos;
1130 TmpFrame.PrevFrame := 0;
1131 End;
1132 TmpFrame.Id := SqHdrId;
1133 TmpFrame.FrameType := SqFrameMsg;
1134 SqInfo^.SqBase.LastFrame := FramePos;
1135 TmpFrame.NextFrame := 0;
1136 TmpFrame.FrameLength := FrameSize;
1137 TmpFrame.MsgLength := MsgSize;
1138 TmpFrame.ControlLength := 0;
1139 If TmpFrame.FrameLength = 0 Then
1140 Begin
1141 TmpFrame.FrameLength := TmpFrame.MsgLength + 0; {slack to minimize free frames}
1142 SqInfo^.SqBase.EndFrame := FramePos + SqFSize + TmpFrame.FrameLength;
1143 End;
1144 If SqInfo^.SqBase.NumMsg >= SqInfo^.SqiAlloc Then
1145 Begin
1146 WriteIdx;
1147 ReadIdx;
1148 End;
1149 If SqIdx = Nil Then
1150 Begin
1151 SqInfo^.Error := 999;
1152 WriteMsg := 999;
1153 End
1154 Else
1155 Begin
1156 WriteVarFrame(TmpFrame, FramePos);
1157 WriteMsgHdr(FramePos);
1158 WriteText(FramePos);
1159 Inc(SqInfo^.SqBase.NumMsg);
1160 SqIdx^[SqInfo^.SqBase.NumMsg].Ofs := FramePos;
1161 SqIdx^[SqInfo^.SqBase.NumMsg].UMsgId := SqInfo^.SqBase.UID;
1162 Move(SqInfo^.MsgHdr.MsgTo, s, SqToSize);
1163 { s := SqInfo^.MsgHdr.MsgTo;}
1164 SqIdx^[SqInfo^.SqBase.NumMsg].Hash := SqHashName(Az2Str(s, 35));
1165 Inc(SqInfo^.SqBase.UId);
1166 SqInfo^.SqBase.HighMsg := SqInfo^.SqBase.NumMsg;
1167 KillExcess;
1168 SqInfo^.CurrIdx := SqInfo^.SqBase.NumMsg;
1169 WriteMsg := 0;
1170 End;
1171 If Not AlreadyLocked Then
1172 If UnLockMsgBase Then;
1173 End
1174 Else
1175 WriteMsg := 5;
1176 End;
1177
1178
1179
SqMsgObj.GetStringnull1180 Function SqMsgObj.GetString: String;
1181 Var
1182 WPos: Word;
1183 WLen: Byte;
1184 StrDone: Boolean;
1185 TxtOver: Boolean;
1186 StartSoft: Boolean;
1187 CurrLen: Word;
1188 PPos: Word;
1189 TmpCh: Char;
1190 Kludge: Boolean;
1191
1192 Begin
1193 Kludge := false;
1194 StrDone := False;
1195 CurrLen := 0;
1196 PPos := SqInfo^.TxtCtr;
1197 WPos := 0;
1198 WLen := 0;
1199 StartSoft := Wrapped;
1200 Wrapped := True;
1201 TmpCh := GetChar;
1202 While ((Not StrDone) And (CurrLen < MaxLen) And (Not EOM)) Do
1203 Begin
1204 Case TmpCh of
1205 #$00: ;
1206 #$0d: Begin
1207 StrDone := True;
1208 Wrapped := False;
1209 End;
1210 #$8d:;
1211 #$0a:;
1212 #$01: begin
1213 if Kludge then begin
1214 dec(SqInfo^.TxtCtr);
1215 StrDone := True;
1216 Wrapped := False;
1217 end else begin
1218 kludge:=true;
1219 Inc(CurrLen);
1220 GetString[CurrLen] := #1;
1221 end;
1222 end;
1223 #$20: Begin
1224 If ((CurrLen <> 0) or (Not StartSoft)) Then
1225 Begin
1226 Inc(CurrLen);
1227 WLen := CurrLen;
1228 GetString[CurrLen] := TmpCh;
1229 WPos := SqInfo^.TxtCtr;
1230 End
1231 Else
1232 StartSoft := False;
1233 End;
1234 Else
1235 Begin
1236 Inc(CurrLen);
1237 GetString[CurrLen] := TmpCh;
1238 End;
1239 End;
1240 If Not StrDone Then
1241 TmpCh := GetChar;
1242 End;
1243 If StrDone Then
1244 Begin
1245 GetString[0] := Chr(CurrLen);
1246 End
1247 Else
1248 If EOM Then
1249 Begin
1250 GetString[0] := Chr(CurrLen);
1251 End
1252 Else
1253 Begin
1254 If WLen = 0 Then
1255 Begin
1256 GetString[0] := Chr(CurrLen);
1257 Dec(SqInfo^.TxtCtr);
1258 End
1259 Else
1260 Begin
1261 GetString[0] := Chr(WLen);
1262 SqInfo^.TxtCtr := WPos;
1263 End;
1264 End;
1265 end;
1266 {var
1267 LineEnd: Word;
1268 i: word;
1269 tmp: string;
1270 cr: word;
1271 Kludge: Boolean;
1272 begin
1273 tmp:='';
1274 LineEnd:=SqInfo^.TxtCtr+MaxLen;
1275 if LineEnd>SqInfo^.Frame.MsgLength then begin
1276 LineEnd:=SqInfo^.TxtCtr;
1277 EOM:=true;
1278 end;
1279 cr:=0;
1280 kludge:=false;
1281 for i:=SqInfo^.TxtCtr to LineEnd do begin
1282 if (SqInfo^.MsgChars[i]=#0) and (Kludge=false) then begin
1283 EOM:=true;
1284 cr:=i;
1285 break;
1286 end;
1287 if (SqInfo^.MsgChars[i]=#1) or ((SqInfo^.MsgChars[i]=#0) and Kludge) then begin
1288 if Kludge then begin
1289 cr:=i;
1290 if (SqInfo^.MsgChars[i]=#0) then inc(cr);
1291 break;
1292 end;
1293 Kludge:=true;
1294 end;
1295 if SqInfo^.MsgChars[i]=#13 then begin
1296 Kludge:=false;
1297 cr:=i;
1298 break;
1299 end;
1300 end;
1301
1302 if cr>0 then begin
1303 Tmp[0]:=char(Cr-SqInfo^.TxtCtr);
1304 Move(SqInfo^.MsgChars[SqInfo^.TxtCtr],Tmp[1],length(tmp));
1305 if not Kludge then inc(cr);
1306 SqInfo^.TxtCtr:=cr;
1307 Wrapped:=false;
1308 end else begin
1309 i:=LineEnd;
1310 while (i>SqInfo^.TxtCtr) do begin
1311 if SqInfo^.MsgChars[i]=#32 then break;
1312 dec(i);
1313 end;
1314 Tmp[0]:=char(i-SqInfo^.TxtCtr);
1315 Move(SqInfo^.MsgChars[SqInfo^.TxtCtr],Tmp[1],length(tmp));
1316 if i=SqInfo^.TxtCtr then i:=LineEnd;
1317 SqInfo^.TxtCtr:=LineEnd;
1318 Wrapped:=true;
1319 end;
1320 GetString:=tmp;
1321 end;}
1322
1323
SqMsgObj.GetCharnull1324 Function SqMsgObj.GetChar: Char;
1325 Begin
1326 If ((SqInfo^.TxtCtr >= SqInfo^.Frame.MsgLength) Or
1327 (SqInfo^.MsgChars[SqInfo^.TxtCtr] = #0) and (SqInfo^.TxtCtr >SqInfo^.Frame.ControlLength)) Then
1328 Begin
1329 GetChar := #0;
1330 EOM:=true;
1331 End
1332 Else
1333 Begin
1334 if SqInfo^.MsgChars[SqInfo^.TxtCtr]<>#0 then GetChar := SqInfo^.MsgChars[SqInfo^.TxtCtr] else GetChar:=#13;
1335 Inc(SqInfo^.TxtCtr);
1336 End;
1337 End;
1338
1339
SqMsgObj.GetHighWaternull1340 Function SqMsgObj.GetHighWater: LongInt; {Get high water umsgid}
1341 Begin
1342 GetHighWater := LongInt(SqInfo^.SqBase.HighWater);
1343 End;
1344
1345
SqMsgObj.GetHighMsgNumnull1346 Function SqMsgObj.GetHighMsgNum: LongInt; {Get highest msg number}
1347 Begin
1348 GetHighMsgNum := LongInt(SqInfo^.SqBase.Uid) - 1;
1349 End;
1350
1351
1352 procedure SqMsgObj.ReadIdx;
1353 var
1354 {$IFDEF VirtualPascal}
1355 NumRead: LongInt;
1356 {$ELSE}
1357 NumRead: Word;
1358 {$ENDIF}
1359
1360 begin
1361 IndexRead:=true;
1362 If SqInfo^.SqiAlloc > 0 Then
1363 If SqIdx <> Nil Then
1364 FreeMem(SqIdx, SqInfo^.SqiAlloc * SizeOf(SqIdxType));
1365 SqInfo^.SqiAlloc := FileSize(SqInfo^.SqiFile) + 100;
1366 If SqInfo^.SqiAlloc > SqIdxArraySize Then
1367 SqInfo^.SqiAlloc := SqIdxArraySize ;
1368 GetMem(SqIdx, SqInfo^.SqiAlloc * SizeOf(SqIdxType));
1369 If SqIdx = nil Then
1370 SqInfo^.Error := 999
1371 Else
1372 Begin
1373 Seek(SqInfo^.SqiFile, 0);
1374 If IoResult = 0 Then Begin
1375 If Not shRead(SqInfo^.SqiFile, SqIdx^, SqInfo^.SqiAlloc, NumRead) Then
1376 SqInfo^.Error := MKFileError;
1377 end else
1378 SqInfo^.Error := 300;
1379 If IoResult = 0 Then;
1380 { if FilePos(SqInfo^.SqiFile)<FileSize(SqInfo^.SqiFile) then
1381 MessageBox('Eine Squisharea darf maximal nur '+Long2Str(SqIdxArraySize)+
1382 ' Nachrichten enthalten. Wenn mehr enthalten sind, kann dies zu fehler fuehren.',nil,mfWarning+mfOkButton);}
1383 If IoResult = 0 Then;
1384 end;
1385 end;
1386
1387
1388 Procedure SqMsgObj.WriteIdx;
1389 Begin
1390 If SqIdx = nil Then
1391 SqInfo^.Error := 999
1392 Else
1393 Begin
1394 Seek(SqInfo^.SqiFile, 0);
1395 Truncate(SqInfo^.SqiFile);
1396 If IoResult = 0 Then
1397 Begin
1398 If Not shWrite(SqInfo^.SqiFile, SqIdx^, SqInfo^.SqBase.NumMsg) Then
1399 SqInfo^.Error := MKFileError;
1400 End
1401 Else
1402 SqInfo^.Error := 300;
1403 End;
1404 End;
1405
1406
1407 procedure SqMsgObj.SeekFirst(MsgNum: LongInt);
1408 begin
1409 SqInfo^.CurrIdx := 1;
1410 if IndexRead=false then ReadIdx;
1411 while ((SqInfo^.CurrIdx <= SqInfo^.SqBase.NumMsg) and
1412 (MsgNum > LongInt(SqIdx^[SqInfo^.CurrIdx].UMsgId))) Do begin
1413 SeekNext;
1414 if (SqInfo^.CurrIdx<=0) or (SqInfo^.CurrIdx>SqIdxArraySize) then break;
1415 end;
1416 end;
1417
1418
SqMsgObj.IdxHighestnull1419 Function SqMsgObj.IdxHighest: LongInt;
1420 Var
1421 i: Word;
1422 Tmp: LongInt;
1423
1424 Begin
1425 Tmp := 0;
1426 i := 1;
1427 While i <= SqInfo^.SqBase.NumMsg Do
1428 Begin
1429 If SqIdx^[i].UMsgId > Tmp Then
1430 Tmp := SqIdx^[i].UMsgId;
1431 Inc(i);
1432 End;
1433 IdxHighest := Tmp;
1434 End;
1435
1436
SqMsgObj.GetMsgNumnull1437 Function SqMsgObj.GetMsgNum: LongInt;
1438 Begin
1439 If ((SqInfo^.CurrIdx <= SqInfo^.SqBase.NumMsg) and
1440 (SqInfo^.CurrIdx > 0) and (SqInfo^.CurrIdx <= SqIdxArraySize)) Then
1441 GetMsgNum := LongInt(SqIdx^[SqInfo^.CurrIdx].UMsgId)
1442 Else
1443 GetMsgNum := -1;
1444 End;
1445
1446
1447 Procedure SqMsgObj.SeekNext;
1448 Begin
1449 Inc(SqInfo^.CurrIdx);
1450 End;
1451
1452
1453 Procedure SqMsgObj.SeekPrior;
1454 Begin
1455 If SqInfo^.CurrIdx > 1 Then
1456 Dec(SqInfo^.CurrIdx)
1457 Else
1458 SqInfo^.CurrIdx := 0;
1459 End;
1460
1461
SqMsgObj.SeekFoundnull1462 Function SqMsgObj.SeekFound: Boolean;
1463 Begin
1464 SeekFound := GetMsgNum >= 0;
1465 End;
1466
1467
SqMsgObj.GetIdxFramePosnull1468 Function SqMsgObj.GetIdxFramePos: LongInt;
1469 Begin
1470 If (SqInfo^.CurrIdx>0) and (SqInfo^.CurrIdx <= SqInfo^.SqBase.NumMsg) Then
1471 GetIdxFramePos := SqIdx^[SqInfo^.CurrIdx].Ofs
1472 Else
1473 GetIdxFramePos := -1;
1474 End;
1475
1476
SqMsgObj.GetIdxHashnull1477 Function SqMsgObj.GetIdxHash: LongInt;
1478 Begin
1479 If (SqInfo^.CurrIdx>0) and (SqInfo^.CurrIdx <= SqInfo^.SqBase.NumMsg) Then
1480 GetIdxHash := SqIdx^[SqInfo^.CurrIdx].Hash
1481 Else
1482 GetIdxHash := 0;
1483 End;
1484
1485
SqMsgObj.IsLocalnull1486 Function SqMsgObj.IsLocal: Boolean; {Is current msg local}
1487 Begin
1488 IsLocal := ((SqInfo^.MsgHdr.Attr and SqMsgLocal) <> 0);
1489 End;
1490
1491
SqMsgObj.IsCrashnull1492 Function SqMsgObj.IsCrash: Boolean; {Is current msg crash}
1493 Begin
1494 IsCrash := ((SqInfo^.MsgHdr.Attr and SqMsgCrash) <> 0);
1495 End;
1496
1497
SqMsgObj.IsKillSentnull1498 Function SqMsgObj.IsKillSent: Boolean; {Is current msg kill sent}
1499 Begin
1500 IsKillSent := ((SqInfo^.MsgHdr.Attr and SqMsgKill) <> 0);
1501 End;
1502
1503
SqMsgObj.IsSentnull1504 Function SqMsgObj.IsSent: Boolean; {Is current msg sent}
1505 Begin
1506 IsSent := ((SqInfo^.MsgHdr.Attr and SqMsgSent) <> 0);
1507 End;
1508
1509
SqMsgObj.IsFAttachnull1510 Function SqMsgObj.IsFAttach: Boolean; {Is current msg file attach}
1511 Begin
1512 IsFAttach := ((SqInfo^.MsgHdr.Attr and SqMsgFile) <> 0);
1513 End;
1514
1515
SqMsgObj.IsReqRctnull1516 Function SqMsgObj.IsReqRct: Boolean; {Is current msg request receipt}
1517 Begin
1518 IsReqRct := ((SqInfo^.MsgHdr.Attr and SqMsgRRQ) <> 0);
1519 End;
1520
1521
SqMsgObj.IsReqAudnull1522 Function SqMsgObj.IsReqAud: Boolean; {Is current msg request audit}
1523 Begin
1524 IsReqAud := ((SqInfo^.MsgHdr.Attr and SqMsgArq) <> 0);
1525 End;
1526
1527
SqMsgObj.IsRetRctnull1528 Function SqMsgObj.IsRetRct: Boolean; {Is current msg a return receipt}
1529 Begin
1530 IsRetRct := ((SqInfo^.MsgHdr.Attr and SqMsgCpt) <> 0);
1531 End;
1532
1533
SqMsgObj.IsFileReqnull1534 Function SqMsgObj.IsFileReq: Boolean; {Is current msg a file request}
1535 Begin
1536 IsFileReq := ((SqInfo^.MsgHdr.Attr and SqMsgFreq) <> 0);
1537 End;
1538
1539
SqMsgObj.IsRcvdnull1540 Function SqMsgObj.IsRcvd: Boolean; {Is current msg received}
1541 Begin
1542 IsRcvd := ((SqInfo^.MsgHdr.Attr and SqMsgRcvd) <> 0);
1543 End;
1544
1545
SqMsgObj.IsPrivnull1546 Function SqMsgObj.IsPriv: Boolean; {Is current msg priviledged/private}
1547 Begin
1548 IsPriv := ((SqInfo^.MsgHdr.Attr and SqMsgPriv) <> 0);
1549 End;
1550
1551
SqMsgObj.IsHoldnull1552 Function SqMsgObj.IsHold: Boolean; {Is current msg hold}
1553 Begin
1554 IsHold := ((SqInfo^.MsgHdr.Attr and SqMsgHold) <> 0);
1555 End;
1556
1557
SqMsgObj.IsEchoednull1558 Function SqMsgObj.IsEchoed: Boolean;
1559 Begin
1560 IsEchoed := ((SqInfo^.MsgHdr.Attr and SqMsgScanned) = 0);
1561 End;
1562
1563
SqMsgObj.IsDeletednull1564 Function SqMsgObj.IsDeleted: Boolean; {Is current msg deleted}
1565 Begin
1566 IsDeleted := False;
1567 End;
1568
1569
SqMsgObj.GetRefernull1570 Function SqMsgObj.GetRefer: LongInt; {Get reply to of current msg}
1571 Begin
1572 GetRefer := LongInt(SqInfo^.MsgHdr.ReplyTo);
1573 End;
1574
1575
1576 Procedure SqMsgObj.SetRefer(Num: LongInt); {Set reply to of current msg}
1577 Begin
1578 SqInfo^.MsgHdr.ReplyTo := LongInt(Num);
1579 End;
1580
1581
SqMsgObj.GetSeeAlsonull1582 Function SqMsgObj.GetSeeAlso: LongInt; {Get see also msg}
1583 Begin
1584 GetSeeAlso := LongInt(SqInfo^.MsgHdr.Replies[1]);
1585 End;
1586
1587
1588 Procedure SqMsgObj.SetSeeAlso(Num: LongInt); {Set see also msg}
1589 Begin
1590 SqInfo^.MsgHdr.Replies[1] := LongInt(Num);
1591 End;
1592
1593
1594 Procedure SqMsgObj.SetAttr(St: Boolean; Mask: LongInt); {Set attribute}
1595 Begin
1596 If St Then
1597 SqInfo^.MsgHdr.Attr := SqInfo^.MsgHdr.Attr or Mask
1598 Else
1599 SqInfo^.MsgHdr.Attr := SqInfo^.MsgHdr.Attr and (Not Mask);
1600 End;
1601
1602
1603 Procedure SqMsgObj.SetLocal(St: Boolean); {Set local status}
1604 Begin
1605 SetAttr(St, SqMsgLocal);
1606 End;
1607
1608
1609 Procedure SqMsgObj.SetRcvd(St: Boolean); {Set received status}
1610 Begin
1611 SetAttr(St, SqMsgRcvd);
1612 End;
1613
1614
1615 Procedure SqMsgObj.SetPriv(St: Boolean); {Set priveledge vs public status}
1616 Begin
1617 SetAttr(St, SqMsgPriv);
1618 End;
1619
1620
1621 Procedure SqMsgObj.SetEcho(ES: Boolean);
1622 Begin
1623 SetAttr(Not ES, SqMsgScanned);
1624 End;
1625
1626
1627 Procedure SqMsgObj.SetCrash(St: Boolean); {Set crash netmail status}
1628 Begin
1629 SetAttr(St, SqMsgCrash);
1630 End;
1631
1632
1633 Procedure SqMsgObj.SetKillSent(St: Boolean); {Set kill/sent netmail status}
1634 Begin
1635 SetAttr(St, SqMsgKill);
1636 End;
1637
1638
1639 Procedure SqMsgObj.SetSent(St: Boolean); {Set sent netmail status}
1640 Begin
1641 SetAttr(St, SqMsgSent);
1642 End;
1643
1644
1645 Procedure SqMsgObj.SetFAttach(St: Boolean); {Set file attach status}
1646 Begin
1647 SetAttr(St, SqMsgFile);
1648 End;
1649
1650
1651 Procedure SqMsgObj.SetReqRct(St: Boolean); {Set request receipt status}
1652 Begin
1653 SetAttr(St, SqMsgRrq);
1654 End;
1655
1656
1657 Procedure SqMsgObj.SetReqAud(St: Boolean); {Set request audit status}
1658 Begin
1659 SetAttr(St, SqMsgarq);
1660 End;
1661
1662
1663 Procedure SqMsgObj.SetRetRct(St: Boolean); {Set return receipt status}
1664 Begin
1665 SetAttr(St, SqMsgCpt);
1666 End;
1667
1668
1669 Procedure SqMsgObj.SetFileReq(St: Boolean); {Set file request status}
1670 Begin
1671 SetAttr(St, SqMsgFreq);
1672 End;
1673
1674 procedure SqMsgObj.SetHold(sh : Boolean);
1675 begin
1676 setAttr(sh, SqMsgHold);
1677 end;
1678
1679 procedure SqMsgObj.InitMsgHdr;
1680 begin
1681 SqInfo^.CurrentFramePos := GetIdxFramePos;
1682 SqInfo^.CurrentUID := SqIdx^[SqInfo^.CurrIdx].UMsgId;
1683 ReadMsgHdr(SqInfo^.CurrentFramePos);
1684 end;
1685
1686
1687 Procedure SqMsgObj.MsgTxtStartUp;
1688 Var
1689 CFrame: LongInt;
1690
1691 Begin
1692 ReadFrame(SqInfo^.CurrentFramePos);
1693 ReadText(SqInfo^.CurrentFramePos);
1694 End;
1695
1696
1697 Procedure SqMsgObj.SetMailType(MT: MsgMailType);
1698 Begin
1699 End;
1700
1701
SqMsgObj.GetSubAreanull1702 Function SqMsgObj.GetSubArea: Word;
1703 Begin
1704 GetSubArea := 0;
1705 End;
1706
1707
1708 Procedure SqMsgObj.ReWriteHdr;
1709 Var
1710 AlreadyLocked: Boolean;
1711 i: LongInt;
1712
1713
1714 Begin
1715 AlreadyLocked := SqInfo^.Locked;
1716 If Not AlreadyLocked Then
1717 If LockMsgBase Then;
1718 WriteFrame(SqInfo^.CurrentFramePos);
1719 WriteMsgHdr(SqInfo^.CurrentFramePos);
1720 i := 1;
1721 While ((i <= SqInfo^.SqBase.NumMsg) and (SqInfo^.CurrentFramePos <> SqIdx^[i].Ofs)) Do
1722 Inc(i);
1723 If SqIdx^[i].Ofs = SqInfo^.CurrentFramePos Then
1724 Begin
1725 If IsRcvd Then
1726 SqIdx^[i].Hash := 0
1727 Else
1728 SqIdx^[i].Hash := SqHashName(SqInfo^.MsgHdr.MsgTo);
1729 End;
1730 If Not AlreadyLocked Then
1731 If UnLockMsgBase Then;
1732 End;
1733
1734
1735 Procedure SqMsgObj.DeleteMsg;
1736 Begin
1737 KillMsg(SqInfo^.CurrentUID);
1738 End;
1739
1740
SqMsgObj.NumberOfMsgsnull1741 Function SqMsgObj.NumberOfMsgs: LongInt;
1742 Var
1743 TmpBase: Record
1744 Len : Word;
1745 Rsvd1 : Word;
1746 NumMsg : LongInt;
1747 end;
1748 f: file;
1749 begin
1750 if ioresult<>0 then;
1751 FileMode := fmReadOnly + fmDenyNone;
1752 assign(f,SqInfo^.FN+'.sqd');
1753 {$I-} reset(f,1);
1754 filemode:=fmReadWrite;
1755 blockread(f,TmpBase,Sizeof(TmpBase));
1756 close(f);
1757 if ioresult<>0 then NumberOfMsgs:=0 else NumberOfMsgs:=TmpBase.NumMsg;
1758 end;
1759
1760
SqMsgObj.GetLastReadnull1761 function SqMsgObj.GetLastRead: LongInt;
1762 var
1763 LRec : LongInt;
1764 f : file;
1765 begin
1766 if ioresult <> 0 then;
1767 FileMode := fmReadOnly or fmDenyNone;
1768 Assign(f, SqInfo^.FN + '.sql');
1769 {$I-} Reset(f, 1);
1770 { Seek(f, Cfg.SquishUNum * SizeOf(LRec));}
1771 Blockread(f, LRec, Sizeof(LRec));
1772 Close(f);
1773 if ioresult <> 0 then
1774 GetLastRead := 0
1775 else
1776 GetLastRead := LRec;
1777 end;
1778
1779 procedure SqMsgObj.SetLastRead(LR: LongInt);
1780 type
1781 TBuf = array[1..4000] of byte;
1782 var
1783 Num : Word;
1784 Buf : ^TBuf;
1785 f : file;
1786 begin
1787 New(Buf);
1788 fillchar(Buf^, sizeof(Buf^), 0);
1789 if ioresult <> 0 then;
1790 FileMode := fmReadWrite or fmDenyNone;
1791 Assign(f, SqInfo^.FN + '.sql');
1792 {$I-} Reset(f, 1);
1793 if ioresult <> 0 then {$I-} Rewrite(f, 1);
1794 if Sizeof(LR) > FileSize(f) then
1795 begin
1796 Seek(f, Filesize(f));
1797 while (Sizeof(LR) > FileSize(f)) and (ioresult = 0) do
1798 begin
1799 Num := (Sizeof(LR)) - FileSize(f);
1800 if Num > 4000 then Num := 4000;
1801 Blockwrite(f, Buf^, Num);
1802 end;
1803 end;
1804 { Seek(f, Cfg.SquishUNum * SizeOf(LR));}
1805 Blockwrite(f, LR, Sizeof(LR));
1806 Close(f);
1807 if ioresult <> 0 then;
1808 Dispose(Buf);
1809 end;
1810
SqMsgObj.GetMsgLocnull1811 Function SqMsgObj.GetMsgLoc: LongInt;
1812 Begin
1813 GetMsgLoc := GetMsgNum;
1814 End;
1815
1816
1817 Procedure SqMsgObj.SetMsgLoc(ML: LongInt);
1818 Begin
1819 SeekFirst(ML);
1820 End;
1821
1822
SqMsgObj.GetMsgDisplayNumnull1823 Function SqMsgObj.GetMsgDisplayNum: LongInt;
1824 Begin
1825 GetMsgDisplayNum := SqInfo^.CurrIdx;
1826 End;
1827
1828
SqMsgObj.GetTxtPosnull1829 Function SqMsgObj.GetTxtPos: LongInt;
1830 Begin
1831 GetTxtPos := SqInfo^.TxtCtr;
1832 End;
1833
1834
1835 Procedure SqMsgObj.SetTxtPos(TP: LongInt);
1836 Begin
1837 SqInfo^.TxtCtr := TP;
1838 End;
1839
1840
SqMsgObj.GetRealMsgNumnull1841 Function SqMsgObj.GetRealMsgNum: LongInt;
1842 begin
1843 GetRealMsgNum:=SqInfo^.CurrIdx;
1844 end;
1845
SqMsgObj.SetReadnull1846 function SqMsgObj.SetRead(RS: Boolean): boolean;
1847 begin
1848 if IsRead=false then begin
1849 SetAttr(RS, SqMsgRead);
1850 SetRead:=true;
1851 end else
1852 SetRead:=false;
1853 end;
1854
SqMsgObj.IsReadnull1855 function SqMsgObj.IsRead: Boolean;
1856 begin
1857 IsRead:=((SqInfo^.MsgHdr.Attr and SqMsgRead)<>0);
1858 end;
1859
1860 { Copyright 1997 by Sascha Lammers }
1861 procedure GetSquishInfo(fn: string; var cur, msgs: longint);
1862 var
1863 num: longint;
1864 sr: searchrec;
1865 f: file;
1866 begin
1867 FileMode := fmReadOnly or fmDenyNone;
1868 FindFirst(fn + '.sqi', AnyFile, sr);
1869 if doserror <> 0 then
1870 Msgs := 0
1871 else
1872 Msgs := sr.size div Sizeof(SqIdxType);
1873 {$IFDEF OS2}
1874 FindClose(sr);
1875 {$ENDIF}
1876 Assign(f, fn + '.sql');
1877 {$I-} reset(f, 1);
1878 blockread(f, num, Sizeof(Num));
1879 close(f);
1880 if ioresult <> 0 then
1881 Cur := 0
1882 else
1883 Cur := Num;
1884 end;
1885
1886 End.
1887
1888