home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / MKMSG102.ZIP / MKMSGFID.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-08-15  |  33.8 KB  |  1,379 lines

  1. Unit MKMsgFid;       {Fido *.Msg Unit}
  2.  
  3. {$I MKB.Def}
  4.  
  5. Interface
  6.  
  7. Uses MKGlobT, MKMsgAbs,
  8. {$IFDEF WINDOWS}
  9.   Strings, WinDos;
  10. {$ELSE}
  11.   Dos;
  12. {$ENDIF}
  13.  
  14.  
  15. Type FMsgType = Record
  16.   MsgFile: File;
  17.   TextCtr: LongInt;
  18.   MsgName: String[13];
  19.   Error: Word;
  20.   NetMailPath: String[128];
  21.   MsgChars: Array[0..33000] of Char;
  22.   Dest: AddrType;
  23.   Orig: AddrType;
  24.   MsgStart: LongInt;
  25.   MsgEnd: LongInt;
  26.   MsgSize: Word;
  27.   DefaultZone: Word;
  28.   QDate: String[8];
  29.   QTime: String[5];
  30.   MsgDone: Boolean;
  31.   CurrMsg: LongInt;
  32.   SeekOver: Boolean;
  33.   {$IFDEF WINDOWS}
  34.   SR: TSearchRec;
  35.   {$ELSE}
  36.   SR: SearchRec;
  37.   {$ENDIF}
  38.   Name: String[35];
  39.   Handle: String[35];
  40.   End;
  41.  
  42.  
  43. Type FidoMsgObj = Object (AbsMsgObj)
  44.   FM: ^FMsgType;
  45.   Constructor Init;                      {Initialize FidoMsgOut}
  46.   Destructor Done; Virtual; {Done FidoMsgOut}
  47.   Procedure PutLong(L: LongInt; Position: Word); {Put long into msg}
  48.   Procedure PutWord(W: Word; Position: Word);  {Put word into msg}
  49.   Procedure PutByte(B: Byte; Position: Word);  {Put byte into msg}
  50.   Procedure PutNullStr(St: String; Position: Word);  {Put string & null into msg}
  51.   Procedure SetMsgPath(St: String); Virtual; {Set netmail path}
  52.   Function  GetHighMsgNum: LongInt; Virtual; {Get highest netmail msg number in area}
  53.   Procedure SetDest(Var Addr: AddrType); Virtual; {Set Zone/Net/Node/Point for Dest}
  54.   Procedure SetOrig(Var Addr: AddrType); Virtual; {Set Zone/Net/Node/Point for Orig}
  55.   Procedure SetFrom(Name: String); Virtual; {Set message from}
  56.   Procedure SetTo(Name: String); Virtual; {Set message to}
  57.   Procedure SetSubj(Str: String); Virtual; {Set message subject}
  58.   Procedure SetCost(SCost: Word); Virtual; {Set message cost}
  59.   Procedure SetRefer(SRefer: LongInt); Virtual; {Set message reference}
  60.   Procedure SetSeeAlso(SAlso: LongInt); Virtual; {Set message see also}
  61.   Procedure SetDate(SDate: String); Virtual; {Set message date}
  62.   Procedure SetTime(STime: String); Virtual; {Set message time}
  63.   Procedure SetLocal(LS: Boolean); Virtual; {Set local status}
  64.   Procedure SetRcvd(RS: Boolean); Virtual; {Set received status}
  65.   Procedure SetPriv(PS: Boolean); Virtual; {Set priveledge vs public status}
  66.   Procedure SetCrash(SS: Boolean); Virtual; {Set crash netmail status}
  67.   Procedure SetKillSent(SS: Boolean); Virtual; {Set kill/sent netmail status}
  68.   Procedure SetSent(SS: Boolean); Virtual; {Set sent netmail status}
  69.   Procedure SetFAttach(SS: Boolean); Virtual; {Set file attach status}
  70.   Procedure SetReqRct(SS: Boolean); Virtual; {Set request receipt status}
  71.   Procedure SetReqAud(SS: Boolean); Virtual; {Set request audit status}
  72.   Procedure SetRetRct(SS: Boolean); Virtual; {Set return receipt status}
  73.   Procedure SetFileReq(SS: Boolean); Virtual; {Set file request status}
  74.   Procedure DoString(Str: String); Virtual; {Add string to message text}
  75.   Procedure DoChar(Ch: Char); Virtual; {Add character to message text}
  76.   Procedure DoStringLn(Str: String); Virtual; {Add string and newline to msg text}
  77.   Function  WriteMsg: Word; Virtual;
  78.   Procedure SetDefaultZone(DZ: Word); Virtual; {Set default zone to use}
  79.   Procedure LineStart; Virtual; {Internal use to skip LF, ^A}
  80.   Function  GetChar: Char; Virtual;
  81.   Procedure CheckZone(ZoneStr: String); Virtual;
  82.   Procedure CheckPoint(PointStr: String); Virtual;
  83.   Procedure CheckLine(TStr: String); Virtual;
  84.   Function  CvtDate: Boolean; Virtual;
  85.   Function  BufferWord(i: Word):Word; Virtual;
  86.   Function  BufferByte(i: Word):Byte; Virtual;
  87.   Function  BufferNullString(i: Word; Max: Word): String; Virtual;
  88.   Procedure MsgStartUp; Virtual; {set up msg for reading}
  89.   Function  EOM: Boolean; Virtual; {No more msg text}
  90.   Function  GetString(MaxLen: Word): String; Virtual; {Get wordwrapped string}
  91.   Function  WasWrap: Boolean; Virtual; {Last line was soft wrapped no CR}
  92.   Procedure SeekFirst(MsgNum: LongInt); Virtual; {Seek msg number}
  93.   Procedure SeekNext; Virtual; {Find next matching msg}
  94.   Procedure SeekPrior; Virtual; {Seek prior matching msg}
  95.   Function  GetFrom: String; Virtual; {Get from name on current msg}
  96.   Function  GetTo: String; Virtual; {Get to name on current msg}
  97.   Function  GetSubj: String; Virtual; {Get subject on current msg}
  98.   Function  GetCost: Word; Virtual; {Get cost of current msg}
  99.   Function  GetDate: String; Virtual; {Get date of current msg}
  100.   Function  GetTime: String; Virtual; {Get time of current msg}
  101.   Function  GetRefer: LongInt; Virtual; {Get reply to of current msg}
  102.   Function  GetSeeAlso: LongInt; Virtual; {Get see also of current msg}
  103.   Function  GetMsgNum: LongInt; Virtual; {Get message number}
  104.   Procedure GetOrig(Var Addr: AddrType); Virtual; {Get origin address}
  105.   Procedure GetDest(Var Addr: AddrType); Virtual; {Get destination address}
  106.   Function  IsLocal: Boolean; Virtual; {Is current msg local}
  107.   Function  IsCrash: Boolean; Virtual; {Is current msg crash}
  108.   Function  IsKillSent: Boolean; Virtual; {Is current msg kill sent}
  109.   Function  IsSent: Boolean; Virtual; {Is current msg sent}
  110.   Function  IsFAttach: Boolean; Virtual; {Is current msg file attach}
  111.   Function  IsReqRct: Boolean; Virtual; {Is current msg request receipt}
  112.   Function  IsReqAud: Boolean; Virtual; {Is current msg request audit}
  113.   Function  IsRetRct: Boolean; Virtual; {Is current msg a return receipt}
  114.   Function  IsFileReq: Boolean; Virtual; {Is current msg a file request}
  115.   Function  IsRcvd: Boolean; Virtual; {Is current msg received}
  116.   Function  IsPriv: Boolean; Virtual; {Is current msg priviledged/private}
  117.   Function  IsDeleted: Boolean; Virtual; {Is current msg deleted}
  118.   Function  IsEchoed: Boolean; Virtual; {Msg should be echoed}
  119.   Function  GetMsgLoc: LongInt; Virtual; {Msg location}
  120.   Procedure SetMsgLoc(ML: LongInt); Virtual; {Msg location}
  121.   Procedure YoursFirst(Name: String; Handle: String); Virtual; {Seek your mail}
  122.   Procedure YoursNext; Virtual; {Seek next your mail}
  123.   Function  YoursFound: Boolean; Virtual; {Message found}
  124.   Procedure StartNewMsg; Virtual;
  125.   Function  OpenMsgBase: Word; Virtual;
  126.   Function  CloseMsgBase: Word; Virtual;
  127.   Function  CreateMsgBase(MaxMsg: Word; MaxDays: Word): Word; Virtual;
  128.   Function  SeekFound: Boolean; Virtual;
  129.   Procedure SetMailType(MT: MsgMailType); Virtual; {Set message base type}
  130.   Function  GetSubArea: Word; Virtual; {Get sub area number}
  131.   Procedure ReWriteHdr; Virtual; {Rewrite msg header after changes}
  132.   Procedure DeleteMsg; Virtual; {Delete current message}
  133.   Function  NumberOfMsgs: LongInt; Virtual; {Number of messages}
  134.   Function  GetLastRead(UNum: LongInt): LongInt; Virtual; {Get last read for user num}
  135.   Procedure SetLastRead(UNum: LongInt; LR: LongInt); Virtual; {Set last read}
  136.   Procedure MsgTxtStartUp; Virtual; {Do message text start up tasks}
  137.   Function  GetTxtPos: LongInt; Virtual; {Get indicator of msg text position}
  138.   Procedure SetTxtPos(TP: LongInt); Virtual; {Set text position}
  139.   End;
  140.  
  141.  
  142. Type FidoMsgPtr = ^FidoMsgObj;
  143.  
  144. Function MonthStr(MoNo: Byte): String; {Return 3 char month name for month num}
  145. Function MonthNum(St: String):Word;
  146.  
  147.  
  148. Implementation
  149.  
  150. Uses MKFile, MKString, MKDos;
  151.  
  152.  
  153. Constructor FidoMsgObj.Init;
  154.   Begin
  155.   New(FM);
  156.   If FM = Nil Then
  157.     Begin
  158.     Fail;
  159.     Exit;
  160.     End;
  161.   FM^.NetMailPath := '';
  162.   FillChar(FM^.MsgChars, SizeOf(FM^.MsgChars), #0);
  163.   FM^.TextCtr := 190;
  164.   FM^.Dest.Zone := 0;
  165.   FM^.Orig.Zone := 0;
  166.   FM^.SeekOver := False;
  167.   FM^.DefaultZone := 1;
  168.   End;
  169.  
  170.  
  171. Destructor FidoMsgObj.Done;
  172.   Begin
  173.   Dispose(FM);
  174.   End;
  175.  
  176.  
  177. Procedure FidoMsgObj.PutLong(L: LongInt; Position: Word);
  178.   Var
  179.     i: Integer;
  180.  
  181.   Begin
  182.   i := 3;
  183.   While i >= 0 Do
  184.     Begin
  185.     FM^.MsgChars[Position + i] := Char(L and $ff);
  186.     L := L shr 8;
  187.     Dec(i);
  188.     End;
  189.   End;
  190.  
  191.  
  192. Procedure FidoMsgObj.PutWord(W: Word; Position: Word);
  193.   Begin
  194.   FM^.MsgChars[Position] := Char(Lo(W));
  195.   FM^.MsgChars[Position + 1] := Char(Hi(W));
  196.   End;
  197.  
  198.  
  199. Procedure FidoMsgObj.PutByte(B: Byte; Position: Word);
  200.   Begin
  201.   FM^.MsgChars[Position] := Char(B);
  202.   End;
  203.  
  204.  
  205.  
  206. Procedure FidoMsgObj.PutNullStr(St: String; Position: Word);
  207.   Var
  208.     i: Word;
  209.  
  210.   Begin
  211.   i := 1;
  212.   While i <= Length(St) Do
  213.     Begin
  214.     FM^.MsgChars[Position + i - 1] := St[i];
  215.     Inc(i);
  216.     End;
  217.   FM^.MsgChars[Position + Length(St)] := #0;
  218.   End;
  219.  
  220.  
  221. Procedure FidoMsgObj.SetMsgPath(St: String);
  222.   Begin
  223.   FM^.NetMailPath := Copy(St, 1, 110);
  224.   AddBackSlash(FM^.NetMailPath);
  225.   End;
  226.  
  227.  
  228. Function FidoMsgObj.GetHighMsgNum: LongInt;
  229.   Var
  230.   {$IFDEF WINDOWS}
  231.     SR: TSearchRec;
  232.     TStr: Array[0..128] of Char;
  233.   {$ELSE}
  234.     SR: SearchRec;
  235.   {$ENDIF}
  236.   TmpName: String[13];
  237.   TmpNum: Word;
  238.   Code: Word;
  239.   Highest: LongInt;
  240.  
  241.   Begin
  242.   Highest := 1;
  243.   {$IFDEF WINDOWS}
  244.   StrPCopy(TStr, FM^.NetMailPath + '*.MSG');
  245.   FindFirst(TStr, faReadOnly + faArchive, SR);
  246.   {$ELSE}
  247.   FindFirst(FM^.NetMailPath + '*.MSG', ReadOnly + Archive, SR);
  248.   {$ENDIF}
  249.   While DosError = 0 Do
  250.     Begin
  251.     {$IFDEF WINDOWS}
  252.     TmpName :=  StrPas(SR.Name);
  253.     {$ELSE}
  254.     TmpName := SR.Name;
  255.     {$ENDIF}
  256.     Val(Copy(TmpName, 1,  Pos('.', TmpName) - 1), TmpNum, Code);
  257.     If ((Code = 0) And (TmpNum > Highest)) Then
  258.       Highest := TmpNum;
  259.     FindNext(SR);
  260.     End;
  261.   GetHighMsgNum := Highest;
  262.   End;
  263.  
  264.  
  265. Function MonthStr(MoNo: Byte): String;
  266.   Begin
  267.   Case MoNo of
  268.     01: MonthStr := 'Jan';
  269.     02: MonthStr := 'Feb';
  270.     03: MonthStr := 'Mar';
  271.     04: MonthStr := 'Apr';
  272.     05: MonthStr := 'May';
  273.     06: MonthStr := 'Jun';
  274.     07: MonthStr := 'Jul';
  275.     08: MonthStr := 'Aug';
  276.     09: MonthStr := 'Sep';
  277.     10: MonthStr := 'Oct';
  278.     11: MonthStr := 'Nov';
  279.     12: MonthStr := 'Dec';
  280.     Else
  281.       MonthStr := '???';
  282.     End;
  283.   End;
  284.  
  285.  
  286. Procedure FidoMsgObj.SetDest(Var Addr: AddrType);
  287.   Begin
  288.   FM^.Dest := Addr;
  289.   PutWord(Addr.Net, 174);
  290.   PutWord(Addr.Node, 166);
  291.   If Addr.Point <> 0 Then
  292.     Begin
  293.     If ((FM^.TextCtr <> 190) And
  294.     (FM^.MsgChars[FM^.TextCtr - 1] <> #13)) Then
  295.       DoChar(#13);
  296.     DoStringLn(#1 + 'TOPT ' + Long2Str(Addr.Point));
  297.     End;
  298.   If ((FM^.Orig.Zone <> 0)) Then
  299.     Begin
  300.     If ((FM^.TextCtr <> 190) And
  301.     (FM^.MsgChars[FM^.TextCtr - 1] <> #13)) Then
  302.       DoChar(#13);
  303.     DoStringLn(#1 + 'INTL ' + AddrStr(FM^.Dest) + ' ' + AddrStr(FM^.Orig));
  304.     End;
  305.   End;
  306.  
  307.  
  308. Procedure FidoMsgObj.SetOrig(Var Addr: AddrType);
  309.   Begin
  310.   FM^.Orig := Addr;
  311.   PutWord(Addr.Net, 172);
  312.   PutWord(Addr.Node, 168);
  313.   If Addr.Point <> 0 Then
  314.     Begin
  315.     If ((FM^.TextCtr <> 190) And
  316.     (FM^.MsgChars[FM^.TextCtr - 1] <> #13)) Then
  317.       DoChar(#13);
  318.     DoStringLn(#1 + 'FMPT ' + Long2Str(Addr.Point));
  319.     End;
  320.   If ((FM^.Dest.Zone <> 0)) Then
  321.     Begin
  322.     If ((FM^.TextCtr <> 190) And
  323.     (FM^.MsgChars[FM^.TextCtr - 1] <> #13)) Then
  324.       DoChar(#13);
  325.     DoStringLn(#1 + 'INTL ' + AddrStr(FM^.Dest) + ' ' + AddrStr(FM^.Orig));
  326.     End;
  327.   End;
  328.  
  329.  
  330. Procedure FidoMsgObj.SetFrom(Name: String);
  331.   Begin
  332.   PutNullStr(Copy(Name, 1, 35),0);
  333.   End;
  334.  
  335.  
  336. Procedure FidoMsgObj.SetTo(Name: String);
  337.   Begin
  338.   PutNullStr(Copy(Name, 1, 35), 36);
  339.   End;
  340.  
  341.  
  342. Procedure FidoMsgObj.SetSubj(Str: String);
  343.   Begin
  344.   PutNullStr(Copy(Str, 1, 71), 72);
  345.   End;
  346.  
  347.  
  348. Procedure FidoMsgObj.SetCost(SCost: Word);
  349.   Begin
  350.   PutWord(SCost, 170);
  351.   End;
  352.  
  353.  
  354. Procedure FidoMsgObj.SetRefer(SRefer: LongInt);
  355.   Begin
  356.   PutWord(SRefer, 184);
  357.   End;
  358.  
  359.  
  360. Procedure FidoMsgObj.SetSeeAlso(SAlso: LongInt);
  361.   Begin
  362.   PutWord(SAlso, 188);
  363.   End;
  364.  
  365.  
  366. Procedure FidoMsgObj.SetDate(SDate: String);
  367.   Var
  368.     TempNum: Word;
  369.     Code: Word;
  370.     TmpStr: String[20];
  371.  
  372.   Begin
  373.   FM^.QDate := Copy(SDate,1,8);
  374.   Val(Copy(SDate,1,2),TempNum, Code);
  375.   TmpStr := Copy(SDate,4,2) + ' ' + MonthStr(TempNum) + ' ' +
  376.     Copy(SDate,7,2) + '  ';
  377.   For TempNum := 1 to 11 Do
  378.     FM^.MsgChars[TempNum + 143] := TmpStr[TempNum];
  379.   End;
  380.  
  381.  
  382. Procedure FidoMsgObj.SetTime(STime: String);
  383.   Begin
  384.   FM^.QTime := Copy(STime,1,5);
  385.   PutNullStr(Copy(STime + ':00', 1, 8), 155);
  386.   End;
  387.  
  388.  
  389. Procedure FidoMsgObj.SetLocal(LS: Boolean);
  390.   Begin
  391.   If LS Then
  392.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) or 1)
  393.   Else
  394.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) and (Not 1));
  395.   End;
  396.  
  397.  
  398. Procedure FidoMsgObj.SetRcvd(RS: Boolean);
  399.   Begin
  400.   If RS Then
  401.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 4)
  402.   Else
  403.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 4));
  404.   End;
  405.  
  406.  
  407. Procedure FidoMsgObj.SetPriv(PS: Boolean);
  408.   Begin
  409.   If PS Then
  410.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 1)
  411.   Else
  412.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 1));
  413.   End;
  414.  
  415.  
  416. Procedure FidoMsgObj.SetCrash(SS: Boolean);
  417.   Begin
  418.   If SS Then
  419.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 2)
  420.   Else
  421.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 2));
  422.   End;
  423.  
  424.  
  425. Procedure FidoMsgObj.SetKillSent(SS: Boolean);
  426.   Begin
  427.   If SS Then
  428.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 128)
  429.   Else
  430.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 128));
  431.   End;
  432.  
  433.  
  434. Procedure FidoMsgObj.SetSent(SS: Boolean);
  435.   Begin
  436.   If SS Then
  437.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 8)
  438.   Else
  439.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 8));
  440.   End;
  441.  
  442.  
  443. Procedure FidoMsgObj.SetFAttach(SS: Boolean);
  444.   Begin
  445.   If SS Then
  446.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) or 16)
  447.   Else
  448.     FM^.MsgChars[186] := Char(Ord(FM^.MsgChars[186]) and (Not 16));
  449.   End;
  450.  
  451.  
  452. Procedure FidoMsgObj.SetReqRct(SS: Boolean);
  453.   Begin
  454.   If SS Then
  455.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) or 16)
  456.   Else
  457.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) and (Not 16));
  458.   End;
  459.  
  460.  
  461. Procedure FidoMsgObj.SetReqAud(SS: Boolean);
  462.   Begin
  463.   If SS Then
  464.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) or 64)
  465.   Else
  466.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) and (Not 64));
  467.   End;
  468.  
  469.  
  470. Procedure FidoMsgObj.SetRetRct(SS: Boolean);
  471.   Begin
  472.   If SS Then
  473.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) or 32)
  474.   Else
  475.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) and (Not 32));
  476.   End;
  477.  
  478.  
  479. Procedure FidoMsgObj.SetFileReq(SS: Boolean);
  480.   Begin
  481.   If SS Then
  482.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) or 8)
  483.   Else
  484.     FM^.MsgChars[187] := Char(Ord(FM^.MsgChars[187]) and (Not 8));
  485.   End;
  486.  
  487.  
  488. Procedure FidoMsgObj.DoString(Str: String);
  489.   Var
  490.     i: Word;
  491.  
  492.   Begin
  493.   i := 1;
  494.   While i <= Length(Str) Do
  495.     Begin
  496.     DoChar(Str[i]);
  497.     Inc(i);
  498.     End;
  499.   End;
  500.  
  501.  
  502. Procedure FidoMsgObj.DoChar(Ch: Char);
  503.   Begin
  504.   If FM^.TextCtr < SizeOf(FM^.MsgChars) Then
  505.     Begin
  506.     FM^.MsgChars[FM^.TextCtr] := Ch;
  507.     Inc(FM^.TextCtr);
  508.     End;
  509.   End;
  510.  
  511.  
  512. Procedure FidoMsgObj.DoStringLn(Str: String);
  513.   Begin
  514.   DoString(Str);
  515.   DoChar(#13);
  516.   End;
  517.  
  518.  
  519. Function  FidoMsgObj.WriteMsg: Word;
  520.   Var
  521.     NetNum: Word;
  522.     TmpDate: LongInt;
  523.     {$IFDEF WINDOWS}
  524.     TmpDT: TDateTime;
  525.     {$ELSE}
  526.     TmpDT: DateTime;
  527.     {$ENDIF}
  528.  
  529.  
  530.   Begin
  531.   NetNum := GetHighMsgNum + 1;
  532.   PutLong(GetDosDate, 180);
  533.   TmpDT.Year := Str2Long(Copy(FM^.QDate,7,2));
  534.   If TmpDT.Year > 79 Then
  535.     Inc(TmpDT.Year, 1900)
  536.   Else
  537.     Inc(TmpDT.Year, 2000);
  538.   TmpDT.Month := Str2Long(Copy(FM^.QDate,1,2));
  539.   TmpDT.Day := Str2Long(Copy(FM^.QDate,4,2));
  540.   TmpDt.Hour := Str2Long(Copy(FM^.QTime,1,2));
  541.   TmpDt.Min := Str2Long(Copy(FM^.QTime, 4,2));
  542.   TmpDt.Sec := 0;
  543.   PackTime(TmpDT, TmpDate);
  544.   PutLong(TmpDate, 176);
  545.   Assign(FM^.MsgFile, FM^.NetMailPath + Long2Str(NetNum) + '.Msg');
  546.   ReWrite(FM^.MsgFile,1);
  547.   BlockWrite(FM^.MsgFile, FM^.MsgChars, FM^.TextCtr + 1);
  548.   Close(FM^.MsgFile);
  549.   FM^.CurrMsg := NetNum;
  550.   WriteMsg := IoResult;
  551.   End;
  552.  
  553.  
  554. Procedure FidoMsgObj.SetDefaultZone(DZ: Word); {Set default zone to use}
  555.   Begin
  556.   FM^.DefaultZone := DZ;
  557.   End;
  558.  
  559.  
  560. Procedure FidoMsgObj.LineStart;
  561.   Begin
  562.   If FM^.MsgChars[FM^.TextCtr] = #10 Then
  563.     Inc(FM^.TextCtr);
  564.   If FM^.MsgChars[FM^.TextCtr] = #1 Then
  565.     Inc(FM^.TextCtr);
  566.   End;
  567.  
  568.  
  569. Function FidoMsgObj.GetChar: Char;
  570.   Begin
  571.   If ((FM^.TextCtr >= FM^.MsgSize) Or (FM^.MsgChars[FM^.TextCtr] = #0)) Then
  572.     Begin
  573.     GetChar := #0;
  574.     FM^.MsgDone := True;
  575.     End
  576.   Else
  577.     Begin
  578.     GetChar := FM^.MsgChars[FM^.TextCtr];
  579.     Inc(FM^.TextCtr);
  580.     End;
  581.   End;
  582.  
  583.  
  584. Procedure FidoMsgObj.CheckZone(ZoneStr: String);
  585.   Var
  586.     DestZoneStr: String;
  587.     Code: Word;
  588.  
  589.   Begin
  590.   If (Upper(Copy(ZoneStr,1,4)) = 'INTL') Then
  591.     Begin
  592.     DestZoneStr := ExtractWord(ZoneStr, 2);
  593.     DestZoneStr := StripBoth(DestZoneStr, ' ');
  594.     DestZoneStr := Copy(DestZoneStr, 1, Pos(':', DestZoneStr) - 1);
  595.     Val(DestZoneStr, FM^.Dest.Zone, Code);
  596.     DestZoneStr := ExtractWord(ZoneStr,3);
  597.     DestZoneStr := StripBoth(DestZoneStr, ' ');
  598.     DestZoneStr := Copy(DestZoneStr, 1, Pos(':', DestZoneStr) - 1);
  599.     Val(DestZoneStr, FM^.Orig.Zone, Code);
  600.     End;
  601.   End;
  602.  
  603.  
  604. Procedure FidoMsgObj.CheckPoint(PointStr: String);
  605.   Var
  606.     DestPointStr: String;
  607.     Code: Word;
  608.     Temp: Word;
  609.  
  610.   Begin
  611.   If (Upper(Copy(PointStr,1,4)) = 'TOPT') Then
  612.     Begin
  613.     DestPointStr := ExtractWord(PointStr, 2);
  614.     DestPointStr := StripBoth(DestPointStr, ' ');
  615.     Val(DestPointStr, Temp, Code);
  616.     If Code = 0 Then
  617.       FM^.Dest.Point := Temp;
  618.     End;
  619.   If (Upper(Copy(PointStr,1,4)) = 'FMPT') Then
  620.     Begin
  621.     DestPointStr := ExtractWord(PointStr, 2);
  622.     DestPointStr := StripBoth(DestPointStr, ' ');
  623.     Val(DestPointStr, Temp, Code);
  624.     If Code = 0 Then
  625.       FM^.Orig.Point := Temp;
  626.     End;
  627.   End;
  628.  
  629.  
  630. Function MonthNum(St: String):Word;
  631.   Begin
  632.   ST := Upper(St);
  633.   MonthNum := 0;
  634.   If St = 'JAN' Then MonthNum := 01;
  635.   If St = 'FEB' Then MonthNum := 02;
  636.   If St = 'MAR' Then MonthNum := 03;
  637.   If St = 'APR' Then MonthNum := 04;
  638.   If St = 'MAY' Then MonthNum := 05;
  639.   If St = 'JUN' Then MonthNum := 06;
  640.   If St = 'JUL' Then MonthNum := 07;
  641.   If St = 'AUG' Then MonthNum := 08;
  642.   If St = 'SEP' Then MonthNum := 09;
  643.   If St = 'OCT' Then MonthNum := 10;
  644.   If St = 'NOV' Then MonthNum := 11;
  645.   If St = 'DEC' Then MonthNum := 12;
  646.   End;
  647.  
  648.  
  649. Function FidoMsgObj.CvtDate: Boolean;
  650.   Var
  651.     MoNo: Word;
  652.     TmpStr: String;
  653.     i: Word;
  654.     MsgDt: String[25];
  655.  
  656.   Begin
  657.   MsgDt := BufferNullString(144, 20);
  658.   MsgDt := PadRight(MsgDt,' ', 20);
  659.   CvtDate := True;
  660.   If MsgDt[3] = ' ' Then
  661.     Begin {Fido or Opus}
  662.     If MsgDt[11] = ' ' Then
  663.       Begin {Fido DD MON YY  HH:MM:SSZ}
  664.       FM^.QTime := Copy (MsgDT,12,5);
  665.       TmpStr := Long2Str(MonthNum(Copy(MsgDt,4,3)));
  666.       If Length(TmpStr) = 1 Then
  667.         TmpStr := '0' + TmpStr;
  668.       FM^.QDate := TmpStr + '-' + Copy(MsgDT,1,2) + '-' + Copy (MsgDt,8,2);
  669.       End
  670.     Else
  671.       Begin {Opus DD MON YY HH:MM:SS}
  672.       FM^.QTime := Copy(MsgDT,11,5);
  673.       TmpStr := Long2Str(MonthNum(Copy(MsgDt,4,3)));
  674.       If Length(TmpStr) = 1 Then
  675.         TmpStr := '0' + TmpStr;
  676.       FM^.QDate := TmpStr + '-' + Copy(MsgDT,1,2) + '-' + Copy (MsgDt,8,2);
  677.       End;
  678.     End
  679.   Else
  680.     Begin
  681.     If MsgDT[4] = ' ' Then
  682.       Begin {SeaDog format DOW DD MON YY HH:MM}
  683.       FM^.QTime := Copy(MsgDT,15,5);
  684.       TmpStr := Long2Str(MonthNum(Copy(MsgDT,8,3)));
  685.       If Length(TmpStr) = 1 Then
  686.         TmpStr := '0' + TmpStr;
  687.       FM^.QDate := TmpStr + '-' + Copy(MsgDT,5,2) + '-' + Copy (MsgDt,12,2);
  688.       End
  689.     Else
  690.       Begin
  691.       If MsgDT[3] = '-' Then
  692.         Begin {Wierd format DD-MM-YYYY HH:MM:SS}
  693.         FM^.QTime := Copy(MsgDt,12,5);
  694.         FM^.QDate := Copy(MsgDt,4,3) + Copy (MsgDt,1,3) + Copy (MsgDt,9,2);
  695.         End
  696.       Else
  697.         Begin  {Bad Date}
  698.         CvtDate := False;
  699.         End;
  700.       End;
  701.     End;
  702.   For i := 1 to 5 Do
  703.     If FM^.QTime[i] = ' ' Then
  704.       FM^.QTime[i] := '0';
  705.   For i := 1 to 8 Do
  706.     If FM^.QDate[i] = ' ' Then
  707.       FM^.QDate[i] := '0';
  708.   If Length(FM^.QDate) <> 8 Then
  709.     CvtDate := False;
  710.   If Length(FM^.QTime) <> 5 Then
  711.     CvtDate := False;
  712.   End;
  713.  
  714.  
  715. Function FidoMsgObj.BufferWord(i: Word):Word;
  716.   Begin
  717.   BufferWord := BufferByte(i) + (BufferByte(i + 1) shl 8);
  718.   End;
  719.  
  720.  
  721. Function FidoMsgObj.BufferByte(i: Word):Byte;
  722.   Begin
  723.   BufferByte := Ord(FM^.MsgChars[i]);
  724.   End;
  725.  
  726.  
  727. Function FidoMsgObj.BufferNullString(i: Word; Max: Word): String;
  728.   Var
  729.     Ctr: Word;
  730.     CurrPos: Word;
  731.  
  732.   Begin
  733.   BufferNullString := '';
  734.   Ctr := i;
  735.   CurrPos := 0;
  736.   While ((CurrPos < Max) and (FM^.MsgChars[Ctr] <> #0)) Do
  737.     Begin
  738.     Inc(CurrPos);
  739.     BufferNullString[CurrPos] := FM^.MsgChars[Ctr];
  740.     Inc(Ctr);
  741.     End;
  742.   BufferNullString[0] := Chr(CurrPos);
  743.   End;
  744.  
  745.  
  746. Procedure FidoMsgObj.CheckLine(TStr: String);
  747.   Begin
  748.   If TStr[1] = #10 Then
  749.     TStr := Copy(TStr,2,255);
  750.   If TStr[1] = #01 Then
  751.     TStr := Copy(TStr,2,255);
  752.   CheckZone(TStr);
  753.   CheckPoint(TStr);
  754.   End;
  755.  
  756.  
  757. Procedure FidoMsgObj.MsgStartUp;
  758.   Var
  759.     TStr: String;
  760.  
  761.   Begin
  762.   LastSoft := False;
  763.   If FileExist (FM^.NetMailPath + Long2Str(FM^.CurrMsg) + '.MSG') Then
  764.     FM^.Error := 0
  765.   Else
  766.     FM^.Error := 200;
  767.   If FM^.Error = 0 Then
  768.     Begin
  769.     If Not shAssign(FM^.MsgFile, FM^.NetMailPath +
  770.       Long2Str(FM^.CurrMsg) + '.MSG')  Then
  771.       FM^.Error := FileError;
  772.     End;
  773.   If FM^.Error = 0 Then
  774.     Begin
  775.     FileMode := fmReadOnly + fmDenyNone;
  776.     If Not shReset(FM^.MsgFile, 1) Then
  777.       FM^.Error := FileError;
  778.     End;
  779.   FillChar(FM^.MsgChars, SizeOf(FM^.MsgChars), 0);
  780.   If FM^.Error = 0 Then
  781.     Begin
  782.     If Not shRead(FM^.MsgFile, FM^.MsgChars, SizeOf(FM^.MsgChars), FM^.MsgSize) Then
  783.       FM^.Error := FileError;
  784.     End;
  785.   Close(FM^.MsgFile);
  786.   If IoResult <> 0 Then;
  787.   FM^.MsgDone := False;
  788.   FM^.MsgEnd := 0;
  789.   FM^.MsgStart := 190;
  790.   FM^.Dest.Zone := FM^.DefaultZone;
  791.   FM^.Dest.Point := 0;
  792.   FM^.Orig.Zone := FM^.DefaultZone;
  793.   FM^.Orig.Point := 0;
  794.   FM^.Orig.Net := BufferWord(172);
  795.   FM^.Orig.Node := BufferWord(168);
  796.   FM^.Dest.Net := BufferWord(174);
  797.   FM^.Dest.Node := BufferWord(166);
  798.   FM^.TextCtr := FM^.MsgStart;
  799.   If FM^.Error = 0 Then
  800.     Begin
  801.     If Not CvtDate Then
  802.       Begin
  803.       FM^.QDate := '09-06-89';
  804.       FM^.QTime := '19:76';
  805.       End;
  806.     TStr := GetString(128);
  807.     CheckLine(TStr);
  808.     While ((FM^.MsgEnd = 0) and (FM^.TextCtr <= FM^.MsgSize)) Do
  809.       Begin
  810.       While ((FM^.MsgChars[FM^.TextCtr] <> #0) and (FM^.MsgChars[FM^.TextCtr] <> #13)) Do
  811.         Inc(FM^.TextCtr);
  812.       If FM^.MsgChars[FM^.TextCtr] = #0 Then
  813.         Begin
  814.         FM^.MsgEnd := FM^.TextCtr - 1;
  815.         End
  816.       Else
  817.         Begin
  818.         Inc(FM^.TextCtr);
  819.         TStr := GetString(128);
  820.         CheckLine(TStr);
  821.         End;
  822.       End;
  823.     If FM^.MsgEnd = 0 Then
  824.       FM^.MsgEnd := FM^.MsgSize;
  825.     FM^.MsgSize := FM^.MsgEnd;
  826.     FM^.MsgStart := 190;
  827.     FM^.TextCtr := FM^.MsgStart;
  828.     FM^.MsgDone := False;
  829.     LastSoft := False;
  830.     End;
  831.   End;
  832.  
  833.  
  834. Procedure FidoMsgObj.MsgTxtStartUp;
  835.   Begin
  836.   FM^.MsgStart := 190;
  837.   FM^.TextCtr := FM^.MsgStart;
  838.   FM^.MsgDone := False;
  839.   LastSoft := False;
  840.   End;
  841.  
  842.  
  843. Function FidoMsgObj.GetString(MaxLen: Word): String;
  844.   Var
  845.     WPos: Word;
  846.     WLen: Byte;
  847.     StrDone: Boolean;
  848.     TxtOver: Boolean;
  849.     StartSoft: Boolean;
  850.     CurrLen: Word;
  851.     PPos: Word;
  852.     TmpCh: Char;
  853.  
  854.   Begin
  855.   StrDone := False;
  856.   CurrLen := 0;
  857.   PPos := FM^.TextCtr;
  858.   WPos := 0;
  859.   WLen := 0;
  860.   StartSoft := LastSoft;
  861.   LastSoft := True;
  862.   TmpCh := GetChar;
  863.   While ((Not StrDone) And (CurrLen < MaxLen) And (Not FM^.MsgDone)) Do
  864.     Begin
  865.     Case TmpCh of
  866.       #$00:;
  867.       #$0d: Begin
  868.             StrDone := True;
  869.             LastSoft := False;
  870.             End;
  871.       #$8d:;
  872.       #$0a:;
  873.       #$20: Begin
  874.             If ((CurrLen <> 0) or (Not StartSoft)) Then
  875.               Begin
  876.               Inc(CurrLen);
  877.               WLen := CurrLen;
  878.               GetString[CurrLen] := TmpCh;
  879.               WPos := FM^.TextCtr;
  880.               End
  881.             Else
  882.               StartSoft := False;
  883.             End;
  884.       Else
  885.         Begin
  886.         Inc(CurrLen);
  887.         GetString[CurrLen] := TmpCh;
  888.         End;
  889.       End;
  890.     If Not StrDone Then
  891.       TmpCh := GetChar;
  892.     End;
  893.   If StrDone Then
  894.     Begin
  895.     GetString[0] := Chr(CurrLen);
  896.     End
  897.   Else
  898.     If FM^.MsgDone Then
  899.       Begin
  900.       GetString[0] := Chr(CurrLen);
  901.       End
  902.     Else
  903.       Begin
  904.       If WLen = 0 Then
  905.         Begin
  906.         GetString[0] := Chr(CurrLen);
  907.         Dec(FM^.TextCtr);
  908.         End
  909.       Else
  910.         Begin
  911.         GetString[0] := Chr(WLen);
  912.         FM^.TextCtr := WPos;
  913.         End;
  914.       End;
  915.   End;
  916.  
  917.  
  918. Function FidoMsgObj.EOM: Boolean;
  919.   Begin
  920.   EOM := FM^.MsgDone;
  921.   End;
  922.  
  923.  
  924. Function FidoMsgObj.WasWrap: Boolean;
  925.   Begin
  926.   WasWrap := LastSoft;
  927.   End;
  928.  
  929.  
  930. Function FidoMsgObj.GetFrom: String; {Get from name on current msg}
  931.   Begin
  932.   GetFrom := BufferNullString(0, 35);
  933.   End;
  934.  
  935.  
  936. Function FidoMsgObj.GetTo: String; {Get to name on current msg}
  937.   Begin
  938.   GetTo := BufferNullString(36,35);
  939.   End;
  940.  
  941.  
  942. Function FidoMsgObj.GetSubj: String; {Get subject on current msg}
  943.   Begin
  944.   GetSubj := BufferNullString(72,71);
  945.   End;
  946.  
  947.  
  948. Function FidoMsgObj.GetCost: Word; {Get cost of current msg}
  949.   Begin
  950.   GetCost := BufferWord(170);
  951.   End;
  952.  
  953.  
  954. Function FidoMsgObj.GetDate: String; {Get date of current msg}
  955.   Begin
  956.   GetDate := FM^.QDate;
  957.   End;
  958.  
  959.  
  960. Function FidoMsgObj.GetTime: String; {Get time of current msg}
  961.   Begin
  962.   GetTime := FM^.QTime;
  963.   End;
  964.  
  965.  
  966. Function FidoMsgObj.GetRefer: LongInt; {Get reply to of current msg}
  967.   Begin
  968.   GetRefer := BufferWord(184);
  969.   End;
  970.  
  971.  
  972. Function FidoMsgObj.GetSeeAlso: LongInt; {Get see also of current msg}
  973.   Begin
  974.   GetSeeAlso := BufferWord(188);
  975.   End;
  976.  
  977.  
  978. Function FidoMsgObj.GetMsgNum: LongInt; {Get message number}
  979.   Begin
  980.   GetMsgNum := FM^.CurrMsg;
  981.   End;
  982.  
  983.  
  984. Procedure FidoMsgObj.GetOrig(Var Addr: AddrType); {Get origin address}
  985.   Begin
  986.   Addr := FM^.Orig;
  987.   End;
  988.  
  989.  
  990. Procedure FidoMsgObj.GetDest(Var Addr: AddrType); {Get destination address}
  991.   Begin
  992.   Addr := FM^.Dest;
  993.   End;
  994.  
  995.  
  996. Function FidoMsgObj.IsLocal: Boolean; {Is current msg local}
  997.   Begin
  998.   IsLocal := ((Ord(FM^.MsgChars[187]) and 001) <> 0);
  999.   End;
  1000.  
  1001.  
  1002. Function FidoMsgObj.IsCrash: Boolean; {Is current msg crash}
  1003.   Begin
  1004.   IsCrash := ((Ord(FM^.MsgChars[186]) and 002) <> 0);
  1005.   End;
  1006.  
  1007.  
  1008. Function FidoMsgObj.IsKillSent: Boolean; {Is current msg kill sent}
  1009.   Begin
  1010.   IsKillSent := ((Ord(FM^.MsgChars[186]) and 128) <> 0);
  1011.   End;
  1012.  
  1013.  
  1014. Function FidoMsgObj.IsSent: Boolean; {Is current msg sent}
  1015.   Begin
  1016.   IsSent := ((Ord(FM^.MsgChars[186]) and 008) <> 0);
  1017.   End;
  1018.  
  1019.  
  1020. Function FidoMsgObj.IsFAttach: Boolean; {Is current msg file attach}
  1021.   Begin
  1022.   IsFAttach := ((Ord(FM^.MsgChars[186]) and 016) <> 0);
  1023.   End;
  1024.  
  1025.  
  1026. Function FidoMsgObj.IsReqRct: Boolean; {Is current msg request receipt}
  1027.   Begin
  1028.   IsReqRct := ((Ord(FM^.MsgChars[187]) and 016) <> 0);
  1029.   End;
  1030.  
  1031.  
  1032. Function FidoMsgObj.IsReqAud: Boolean; {Is current msg request audit}
  1033.   Begin
  1034.   IsReqAud := ((Ord(FM^.MsgChars[187]) and 064) <> 0);
  1035.   End;
  1036.  
  1037.  
  1038. Function FidoMsgObj.IsRetRct: Boolean; {Is current msg a return receipt}
  1039.   Begin
  1040.   IsRetRct := ((Ord(FM^.MsgChars[187]) and 032) <> 0);
  1041.   End;
  1042.  
  1043.  
  1044. Function FidoMsgObj.IsFileReq: Boolean; {Is current msg a file request}
  1045.   Begin
  1046.   IsFileReq := ((Ord(FM^.MsgChars[187]) and 008) <> 0);
  1047.   End;
  1048.  
  1049.  
  1050. Function FidoMsgObj.IsRcvd: Boolean; {Is current msg received}
  1051.   Begin
  1052.   IsRcvd := ((Ord(FM^.MsgChars[186]) and 004) <> 0);
  1053.   End;
  1054.  
  1055.  
  1056. Function FidoMsgObj.IsPriv: Boolean; {Is current msg priviledged/private}
  1057.   Begin
  1058.   IsPriv := ((Ord(FM^.MsgChars[186]) and 001) <> 0);
  1059.   End;
  1060.  
  1061.  
  1062. Function FidoMsgObj.IsDeleted: Boolean; {Is current msg deleted}
  1063.   Begin
  1064.   IsDeleted := Not FileExist (FM^.NetMailPath + Long2Str(FM^.CurrMsg) + '.MSG');
  1065.   End;
  1066.  
  1067.  
  1068. Function FidoMsgObj.IsEchoed: Boolean; {Is current msg echoed}
  1069.   Begin
  1070.   IsEchoed := True;
  1071.   End;
  1072.  
  1073.  
  1074. Procedure FidoMsgObj.SeekFirst(MsgNum: LongInt); {Start msg seek}
  1075.   Begin
  1076.   FM^.CurrMsg := MsgNum - 1;
  1077.   SeekNext;
  1078.   End;
  1079.  
  1080.  
  1081. Procedure FidoMsgObj.SeekNext; {Find next matching msg}
  1082.   Var
  1083.     Code: Word;
  1084.     BestMatch: LongInt;
  1085.     CurrTry : LongInt;
  1086.     {$IFDEF WINDOWS}
  1087.       TStr: Array[0..128] of Char;
  1088.     {$ENDIF}
  1089.     MsgWasFound: Boolean;
  1090.  
  1091.   Begin
  1092.   CurrTry := 0;
  1093.   MsgWasFound := False;
  1094.   BestMatch := $7fffffff;
  1095.   Inc(FM^.CurrMsg);
  1096.   {$IFDEF WINDOWS}
  1097.   StrPCopy(TStr, FM^.NetMailPath + '*.MSG');
  1098.   FindFirst(TStr, faReadOnly + faArchive, FM^.SR);
  1099.   {$ELSE}
  1100.   FindFirst(FM^.NetMailPath + '*.MSG', ReadOnly + Archive, FM^.SR);
  1101.   {$ENDIF}
  1102.   While DosError = 0 Do
  1103.     Begin
  1104.     {$IFDEF WINDOWS}
  1105.       FM^.MsgName := StrPas(FM^.SR.Name);
  1106.     {$ELSE}
  1107.       FM^.MsgName := FM^.SR.Name;
  1108.     {$ENDIF}
  1109.     Val(Copy(FM^.MsgName, 1, Pos('.', FM^.MsgName) - 1), CurrTry, Code);
  1110.     If Code = 0 Then
  1111.       Begin
  1112.       If ((CurrTry >= FM^.CurrMsg) and (CurrTry < BestMatch)) Then
  1113.         Begin
  1114.         BestMatch := CurrTry;
  1115.         MsgWasFound := True;
  1116.         End;
  1117.       End;
  1118.     FindNext(FM^.SR);
  1119.     End;
  1120.   If MsgWasFound Then
  1121.     FM^.CurrMsg := BestMatch
  1122.   Else
  1123.     FM^.CurrMsg := 0;
  1124.   End;
  1125.  
  1126.  
  1127. Procedure FidoMsgObj.SeekPrior;
  1128.   Var
  1129.     Code: Word;
  1130.     BestMatch: LongInt;
  1131.     CurrTry : LongInt;
  1132.     {$IFDEF WINDOWS}
  1133.       TStr: Array[0..128] of Char;
  1134.     {$ENDIF}
  1135.     MsgWasFound: Boolean;
  1136.  
  1137.   Begin
  1138.   CurrTry := 0;
  1139.   MsgWasFound := False;
  1140.   BestMatch := 0;
  1141.   Dec(FM^.CurrMsg);
  1142.   {$IFDEF WINDOWS}
  1143.   StrPCopy(TStr, FM^.NetMailPath + '*.MSG');
  1144.   FindFirst(TStr, faReadOnly + faArchive, FM^.SR);
  1145.   {$ELSE}
  1146.   FindFirst(FM^.NetMailPath + '*.MSG', ReadOnly + Archive, FM^.SR);
  1147.   {$ENDIF}
  1148.   While DosError = 0 Do
  1149.     Begin
  1150.     {$IFDEF WINDOWS}
  1151.       FM^.MsgName := StrPas(FM^.SR.Name);
  1152.     {$ELSE}
  1153.       FM^.MsgName := FM^.SR.Name;
  1154.     {$ENDIF}
  1155.     Val(Copy(FM^.MsgName, 1, Pos('.', FM^.MsgName) - 1), CurrTry, Code);
  1156.     If Code = 0 Then
  1157.       Begin
  1158.       If ((CurrTry <= FM^.CurrMsg) and (CurrTry > BestMatch)) Then
  1159.         Begin
  1160.         BestMatch := CurrTry;
  1161.         MsgWasFound := True;
  1162.         End;
  1163.       End;
  1164.     FindNext(FM^.SR);
  1165.     End;
  1166.   If MsgWasFound Then
  1167.     FM^.CurrMsg := BestMatch
  1168.   Else
  1169.     FM^.CurrMsg := 0;
  1170.   End;
  1171.  
  1172.  
  1173. Function FidoMsgObj.SeekFound: Boolean;
  1174.   Begin
  1175.   SeekFound := FM^.CurrMsg <> 0;
  1176.   End;
  1177.  
  1178.  
  1179. Function FidoMsgObj.GetMsgLoc: LongInt; {Msg location}
  1180.   Begin
  1181.   GetMsgLoc := GetMsgNum;
  1182.   End;
  1183.  
  1184.  
  1185. Procedure FidoMsgObj.SetMsgLoc(ML: LongInt); {Msg location}
  1186.   Begin
  1187.   FM^.CurrMsg := ML;
  1188.   End;
  1189.  
  1190.  
  1191. Procedure FidoMsgObj.YoursFirst(Name: String; Handle: String);
  1192.   Begin
  1193.   FM^.Name := Upper(Name);
  1194.   FM^.Handle := Upper(Handle);
  1195.   FM^.CurrMsg := 0;
  1196.   YoursNext;
  1197.   End;
  1198.  
  1199.  
  1200. Procedure FidoMsgObj.YoursNext;
  1201.   Var
  1202.     FoundDone: Boolean;
  1203.  
  1204.   Begin
  1205.   FoundDone := False;
  1206.   SeekFirst(FM^.CurrMsg + 1);
  1207.   While ((FM^.CurrMsg <> 0) And (Not FoundDone)) Do
  1208.     Begin
  1209.     MsgStartUp;
  1210.     If ((Upper(GetTo) = FM^.Name) Or (Upper(GetTo) = FM^.Handle)) Then
  1211.       FoundDone := True;
  1212.     If IsRcvd Then FoundDone := False;
  1213.     If Not FoundDone Then
  1214.       SeekNext;
  1215.     If Not SeekFound Then
  1216.       FoundDone := True;
  1217.     End;
  1218.   End;
  1219.  
  1220.  
  1221. Function FidoMsgObj.YoursFound: Boolean;
  1222.   Begin
  1223.   YoursFound := SeekFound;
  1224.   End;
  1225.  
  1226.  
  1227. Procedure FidoMsgObj.StartNewMsg;
  1228.   Begin
  1229.   FillChar(FM^.MsgChars, SizeOf(FM^.MsgChars), #0);
  1230.   FM^.TextCtr := 190;
  1231.   FM^.Dest.Zone := 0;
  1232.   FM^.Orig.Zone := 0;
  1233.   FM^.Dest.Point := 0;
  1234.   FM^.Orig.Point := 0;
  1235.   End;
  1236.  
  1237.  
  1238. Function FidoMsgObj.OpenMsgBase: Word;
  1239.   Begin
  1240.   OpenMsgBase := 0;
  1241.   End;
  1242.  
  1243.  
  1244. Function FidoMsgObj.CloseMsgBase: Word;
  1245.   Begin
  1246.   CloseMsgBase := 0;
  1247.   End;
  1248.  
  1249.  
  1250. Function FidoMsgObj.CreateMsgBase(MaxMsg: Word; MaxDays: Word): Word;
  1251.   Begin
  1252.   CreateMsgBase := 0;
  1253.   End;
  1254.  
  1255.  
  1256. Procedure FidoMsgObj.SetMailType(MT: MsgMailType);
  1257.   Begin
  1258.   End;
  1259.  
  1260.  
  1261. Function FidoMsgObj.GetSubArea: Word;
  1262.   Begin
  1263.   GetSubArea := 0;
  1264.   End;
  1265.  
  1266.  
  1267. Procedure FidoMsgObj.ReWriteHdr;
  1268.   Var
  1269.     NetNum: LongInt;
  1270.  
  1271.   Begin
  1272.   NetNum := FM^.CurrMsg;
  1273.   Assign(FM^.MsgFile, FM^.NetMailPath + Long2Str(NetNum) + '.Msg');
  1274.   ReWrite(FM^.MsgFile,1);
  1275.   BlockWrite(FM^.MsgFile, FM^.MsgChars, FM^.TextCtr + 1);
  1276.   Close(FM^.MsgFile);
  1277.   End;
  1278.  
  1279.  
  1280. Procedure FidoMsgObj.DeleteMsg;
  1281.   Begin
  1282.   Assign(FM^.MsgFile, FM^.NetMailPath + Long2Str(FM^.CurrMsg) + '.MSG');
  1283.   Erase(FM^.MsgFile);
  1284.   If IoResult <> 0 Then;
  1285.   End;
  1286.  
  1287.  
  1288. Function FidoMsgObj.NumberOfMsgs: LongInt;
  1289.   Var
  1290.   {$IFDEF WINDOWS}
  1291.     SR: TSearchRec;
  1292.     TStr: Array[0..128] of Char;
  1293.   {$ELSE}
  1294.     SR: SearchRec;
  1295.   {$ENDIF}
  1296.   TmpName: String[13];
  1297.   TmpNum: Word;
  1298.   Code: Word;
  1299.   Active: LongInt;
  1300.  
  1301.   Begin
  1302.   Active := 0;
  1303.   {$IFDEF WINDOWS}
  1304.   StrPCopy(TStr, FM^.NetMailPath + '*.MSG');
  1305.   FindFirst(TStr, faReadOnly + faArchive, SR);
  1306.   {$ELSE}
  1307.   FindFirst(FM^.NetMailPath + '*.MSG', ReadOnly + Archive, SR);
  1308.   {$ENDIF}
  1309.   While DosError = 0 Do
  1310.     Begin
  1311.     {$IFDEF WINDOWS}
  1312.     TmpName :=  StrPas(SR.Name);
  1313.     {$ELSE}
  1314.     TmpName := SR.Name;
  1315.     {$ENDIF}
  1316.     Val(Copy(TmpName, 1,  Pos('.', TmpName) -1), TmpNum, Code);
  1317.     If (Code = 0) Then
  1318.       Inc(Active);
  1319.     FindNext(SR);
  1320.     End;
  1321.   NumberOfMsgs := Active;
  1322.   End;
  1323.  
  1324.  
  1325. Function FidoMsgObj.GetLastRead(UNum: LongInt): LongInt;
  1326.   Var
  1327.     LRec: Word;
  1328.  
  1329.   Begin
  1330.   If ((UNum + 1) * SizeOf(LRec)) >
  1331.   SizeFile(FM^.NetMailPath + 'LastRead') Then
  1332.     GetLastRead := 0
  1333.   Else
  1334.     Begin
  1335.     If LoadFilePos(FM^.NetMailPath + 'LastRead', LRec, SizeOf(LRec),
  1336.     UNum * SizeOf(LRec)) = 0 Then
  1337.       GetLastRead := LRec
  1338.     Else
  1339.       GetLastRead := 0;
  1340.     End;
  1341.   End;
  1342.  
  1343.  
  1344. Procedure FidoMsgObj.SetLastRead(UNum: LongInt; LR: LongInt);
  1345.   Var
  1346.     LRec: Word;
  1347.     Status: Word;
  1348.  
  1349.   Begin
  1350.   If ((UNum + 1) * SizeOf(LRec)) >
  1351.   SizeFile(FM^.NetMailPath + 'LastRead') Then
  1352.     Begin
  1353.     Status := ExtendFile(FM^.NetMailPath + 'LastRead',
  1354.     (UNum + 1) * SizeOf(LRec));
  1355.     End;
  1356.   If LoadFilePos(FM^.NetMailPath + 'LastRead', LRec, SizeOf(LRec),
  1357.   UNum * SizeOf(LRec)) = 0 Then
  1358.     Begin
  1359.     LRec := LR;
  1360.     Status := SaveFilePos(FM^.NetMailPath + 'LastRead', LRec, SizeOf(LRec),
  1361.     UNum * SizeOf(LRec));
  1362.     End;
  1363.   End;
  1364.  
  1365.  
  1366. Function FidoMsgObj.GetTxtPos: LongInt;
  1367.   Begin
  1368.   GetTxtPos := FM^.TextCtr;
  1369.   End;
  1370.  
  1371.  
  1372. Procedure FidoMsgObj.SetTxtPos(TP: LongInt);
  1373.   Begin
  1374.   FM^.TextCtr := TP;
  1375.   End;
  1376.  
  1377.  
  1378. End.
  1379.