home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / PASCAL / MKMSG104 / MKMSGEZY.PAS < prev    next >
Pascal/Delphi Source File  |  1994-01-09  |  29KB  |  1,103 lines

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