home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 11
/
Freelog011.iso
/
BestOf
/
PhoenixMail
/
Source
/
phoenix
/
TDOnline.pas
< prev
Wrap
Pascal/Delphi Source File
|
1998-12-04
|
30KB
|
923 lines
{*****************************************************************************
*
* TDOnline.pas - Online Thread (28-January-1999)
*
* 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 TDOnline;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
PXStuff, Winsock, ParserSup, MailParser, ComCtrls, FMSelectMail, FileCtrl,
WinSocket;
{
After ending the OnlineThread there are more threads than before you started
it, because some methodes (like PlaySnd) create their own thread.
}
type
TOnlineThread = class(TThread)
private
WinSocket: TWinSocket;
Server, Port, User, Pass, Sender, StandardDownload: String;
DeleteFilter, KeepFilter, AccPath, NodePtr: String;
SLItemCount, CDown, CDel: Integer;
SL: TStringList;
FErrorMsg, FDispMessage, FAnswerBuffer: String;
FStatus1, FStatus2, FCommand, FSLItem: String;
FCounterMax, FCounterPos, FOldCounterPos, FDummy1, FDummy2, FDummy3: Integer;
FProtFile: File;
FMailPrepared, FDummyBol: Boolean;
FFilename, FOldFilename, FPOPMailListItem: String;
procedure AddPOPMailToList;
procedure Wait;
procedure AskForPOPPassword;
function IsSMTPOK(S: String): String;
function IsPOPOK(S: String): String;
procedure FUpdateStatus;
procedure FGetLangString;
procedure FGetCommand;
procedure FShowError;
procedure FDisplayMessage;
procedure FSetCounter;
procedure FGetSLItem;
procedure FPrepareMailForSending;
procedure FGetPOPMailListItem;
procedure FAddSLItem;
procedure FParsePOPMailHeader;
procedure FUserChoosesPOPMail;
procedure FSavePOPNewMailToFolder;
procedure FAskToDeleteFromServer;
procedure FShowStatusMessage;
procedure OnWinSocketClose(Sender: TObject);
procedure OnWinSocketError(Sender: TObject; Msg: String);
protected
procedure Execute; override;
public
Name: String;
CommandCount: Integer;
procedure SetStatusString(Index: Integer; Status1, Status2: String);
function GetNextCommand: String;
function Aborted: Boolean;
function AddToLog(Typ: Byte; S: String): String;
function Receive: String;
procedure Send(S: String);
procedure ShowError(ErrorMsg: String);
procedure DisplayMessage(Msg: String);
procedure SetCounter(Pos: Integer);
function GetNextSLItem: String;
function PrepareMailForSending(Filename: String): Boolean;
procedure GetPOPMailListItem(Index: Integer; var Number, Download: Integer);
constructor Create;
destructor Destroy; override;
end;
var
OnlineThread: TOnlineThread;
Abort, UsingProtPOP3, UsingProtSMTP,
UsingProtocol: Boolean;
AvailableMailCount, FetchedMailCount, SendMailCount, OnlineCounter: Integer;
implementation
uses
Main, FMOnline;
var
F: Text;
// Begin Synchronized Methods //////////////////////////////////////////////////
procedure TOnlineThread.FUpdateStatus;
//Shows the Status in the Statusbar
begin
MainForm.Label5.Caption := Name+': '+FStatus1;
if MainForm.StatusBar1.Panels[3].Text = '' then MainForm.StatusBar1.Panels[3].Text := 'Dummy Text';
end;
procedure TOnlineThread.FSetCounter;
//Sets the counter in the Statusbar of MainForm
begin
if FOldCounterPos = -1 then begin
MainForm.Label4.Caption := '';
end else begin
MainForm.Label4.Caption := Format(MainForm.ListBox1.Items[88], [IntToStr(FOldCounterPos)+'%', FormatByteText(FCounterMax)]);
end;
end;
procedure TOnlineThread.FGetLangString;
//Get Language String by Number from ListBox1
begin
FStatus2 := MainForm.ListBox1.Items[StrToInt(FStatus2)];
end;
procedure TOnlineThread.FGetCommand;
//Get next command from OnlineForm.CommandList and sets CommandCount
begin
if OnlineForm.CommandList.Count > 0 then begin
FCommand := OnlineForm.CommandList[0];
OnlineForm.CommandList.Delete(0);
end else FCommand := '';
CommandCount := OnlineForm.CommandList.Count;
end;
procedure TOnlineThread.FGetSLItem;
//Get the next item of the SL-StringList
begin
if SL.Count > 0 then begin
FSLItem := SL[0];
SL.Delete(0);
end else FSLItem := '';
SLItemCount := SL.Count;
end;
procedure TOnlineThread.FShowError;
//Shows an error message and cleans up
var
S: String;
pBuff: PChar;
I: Integer;
begin
if Abort then Exit;
Abort := True;
try
AddToLog(1, FErrorMsg);
if UsingProtPOP3 or UsingProtSMTP then begin
if WinSocket.Socket <> INVALID_SOCKET then begin
S := 'QUIT'+#13+#10;
pBuff := StrAlloc(Length(S)+1);
StrPCopy(pBuff, S);
Winsock.Send(WinSocket.Socket, pBuff^, Length(S), 0);
StrDispose(pBuff);
end;
UsingProtPOP3 := False;
UsingProtSMTP := False;
end;
WinSocket.Close;
try WinSocket.Free; except end;
if FFilename = sWinTempFolder+'pxrecv' then
DeleteFile(FFilename) else RenameFile(FFilename, FOldFilename);
if UsingProtocol then begin
UsingProtocol := False;
try CloseFile(FProtFile); except end;
end;
OnlineForm.SetCancelOpportunitiesFalse;
OnlineForm.Label2.Caption := FErrorMsg;
OnlineForm.Label7.Caption := MainForm.ListBox1.Items[58];
OnlineForm.Button7.Enabled := bMakeProtocol;
OnlineForm.Notebook1.ActivePage := 'Error';
Screen.Cursor := crDefault;
if bDUNNormalQuit then MainForm.DialUp1.GoOffline;
PlaySound(sSoundFile2);
if not MainForm.Terminating then begin
MainForm.ShowPhoenixMail1Click(Self);
for I := 0 to 15 do Wait;
OnlineForm.ShowModal;
end;
except end;
FShowStatusMessage;
end;
procedure TOnlineThread.FShowStatusMessage;
//Shows the status. MUST be called at the end of the online session
begin
OnlineForm.ShowStatusMessage;
end;
procedure TOnlineThread.Wait;
//Waits a time span (the application is not frozen)
begin
Application.HandleMessage;
end;
procedure TOnlineThread.FDisplayMessage;
//Displays a message - for debugging use
begin
MessageDlg(FDispMessage, mtInformation, [mbOK], 0);
end;
procedure TOnlineThread.FPrepareMailForSending;
//Parses the mail before it will be sent
var
EMail: TEMail;
NewName: String;
I: Integer;
begin
FMailPrepared := False;
SL.Clear;
FFilename := LowerCase(FFilename);
FOldFilename := FFilename;
if FileExists(FFilename) = False then Exit;
FCounterPos := 0;
FOldCounterPos := -2;
NewName := MakeValidDirName(ExtractFilePath(FFilename))+'sending';
if LowerCase(MainForm.ActualMailFile) = FFilename then Exit;
SetFileAttr(FFilename, False, True, False, False);
RenameFile(FFilename, NewName);
for I := 0 to MainForm.ListView1.Items.Count-1 do
if LowerCase(MainForm.ListView1.Items[I].SubItems[4]) = FFilename then begin
MainForm.ListView1.Items.BeginUpdate;
MainForm.ListView1.Items[I].Delete;
MainForm.ListView1.Items.EndUpdate;
MainForm.ListView1.Invalidate;
Application.ProcessMessages;
Break;
end;
FCounterMax := GetFileSize(NewName);
EMail := TEMail.Create;
EMail.ParseMail(NewName, True);
for I := 0 to EMail.ToReceiver.Count-1 do
SL.Add('<'+ExtractEMailAddress(EMail.ToReceiver.Strings[I])+'>');
for I := 0 to EMail.CC.Count-1 do
SL.Add('<'+ExtractEMailAddress(EMail.CC.Strings[I])+'>');
for I := 0 to EMail.BCC.Count-1 do
SL.Add('<'+ExtractEMailAddress(EMail.BCC.Strings[I])+'>');
SLItemCount := SL.Count;
EMail.Free;
FFilename := NewName;
FMailPrepared := True;
end;
procedure TOnlineThread.AskForPOPPassword;
//Asks user for POP3 password if it is undefined
begin
if Pass = '' then begin
SetStatusString(-1, OnlineForm.Label16.Caption+'...', '');
OnlineForm.Notebook1.ActivePage := 'Password';
OnlineForm.ActiveControl := OnlineForm.Edit1;
OnlineForm.Edit1.Text := '';
OnlineForm.Caption := Name;
MainForm.ShowPhoenixMail1Click(Self);
if OnlineForm.ShowModal = mrOK then
Pass := OnlineForm.Edit1.Text
else
ShowError(MainForm.ListBox1.Items[82]);
OnlineForm.Caption := 'Phoenix Mail - '+MainForm.ListBox1.Items[36];
end;
end;
procedure TOnlineThread.AddPOPMailToList;
//Add mailheader to SelectMailForm.ListView
var
Item: TListItem;
I, D1, D2: Integer;
begin
if FPOPMailListItem = '' then begin
SelectMailForm.ListView1.Items.Clear;
SelectMailForm.Label8.Caption := Name;
Exit;
end;
try
D1 := StrToInt(GetToken(FPOPMailListItem));
D2 := StrToInt(GetToken(FPOPMailListItem));
except
Exit;
end;
Item := SelectMailForm.ListView1.Items.Add;
Item.ImageIndex := D1; // Msg Index
Item.StateIndex := StrToInt(StandardDownload);
I := D2+5;
Item.SubItems.Add('');
Item.SubItems.Add('');
Item.SubItems.Add(FormatByteText(I)); // Size of mail
Item.SubItems.Add('');
Item.SubItems.Add('');
Item.SubItems.Add('');
Item.SubItems.Add(IntToStr(I));
Inc(AvailableMailCount);
end;
procedure TOnlineThread.FGetPOPMailListItem;
//Get Item of SelectMailForm.ListView
begin
FDummy2 := SelectMailForm.ListView1.Items[FDummy1].ImageIndex;
FDummy3 := SelectMailForm.ListView1.Items[FDummy1].StateIndex;
FCounterPos := 0;
FCounterMax := StrToInt(SelectMailForm.ListView1.Items[FDummy1].SubItems[6]);
FOldCounterPos := -2;
end;
procedure TOnlineThread.FAddSLItem;
//Add Item to the SL-StringList
begin
SL.Add(FSLItem);
end;
procedure TOnlineThread.FParsePOPMailHeader;
//Apply filters to mail header
var
EMail: TEMail;
Item: TListItem;
E, G: Integer;
begin
if FDummy1 = -1 then begin SL.Clear; Exit; end;
EMail := TEMail.Create;
EMail.GetMailHeader(SL);
Item := SelectMailForm.ListView1.Items[FDummy1];
Item.SubItems[0] := EMail.Subject;
Item.SubItems[1] := EMail.From;
Item.SubItems[3] := DateToStr(EMail.ADate);
Item.SubItems[4] := TimeToStr(EMail.ATime);
Item.SubItems[5] := EMail.From+EMail.Subject+EMail.Keywords;
E := 0; G := 0;
if DeleteFilter <> '' then ApplyFilter(Item.SubItems[5], DeleteFilter, E);
if KeepFilter <> '' then ApplyFilter(Item.SubItems[5], KeepFilter, G);
if (G > 0) or (E > 0) then
if G >= E then Item.StateIndex := 2 else Item.StateIndex := 1;
EMail.Free;
end;
procedure TOnlineThread.FUserChoosesPOPMail;
//Show SelectMailForm
var
I: Integer;
begin
SelectMailForm.ListView1.Resort;
if Aborted then Exit;
if bListMailsAtDownload then begin
PlaySound(sSoundFile1);
SetStatusString(-1, SelectMailForm.Caption, '');
MainForm.ShowPhoenixMail1Click(Self);
if SelectMailForm.ShowModal <> mrOK then begin
ShowError(MainForm.ListBox1.Items[82]);
Exit;
end;
end;
CDown := 0; CDel := 0;
for I := 0 to SelectMailForm.ListView1.Items.Count-1 do begin
if SelectMailForm.ListView1.Items[I].StateIndex in [0,3] then Inc(CDown);
if SelectMailForm.ListView1.Items[I].StateIndex in [0,1] then Inc(CDel);
end;
end;
procedure TOnlineThread.FSavePOPNewMailToFolder;
//Copies the downloaded mail into folder and adds it (if available) to the MainForm.ListView1
var
SL, PL: TStringList;
FL: TList;
AccountPath, FilterMsg, Result: String;
I, E, K: Integer;
Folder, Node: TTreeNode;
Item: TListItem;
EMail: TEMail;
procedure GetSubNotes(Node: TTreeNode);
var
I, P: Integer;
begin
for I := 0 to Node.Count-1 do begin
if PFolderData(Node.Item[I].Data)^.Inbox then begin
ApplyFilter(FilterMsg, PFolderData(Node.Item[I].Data)^.Filter, P);
if P >= 0 then begin
SL.Add(PFolderData(Node.Item[I].Data)^.Path);
PL.Add(IntToStr(P));
FL.Add(Node.Item[I]);
end;
end;
if Node.Count > 0 then GetSubNotes(Node.Item[I]);
end;
end;
begin
Folder := nil;
if DirectoryExists(AccPath) then begin // Does the account still exist ;-)
Node := MainForm.GetActualAccount; //You never know...
for I := 0 to MainForm.TreeView1.Items.Count-1 do
if MainForm.TreeView1.Items[I].StateIndex = 1 then
if LowerCase(PAccountData(MainForm.TreeView1.Items[I].Data)^.Path) = LowerCase(AccPath) then
Node := MainForm.TreeView1.Items[I];
if Node = nil then Node := MainForm.RepositoryNode;
FilterMsg := SelectMailForm.ListView1.Items[FDummy1].SubItems[5];
SL := TStringList.Create;
PL := TStringList.Create;
FL := TList.Create;
AccountPath := PAccountData(Node.Data)^.Path;
GetSubNotes(Node);
K := -1; E := 0;
for I := 0 to PL.Count-1 do
if StrToInt(PL.Strings[I]) >= E then begin
E := StrToInt(PL.Strings[I]);
K := I;
end;
if K = -1 then begin
Result := AccountPath + GetUniqueMailName + '.msg';
Folder := Node;
end else begin
Result := SL.Strings[K] + GetUniqueMailName + '.msg';
Folder := FL[K];
end;
SL.Free; PL.Free; FL.Free;
end else begin
Result := sRepositoryFolder + GetUniqueMailName + '.msg';
end;
FileCopy(nil, FFilename, Result);
SetFileAttr(Result, False, False, False, False);
DeleteFile(FFilename);
// add listview item
if MainForm.TreeView1.Selected = Folder then begin
EMail := TEMail.Create;
EMail.ParseMail(Result, True);
MainForm.ListView1.Items.BeginUpdate;
Item := MainForm.ListView1.Items.Add;
MainForm.ListView1.Items.EndUpdate;
MainForm.ListView1.Invalidate;
Application.ProcessMessages;
Item.ImageIndex := -1;
if FileGetAttr(Result) and faArchive = 0 then begin
if (LowerCase(EMail.Priority) = 'low') then Item.ImageIndex := 9;
if (LowerCase(EMail.Priority) = 'normal') then Item.ImageIndex := 10;
if (LowerCase(EMail.Priority) = 'high') then Item.ImageIndex := 11;
end;
Item.SubItems.Add(EMail.Subject);
Item.SubItems.Add(EMail.From);
Item.SubItems.Add(DateToStr(EMail.ADate));
Item.SubItems.Add(TimeToStr(EMail.ATime));
Item.SubItems.Add(Result);
EMail.Free;
end;
SetPXTreeNodeName(Folder);
Inc(FetchedMailCount);
end;
procedure TOnlineThread.FAskToDeleteFromServer;
//Ask user if he wants to delete a message from the server
var
S: String;
begin
S := Format(MainForm.ListBox1.Items[89], [SelectMailForm.ListView1.Items[FDummy1].SubItems[0], SelectMailForm.ListView1.Items[FDummy1].SubItems[1]]);
if MessageDlg(S, mtWarning, [mbYes, mbNo], 0) = mrNo then FDummyBol := False;
end;
// End Synchronized Methods ////////////////////////////////////////////////////
function TOnlineThread.PrepareMailForSending(Filename: String): Boolean;
//Parses the mail before it will be sent
begin
FFilename := Filename;
Synchronize(FPrepareMailForSending);
Result := FMailPrepared;
end;
procedure TOnlineThread.SetCounter(Pos: Integer);
//Sets the counter in the Statusbar of MainForm
begin
if Pos = -1 then begin
FOldCounterPos := Pos;
Synchronize(FSetCounter);
end else begin
Inc(FCounterPos, Pos);
Pos := Round(100 / FCounterMax * FCounterPos);
if Pos <> FOldCounterPos then begin
FOldCounterPos := Pos;
Synchronize(FSetCounter);
end;
end;
end;
procedure TOnlineThread.SetStatusString(Index: Integer; Status1, Status2: String);
//Shows the status in the StatusBar
var
T: String;
I: Integer;
begin
FStatus1 := Status1;
if Index <> -1 then begin
FStatus2 := IntToStr(Index);
Synchronize(FGetLangString);
if Status1 <> '' then begin
if Status2 <> '' then FStatus1 := Format(FStatus2, [Status1, Status2])
else FStatus1 := Format(FStatus2, [Status1]);
end else FStatus1 := FStatus2;
end;
T := '';
FStatus1 := SkipChar(FStatus1, #10);
for I := 1 to Length(FStatus1) do
if FStatus1[I] = #13 then T := T + ' | ' else T := T + FStatus1[I];
FStatus1 := T;
Synchronize(FUpdateStatus);
end;
function TOnlineThread.GetNextCommand: String;
//Get next command from OnlineForm.CommandList
begin
Synchronize(FGetCommand);
Result := FCommand;
end;
function TOnlineThread.GetNextSLItem: String;
//Get the next item of the SL-StringList
begin
Synchronize(FGetSLItem);
Result := FSLItem;
end;
function TOnlineThread.Aborted: Boolean;
//True if Abort is True or if the Thread is terminated
begin
Result := False;
if Terminated then Result := True;
if Abort then Result := True;
end;
function TOnlineThread.AddToLog(Typ: Byte; S: String): String;
//Adds string to protocol.txt
var
T: String;
I: Integer;
begin
T := ''; S := SkipChar(S, #10);
for I := 1 to Length(S) do if S[I] = #13 then T := T + ' | ' else T := T + S[I];
case Typ of
1: T := 'stat: ' + T + #13 + #10;
2: T := 'send: ' + T + #13 + #10;
3: T := 'recv: ' + T + #13 + #10;
end;
if UsingProtocol then try BlockWrite(FProtFile, T[1], Length(T)); except end;
Result := S;
end;
procedure TOnlineThread.Send(S: String);
//Sends a string to the web
begin
if Aborted then Exit;
WinSocket.Send(S + #13 + #10);
end;
function TOnlineThread.Receive: String;
//Receives a string from the web
var
I, K: Integer;
begin
if Aborted then Exit;
repeat
K := Pos(#13, FAnswerBuffer);
I := Pos(#13+#10, FAnswerBuffer);
if Aborted then Exit;
if (I = 0) and (K = 0) then FAnswerBuffer := FAnswerBuffer + WinSocket.Receive;
//if (I <= 0) and (K <= 0) then Synchronize(Wait);
until ((I > 0) or (K > 0));
if (I > 0) then begin
Result := Copy(FAnswerBuffer, 1, I-1);
Delete(FAnswerBuffer, 1, I+1);
end;
if (I = 0) and (K > 0) then begin
Result := Copy(FAnswerBuffer, 1, K-1);
Delete(FAnswerBuffer, 1, K);
end;
end;
procedure TOnlineThread.ShowError(ErrorMsg: String);
//Shows an error message
begin
if Abort then Exit;
FErrorMsg := ErrorMsg;
Synchronize(FShowError);
end;
procedure TOnlineThread.DisplayMessage(Msg: STring);
//Displays a message - for debugging use
begin
FDispMessage := Msg;
Synchronize(FDisplayMessage);
end;
function TOnlineThread.IsSMTPOK(S: String): String;
//Is the SMTP command positive?
var
I: Integer;
begin
Result := S;
try
I := StrToInt(Copy(S, 1, 3));
if I >= 400 then if I <> 550 then ShowError('SMTP error '+S);
except end;
end;
function TOnlineThread.IsPOPOK(S: String): String;
//Is the POP3 command positive?
begin
Result := S;
try if UpperCase(Copy(S, 1, 3)) <> '+OK' then ShowError(Copy(S, 5, Length(S)-4)); except end;
end;
procedure TOnlineThread.GetPOPMailListItem(Index: Integer; var Number, Download: Integer);
//Get Item of SelectMailForm.ListView
begin
FDummy1 := Index;
Synchronize(FGetPOPMailListItem);
Number := FDummy2;
Download := FDummy3;
end;
procedure TOnlineThread.OnWinSocketClose(Sender: TObject);
var
S: String;
begin
S := Format('Lost connection on socket %s', [IntToStr(WinSocket.Socket)]);
if UsingProtPOP3 or UsingProtSMTP then ShowError(S) else AddToLog(1, S);
end;
procedure TOnlineThread.OnWinSocketError(Sender: TObject; Msg: String);
begin
if Abort then Exit;
ShowError(Msg);
end;
// Execute /////////////////////////////////////////////////////////////////////
procedure TOnlineThread.Execute;
var
ProtType, S1, S2: String;
I, Count, Nb, Dt, CIndex: Integer;
B: Boolean;
begin
try
while CommandCount > 0 do begin
ProtType := GetNextCommand;
Name := GetNextCommand;
Server := GetNextCommand;
Port := GetNextCommand;
User := GetNextCommand;
Pass := GetNextCommand;
Sender := GetNextCommand;
StandardDownload := GetNextCommand;
DeleteFilter := GetNextCommand;
KeepFilter := GetNextCommand;
AccPath := GetNextCommand;
NodePtr := GetNextCommand;
//Ask for POP3 password
if ProtType = 'POP3' then Synchronize(AskForPOPPassword);
if Aborted then Exit;
//Connect to server
WinSocket := TWinSocket.Create(Application);
WinSocket.Parent := OnlineForm;
WinSocket.OnError := OnWinSocketError;
WinSocket.OnClose := OnWinSocketClose;
WinSocket.BlockTime := 0;
WinSocket.Blocking := True;
WinSocket.PortName := Port;
WinSocket.HostName := Server;
WinSocket.Open;
if Aborted then Exit;
AddToLog(1, 'Connected to '+Server+' at port '+Port);
if ProtType = 'SMTP' then begin
// Simple Mail Transfer Protocol
UsingProtSMTP := True;
IsSMTPOK(AddToLog(3, Receive));
SetStatusString(71, '', '');
if Aborted then Exit;
Send(AddToLog(2, 'HELO '+GetLocalHostName));
if Aborted then Exit;
IsSMTPOK(AddToLog(3, Receive));
Count := StrToInt(GetNextCommand);
for I := 0 to Count-1 do begin
S1 := GetNextCommand;
if Aborted then Exit;
if PrepareMailForSending(S1) then begin
SetStatusString(72, '', '');
if Aborted then Exit;
Send(AddToLog(2, 'MAIL FROM:'+Sender));
if Aborted then Exit;
IsSMTPOK(AddToLog(3, Receive));
while SLItemCount > 0 do begin
if Aborted then Exit;
Send(AddToLog(2, 'RCPT TO:'+GetNextSLItem));
if Aborted then Exit;
IsSMTPOK(AddToLog(3, Receive));
end;
SetStatusString(73, '', '');
if Aborted then Exit;
Send(AddToLog(2, 'DATA'));
if Aborted then Exit;
IsSMTPOK(AddToLog(3, Receive));
if Abort then Exit;
AssignFile(F, FFilename);
Reset(F);
while not EoF(F) do begin
if Aborted then begin
CloseFile(F); RenameFile(FFilename, FOldFilename); Exit;
end;
ReadLn(F, S2);
if S2 = '.' then S2 := '..';
Send(AddToLog(2, S2));
SetCounter(Length(S2)+2);
end;
SetCounter(-1);
try CloseFile(F); except end;
if Aborted then Exit;
Send(AddToLog(2, ''));
Send(AddToLog(2, '.'));
SetStatusString(74, '', '');
if Aborted then Exit;
IsSMTPOK(AddToLog(3, Receive));
if Aborted then Exit;
Inc(SendMailCount);
try
CopyFile(PChar(FFilename), PChar(sRepositoryFolder+ExtractFileName(FOldFilename)), False);
DeleteFile(PChar(FFilename));
except end;
end;
end;
SetStatusString(70, '', '');
if Aborted then Exit;
UsingProtSMTP := False;
Send(AddToLog(2, 'QUIT'));
IsSMTPOK(AddToLog(3, Receive));
WinSocket.Close;
end;
if ProtType = 'POP3' then begin
// Post Office Protocol Vers. 3
UsingProtPOP3 := True;
SetStatusString(64, Server, '');
if Aborted then Exit;
IsPOPOK(AddToLog(3, Receive));
SetStatusString(65, '', '');
if Aborted then Exit;
Send(AddToLog(2, 'USER '+User));
if Aborted then Exit;
IsPOPOK(AddToLog(3, Receive));
if Aborted then Exit;
Send('PASS '+Pass);
AddToLog(2, 'PASS ********');
if Aborted then Exit;
IsPOPOK(AddToLog(3, Receive));
SetStatusString(66, '', '');
if Aborted then Exit;
//Clear Msg List
FPOPMailListItem := '';
Synchronize(AddPOPMailToList);
//List mails
Count := 0;
B := False;
if Aborted then Exit;
Send(AddToLog(2, 'LIST'));
if Aborted then Exit;
S1 := AddToLog(3, Receive);
if UpperCase(Copy(S1, 1, 3)) = '+OK' then B := True;
if B then begin
// Get Mail Count/Size
if Aborted then Exit;
S1 := AddToLog(3, Receive);
while S1 <> '.' do begin
FPOPMailListItem := S1;
Inc(Count);
Synchronize(AddPOPMailToList);
if Aborted then Exit;
S1 := AddToLog(3, Receive);
end;
for I := 0 to Count-1 do begin
SetStatusString(67, IntToStr(I+1), IntToStr(Count));
GetPOPMailListItem(I, Nb, Dt);
if Aborted then Exit;
Send(AddToLog(2, 'TOP '+IntToStr(Nb)+' 0'));
if Aborted then Exit;
IsPOPOK(AddToLog(3, Receive));
if Aborted then Exit;
FDummy1 := -1; Synchronize(FParsePOPMailHeader); // Clear StringList
S1 := AddToLog(3, Receive);
while S1 <> '.' do begin
if S1 = '..' then S1 := '.';
FSLItem := S1;
Synchronize(FAddSLItem);
if Aborted then Exit;
S1 := AddToLog(3, Receive);
end;
FDummy1 := I;
Synchronize(FParsePOPMailHeader);
end;
if Count > 0 then Synchronize(FUserChoosesPOPMail);
if Aborted then Exit;
//Download Mail
CIndex := 1;
for I := 0 to Count-1 do begin
GetPOPMailListItem(I, Nb, Dt);
if Dt in [0, 3] then begin
SetStatusString(68, IntToStr(CIndex), IntToStr(CDown));
if Aborted then Exit;
Send(AddToLog(2, 'RETR '+IntToStr(Nb)));
if Aborted then Exit;
IsPOPOK(AddToLog(3, Receive));
FFilename := sWinTempFolder+'pxrecv';
if Aborted then Exit;
AssignFile(F, FFilename);
Rewrite(F);
S1 := AddToLog(3, Receive);
while S1 <> '.' do begin
if S1 = '..' then S1 := '.';
WriteLn(F, S1);
if Aborted then begin
CloseFile(F);
DeleteFile(S1);
Exit;
end;
S1 := AddToLog(3, Receive);
SetCounter(Length(S1));
end;
try CloseFile(F); except end;
SetCounter(-1);
FDummy1 := I;
Synchronize(FSavePOPNewMailToFolder);
Inc(CIndex);
end;
end;
// Delete mails
CIndex := 1;
for I := 0 to Count-1 do begin
GetPOPMailListItem(I, Nb, Dt);
if Dt in [0, 1] then begin
SetStatusString(69, IntToStr(CIndex), IntToStr(CDel));
FDummyBol := True;
FDummy1 := I;
if (Dt = 1) and (bAskForDelFromServer = True) then Synchronize(FAskToDeleteFromServer);
if FDummyBol then begin
if Aborted then Exit;
Send(AddToLog(2, 'DELE '+IntToStr(Nb)));
if Aborted then Exit;
IsPOPOK(AddToLog(3, Receive));
end;
Inc(CIndex);
end;
end;
end;
SetStatusString(70, '', '');
if Aborted then Exit;
UsingProtPOP3 := False;
Send(AddToLog(2, 'QUIT'));
IsPOPOK(AddToLog(3, Receive));
WinSocket.Close;
end;
end; //end while commandcount > 0
UsingProtocol := False;
if UsingProtocol then try CloseFile(FProtFile); except end;
except
on Error: Exception do begin Exception.Create(Error.Message); Exit; end;
end;
WinSocket.Free;
Synchronize(FShowStatusMessage);
end;
constructor TOnlineThread.Create;
begin
Priority := tpNormal;
UsingProtPOP3 := False;
UsingProtSMTP := False;
UsingProtocol := False;
OnlineCounter := 0;
FAnswerBuffer := '';
SL := TStringList.Create;
if bMakeProtocol then begin
try
AssignFile(FProtFile, sProtocolFile);
Rewrite(FProtFile, 1);
UsingProtocol := True;
except end;
end;
AddToLog(1, sXMailer);
AddToLog(1, 'Session started on '+DateToStr(Date)+' '+TimeToStr(Time));
AddToLog(1, 'Winsock Description: '+GetWinsockDescription);
AddToLog(1, 'System Status: '+GetWinsockSystemStatus);
inherited Create(True);
end;
destructor TOnlineThread.Destroy;
begin
try SL.Free; except end;
inherited Destroy;
end;
initialization
OnlineThread := nil;
end.