home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 11
/
Freelog011.iso
/
BestOf
/
PhoenixMail
/
Source
/
phoenix
/
MailParser.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1999-02-04
|
9KB
|
301 lines
{*****************************************************************************
*
* MailParser.pas - E-mail Parser (22-July-1998)
*
* Copyright (c) 1998-99 Michael Haller
*
* Author: Michael Haller
* E-mail: michael@discountdrive.com
* Homepage: http://www.discountdrive.com/sunrise
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
*----------------------------------------------------------------------------
*
* Revision history:
*
* DATE REV DESCRIPTION
* ----------- --- ----------------------------------------------------------
*
*****************************************************************************}
unit MailParser;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
BASE64Sup, DateSup, ParserSup;
type
TMsgType = (mtText, mtHtml, mtRich);
TEMail = class(TObject)
private
public
ToReceiver, CC, BCC: TStringList;
Fields, FieldValues: TStringList;
Subject, Keywords, Priority, From: String;
ADate, ATime: TDateTime;
UseMime10: Boolean;
ContentType, ContentEncoding: String;
MsgType: TMsgType;
constructor Create;
destructor Destroy; override;
procedure GetMailHeader(var SL: TStringList);
procedure ParseMail(Filename: String; OnlyHeader: Boolean);
procedure CompileMsgFileOnDisk(Filename: String);
end;
implementation
uses
Main, PXStuff;
var
F, G: Text;
constructor TEMail.Create;
begin
inherited Create;
ToReceiver := TStringList.Create;
CC := TStringList.Create;
BCC := TStringList.Create;
Fields := TStringList.Create;
FieldValues := TStringList.Create;
end;
destructor TEMail.Destroy;
begin
ToReceiver.Free;
CC.Free;
BCC.Free;
Fields.Free;
FieldValues.Free;
inherited Destroy;
end;
procedure TEMail.GetMailHeader(var SL: TStringList);
var
I: Integer;
S1, S2: String;
begin
try
ToReceiver.Clear;
CC.Clear;
BCC.Clear;
Fields.Clear;
FieldValues.Clear;
From := '';
Priority := '';
Subject := '';
Keywords := '';
ADate := Date;
ATime := Time;
UseMIME10 := False;
ContentEncoding := '7Bit';
ContentType := 'text/plain';
MsgType := StandardMsgType;
MakeFields(SL, True);
for I := 0 to SL.Count-1 do begin
GetFieldArguments(SL.Strings[I], S1, S2);
if LowerCase(S1) = 'from' then From := SkipChar(S2, '"') else
if LowerCase(S1) = 'subject' then Subject := S2 else
if LowerCase(S1) = 'to' then CommataStringToStringList(S2, ToReceiver) else
if LowerCase(S1) = 'cc' then CommataStringToStringList(S2, CC) else
if LowerCase(S1) = 'bcc' then CommataStringToStringList(S2, BCC) else
if LowerCase(S1) = 'date' then MailTimeToDateTime(S2, ADate, ATime) else
if LowerCase(S1) = 'keywords' then Keywords := S2 else
if LowerCase(S1) = 'priority' then Priority := S2 else
if (LowerCase(S1) = 'mime-version') and (LowerCase(S2) = '1.0') then UseMime10 := True else
if LowerCase(S1) = 'content-type' then ContentType := S2 else
if LowerCase(S1) = 'content-transfer-encoding' then ContentEncoding := S2 else
begin {else}
Fields.Add(S1);
FieldValues.Add(S2);
end;
end;
// proof the value of some 'special' fields
if (LowerCase(Priority) <> 'low') and
(LowerCase(Priority) <> 'normal') and
(LowerCase(Priority) <> 'high') then Priority := 'Normal';
except end;
end;
procedure TEMail.ParseMail(Filename: String; OnlyHeader: Boolean);
var
S, T, S1, S2, CntType, CntEncoding: String;
SL: TStringList;
I: Integer;
BoundarayExists: Boolean;
begin
try
AssignFile(F, Filename);
Reset(F);
SL := TStringList.Create;
//Load mail header
ReadLn(F, S);
while S <> '' do begin // until CRLF
SL.Add(S);
ReadLn(F, S); // fetch new line
end;
GetMailHeader(SL);
if OnlyHeader then begin
CloseFile(F);
Exit;
end;
SL.Clear;
BoundarayExists := FAlse;
if UseMIME10 = True then begin
S := LowerCase(GetContentType('', ContentType));
if S = 'multipart/mixed' then begin
T := '--'+GetContentType('boundary', ContentType);
T := SkipChar(T, '"');
CntType := '';
CntEncoding := '';
while not EoF(F) do begin
ReadLn(F, S);
if S = T then begin
// save previous Boundary Block
if BoundarayExists then SaveMIMEToFile(SL, CntType, CntEncoding);
// Load new boundary header
BoundarayExists := True;
SL.Clear;
ReadLn(F, S);
while S <> '' do begin
SL.Add(S);
ReadLn(F, S);
end;
MakeFields(SL, True);
for I := 0 to SL.Count-1 do begin
GetFieldArguments(SL.Strings[I], S1, S2);
if LowerCase(S1) = 'content-type' then CntType := S2;
if LowerCase(S1) = 'content-transfer-encoding' then CntEncoding := S2;
end;
SL.Clear;
end else
if S = T+'--' then begin
if (CntEncoding <> '') and (CntType <> '') then
SaveMIMEToFile(SL, CntType, CntEncoding);
// End of mail
CloseFile(F);
SL.Free;
Exit;
end else
SL.Add(S);
end;
end else begin
while not EoF(F) do begin
ReadLn(F, S);
SL.Add(S);
end;
SaveMIMEToFile(SL, ContentType, ContentEncoding);
end;
end;
if UseMIME10 = False then begin
MsgType := mtText;
AssignFile(G, sTempMessageFile);
Rewrite(G);
while not EoF(F) do begin
ReadLn(F, S);
WriteLn(G, S);
end;
CloseFile(G);
end;
CloseFile(F);
except end;
end;
procedure TEMail.CompileMsgFileOnDisk(Filename: String);
var
S, S1: String;
I, Found: Integer;
B: Byte;
SearchRec: TSearchRec;
begin
AssignFile(F, Filename);
Rewrite(F);
// Header
S := 'From: '+SetMIMEHeaderField(From);
WriteLn(F, BreakString(S));
S := 'To: '+StringListToCommataString(ToReceiver, True);
WriteLn(F, BreakString(S));
S := StringListToCommataString(CC, True);
if S <> '' then begin S := 'CC: '+S; WriteLn(F, BreakString(S)); end;
S := StringListToCommataString(BCC, True);
if S <> '' then begin S := 'BCC: '+S; WriteLn(F, BreakString(S)); end;
DateTimeToMailTime(S, ADate, ATime);
S := 'Date: '+S;
WriteLn(F, BreakString(S));
S := Subject;
if S <> '' then begin S := 'Subject: '+SetMIMEHeaderField(S); WriteLn(F, BreakString(S)); end;
S := Keywords;
if S <> '' then begin S := 'Keywords: '+SetMIMEHeaderField(S); WriteLn(F, BreakString(S)); end;
S := Priority;
if S <> '' then begin S := 'Priority: '+SetMIMEHeaderField(S); WriteLn(F, BreakString(S)); end;
for I := 0 to Fields.Count-1 do
if Fields.Strings[I] <> '' then begin
S := Fields.Strings[I];
if LowerCase(S) <> 'x-mailer' then begin
S := S+': '+SetMIMEHeaderField(FieldValues.Strings[I]);
WriteLn(F, BreakString(S));
end;
end;
WriteLn(F, BreakString('X-mailer: '+sXMailer));
WriteLn(F, BreakString('MIME-Version: 1.0'));
WriteLn(F, BreakString('Content-type: multipart/mixed; boundary=-----Phoenix-Boundary-07081998-'));
WriteLn(F, '');
//Message text
if FileExists(sTempMessageFile) then begin
WriteLn(F, '-------Phoenix-Boundary-07081998-');
if MsgType = mtText then
WriteLn(F, 'Content-type: text/plain; charset=ISO-8859-1');
if MsgType = mtRich then
WriteLn(F, 'Content-type: text/richtext; charset=ISO-8859-1');
if MsgType = mtHtml then
WriteLn(F, 'Content-type: text/html; charset=ISO-8859-1');
WriteLn(F, 'Content-transfer-encoding: Quoted-printable');
WriteLn(F, '');
AttachFileToTextfile(F, sTempMessageFile, 0);
WriteLn(F, '');
end;
//Attachments
Found := FindFirst(sTemporaryFolder+'*.*', faReadOnly+faArchive+faHidden+faSysFile, SearchRec);
while Found = 0 do begin
if (sTemporaryFolder+SearchRec.Name <> sTempMessageFile) then begin
GetMIMEType(SearchRec.Name, S, S1, B);
WriteLn(F, '-------Phoenix-Boundary-07081998-');
WriteLn(F, 'Content-type: '+S);
WriteLn(F, 'Content-transfer-encoding: '+S1);
WriteLn(F, '');
AttachFileToTextfile(F, sTemporaryFolder+SearchRec.Name, B);
WriteLn(F, '');
end;
Found := FindNext(SearchRec);
end;
FindClose(SearchRec);
//End header
WriteLn(F, '-------Phoenix-Boundary-07081998---');
WriteLn(F, '');
CloseFile(F);
end;
end.