NMSMTP.pas
上传用户:szzdds
上传日期:2013-09-18
资源大小:293k
文件大小:26k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit NMsmtp;
  2. {$X+}
  3. {$R-}
  4. {$IFDEF VER100}
  5. {$DEFINE NMF3}
  6. {$ENDIF}
  7. {$IFDEF VER110}
  8. {$DEFINE NMF3}
  9. {$ENDIF}
  10. {$IFDEF VER120}
  11. {$DEFINE NMF3}
  12. {$ENDIF}
  13. {$IFDEF VER125}
  14. {$DEFINE NMF3}
  15. {$ENDIF}
  16. interface
  17. uses
  18.   Classes, PSock, sysutils, NMuue, NMExtstr, NMConst;
  19. {$IFDEF VER110}
  20. {$OBJEXPORTALL On}
  21. {$ENDIF}
  22. {$IFDEF VER120}
  23. {$OBJEXPORTALL On}
  24. {$ENDIF}
  25. {$IFDEF VER125}
  26. {$OBJEXPORTALL On}
  27. {$ENDIF}
  28. const
  29.   SMTP_PORT = 25;
  30.   //  CompName     ='TNMSMTP';
  31.   //  Major_Version='4';
  32.   //  Minor_Version='03';
  33.   //  Date_Version ='020398';
  34.   CRLF = #13#10;
  35.   hiFromAddress = 1;
  36.   hiToAddress = 2;
  37. const {protocol}
  38.   Cons_Helo = 'HELO ';
  39.   Cons_Quit = 'QUIT';
  40.   Cons_Rset = 'RSET';
  41.   Cons_From = 'MAIL FROM:<';
  42.   Cons_To = 'RCPT TO:<';
  43.   Cons_Date = 'DATA';
  44.   Cons_Expn = 'EXPN ';
  45.   Cons_Vrfy = 'VRFY ';
  46.   Cons_Head_subj = 'Subject';
  47.   Cons_Head_from = 'From: ';
  48.   Cons_Head_To = 'To: ';
  49.   Cons_Head_CC = 'CC: ';
  50.   Cons_Head_mail = 'X-Mailer';
  51.   Cons_Head_ReplyTo = 'Reply-To';
  52.   Cons_Head_Date = 'Date';
  53.   Cons_Head_mime = 'Mime-Version: 1.0';
  54.   Cons_Head_disp = 'Content-Disposition: attachment; filename="';
  55.   Cons_Head_ba64 = 'Content-Transfer-Encoding: base64';
  56.   Cons_Head_appl = 'Content-Type: application/octet-stream; name="';
  57.   Cons_Head_text = 'Content-Type: text/plain; charset=';
  58.   Cons_Head_Enriched = 'Content-Type: text/enriched; charset=';
  59.   Cons_Head_Sgml = 'Content-Type: text/sgml; charset=';
  60.   Cons_Head_TabSeperated = 'Content-Type: text/tab-separated-values; charset=';
  61.   Cons_Head_mtHtml = 'Content-Type: text/html; charset=';
  62.   // Cons_Head_text2       = 'Content-Type: text/plain, charset="iso-8859-1"';
  63.   Cons_Head_mult = 'Content-Type: multipart/mixed; boundary="';
  64.   Cons_Head_7Bit = 'Content-Transfer-Encoding: 7Bit';
  65. type
  66.   TSubType = (mtPlain, mtEnriched, mtSgml, mtTabSeperated, mtHtml);
  67.   THeaderInComplete = procedure(var handled: boolean; hiType: integer) of object;
  68.   TRecipientNotFound = procedure(Recipient: string) of object;
  69.   TMailListReturn = procedure(MailAddress: string) of object;
  70.   TFileItem = procedure(Filename: string) of object;
  71.   TPostMessage = class(TPersistent)
  72.   private
  73.     FFromName, FFrom, FSubject, FLocalProgram, FDate, FReplyTo: string;
  74.     FAttachments, FTo, FCC, FBCC: TStringList;
  75.     FBody: TStringList;
  76.   protected
  77.     procedure SetLinesTo(Value: TStringList);
  78.     procedure SetLinesCC(Value: TStringList);
  79.     procedure SetLinesBCC(Value: TStringList);
  80.     procedure SetLinesBody(Value: TStringList);
  81.     procedure SetLinesAttachments(Value: TStringList);
  82.   public
  83.     constructor Create;
  84.     destructor Destroy; override;
  85.   published
  86.     property FromAddress: string read FFrom write FFrom;
  87.     property FromName: string read FFromName write FFromName;
  88.     property ToAddress: TStringList read FTo write SetLinesTo;
  89.     property ToCarbonCopy: TStringList read FCC write SetLinesCC;
  90.     property ToBlindCarbonCopy: TStringList read FBCC write SetLinesBCC;
  91.     property Body: TStringList read FBody write SetLinesBody;
  92.     property Attachments: TStringList read FAttachments write SetLinesAttachments;
  93.     property Subject: string read FSubject write FSubject;
  94.     property LocalProgram: string read FLocalProgram write FLocalProgram;
  95.     property Date: string read FDate write FDate;
  96.     property ReplyTo: string read FReplyTo write FReplyTo;
  97.   end;
  98.   TNMSMTP = class(TPowerSock)
  99.   private
  100.     FCharset: string;
  101.     FOnConnect: TNotifyEvent;
  102.     FPostMessage: TPostMessage;
  103.     FsenFmem: TMemoryStream;
  104.     (*{$IFDEF NMF3}
  105.           FSendFile: TS_BufferStream;
  106.     {$ELSE}   *)
  107.     FSendFile: TMemoryStream;
  108.     //{$ENDIF}
  109.     FFinalHeader: TExStringList;
  110.     FTransactionInProgress, FAbort: boolean;
  111.     FUserID, FBoundary: string;
  112.     FSubType: TSubType;
  113.     FOnHeaderInComplete: THeaderInComplete;
  114.     FOnSendStart, FOnSuccess, FOnFailure: TNotifyEvent;
  115.     FOnEncodeStart, FOnEncodeEnd: TFileItem;
  116.     FOnAttachmentNotFound: TFileItem;
  117.     FRecipientNotFound {,FMessageSent}: TRecipientNotFound;
  118.     FMailListReturn: TMailListReturn;
  119.     FOnAuthenticationFailed: THandlerEvent;
  120.     fUUMethod: UUMethods;
  121.     FClearParams: boolean;
  122.     WaitForReset: integer;
  123. {$IFDEF NMDEMO}
  124.     DemoStamped: boolean;
  125. {$ENDIF}
  126.     procedure ReadExtraLines(var ReplyMess: string);
  127.     procedure SendAttachments(i: integer);
  128.     procedure AssembleMail;
  129.     procedure AbortResume(Sender: TObject);
  130.     procedure SetFinalHeader(Value: TExStringList);
  131.     //function CreateTemporaryFileName: string;
  132.   protected
  133.   public
  134.     constructor Create(AOwner: TComponent); override;
  135.     destructor Destroy; override;
  136.     procedure Connect; override;
  137.     procedure Disconnect; override;
  138.     procedure SendMail;
  139.     procedure Abort; override;
  140.     procedure ClearParameters;
  141.     function ExtractAddress(TotalAddress: string): string;
  142.     function Verify(UserName: string): boolean;
  143.     function ExpandList(MailList: string): boolean;
  144.   published
  145.     property OnPacketSent;
  146.     property OnConnectionRequired;
  147.     property OnConnect: TNotifyEvent read FOnConnect write FOnConnect;
  148.     property UserID: string read FUserID write FUserID;
  149.     property PostMessage: TPostMessage read FPostMessage write FPostMessage;
  150.     property FinalHeader: TExStringList read FFinalHeader write SetFinalHeader;
  151.     property EncodeType: UUMethods read fUUMethod write fUUMethod;
  152.     property ClearParams: boolean read FClearParams write FClearParams;
  153.     property SubType: TSubType read FSubType write FSubType;
  154.     property Charset: string read FCharset write FCharset;
  155.     property OnRecipientNotFound: TRecipientNotFound read FRecipientNotFound write FRecipientNotFound;
  156.     property OnHeaderIncomplete: THeaderInComplete read FOnHeaderInComplete write FOnHeaderInComplete;
  157.     property OnSendStart: TNotifyEvent read FOnSendStart write FOnSendStart;
  158.     property OnSuccess: TNotifyEvent read FOnSuccess write FOnSuccess;
  159.     property OnFailure: TNotifyEvent read FOnFailure write FOnFailure;
  160.     property OnEncodeStart: TFileItem read FOnEncodeStart write FOnEncodeStart;
  161.     property OnEncodeEnd: TFileItem read FOnEncodeEnd write FOnEncodeEnd;
  162.     property OnMailListReturn: TMailListReturn read FMailListReturn write FMailListReturn;
  163.     property OnAttachmentNotFound: TFileItem read FOnAttachmentNotFound write FOnAttachmentNotFound;
  164.     property OnAuthenticationFailed: THandlerEvent read FOnAuthenticationFailed write FOnAuthenticationFailed;
  165.   end;
  166. implementation
  167. uses
  168.   Windows;
  169. var
  170.   mailcount: integer;
  171. function StripCRLF(InStr: string): string;
  172. begin
  173.   if InStr <> '' then
  174.     if InStr[Length(InStr)] = #10 then
  175.       Result := Copy(InStr, 1, Length(InStr) - 2)
  176.     else Result := InStr;
  177. end;
  178. {*******************************************************************************************
  179. Constructor - Create String Lists to hold body, attachment list and distribution lists.
  180. Sets Default port and clears Transaction in Progress flag.
  181. ********************************************************************************************}
  182. constructor TNMSMTP.Create(AOwner: TComponent);
  183. begin
  184.   inherited Create(AOwner);
  185.   try
  186.     Port := SMTP_PORT;
  187.     EncodeType := UUMime;
  188.     FTransactionInProgress := FALSE;
  189.     FPostMessage := TPostMessage.Create;
  190.     FFinalHeader := TExStringList.Create;
  191.     FsenFmem := TMemoryStream.Create;
  192.     (*{$IfDef NMF3}
  193.         FSendFile := TS_BufferStream.create(FsenFmem);
  194.     {$ELSE}  *)
  195.     FSendFile := TMemoryStream.Create;
  196.     // {$ENDIF}
  197.     FClearParams := TRUE;
  198.     FSubType := mtPlain;
  199.     FCharset := 'GB2312';
  200.     OnAbortRestart := AbortResume;
  201.     WaitForReset := 2;
  202.   except
  203.     Destroy;
  204.   end;
  205. end;
  206. {*******************************************************************************************
  207. Constructor - Destroys String Lists holding body, attachment list and distribution lists.
  208. ********************************************************************************************}
  209. destructor TNMSMTP.Destroy;
  210. begin
  211.   if FPostMessage <> nil then
  212.     FPostMessage.free;
  213.   FFinalHeader.free;
  214.   FSendFile.free;
  215.   FsenFmem.free;
  216.   inherited Destroy;
  217. end;
  218. {*******************************************************************************************
  219. Connect - Calls inherited socket connect and gets reply. Sends Greeting to server
  220. and gets reply.
  221. ********************************************************************************************}
  222. procedure TNMSMTP.Connect;
  223. var
  224.   ReplyMess: string;
  225.   TryCt: integer;
  226.   ConnCalled, handled: boolean;
  227.   Done: boolean;
  228. begin
  229.   ConnCalled := FALSE;
  230.   Done := FALSE;
  231.   if FTransactionInProgress then
  232.     ConnCalled := TRUE
  233.   else
  234.     FTransactionInProgress := TRUE;
  235.   try
  236.     inherited Connect;
  237.     try
  238.       ReplyMess := Readln;
  239.       ReadExtraLines(ReplyMess);
  240.       if ReplyNumber > 399 then
  241.         raise Exception.Create(ReplyMess);
  242.       TryCt := 0;
  243.       repeat
  244.         ReplyMess := Transaction(Cons_Helo + FUserID);
  245.         ReadExtraLines(ReplyMess);
  246.         if ReplyNumber > 299 then
  247.           if TryCt > 0 then
  248.             raise Exception.Create(Cons_Msg_Auth_Fail)
  249.           else if not Assigned(FOnAuthenticationFailed) then
  250.             raise Exception.Create(Cons_Msg_Auth_Fail)
  251.           else
  252.           begin
  253.             handled := FALSE;
  254.             FOnAuthenticationFailed(handled);
  255.             if not handled then
  256.               raise Exception.Create(Cons_Msg_Auth_Fail);
  257.             TryCt := TryCt + 1;
  258.           end;
  259.       until ReplyNumber < 299;
  260.       Done := TRUE;
  261.     except
  262.       Disconnect;
  263.       raise
  264.     end;
  265.   finally
  266.     if not ConnCalled then
  267.       FTransactionInProgress := FALSE;
  268.     if Done then
  269.       if Assigned(FOnConnect) then
  270.         FOnConnect(self);
  271.   end;
  272. end;
  273. {*******************************************************************************************
  274. Disconnect - Sends Quit message to server and gets Reply. Calls inherited disconnect to
  275. close socket.
  276. ********************************************************************************************}
  277. procedure TNMSMTP.Disconnect;
  278. var ReplyMess: string;
  279. begin
  280.   Beencanceled := FALSE;
  281.   try
  282.     ReplyMess := Transaction(Cons_Quit);
  283.     if ReplyNumber > 339 then
  284.       raise Exception.Create(ReplyMess);
  285.   finally
  286.     inherited Disconnect;
  287.   end;
  288. end;
  289. {*******************************************************************************************
  290. SendMail - Posts a mail message to the server
  291. ********************************************************************************************}
  292. procedure TNMSMTP.SendMail;
  293. var
  294.   ReplyMess: string;
  295.   i, TryCt: integer;
  296.   Done, handled: boolean;
  297.   TAdd: string;
  298. begin
  299.   if not FTransactionInProgress then
  300.   begin
  301.     Done := FALSE;
  302.     FTransactionInProgress := TRUE;
  303.     try
  304.       AssembleMail;
  305.       CertifyConnect;
  306.       TryCt := 0;
  307.       repeat
  308.         if (FPostMessage.FFrom = '') or ((FPostMessage.FTo.count = 0) and (FPostMessage.FCC.count = 0) and (FPostMessage.FBCC.count = 0)) then
  309.           if TryCt > 0 then
  310.             raise Exception.Create(sSMTP_Msg_Incomp_Head)
  311.           else if not Assigned(FOnHeaderInComplete) then
  312.             raise Exception.Create(sSMTP_Msg_Incomp_Head)
  313.           else
  314.           begin
  315.             handled := FALSE;
  316.             if FPostMessage.FFrom = '' then
  317.               FOnHeaderInComplete(handled, hiFromAddress)
  318.             else
  319.               FOnHeaderInComplete(handled, hiToAddress);
  320.             if not handled then
  321.               raise Exception.Create(sSMTP_Msg_Incomp_Head);
  322.             TryCt := TryCt + 1;
  323.           end;
  324.       until (FPostMessage.FFrom <> '') and ((FPostMessage.FTo.count <> 0) or (FPostMessage.FCC.count <> 0) or (FPostMessage.FBCC.count <> 0));
  325.       if Assigned(FOnSendStart) then
  326.         FOnSendStart(self);
  327.       FAbort := FALSE;
  328.       ReplyMess := Transaction(Cons_Rset);
  329.       if ReplyNumber > 399 then
  330.         raise Exception.Create(ReplyMess);
  331.       if not FAbort then
  332.         ReplyMess := Transaction(Cons_From + FPostMessage.FFrom + '>');
  333.       if ReplyNumber > 399 then
  334.         raise Exception.Create(ReplyMess);
  335.       if not FAbort then
  336.         for i := 1 to FPostMessage.FTo.count do
  337.         begin
  338.           TAdd := ExtractAddress(StripCRLF(FPostMessage.FTo.strings[i - 1]));
  339.           if TAdd <> '' then
  340.           begin
  341.             ReplyMess := Transaction(Cons_To + TAdd + '>');
  342.             if ReplyNumber > 300 then
  343.               if Assigned(FRecipientNotFound) then
  344.                 FRecipientNotFound(FPostMessage.FTo.strings[i - 1]);
  345.           end;
  346.         end;
  347.       if not FAbort then
  348.         for i := 1 to FPostMessage.FCC.count do
  349.         begin
  350.           TAdd := ExtractAddress(StripCRLF(FPostMessage.FCC.strings[i - 1]));
  351.           if TAdd <> '' then
  352.           begin
  353.             ReplyMess := Transaction(Cons_To + TAdd + '>');
  354.             if ReplyNumber > 300 then
  355.               if Assigned(FRecipientNotFound) then
  356.                 FRecipientNotFound(FPostMessage.FTo.strings[i - 1]);
  357.           end;
  358.         end;
  359.       if not FAbort then
  360.         for i := 1 to FPostMessage.FBCC.count do
  361.         begin
  362.           TAdd := ExtractAddress(FPostMessage.FBCC.strings[i - 1]);
  363.           if TAdd <> '' then
  364.           begin
  365.             ReplyMess := Transaction(Cons_To + TAdd + '>');
  366.             if ReplyNumber > 300 then
  367.               if Assigned(FRecipientNotFound) then
  368.                 FRecipientNotFound(FPostMessage.FTo.strings[i - 1]);
  369.           end;
  370.         end;
  371.       if not FAbort then
  372.         ReplyMess := Transaction(Cons_Date);
  373.       if ReplyNumber > 399 then
  374.         raise Exception.Create(ReplyMess);
  375.       Write(FFinalHeader.Text + CRLF);
  376.       SendStream(FSendFile);
  377.       ReplyMess := Transaction(CRLF + '.');
  378.       if ReplyNumber > 399 then
  379.       begin
  380.         if Assigned(FOnFailure) then
  381.           FOnFailure(self);
  382.         raise Exception.Create(ReplyMess);
  383.       end
  384.       else
  385.         Done := TRUE;
  386.       if FAbort then
  387.         ReplyMess := Transaction(CRLF + Cons_Rset);
  388.       if FClearParams then
  389.         ClearParameters;
  390.     finally
  391.       FTransactionInProgress := FALSE;
  392.       if Done then
  393.         if Assigned(FOnSuccess) then
  394.           FOnSuccess(self);
  395.     end;
  396.   end;
  397. end;
  398. procedure TNMSMTP.AssembleMail;
  399. var
  400.   i: integer;
  401.   Tstr: string;
  402. begin
  403.   FFinalHeader.clear;
  404.   FFinalHeader.add(Cons_Head_from + FPostMessage.FFromName + '<' + FPostMessage.FFrom + '>');
  405.   for i := 1 to FPostMessage.FTo.count do
  406.   begin
  407.     if (i = 1) then
  408.       Tstr := Cons_Head_To + StripCRLF(FPostMessage.FTo.strings[0])
  409.     else
  410.       Tstr := Tstr + ',' + StripCRLF(FPostMessage.FTo.strings[i - 1]);
  411.     if (i = FPostMessage.FTo.count) then
  412.       FFinalHeader.add(Tstr);
  413.   end;
  414.   for i := 1 to FPostMessage.FCC.count do
  415.   begin
  416.     if (i = 1) then
  417.       Tstr := Cons_Head_CC + StripCRLF(FPostMessage.FCC.strings[0])
  418.     else
  419.       Tstr := Tstr + ',' + StripCRLF(FPostMessage.FCC.strings[i - 1]);
  420.     if (i = FPostMessage.FCC.count) then
  421.       FFinalHeader.add(Tstr);
  422.   end;
  423.   FFinalHeader.values[Cons_Head_subj] := FPostMessage.FSubject;
  424.   FFinalHeader.values[Cons_Head_mail] := FPostMessage.FLocalProgram;
  425.   if (FPostMessage.FReplyTo <> '') then
  426.     FFinalHeader.values[Cons_Head_ReplyTo] := FPostMessage.FReplyTo;
  427.   if (FPostMessage.FDate <> '') then
  428.     FFinalHeader.values[Cons_Head_Date] := FPostMessage.FDate;
  429.   FFinalHeader.add(Cons_Head_mime);
  430.   if (FPostMessage.FAttachments.count = 0) then
  431.   begin
  432.     case FSubType of
  433.       mtEnriched: FFinalHeader.add(Cons_Head_Enriched + FCharset);
  434.       mtSgml: FFinalHeader.add(Cons_Head_Sgml + FCharset);
  435.       mtTabSeperated: FFinalHeader.add(Cons_Head_TabSeperated + FCharset);
  436.       mtHtml: FFinalHeader.add(Cons_Head_mtHtml + FCharset);
  437.     else
  438.       FFinalHeader.add(Cons_Head_text + FCharset);
  439.     end;
  440.       {FFinalHeader.add(Cons_Head_7Bit);    }
  441.   end
  442.   else
  443.   begin
  444.     FBoundary := '====================54535' + TimeToStr(mailcount) + '====';
  445.     inc(mailcount);
  446.     FFinalHeader.add(Cons_Head_mult + FBoundary + '"');
  447.   end;
  448.   (*  {$IfDef NMF3}
  449.        FSendFile.Flushbuffer;
  450.    {$ELSE}    *)
  451.   FSendFile.clear;
  452.   // {$ENDIF}
  453.   try
  454.     if (FPostMessage.FAttachments.count = 0) then
  455.       for i := 1 to FPostMessage.FBody.count do
  456.       begin
  457.         Tstr := FPostMessage.FBody[i - 1] + CRLF;
  458.         if Tstr[1] = '.' then
  459.           Tstr := '.' + Tstr;
  460.         FSendFile.Write(Tstr[1], Length(Tstr));
  461.       end
  462.     else
  463.     begin
  464.       Tstr := '--' + FBoundary + CRLF + Cons_Head_text + FCharset + CRLF + CRLF;
  465.       FSendFile.Write(Tstr[1], Length(Tstr));
  466.       for i := 1 to FPostMessage.FBody.count do
  467.       begin
  468.         Tstr := FPostMessage.FBody[i - 1] + CRLF;
  469.         if Tstr[1] = '.' then
  470.           Tstr := '.' + Tstr;
  471.         FSendFile.Write(Tstr[1], Length(Tstr));
  472.       end;
  473.       for i := 1 to FPostMessage.FAttachments.count do
  474.         SendAttachments(i);
  475.       Tstr := '--' + FBoundary + '--' + CRLF;
  476.       FSendFile.Write(Tstr[1], Length(Tstr));
  477.     end;
  478.     FSendFile.Position := 0;
  479.   finally
  480.     {FSendFile.free; }
  481.   end;
  482. end;
  483. {
  484. function TNMSMTP.CreateTemporaryFileName: string;
  485. var
  486.   nBufferLength: DWord;
  487.   lpPathName, lpTempFileName: PChar;
  488. begin
  489.   Result := '';
  490.   lpPathName := nil;
  491.   lpTempFileName := nil;
  492.   // first get the length of the tempory path
  493.   nBufferLength := GetTempPath( 0, lpPathName );
  494.   Win32Check( BOOL( nBufferLength ) );
  495.   // Allocate a buffer of the specified length + 1
  496.   lpPathName := AllocMem( nBufferLength );
  497.   try
  498.     // Get the tempory path
  499.     Win32Check( BOOL( GetTempPath( nBufferLength, lpPathName ) ) );
  500.     // Increase the tempory path to hold the file name also.
  501.     lpTempFileName := AllocMem( 256 );
  502.     try
  503.       // Get the temporary file name
  504.       Win32Check( BOOL( GetTempFileName( lpPathName, PChar( 'Buf' ), 0, lpTempFileName ) ) );
  505.       // return the file name and path
  506.       SetString( Result, lpTempFileName, StrLen( lpTempFileName ) );
  507.       // Lastly free the buffers.
  508.     finally
  509.       FreeMem( lpPathName );
  510.     end;
  511.   finally
  512.     FreeMem( lpTempFileName );
  513.   end;
  514.   if Result = '' then
  515.     raise Exception.Create( 'Can''t create a temporary file' );
  516. end;
  517. }
  518. {*******************************************************************************************
  519. SendAttachments - Sends attachched file to server.
  520. ********************************************************************************************}
  521. procedure TNMSMTP.SendAttachments;
  522. var
  523.   UUPROC: TNMUUProcessor;
  524.   Tstr: string;
  525.   //  SFileS: TFileStream;
  526.   SfileF: TFileStream;
  527. begin
  528.   Tstr := '--' + FBoundary + CRLF;
  529.   Tstr := Tstr + Cons_Head_appl + ExtractFileName(FPostMessage.FAttachments[i - 1]) + '"' + CRLF;
  530.   Tstr := Tstr + Cons_Head_ba64 + CRLF;
  531.   Tstr := Tstr + Cons_Head_disp + ExtractFileName(FPostMessage.FAttachments[i - 1]) + '"';
  532.   Tstr := Tstr + CRLF + CRLF;
  533.   FSendFile.Write(Tstr[1], Length(Tstr));
  534.   //SfileS := nil;
  535.   UUPROC := nil;
  536.   try
  537.     UUPROC := TNMUUProcessor.Create(self);
  538.     //    Tstr := CreateTemporaryFileName;
  539.     //    SFileS := TFileStream.create(Tstr, fmCreate);
  540.     UUPROC.method := EncodeType;
  541.     SfileF := TFileStream.Create(FPostMessage.FAttachments[i - 1], fmOpenRead);
  542.     UUPROC.InPutStream := SfileF;
  543.     UUPROC.OutPutStream := FSendFile;
  544.     //    uuproc.OutPutStream := SFileS;
  545.     if Assigned(OnEncodeStart) then
  546.       OnEncodeStart(FPostMessage.FAttachments[i - 1]);
  547.     try
  548.       UUPROC.encode;
  549.     except
  550.       on E: EFOpenError do
  551.       begin
  552.         if Assigned(OnAttachmentNotFound) then
  553.           OnAttachmentNotFound(FPostMessage.FAttachments[i - 1]);
  554.         raise;
  555.       end;
  556.     end;
  557.     if Assigned(OnEncodeEnd) then
  558.       OnEncodeEnd(FPostMessage.FAttachments[i - 1]);
  559.     try
  560.       //SFileS.position := 0;
  561.       //FSendFile.CopyFrom(SFileS, SFileS.size);
  562.     finally
  563.       //SFileA.Free;
  564.       SfileF.free;
  565.     end;
  566.   finally
  567.     //SysUtils.DeleteFile( Tstr );
  568.     FSendFile.Position := FSendFile.Size;
  569.     Tstr := CRLF;
  570.     FSendFile.Write(Tstr[1], Length(Tstr));
  571.     //SfileS.Free;
  572.     UUPROC.free
  573.   end;
  574. end;
  575. {*******************************************************************************************
  576. Process Extra Lines in Transaction
  577. ********************************************************************************************}
  578. procedure TNMSMTP.ReadExtraLines;
  579. begin
  580.   while (ReplyMess[1] = ' ') or (ReplyMess[4] = '-') do {If extra Lines}
  581.     ReplyMess := Readln;
  582. end;
  583. {*******************************************************************************************
  584. Verify
  585. ********************************************************************************************}
  586. function TNMSMTP.Verify(UserName: string): boolean;
  587. var
  588.   ReplyMess: string;
  589. begin
  590.   CertifyConnect;
  591.   ReplyMess := Transaction(Cons_Vrfy + UserName);
  592.   if ReplyNumber > 251 then Result := FALSE else Result := TRUE;
  593. end;
  594. {*******************************************************************************************
  595. Aborts a transaction
  596. ********************************************************************************************}
  597. procedure TNMSMTP.Abort;
  598. begin
  599.   inherited Abort;
  600.   (*if (not BeenCanceled) and Connected then
  601.   begin
  602.      if FTransactionInProgress then
  603.      begin
  604.         Cancel;
  605.      end
  606.      else
  607.      begin
  608.         inherited Disconnect;
  609.         TMemoryStream(FIstream).clear;
  610.      end;
  611.   end;    *)
  612. end;
  613. procedure TNMSMTP.AbortResume(Sender: TObject);
  614. begin
  615.   inherited Disconnect;
  616.   ClearInput;
  617. end;
  618. {*******************************************************************************************
  619. Aborts a transaction
  620. ********************************************************************************************}
  621. function TNMSMTP.ExpandList(MailList: string): boolean;
  622. var
  623.   ReplyMess: string;
  624. begin
  625.   Result := FALSE;
  626.   if not FTransactionInProgress then
  627.   begin
  628.     FTransactionInProgress := TRUE;
  629.     try
  630.       CertifyConnect;
  631.       ReplyMess := Transaction(Cons_Expn + MailList);
  632.       if ReplyNumber > 399 then
  633.         Result := FALSE
  634.       else
  635.       begin
  636.         Result := TRUE;
  637.         if Assigned(OnMailListReturn) then
  638.           OnMailListReturn(ReplyMess);
  639.         ReadExtraLines(ReplyMess);
  640.       end;
  641.     finally
  642.       FTransactionInProgress := TRUE;
  643.     end;
  644.   end;
  645. end;
  646. {*******************************************************************************************
  647. Aborts a transaction
  648. ********************************************************************************************}
  649. function TNMSMTP.ExtractAddress(TotalAddress: string): string;
  650. begin
  651.   if Pos('<', TotalAddress) > 0 then
  652.     Result := NthWord(NthWord(TotalAddress, '<', 2), '>', 1)
  653.   else if Pos(':', TotalAddress) > 0 then
  654.     Result := NthWord(TotalAddress, ':', 2)
  655.   else
  656.     Result := TotalAddress;
  657. end;
  658. procedure TNMSMTP.SetFinalHeader(Value: TExStringList);
  659. begin
  660.   FFinalHeader.assign(Value);
  661. end;
  662. {*******************************************************************************************
  663. Constructor - Create String Lists to hold body, attachment list and distribution lists.
  664. Sets Default port and clears Transaction in Progress flag.
  665. ********************************************************************************************}
  666. constructor TPostMessage.Create;
  667. begin
  668.   inherited Create;
  669.   FTo := TStringList.Create;
  670.   FCC := TStringList.Create;
  671.   FBCC := TStringList.Create;
  672.   FBody := TStringList.Create;
  673.   FAttachments := TStringList.Create;
  674. end;
  675. {*******************************************************************************************
  676. Constructor - Destroys String Lists holding body, attachment list and distribution lists.
  677. ********************************************************************************************}
  678. destructor TPostMessage.Destroy;
  679. begin
  680.   FTo.free;
  681.   FCC.free;
  682.   FBCC.free;
  683.   FAttachments.free;
  684.   FBody.free;
  685.   inherited Destroy;
  686. end;
  687. {*******************************************************************************************
  688. ClearParameters - Clears distribution lists and Attachments.
  689. ********************************************************************************************}
  690. procedure TNMSMTP.ClearParameters;
  691. begin
  692.   FPostMessage.FTo.clear;
  693.   FPostMessage.FCC.clear;
  694.   FPostMessage.FBCC.clear;
  695.   FPostMessage.FAttachments.clear;
  696. end;
  697. {*******************************************************************************************
  698. Aborts a transaction
  699. ********************************************************************************************}
  700. procedure TPostMessage.SetLinesTo(Value: TStringList);
  701. begin
  702.   FTo.assign(Value);
  703. end;
  704. {*******************************************************************************************
  705. Aborts a transaction
  706. ********************************************************************************************}
  707. procedure TPostMessage.SetLinesCC(Value: TStringList);
  708. begin
  709.   FCC.assign(Value);
  710. end;
  711. {*******************************************************************************************
  712. Aborts a transaction
  713. ********************************************************************************************}
  714. procedure TPostMessage.SetLinesBCC(Value: TStringList);
  715. begin
  716.   FBCC.assign(Value);
  717. end;
  718. {*******************************************************************************************
  719. Aborts a transaction
  720. ********************************************************************************************}
  721. procedure TPostMessage.SetLinesBody(Value: TStringList);
  722. begin
  723.   FBody.assign(Value);
  724. end;
  725. {*******************************************************************************************
  726. Aborts a transaction
  727. ********************************************************************************************}
  728. procedure TPostMessage.SetLinesAttachments(Value: TStringList);
  729. begin
  730.   FAttachments.assign(Value);
  731. end;
  732. end.