1 { $O+,F+,I-,S-,R-,V-}
2 Unit MKMsgEZY; {EZYCom Msg Unit}
3
4 {$IfDef FPC}
5 {$PackRecords 1}
6 {$EndIf}
7
8 Interface
9
10 Uses MKGlobT, MKMsgAbs, Dos, GeneralP;
11
12 Const
13 MaxEzMsgAreas = 1536;
14
15 EzyLastRead : String[12] = 'LASTCOMB.BBS';
16
17 Type EZMsgHdrType = Record
18 ReplyTo: Word; {Message is reply to this number}
19 SeeAlso: Word; {Message has replies}
20 TxtStart: LongInt; {Text start position}
21 TxtLen: LongInt; {Length of msg text incl nul term}
22 DestAddr: OldAddrType; {Destination address}
23 OrigAddr: OldAddrType; {Origination address}
24 Cost: Word; {Message cost}
25 MsgAttr: Byte; {Message attribute - see constants}
26 NetAttr: Byte; {Netmail attribute - see constants}
27 ExtraAttr: Byte; {Future use}
28 Date: LongInt; {Date message was written}
29 RcvdDate: LongInt; {Date msg received bye MsgTo}
30 MsgTo: String[35]; {Message is intended for}
31 MsgFrom: String[35]; {Message was written by}
32 Subj: String[72]; {Message subject}
33 End;
34
35
36 Const {MsgHdr.MsgAttr}
37 ezDeleted = 1; {Message is deleted}
38 ezUnmovedNet = 2; {Unexported Netmail message}
39 ezRsvAttr = 4;
40 ezPriv = 8; {Message is private}
41 ezRcvd = 16; {Message is received}
42 ezUnmovedEcho = 32; {Unexported Echomail message}
43 ezLocal = 64; {"Locally" entered message}
44 ezNoKill = 128;
45
46
47 Const {MsgHdr.NetAttr}
48 ezKillSent = 1; {Delete after exporting}
49 ezSent = 2; {Msg has been sent}
50 ezFAttach = 4; {Msg has file attached}
51 ezCrash = 8; {Msg is crash}
52 ezFileReq = 16; {Msg is a file request}
53 ezReqRcpt = 32; {Msg is return receipt request}
54 ezRetAudit = 64; {Msg is a audit request}
55 ezRetRcpt = 128; {Msg is a return receipt}
56
57
58 Const
59 EzMsgLen = 16000;
60
61 Type EZMsgType = Record
62 MsgHdrFile: File; { MsgH???.BBS }
63 MsgTxtFile: File; { MsgT???.BBS }
64 MsgTxtWFile: File;
65 MsgHdr: EzMsgHdrType;
66 TextCtr: LongInt;
67 MsgPath: String[128];
68 MsgAreaPath: String[128];
69 MsgArea: Word;
70 Error: Word;
71 MsgChars: Array[0..EZMsgLen] of Char;
72 CurrMsg: LongInt;
73 SeekOver: Boolean;
74 Name: String[35];
75 Handle: String[35];
76 MailType: MsgMailType;
77 Found: Boolean;
78 StrDate: String[8];
79 StrTime: String[5];
80 CRLast: Boolean;
81 End;
82
83
84 Type EzyMsgObj = Object (AbsMsgObj)
85 EZM: ^EZMsgType;
86 Constructor Init; {Initialize}
87 Destructor Done; Virtual; {Done}
88 Procedure SetMsgPath(St: String); Virtual; {Set netmail path}
SetReadnull89 Function SetRead(RS: Boolean): boolean; Virtual; {Set read status}
IsReadnull90 Function IsRead: Boolean; Virtual; {Is current msg received}
GetHighMsgNumnull91 Function GetHighMsgNum: LongInt; Virtual; {Get highest netmail msg number in area}
92 Procedure SetDest(Var Addr: AddrType); Virtual; {Set Zone/Net/Node/Point for Dest}
93 Procedure SetOrig(Var Addr: AddrType); Virtual; {Set Zone/Net/Node/Point for Orig}
94 Procedure SetFrom(Name: String); Virtual; {Set message from}
95 Procedure SetTo(Name: String); Virtual; {Set message to}
96 Procedure SetSubj(Str: String); Virtual; {Set message subject}
97 Procedure SetCost(SCost: Word); Virtual; {Set message cost}
98 Procedure SetRefer(SRefer: LongInt); Virtual; {Set message reference}
99 Procedure SetSeeAlso(SAlso: LongInt); Virtual; {Set message see also}
100 Procedure SetDate(SDate: String); Virtual; {Set message date}
101 Procedure SetTime(STime: String); Virtual; {Set message time}
102 Procedure SetLocal(LS: Boolean); Virtual; {Set local status}
103 Procedure SetRcvd(RS: Boolean); Virtual; {Set received status}
104 Procedure SetPriv(PS: Boolean); Virtual; {Set priveledge vs public status}
105 Procedure SetCrash(SS: Boolean); Virtual; {Set crash netmail status}
106 Procedure SetKillSent(SS: Boolean); Virtual; {Set kill/sent netmail status}
107 Procedure SetSent(SS: Boolean); Virtual; {Set sent netmail status}
108 Procedure SetFAttach(SS: Boolean); Virtual; {Set file attach status}
109 Procedure SetReqRct(SS: Boolean); Virtual; {Set request receipt status}
110 Procedure SetReqAud(SS: Boolean); Virtual; {Set request audit status}
111 Procedure SetRetRct(SS: Boolean); Virtual; {Set return receipt status}
112 Procedure SetFileReq(SS: Boolean); Virtual; {Set file request status}
113 Procedure SetEcho(ES: Boolean); Virtual; {Set echo status}
114 Procedure DoString(Str: String); Virtual; {Add string to message text}
115 Procedure DoChar(Ch: Char); Virtual; {Add character to message text}
116 Procedure DoStringLn(Str: String); Virtual; {Add string and newline to msg text}
WriteMsgnull117 Function WriteMsg: Word; Virtual;
GetCharnull118 Function GetChar: Char; Virtual;
119 Procedure InitMsgHdr; Virtual; {set up msg for reading}
120 Procedure SeekFirst(MsgNum: LongInt); Virtual; {Seek msg number}
121 Procedure SeekNext; Virtual; {Find next matching msg}
122 Procedure SeekPrior; Virtual; {Seek prior matching msg}
GetFromnull123 Function GetFrom: String; Virtual; {Get from name on current msg}
GetTonull124 Function GetTo: String; Virtual; {Get to name on current msg}
GetSubjnull125 Function GetSubj: String; Virtual; {Get subject on current msg}
GetCostnull126 Function GetCost: Word; Virtual; {Get cost of current msg}
GetDatenull127 Function GetDate: String; Virtual; {Get date of current msg}
GetTimenull128 Function GetTime: String; Virtual; {Get time of current msg}
GetRefernull129 Function GetRefer: LongInt; Virtual; {Get reply to of current msg}
GetSeeAlsonull130 Function GetSeeAlso: LongInt; Virtual; {Get see also of current msg}
GetMsgNumnull131 Function GetMsgNum: LongInt; Virtual; {Get message number}
132 Procedure GetOrig(Var Addr: AddrType); Virtual; {Get origin address}
133 Procedure GetDest(Var Addr: AddrType); Virtual; {Get destination address}
IsLocalnull134 Function IsLocal: Boolean; Virtual; {Is current msg local}
IsCrashnull135 Function IsCrash: Boolean; Virtual; {Is current msg crash}
IsKillSentnull136 Function IsKillSent: Boolean; Virtual; {Is current msg kill sent}
IsSentnull137 Function IsSent: Boolean; Virtual; {Is current msg sent}
IsFAttachnull138 Function IsFAttach: Boolean; Virtual; {Is current msg file attach}
IsReqRctnull139 Function IsReqRct: Boolean; Virtual; {Is current msg request receipt}
IsReqAudnull140 Function IsReqAud: Boolean; Virtual; {Is current msg request audit}
IsRetRctnull141 Function IsRetRct: Boolean; Virtual; {Is current msg a return receipt}
IsFileReqnull142 Function IsFileReq: Boolean; Virtual; {Is current msg a file request}
IsRcvdnull143 Function IsRcvd: Boolean; Virtual; {Is current msg received}
IsPrivnull144 Function IsPriv: Boolean; Virtual; {Is current msg priviledged/private}
IsDeletednull145 Function IsDeleted: Boolean; Virtual; {Is current msg deleted}
IsEchoednull146 Function IsEchoed: Boolean; Virtual; {Msg should be echoed}
GetMsgLocnull147 Function GetMsgLoc: LongInt; Virtual; {Msg location}
148 Procedure SetMsgLoc(ML: LongInt); Virtual; {Msg location}
149 Procedure StartNewMsg; Virtual;
OpenMsgBasenull150 Function OpenMsgBase: Word; Virtual;
CloseMsgBasenull151 Function CloseMsgBase: Word; Virtual;
CreateMsgBasenull152 Function CreateMsgBase(MaxMsg: Word; MaxDays: Word): Word; Virtual;
SeekFoundnull153 Function SeekFound: Boolean; Virtual;
154 Procedure SetMailType(MT: MsgMailType); Virtual; {Set message base type}
GetSubAreanull155 Function GetSubArea: Word; Virtual; {Get sub area number}
156 Procedure ReWriteHdr; Virtual; {Rewrite msg header after changes}
157 Procedure DeleteMsg; Virtual; {Delete current message}
NumberOfMsgsnull158 Function NumberOfMsgs: LongInt; Virtual; {Number of messages}
GetLastReadnull159 Function GetLastRead: LongInt; Virtual; {Get last read for user num}
160 Procedure SetLastRead(LR: LongInt); Virtual; {Set last read}
161 Procedure MsgTxtStartUp; Virtual; {Do message text start up tasks}
GetTxtPosnull162 Function GetTxtPos: LongInt; Virtual; {Get indicator of msg text position}
163 Procedure SetTxtPos(TP: LongInt); Virtual; {Set text position}
164 Procedure SetMsgAttr(Mask: Word; St: Boolean); {Set msgattr}
165 Procedure SetNetAttr(Mask: Word; St: Boolean); {Set netattr}
MsgBaseExistsnull166 Function MsgBaseExists: Boolean; Virtual;
GetIDnull167 function GetID: Byte; Virtual;
168 End;
169
170
171 Type EzyMsgPtr = ^EzyMsgObj;
172
173 Implementation
174
175
176 Uses MKFile, MKString, MKDos, Crc32 {, Global};
177
178
EzyMsgObj.GetIDnull179 function EzyMsgObj.GetID: Byte;
180 begin
181 GetID:=msgEzy;
182 end;
183
184 Constructor EzyMsgObj.Init;
185 Begin
186 New(Ezm);
187 If Ezm = Nil Then
188 Begin
189 Fail;
190 Exit;
191 End;
192 EZM^.MsgPath := '';
193 Ezm^.MsgAreaPath := '';
194 EZM^.MsgArea := 0;
195 EZM^.TextCtr := 0;
196 EZM^.SeekOver := False;
197 Ezm^.Error := 0;
198 End;
199
200
201 Destructor EzyMsgObj.Done;
202 Begin
203 Dispose(Ezm);
204 End;
205
206
207 Procedure EzyMsgObj.SetMsgPath(St: String);
208 Var
209 ANum: Word;
210 s: String;
211
212 Begin
213 s := Copy(St, 5, 110);
214 s := AddDirSep(s);
215 EZM^.MsgPath := s;
216 EZM^.MsgArea := Str2Long(Copy(St,1,4));
217 ANum := ((EZM^.MsgArea - 1) Div 100) + 1;
218 Ezm^.MsgAreaPath := Ezm^.Msgpath + 'AREA' + Long2Str(ANum) + DirSep;
219 End;
220
221
EzyMsgObj.GetHighMsgNumnull222 Function EzyMsgObj.GetHighMsgNum: LongInt;
223 Var
224 ANum: Word;
225
226 Begin
227 GetHighMsgNum := SizeFile(Ezm^.MsgAreaPath + 'MsgH' +
228 PadLeft(Long2Str(Ezm^.MsgArea),'0',3) + '.bbs') Div SizeOf(EzMsgHdrType);
229 End;
230
231
232 Procedure EzyMsgObj.SetDest(Var Addr: AddrType);
233 Begin
234 move(addr, EZM^.MsgHdr.DestAddr, sizeof(EZM^.MsgHdr.DestAddr));
235 End;
236
237
238 Procedure EzyMsgObj.SetOrig(Var Addr: AddrType);
239 Begin
240 move(Addr, EZM^.MsgHdr.OrigAddr, sizeof(EZM^.MsgHdr.OrigAddr));
241 End;
242
243
244 Procedure EzyMsgObj.SetFrom(Name: String);
245 Begin
246 EZM^.MsgHdr.MsgFrom := Name;
247 End;
248
249
250 Procedure EzyMsgObj.SetTo(Name: String);
251 Begin
252 Ezm^.MsgHdr.MsgTo := Name;
253 End;
254
255
256 Procedure EzyMsgObj.SetSubj(Str: String);
257 Begin
258 Ezm^.MsgHdr.Subj := Str;
259 End;
260
261
262 Procedure EzyMsgObj.SetCost(SCost: Word);
263 Begin
264 Ezm^.MsgHdr.Cost := SCost;
265 End;
266
267
268 Procedure EzyMsgObj.SetRefer(SRefer: LongInt);
269 Begin
270 Ezm^.MsgHdr.ReplyTo := SRefer and $ffff;
271 End;
272
273
274 Procedure EzyMsgObj.SetSeeAlso(SAlso: LongInt);
275 Begin
276 Ezm^.MsgHdr.SeeAlso := SAlso and $ffff;
277 End;
278
279
280 Procedure EzyMsgObj.SetDate(SDate: String);
281 Begin
282 Ezm^.StrDate := SDate;
283 End;
284
285
286 Procedure EzyMsgObj.SetTime(STime: String);
287 Begin
288 Ezm^.StrTime := STime;
289 End;
290
291
292 Procedure EzyMsgObj.SetMsgAttr(Mask: Word; St: Boolean); {Set msgattr}
293 Begin
294 If St Then
295 Ezm^.MsgHdr.MsgAttr := Ezm^.MsgHdr.MsgAttr or Mask
296 Else
297 Ezm^.MsgHdr.MsgAttr := Ezm^.MsgHdr.MsgAttr and (Not Mask);
298 End;
299
300
301 Procedure EzyMsgObj.SetNetAttr(Mask: Word; St: Boolean); {Set netattr}
302 Begin
303 If St Then
304 Ezm^.MsgHdr.NetAttr := Ezm^.MsgHdr.NetAttr or Mask
305 Else
306 Ezm^.MsgHdr.NetAttr := Ezm^.MsgHdr.NetAttr and (not Mask);
307 End;
308
309
310 Procedure EzyMsgObj.SetLocal(LS: Boolean);
311 Begin
312 SetMsgAttr(ezLocal, LS);
313 End;
314
315
316 Procedure EzyMsgObj.SetRcvd(RS: Boolean);
317 Begin
318 SetMsgAttr(ezRcvd, RS);
319 End;
320
321
322 Procedure EzyMsgObj.SetPriv(PS: Boolean);
323 Begin
324 SetMsgAttr(ezPriv, PS);
325 End;
326
327
328 Procedure EzyMsgObj.SetCrash(SS: Boolean);
329 Begin
330 SetNetAttr(ezCrash, SS);
331 End;
332
333
334 Procedure EzyMsgObj.SetKillSent(SS: Boolean);
335 Begin
336 SetNetAttr(ezKillSent, SS);
337 End;
338
339
340 Procedure EzyMsgObj.SetSent(SS: Boolean);
341 Begin
342 SetNetAttr(ezSent, SS);
343 End;
344
345
346 Procedure EzyMsgObj.SetFAttach(SS: Boolean);
347 Begin
348 SetNetAttr(ezFAttach, SS);
349 End;
350
351
352 Procedure EzyMsgObj.SetReqRct(SS: Boolean);
353 Begin
354 SetNetAttr(ezReqRcpt, SS);
355 End;
356
357
358 Procedure EzyMsgObj.SetReqAud(SS: Boolean);
359 Begin
360 End;
361
362
363 Procedure EzyMsgObj.SetRetRct(SS: Boolean);
364 Begin
365 SetNetAttr(ezRetRcpt, SS);
366 End;
367
368
369 Procedure EzyMsgObj.SetFileReq(SS: Boolean);
370 Begin
371 SetNetAttr(ezFileReq, SS);
372 End;
373
374
375 Procedure EzyMsgObj.DoString(Str: String);
376 Var
377 i: Word;
378
379 Begin
380 i := 1;
381 While i <= Length(Str) Do
382 Begin
383 DoChar(Str[i]);
384 Inc(i);
385 End;
386 End;
387
388
389 Procedure EzyMsgObj.DoChar(Ch: Char);
390 Begin
391 If EZM^.TextCtr < SizeOf(EZM^.MsgChars) Then
392 Begin
393 Case(Ch) of
394 #13: Ezm^.CRLast := True;
395 #10:;
396 Else
397 Ezm^.CRLast := False;
398 End;
399 EZM^.MsgChars[EZM^.TextCtr] := Ch;
400 Inc(EZM^.TextCtr);
401 End;
402 End;
403
404
405 Procedure EzyMsgObj.DoStringLn(Str: String);
406 Begin
407 DoString(Str);
408 DoChar(#13);
409 End;
410
411
EzyMsgObj.WriteMsgnull412 Function EzyMsgObj.WriteMsg: Word;
413
414 Type MsgFastAccessType = Record
415 CrcTo: LongInt;
416 Area: Word;
417 MsgNum: Word;
418 End;
419
420 Var
421 {$IFDEF WINDOWS}
422 TmpDT: TDateTime;
423 {$ELSE}
424 TmpDT: DateTime;
425 {$ENDIF}
426 MsgFast: MsgFastAccessType; {MsgPath\MsgFast.Bbs}
427 MsgFastFile: File;
428 MsgExport: Boolean;
429 MsgExportFile: File;
430 MsgCount: Word;
431 MsgCountFile: File;
432 i: Word;
433 {$IFDEF VirtualPascal}
434 NumRead: LongInt;
435 {$ELSE}
436 {$IfDef SPEED}
437 NumRead: LongWord;
438 {$Else}
439 NumRead: Word;
440 {$EndIf}
441 {$ENDIF}
442
443 Begin
444 If Not Ezm^.CRLast Then
445 DoChar(#13);
446 DoChar(#0);
447 TmpDT.Year := Str2Long(Copy(Ezm^.StrDate,7,2));
448 If TmpDT.Year > 79 Then
449 Inc(TmpDT.Year, 1900)
450 Else
451 Inc(TmpDT.Year, 2000);
452 TmpDT.Month := Str2Long(Copy(Ezm^.StrDate,1,2));
453 TmpDT.Day := Str2Long(Copy(Ezm^.StrDate,4,2));
454 TmpDt.Hour := Str2Long(Copy(Ezm^.StrTime,1,2));
455 TmpDt.Min := Str2Long(Copy(Ezm^.StrTime, 4,2));
456 TmpDt.Sec := 0;
457 PackTime(TmpDT, Ezm^.MsgHdr.Date);
458 Ezm^.MsgHdr.RcvdDate := Ezm^.MsgHdr.Date;
459 FileMode := fmReadWrite + fmDenyWrite;
460 If shReset(Ezm^.MsgTxtWFile, 1) Then
461 Begin
462 Ezm^.MsgHdr.TxtStart := FileSize(Ezm^.MsgTxtWFile);
463 Seek(Ezm^.MsgTxtWFile, Ezm^.MsgHdr.TxtStart);
464 Ezm^.Error := IoResult;
465 Ezm^.MsgHdr.TxtLen := Ezm^.TextCtr;
466 If Ezm^.Error = 0 Then
467 Begin
468 BlockWrite(Ezm^.MsgTxtWFile, Ezm^.MsgChars, Ezm^.TextCtr);
469 Ezm^.Error := IoResult;
470 End;
471 If Ezm^.Error = 0 Then
472 Begin
473 Seek(Ezm^.MsgHdrFile, FileSize(Ezm^.MsgHdrFile));
474 Ezm^.Error := IoResult;
475 End;
476 If Ezm^.Error = 0 Then
477 Begin
478 BlockWrite(Ezm^.MsgHdrFile, Ezm^.MsgHdr, 1);
479 Ezm^.Error := IoResult;
480 Ezm^.CurrMsg := FileSize(Ezm^.MsgHdrFile);
481 End;
482 If ((Ezm^.Error = 0) and (Not IsRcvd)) Then
483 Begin
484 MsgFast.CrcTo := $ffffffff;
485 For i := 1 to Length(Ezm^.MsgHdr.MsgTo) Do
486 MsgFast.CrcTo := UpDC32(Ord(UpCase(Ezm^.MsgHdr.MsgTo[i])), MsgFast.CrcTo);
487 MsgFast.Area := Ezm^.MsgArea;
488 MsgFast.MsgNum := Ezm^.CurrMsg;
489 Assign(MsgFastFile, Ezm^.MsgPath + 'MsgFast.Bbs');
490 FileMode := fmReadWrite + fmDenyNone;
491 If shReset(MsgFastFile, SizeOf(MsgFastAccessType)) Then
492 Begin
493 Seek(MsgFastFile, FileSize(MsgFastFile));
494 If IoResult <> 0 Then;
495 BlockWrite(MsgFastFile, MsgFast, 1);
496 If IoResult <> 0 Then;
497 Close(MsgFastFile);
498 If IoResult <> 0 Then;
499 End;
500 End;
501 If ((Ezm^.Error = 0) and (IsEchoed)) Then
502 Begin
503 Assign(MsgExportFile, Ezm^.MsgPath + 'MsgExprt.Bbs');
504 FileMode := fmReadWrite + fmDenyNone;
505 If shReset(MsgExportFile, SizeOf(MsgExport)) Then
506 Begin
507 MsgExport := True;
508 Seek(MsgExportFile, Ezm^.MsgArea - 1);
509 If IoResult <> 0 Then;
510 BlockWrite(MsgExportFile, MsgExport, 1);
511 If IoResult <> 0 Then;
512 Close(MsgExportFile);
513 If IoResult <> 0 Then;
514 End;
515 End;
516 If Ezm^.Error = 0 Then
517 Begin
518 Assign(MsgCountFile, Ezm^.MsgPath + 'MsgCount.Bbs');
519 MsgCount := 0;
520 If shReset(MsgCountFile, SizeOf(MsgCount)) Then
521 Begin
522 Seek(MsgCountFile, Ezm^.MsgArea - 1);
523 If IoResult <> 0 Then;
524 BlockRead(MsgCountFile, MsgCount, 1, NumRead);
525 If IoResult <> 0 Then;
526 Inc(MsgCount);
527 Seek(MsgCountFile, Ezm^.MsgArea - 1);
528 If IoResult <> 0 Then;
529 BlockWrite(MsgCountFile, MsgCount, 1);
530 If IoResult <> 0 Then;
531 End;
532 End;
533 If Ezm^.Error = 0 Then
534 Begin
535 Close(Ezm^.MsgTxtWFile);
536 Ezm^.Error := IoResult;
537 End;
538 End
539 Else
540 Ezm^.Error := 5;
541 WriteMsg := Ezm^.Error;
542 End;
543
544
EzyMsgObj.GetCharnull545 Function EzyMsgObj.GetChar: Char;
546 Begin
547 If ((EZM^.TextCtr >= EZM^.MsgHdr.TxtLen) Or (EZM^.MsgChars[EZM^.TextCtr] = #0)
548 Or(Ezm^.TextCtr >= EzMsgLen)) Then
549 Begin
550 GetChar := #0;
551 EOM := True;
552 End
553 Else
554 Begin
555 GetChar := EZM^.MsgChars[EZM^.TextCtr];
556 Inc(EZM^.TextCtr);
557 End;
558 End;
559
560
561 procedure EzyMsgObj.InitMsgHdr;
562 begin
563 If (Ezm^.CurrMsg > 0) and (Ezm^.CurrMsg <= FileSize(Ezm^.MsgHdrFile)) Then begin
564 Wrapped := False;
565 EOM := False;
566 Seek(Ezm^.MsgHdrFile, Ezm^.CurrMsg - 1);
567 Ezm^.Error := IoResult;
568 BlockRead(Ezm^.MsgHdrFile, Ezm^.MsgHdr, 1);
569 Ezm^.Error := IoResult;
570 end;
571 end;
572
573
574 Procedure EzyMsgObj.MsgTxtStartUp;
575 Var
576 {$IFDEF VirtualPascal}
577 NumRead: LongInt;
578 {$ELSE}
579 {$IfDef SPEED}
580 NumRead: LongWord;
581 {$Else}
582 NumRead: Word;
583 {$EndIf}
584 {$ENDIF}
585
586 Begin
587 If ((Ezm^.MsgHdr.TxtStart >= 0) and (Ezm^.MsgHdr.TxtStart <=
588 FileSize(Ezm^.MsgTxtFile))) Then
589 Begin
590 Ezm^.Error := 0;
591 EZM^.TextCtr := 0;
592 EOM := False;
593 FillChar(Ezm^.MsgChars, SizeOf(Ezm^.MsgChars), #0);
594 Seek(Ezm^.MsgTxtFile, Ezm^.Msghdr.TxtStart);
595 Ezm^.Error := IoResult;
596 If Ezm^.Error = 0 Then
597 Begin
598 If Ezm^.MsgHdr.TxtLen > EzMsgLen Then
599 BlockRead(Ezm^.MsgTxtFile, Ezm^.MsgChars, Ezm^.MsgHdr.TxtLen, NumRead)
600 Else
601 BlockRead(Ezm^.MsgTxtFile, Ezm^.MsgChars, EzMsgLen, NumRead);
602 Ezm^.Error := IoResult;
603 End;
604 Wrapped := False;
605 End
606 Else
607 Begin
608 Ezm^.Error := 400;
609 End;
610 End;
611
612
EzyMsgObj.GetFromnull613 Function EzyMsgObj.GetFrom: String; {Get from name on current msg}
614 Begin
615 GetFrom := Ezm^.MsgHdr.MsgFrom;
616 End;
617
618
EzyMsgObj.GetTonull619 Function EzyMsgObj.GetTo: String; {Get to name on current msg}
620 Begin
621 GetTo := Ezm^.MsgHdr.MsgTo;
622 End;
623
624
EzyMsgObj.GetSubjnull625 Function EzyMsgObj.GetSubj: String; {Get subject on current msg}
626 Begin
627 GetSubj := Ezm^.MsgHdr.Subj;
628 End;
629
630
EzyMsgObj.GetCostnull631 Function EzyMsgObj.GetCost: Word; {Get cost of current msg}
632 Begin
633 GetCost := Ezm^.MsgHdr.Cost;
634 End;
635
636
EzyMsgObj.GetDatenull637 Function EzyMsgObj.GetDate: String; {Get date of current msg}
638 Begin
639 GetDate := DateStr(Ezm^.MsgHdr.Date);
640 End;
641
642
EzyMsgObj.GetTimenull643 Function EzyMsgObj.GetTime: String; {Get time of current msg}
644 Begin
645 GetTime := Copy(TimeStr(Ezm^.MsgHdr.Date),1, 5);
646 End;
647
648
EzyMsgObj.GetRefernull649 Function EzyMsgObj.GetRefer: LongInt; {Get reply to of current msg}
650 Begin
651 GetRefer := Ezm^.MsgHdr.ReplyTo;
652 End;
653
654
EzyMsgObj.GetSeeAlsonull655 Function EzyMsgObj.GetSeeAlso: LongInt; {Get see also of current msg}
656 Begin
657 GetSeeAlso := Ezm^.MsgHdr.SeeAlso;
658 End;
659
660
EzyMsgObj.GetMsgNumnull661 Function EzyMsgObj.GetMsgNum: LongInt; {Get message number}
662 Begin
663 GetMsgNum := EZM^.CurrMsg;
664 End;
665
666
667 Procedure EzyMsgObj.GetOrig(Var Addr: AddrType); {Get origin address}
668 Begin
669 move(EZM^.MsgHdr.OrigAddr, addr, sizeof(EZM^.MsgHdr.OrigAddr));
670 addr.domain := '';
671 End;
672
673
674 Procedure EzyMsgObj.GetDest(Var Addr: AddrType); {Get destination address}
675 Begin
676 move(EZM^.MsgHdr.DestAddr, addr, sizeof(EZM^.MsgHdr.DestAddr));
677 addr.domain := '';
678 End;
679
680
EzyMsgObj.IsLocalnull681 Function EzyMsgObj.IsLocal: Boolean; {Is current msg local}
682 Begin
683 IsLocal := (Ezm^.MsgHdr.MsgAttr and ezLocal) <> 0;
684 End;
685
686
EzyMsgObj.IsCrashnull687 Function EzyMsgObj.IsCrash: Boolean; {Is current msg crash}
688 Begin
689 IsCrash := (Ezm^.MsgHdr.NetAttr and ezCrash) <> 0;
690 End;
691
692
EzyMsgObj.IsKillSentnull693 Function EzyMsgObj.IsKillSent: Boolean; {Is current msg kill sent}
694 Begin
695 IsKillSent := (Ezm^.MsgHdr.NetAttr and ezKillSent) <> 0;
696 End;
697
698
EzyMsgObj.IsSentnull699 Function EzyMsgObj.IsSent: Boolean; {Is current msg sent}
700 Begin
701 IsSent := (Ezm^.MsgHdr.NetAttr and ezSent) <> 0;
702 End;
703
704
EzyMsgObj.IsFAttachnull705 Function EzyMsgObj.IsFAttach: Boolean; {Is current msg file attach}
706 Begin
707 IsFAttach := (Ezm^.MsgHdr.NetAttr and ezFAttach) <> 0;
708 End;
709
710
EzyMsgObj.IsReqRctnull711 Function EzyMsgObj.IsReqRct: Boolean; {Is current msg request receipt}
712 Begin
713 IsReqRct := (Ezm^.MsgHdr.NetAttr and ezReqRcpt) <> 0;
714 End;
715
716
EzyMsgObj.IsReqAudnull717 Function EzyMsgObj.IsReqAud: Boolean; {Is current msg request audit}
718 Begin
719 IsReqAud := False;
720 End;
721
722
EzyMsgObj.IsRetRctnull723 Function EzyMsgObj.IsRetRct: Boolean; {Is current msg a return receipt}
724 Begin
725 IsRetRct := (Ezm^.MsgHdr.NetAttr and ezRetRcpt) <> 0;
726 End;
727
728
EzyMsgObj.IsFileReqnull729 Function EzyMsgObj.IsFileReq: Boolean; {Is current msg a file request}
730 Begin
731 IsFileReq := (Ezm^.MsgHdr.NetAttr and ezFileReq) <> 0;
732 End;
733
734
EzyMsgObj.IsRcvdnull735 Function EzyMsgObj.IsRcvd: Boolean; {Is current msg received}
736 Begin
737 IsRcvd := (Ezm^.MsgHdr.MsgAttr and ezRcvd) <> 0;
738 End;
739
740
EzyMsgObj.IsPrivnull741 Function EzyMsgObj.IsPriv: Boolean; {Is current msg priviledged/private}
742 Begin
743 IsPriv := (Ezm^.MsgHdr.MsgAttr and ezPriv) <> 0;
744 End;
745
746
EzyMsgObj.IsDeletednull747 Function EzyMsgObj.IsDeleted: Boolean; {Is current msg deleted}
748 Begin
749 IsDeleted := (Ezm^.MsgHdr.MsgAttr and ezDeleted) <> 0;
750 End;
751
752
EzyMsgObj.IsEchoednull753 Function EzyMsgObj.IsEchoed: Boolean; {Is current msg echoed}
754 Begin
755 Case EZM^.MailType of
756 mmtNormal: IsEchoed := False;
757 mmtNetMail: IsEchoed := (EZM^.MsgHdr.MsgAttr and ezUnMovedNet) <> 0;
758 mmtEchoMail: IsEchoed := (EZM^.MsgHdr.MsgAttr and ezUnMovedEcho) <> 0;
759 Else
760 IsEchoed := False;
761 End;
762 End;
763
764
765 Procedure EzyMsgObj.SetEcho(ES: Boolean);
766 Begin
767 Case Ezm^.MailType of
768 mmtNetMail:
769 Begin
770 If ES Then
771 Ezm^.MsgHdr.MsgAttr := Ezm^.MsgHdr.MsgAttr or ezUnMovedNet
772 Else
773 Ezm^.MsgHdr.MsgAttr := Ezm^.MsgHdr.MsgAttr and (Not ezUnMovedNet);
774 End;
775 mmtEchoMail:
776 Begin
777 If ES Then
778 Ezm^.MsgHdr.MsgAttr := Ezm^.MsgHdr.MsgAttr or ezUnMovedEcho
779 Else
780 Ezm^.MsgHdr.MsgAttr := Ezm^.MsgHdr.MsgAttr and (Not ezUnMovedEcho);
781 End;
782 End;
783 End;
784
785
786 Procedure EzyMsgObj.SeekFirst(MsgNum: LongInt); {Start msg seek}
787 Begin
788 EZM^.CurrMsg := MsgNum - 1;
789 SeekNext;
790 End;
791
792
793 Procedure EzyMsgObj.SeekNext; {Find next matching msg}
794 Begin
795 Ezm^.Found := True;
796 If Ezm^.CurrMsg < FileSize(Ezm^.MsgHdrFile) Then
797 Inc(Ezm^.CurrMsg)
798 Else
799 Ezm^.Found := False;
800 End;
801
802
803 Procedure EzyMsgObj.SeekPrior;
804 Begin
805 If Ezm^.CurrMsg > 0 Then
806 Begin
807 Dec(Ezm^.CurrMsg);
808 End;
809 If Ezm^.CurrMsg <= 0 Then
810 Ezm^.Found := False;
811 End;
812
813
EzyMsgObj.SeekFoundnull814 Function EzyMsgObj.SeekFound: Boolean;
815 Begin
816 SeekFound := EZM^.Found;
817 End;
818
819
EzyMsgObj.GetMsgLocnull820 Function EzyMsgObj.GetMsgLoc: LongInt; {Msg location}
821 Begin
822 GetMsgLoc := GetMsgNum;
823 End;
824
825
826 Procedure EzyMsgObj.SetMsgLoc(ML: LongInt); {Msg location}
827 Begin
828 EZM^.CurrMsg := ML;
829 End;
830
831
832 Procedure EzyMsgObj.StartNewMsg;
833 Begin
834 FillChar(EZM^.MsgChars, SizeOf(EZM^.MsgChars), #0);
835 FillChar(Ezm^.MsgHdr, SizeOf(Ezm^.MsgHdr), 0);
836 EZM^.TextCtr := 0;
837 End;
838
839
EzyMsgObj.OpenMsgBasenull840 Function EzyMsgObj.OpenMsgBase: Word;
841 Begin
842 Ezm^.Error := 0;
843 If Not FileExist(Ezm^.MsgAreaPath + 'MsgH' +
844 PadLeft(Long2Str(Ezm^.MsgArea),'0',3) + '.bbs') Then
845 If CreateMsgBase(0,0) = 0 Then;
846 Assign(Ezm^.MsgHdrFile, Ezm^.MsgAreaPath + 'MsgH' +
847 PadLeft(Long2Str(Ezm^.MsgArea),'0',3) + '.bbs');
848 Assign(Ezm^.MsgTxtFile, Ezm^.MsgAreaPath + 'MsgT' +
849 PadLeft(Long2Str(Ezm^.MsgArea),'0',3) + '.bbs');
850 Assign(Ezm^.MsgTxtWFile, Ezm^.MsgAreaPath + 'MsgT' +
851 PadLeft(Long2Str(Ezm^.MsgArea),'0',3) + '.bbs');
852 FileMode := fmReadWrite + fmDenyNone;
853 Reset(Ezm^.MsgHdrFile, SizeOf(Ezm^.MsgHdr));
854 Ezm^.Error := IoResult;
855 If Ezm^.Error = 0 Then
856 Begin
857 FileMode := fmReadOnly + fmDenyNone;
858 Reset(Ezm^.MsgTxtFile, 1);
859 Ezm^.Error := IoResult;
860 End;
861 If Ezm^.Error <> 0 Then
862 Begin
863 Close(Ezm^.MsgTxtFile);
864 If IoResult <> 0 Then;
865 Close(Ezm^.MsgHdrFile);
866 If IoResult <> 0 Then;
867 End;
868 OpenMsgBase := Ezm^.Error;
869 End;
870
871
EzyMsgObj.CloseMsgBasenull872 Function EzyMsgObj.CloseMsgBase: Word;
873 Begin
874 If IoResult <> 0 Then;
875 Close(Ezm^.MsgHdrFile);
876 If IoResult <> 0 Then;
877 Close(Ezm^.MsgTxtFile);
878 If IoResult <> 0 Then;
879 Close(Ezm^.MsgTxtWFile);
880 If IoResult <> 0 Then;
881 End;
882
883
EzyMsgObj.CreateMsgBasenull884 Function EzyMsgObj.CreateMsgBase(MaxMsg: Word; MaxDays: Word): Word;
885 Type MsgExportType = Array[1..MaxEzMsgAreas] of Boolean;
886 Type MsgCountType = Array[1..MaxEzMsgAreas] of Word;
887
888 Var
889 HdrFile: File;
890 TxtFile: File;
891 TempFile: File;
892 MsgExport: MsgExportType;
893 MsgCount: MsgCountType;
894
895 Begin
896 Assign(HdrFile, Ezm^.MsgAreaPath + 'MsgH' +
897 PadLeft(Long2Str(Ezm^.MsgArea),'0',3) + '.bbs');
898 Assign(TxtFile, Ezm^.MsgAreaPath + 'MsgT' +
899 PadLeft(Long2Str(Ezm^.MsgArea),'0',3) + '.bbs');
900 ReWrite(HdrFile);
901 Ezm^.Error := IoResult;
902 If Ezm^.Error = 0 Then
903 Begin
904 ReWrite(TxtFile);
905 Ezm^.Error := IoResult;
906 End;
907 Close(HdrFile);
908 If IoResult <> 0 Then;
909 Close(TxtFile);
910 If IoResult <> 0 Then;
911 If Not FileExist(Ezm^.MsgPath + 'MsgFast.Bbs') Then
912 Begin
913 Assign(TempFile, Ezm^.MsgPath + 'Msgfast.Bbs');
914 ReWrite(TempFile);
915 If IoResult <> 0 Then;
916 Close(TempFile);
917 If IoResult <> 0 Then;
918 End;
919 If Not FileExist(Ezm^.MsgPath + 'MsgExprt.Bbs') Then
920 Begin
921 FillChar(MsgExport, SizeOf(MsgExport), #0);
922 Assign(TempFile, Ezm^.Msgpath + 'MsgExprt.Bbs');
923 ReWrite(TempFile, SizeOf(MsgExport));
924 If IoResult <> 0 Then;
925 BlockWrite(TempFile, MsgExport, 1);
926 If IoResult <> 0 Then;
927 Close(TempFile);
928 If IoResult <> 0 Then;
929 End;
930 If Not FileExist(Ezm^.MsgPath + 'MsgCount.Bbs') Then
931 Begin
932 FillChar(MsgCount, SizeOf(MsgCount), #0);
933 Assign(TempFile, Ezm^.MsgPath + 'MsgCount.Bbs');
934 ReWrite(TempFile, SizeOf(MsgCount));
935 If IoResult <> 0 Then;
936 BlockWrite(TempFile, MsgCount, 1);
937 If IoResult <> 0 Then;
938 Close(TempFile);
939 If IoResult <> 0 Then;
940 End;
941 CreateMsgBase := Ezm^.Error;
942 End;
943
944
945 Procedure EzyMsgObj.SetMailType(MT: MsgMailType);
946 Begin
947 Ezm^.MailType := MT;
948 End;
949
950
EzyMsgObj.GetSubAreanull951 Function EzyMsgObj.GetSubArea: Word;
952 Begin
953 GetSubArea := Ezm^.MsgArea;
954 End;
955
956
957 Procedure EzyMsgObj.ReWriteHdr;
958 Begin
959 If ((Ezm^.CurrMsg > 0) and (Ezm^.CurrMsg <= FileSize(Ezm^.MsgHdrFile))) Then
960 Begin
961 Seek(Ezm^.MsgHdrFile, Ezm^.CurrMsg - 1);
962 Ezm^.Error := IoResult;
963 If Ezm^.Error = 0 Then
964 Begin
965 BlockWrite(Ezm^.MsgHdrFile, Ezm^.MsgHdr, 1);
966 Ezm^.Error := IoResult;
967 End;
968 End;
969 End;
970
971
972 Procedure EzyMsgObj.DeleteMsg;
973 Begin
974 SetMsgAttr(ezDeleted, True);
975 ReWriteHdr;
976 End;
977
978
EzyMsgObj.NumberOfMsgsnull979 Function EzyMsgObj.NumberOfMsgs: LongInt;
980 Begin
981 NumberOfMsgs := FileSize(Ezm^.MsgHdrFile);
982 End;
983
984
985
EzyMsgObj.GetLastReadnull986 function EzyMsgObj.GetLastRead: LongInt;
987 var
988 Count : LongInt;
989 LR : Word;
990 f : File;
991 begin
992 if ioresult <> 0 then;
993 FileMode := fmReadOnly + fmDenyNone;
994 Count := ((Ezm^.MsgArea - 1) Div 16) + 1; { number of combined info to skip }
995 Inc(Count, (Ezm^.MsgArea - 1)); { point to current area }
996 Assign(f, EZM^.MsgAreaPath + EzyLastRead);
997 Reset(f, 1);
998 Seek(f, (Count * 2));
999 BlockRead(f, LR, 2);
1000 Close(f);
1001 if ioresult <> 0 then
1002 GetLastRead := 0
1003 else
1004 GetLastRead := LR - 1;
1005 end;
1006
1007 procedure EzyMsgObj.SetLastRead(LR: LongInt);
1008 var
1009 Count : LongInt;
1010 Tmp : Word;
1011 f : file;
1012 begin
1013 FileMode := fmReadWrite + fmDenyNone;
1014 Count := ((Ezm^.MsgArea - 1) Div 16) + 1; { number of combined info to skip }
1015 Inc(Count, (Ezm^.MsgArea - 1)); { point to current area }
1016 Assign(f, EZM^.MsgAreaPath + EzyLastRead);
1017 Reset(f, 1);
1018 If IoResult <> 0 Then Rewrite(f, 1);
1019 Seek(f, (Count * 2));
1020 Tmp := LR + 1;
1021 Blockwrite(f, Tmp, 2);
1022 Close(f);
1023 if ioresult <> 0 then;
1024 end;
1025
1026
EzyMsgObj.GetTxtPosnull1027 Function EzyMsgObj.GetTxtPos: LongInt;
1028 Begin
1029 GetTxtPos := EZM^.TextCtr;
1030 End;
1031
1032
1033 Procedure EzyMsgObj.SetTxtPos(TP: LongInt);
1034 Begin
1035 EZM^.TextCtr := TP;
1036 End;
1037
1038
EzyMsgObj.MsgBaseExistsnull1039 Function EzyMsgObj.MsgBaseExists: Boolean;
1040 Begin
1041 MsgBaseExists := FileExist(Ezm^.MsgAreaPath + 'MsgH' +
1042 PadLeft(Long2Str(Ezm^.MsgArea),'0',3) + '.bbs');
1043 End;
1044
EzyMsgObj.SetReadnull1045 function EzyMsgObj.SetRead(RS: Boolean): boolean;
1046 begin
1047 if IsRead=false then begin
1048 if RS then
1049 Ezm^.MsgHdr.ExtraAttr:=Ezm^.MsgHdr.ExtraAttr or $80
1050 else
1051 Ezm^.MsgHdr.ExtraAttr:=Ezm^.MsgHdr.ExtraAttr and (not $80);
1052 SetRead:=true;
1053 end else
1054 SetRead:=false;
1055 end;
1056
EzyMsgObj.IsReadnull1057 function EzyMsgObj.IsRead: Boolean;
1058 begin
1059 IsRead:=(Ezm^.MsgHdr.ExtraAttr and $80<>0);
1060 end;
1061
1062 End.
1063