IdReplySMTP.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. {
  2. $Project$
  3. $Workfile$
  4. $Revision$
  5. $DateUTC$
  6. $Id$
  7. This file is part of the Indy (Internet Direct) project, and is offered
  8. under the dual-licensing agreement described on the Indy website.
  9. (http://www.indyproject.org/)
  10. Copyright:
  11. (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
  12. }
  13. {
  14. $Log$
  15. }
  16. {
  17. Rev 1.24 10/26/2004 10:39:54 PM JPMugaas
  18. Updated refs.
  19. Rev 1.23 10/4/2004 3:16:44 PM BGooijen
  20. Added constructor
  21. Rev 1.22 8/3/2004 11:49:56 AM JPMugaas
  22. Fix for issue where 2.0.0 was always being set even if it should not have
  23. been set.
  24. Rev 1.21 7/27/2004 7:18:20 PM JPMugaas
  25. Fixed the TIdReplySMTP object as per Bas's suggestion. He told me that we
  26. were overriding the wrong object.
  27. I also fixed the Assign so it will work properly.
  28. Rev 1.20 7/24/04 1:04:48 PM RLebeau
  29. Bug fix for TIdReplySMTP.AssignTo(). The logic was backwards
  30. Rev 1.19 5/31/04 12:47:02 PM RLebeau
  31. Bug fixes for TIdSMTPEnhancedCode.AssignTo() and TIdReplySMTP.AssignTo()
  32. Rev 1.18 5/18/04 2:39:52 PM RLebeau
  33. Changed TIdRepliesSMTP constructor back to using 'override'
  34. Rev 1.17 5/18/04 11:21:54 AM RLebeau
  35. Changed TIdRepliesSMTP constructor to use 'reintroduce' instead
  36. Rev 1.16 5/16/04 5:27:32 PM RLebeau
  37. Added TIdRepliesSMTP class
  38. Rev 1.15 2004.02.03 5:45:44 PM czhower
  39. Name changes
  40. Rev 1.14 2004.01.29 12:07:54 AM czhower
  41. .Net constructor problem fix.
  42. Rev 1.13 2004.01.23 10:09:54 PM czhower
  43. REmoved unneded check because of CharIsInSet functinoalty. Also was a short
  44. circuit which is not permitted.
  45. Rev 1.12 1/22/2004 4:23:02 PM JPMugaas
  46. Undid a set change that didn't work.
  47. Rev 1.11 1/22/2004 4:51:40 PM SPerry
  48. fixed set problems
  49. Rev 1.10 1/3/2004 8:05:54 PM JPMugaas
  50. Bug fix: Sometimes, replies will appear twice due to the way functionality
  51. was enherited.
  52. Rev 1.9 2003.10.18 9:42:14 PM czhower
  53. Boatload of bug fixes to command handlers.
  54. Rev 1.8 10/17/2003 12:58:54 AM DSiders
  55. Added localization comments.
  56. Rev 1.7 2003.09.20 10:38:42 AM czhower
  57. Bug fix to allow clearing code field (Return to default value)
  58. Rev 1.6 6/5/2003 04:54:24 AM JPMugaas
  59. Reworkings and minor changes for new Reply exception framework.
  60. Rev 1.5 5/30/2003 8:46:28 PM BGooijen
  61. Rev 1.4 5/26/2003 12:22:08 PM JPMugaas
  62. Rev 1.3 5/25/2003 03:45:16 AM JPMugaas
  63. Rev 1.2 5/25/2003 02:46:16 AM JPMugaas
  64. Rev 1.1 5/23/2003 04:52:30 AM JPMugaas
  65. Work started on TIdDirectSMTP to support enhanced error codes.
  66. Rev 1.0 5/22/2003 05:24:52 PM JPMugaas
  67. RFC 2034 descendant of TIdRFCReply for IdSMTP. This also includes some
  68. extended error code constants.
  69. }
  70. unit IdReplySMTP;
  71. interface
  72. {$i IdCompilerDefines.inc}
  73. uses
  74. Classes,
  75. IdGlobal,
  76. IdException,
  77. IdReply,
  78. IdReplyRFC;
  79. const
  80. ValidClassChars = '245';
  81. ValidClassVals = [2,4,5];
  82. CLASS_DEF = 2;
  83. AVAIL_DEF = False;
  84. NODETAILS = 0;
  85. PARTSEP = '.';
  86. type
  87. TIdSMTPEnhancedCode = class(TPersistent)
  88. protected
  89. FStatusClass : UInt32;
  90. FSubject : UInt32;
  91. FDetails : UInt32;
  92. FAvailable : Boolean;
  93. procedure AssignTo(ADest: TPersistent); override;
  94. function IsValidReplyCode(const AText : String) : Boolean;
  95. function GetReplyAsStr : String;
  96. procedure SetReplyAsStr(const AText : String);
  97. procedure SetStatusClass(const AValue: UInt32);
  98. procedure SetAvailable(const AValue: Boolean);
  99. public
  100. constructor Create;
  101. procedure Clear;
  102. published
  103. property StatusClass : UInt32 read FStatusClass write SetStatusClass default CLASS_DEF;
  104. property Subject : UInt32 read FSubject write FSubject default NODETAILS;
  105. property Details : UInt32 read FDetails write FDetails default NODETAILS;
  106. property Available : Boolean read FAvailable write SetAvailable default AVAIL_DEF;
  107. property ReplyAsStr : String read GetReplyAsStr write SetReplyAsStr;
  108. end;
  109. TIdReplySMTP = class(TIdReplyRFC)
  110. protected
  111. FEnhancedCode : TIdSMTPEnhancedCode;
  112. procedure AssignTo(ADest: TPersistent); override;
  113. procedure SetEnhancedCode(AValue : TIdSMTPEnhancedCode);
  114. function GetFormattedReply: TStrings; override;
  115. procedure SetFormattedReply(const AValue: TStrings); override;
  116. public
  117. constructor Create(ACollection: TCollection); overload; override;
  118. constructor CreateWithReplyTexts(ACollection: TCollection; AReplyTexts: TIdReplies); overload; override;
  119. destructor Destroy; override;
  120. procedure Clear; override;
  121. procedure RaiseReplyError; override;
  122. procedure SetEnhReply(const ANumericCode : Integer; const AEnhReply, AText : String);
  123. published
  124. property EnhancedCode : TIdSMTPEnhancedCode read FEnhancedCode write SetEnhancedCode;
  125. end;
  126. TIdRepliesSMTP = class(TIdRepliesRFC)
  127. public
  128. constructor Create(AOwner: TPersistent); override;
  129. end;
  130. //note that this is here so we don't have to put this unit in an implementaiton clause
  131. //and both TIdSMTP and TIdDirectSMTP share this.
  132. EIdSMTPReplyError = class(EIdReplyRFCError)
  133. protected
  134. FEnhancedCode : TIdSMTPEnhancedCode;
  135. public
  136. constructor CreateError(const AErrCode: Integer;
  137. AEnhanced : TIdSMTPEnhancedCode;
  138. const AReplyMessage: string); reintroduce;
  139. destructor Destroy; override;
  140. property EnhancedCode : TIdSMTPEnhancedCode read FEnhancedCode;
  141. end;
  142. type
  143. EIdSMTPReply = class(EIdException);
  144. EIdSMTPReplyInvalidReplyString = class(EIdSMTPReply);
  145. EIdSMTPReplyInvalidClass = class(EIdSMTPReply);
  146. //suggested extended replies
  147. const
  148. //{ From RFC 3463 Enhanced Mail System Status Codes
  149. Id_EHR_USE_STARTTLS = '5.7.0'; //required by RFC 2487 {do not localize}
  150. //X.0.0 Other undefined Status
  151. Id_EHR_GENERIC_OK = '2.0.0'; {do not localize}
  152. Id_EHR_GENERIC_TRANS = '4.0.0'; {do not localize}
  153. Id_EHR_GENERIC_PERM = '5.0.0'; {do not localize}
  154. //X.1.0 Other address status
  155. Id_EHR_MSG_OTH_OK = '2.1.0'; {do not localize}
  156. Id_EHR_MSG_OTH_TRANS = '4.1.0'; {do not localize}
  157. Id_EHR_MSG_OTH_PERM = '5.1.0'; {do not localize}
  158. //X.1.1 Bad destination mailbox address
  159. Id_EHR_MSG_BAD_DEST = '5.1.1'; {do not localize}
  160. //X.1.2 Bad destination system address
  161. Id_EHR_MSG_BAD_DEST_SYST = '5.1.2'; {do not localize}
  162. //X.1.3 Bad destination mailbox address syntax
  163. Id_EHR_MSG_BAD_DEST_SYNTAX = '5.1.3'; {do not localize}
  164. //X.1.4 Destination mailbox address ambiguous
  165. Id_EHR_MSG_AMBIG_DEST = '5.1.4'; {do not localize}
  166. //X.1.5 Destination address valid
  167. Id_EHR_MSG_VALID_DEST = '2.1.5'; {do not localize}
  168. //X.1.6 Destination mailbox has moved, No forwarding address
  169. Id_EHR_MSG_DEST_MOVED_NOFORWARD = '2.1.6'; {do not localize}
  170. //X.1.7 Bad sender’s mailbox address syntax
  171. Id_EHR_MSG_SENDER_BOX_SYNTAX = '5.1.7'; {do not localize}
  172. //X.1.8 Bad sender’s system address
  173. Id_EHR_MSG_BAD_SENDER_ADDR = '5.1.8'; {do not localize}
  174. //X.2.0 Other or undefined mailbox status
  175. Id_EHR_MB_OTHER_STATUS_OK = '2.2.0'; {do not localize}
  176. Id_EHR_MB_OTHER_STATUS_TRANS = '4.2.0'; {do not localize}
  177. Id_EHR_MB_OTHER_STATUS_PERM = '5.2.0'; {do not localize}
  178. //X.2.1 Mailbox disabled, not accepting messages
  179. Id_EHR_MB_DISABLED_TEMP = '4.2.1'; {do not localize}
  180. Id_EHR_MB_DISABLED_PERM = '5.2.1'; {do not localize}
  181. //X.2.2 Mailbox full - user can probably delete some messages to make more room
  182. Id_EHR_MB_FULL = '4.2.2'; {do not localize}
  183. //X.2.3 Message length exceeds administrative limit - probably can not be fixed by a user deleting messages
  184. Id_EHR_MB_MSG_LEN_LIMIT = '5.2.3'; {do not localize}
  185. //X.2.4 Mailing list expansion problem
  186. Id_EHR_MB_ML_EXPAN_TEMP = '4.2.4'; {do not localize}
  187. Id_EHR_MB_ML_EXPAN_PERM = '5.2.4'; {do not localize}
  188. //X.3.0 Other or undefined mail system status
  189. Id_EHR_MD_OTHER_OK = '2.3.0'; {do not localize}
  190. Id_EHR_MD_OTHER_TRANS = '4.3.0'; {do not localize}
  191. Id_EHR_MD_OTHER_PERM = '5.3.0'; {do not localize}
  192. //X.3.1 Mail system full
  193. Id_EHR_MD_MAIL_SYSTEM_FULL = '4.3.1'; {do not localize}
  194. //X.3.2 System not accepting network messages
  195. Id_EHR_MD_NOT_EXCEPTING_TRANS = '4.3.2'; {do not localize}
  196. Id_EHR_MD_NOT_EXCEPTING_PERM = '5.3.2'; {do not localize}
  197. //X.3.3 System not capable of selected features
  198. Id_EHR_MD_NOT_CAPABLE_FEAT_TRANS = '4.3.3'; {do not localize}
  199. Id_EHR_MD_NOT_CAPABLE_FEAT_PERM = '5.3.3'; {do not localize}
  200. //X.3.4 Message too big for system
  201. Id_EHR_MD_TOO_BIG = '5.3.4'; {do not localize}
  202. //X.3.5 System incorrectly configured
  203. Id_EHR_MD_INCORRECT_CONFIG_TRANS = '4.3.5'; {do not localize}
  204. Id_EHR_MD_INCORRECT_CONFIG_PERM = '5.3.5'; {do not localize}
  205. //X.4.0 Other or undefined network or routing status
  206. Id_EHR_NR_OTHER_OK = '2.4.0'; {do not localize}
  207. Id_EHR_NR_OTHER_TRANS = '4.4.0'; {do not localize}
  208. Id_EHR_NR_OTHER_PERM = '5.4.0'; {do not localize}
  209. //X.4.1 No answer from host
  210. Id_EHR_NR_NO_ANSWER = '4.4.1'; {do not localize}
  211. //X.4.2 Bad connection
  212. Id_EHR_NR_BAD_CONNECTION = '4.4.2'; {do not localize}
  213. //X.4.3 Directory server failure
  214. Id_EHR_NR_DIR_SVR_FAILURE = '4.4.3'; {do not localize}
  215. //X.4.4 Unable to route
  216. Id_EHR_NR_UNABLE_TO_ROUTE_TRANS = '4.4.4'; {do not localize}
  217. Id_EHR_NR_UNABLE_TO_ROUTE_PERM = '5.4.4'; {do not localize}
  218. //X.4.5 Mail system congestion
  219. Id_EHR_NR_SYSTEM_CONGESTION = '4.4.5'; {do not localize}
  220. //X.4.6 Routing loop detected
  221. Id_EHR_NR_LOOP_DETECTED = '4.4.6'; {do not localize}
  222. //X.4.7 Delivery time expired
  223. Id_EHR_NR_DELIVERY_EXPIRED_TEMP = '4.4.7'; {do not localize}
  224. Id_EHR_NR_DELIVERY_EXPIRED_PERM = '5.4.7'; {do not localize}
  225. //X.5.0 Other or undefined protocol status
  226. Id_EHR_PR_OTHER_OK = '2.5.0'; {do not localize}
  227. Id_EHR_PR_OTHER_TEMP = '4.5.0'; {do not localize}
  228. Id_EHR_PR_OTHER_PERM = '5.5.0'; {do not localize}
  229. //X.5.1 Invalid command
  230. Id_EHR_PR_INVALID_CMD = '5.5.1'; {do not localize}
  231. //X.5.2 Syntax error
  232. Id_EHR_PR_SYNTAX_ERR = '5.5.2'; {do not localize}
  233. //X.5.3 Too many recipients - note that this is given if segmentation isn't possible
  234. Id_EHR_PR_TOO_MANY_RECIPIENTS_TEMP = '4.5.3'; {do not localize}
  235. Id_EHR_PR_TOO_MANY_RECIPIENTS_PERM = '5.5.3'; {do not localize}
  236. //X.5.4 Invalid command arguments
  237. Id_EHR_PR_INVALID_CMD_ARGS = '5.5.4'; {do not localize}
  238. //X.5.5 Wrong protocol version
  239. Id_EHR_PR_WRONG_VER_TRANS = '4.5.5'; {do not localize}
  240. Id_EHR_PR_WRONG_VER_PERM = '5.5.5'; {do not localize}
  241. //X.6.0 Other or undefined media error
  242. Id_EHR_MED_OTHER_OK = '2.6.0'; {do not localize}
  243. Id_EHR_MED_OTHER_TRANS = '4.6.0'; {do not localize}
  244. Id_EHR_MED_OTHER_PERM = '5.6.0'; {do not localize}
  245. //X.6.1 Media not supported
  246. Id_EHR_MED_NOT_SUPPORTED = '5.6.1'; {do not localize}
  247. //6.2 Conversion required and prohibited
  248. Id_EHR_MED_CONV_REQUIRED_PROHIB_TRANS = '4.6.2'; {do not localize}
  249. Id_EHR_MED_CONV_REQUIRED_PROHIB_PERM = '5.6.2'; {do not localize}
  250. //X.6.3 Conversion required but not supported
  251. Id_EHR_MED_CONV_REQUIRED_NOT_SUP_TRANS = '4.6.3'; {do not localize}
  252. Id_EHR_MED_CONV_REQUIRED_NOT_SUP_PERM = '5.6.3'; {do not localize}
  253. //X.6.4 Conversion with loss performed
  254. Id_EHR_MED_CONV_LOSS_WARNING = '2.6.4'; {do not localize}
  255. Id_EHR_MED_CONV_LOSS_ERROR = '5.6.4'; {do not localize}
  256. //X.6.5 Conversion Failed
  257. Id_EHR_MED_CONV_FAILED_TRANS = '4.6.5'; {do not localize}
  258. Id_EHR_MED_CONV_FAILED_PERM = '5.6.5'; {do not localize}
  259. //X.7.0 Other or undefined security status
  260. Id_EHR_SEC_OTHER_OK = '2.7.0'; {do not localize}
  261. Id_EHR_SEC_OTHER_TRANS = '4.7.0'; {do not localize}
  262. Id_EHR_SEC_OTHER_PERM = '5.7.0'; {do not localize}
  263. //X.7.1 Delivery not authorized, message refused
  264. Id_EHR_SEC_DEL_NOT_AUTH = '5.7.1'; {do not localize}
  265. //X.7.2 Mailing list expansion prohibited
  266. Id_EHR_SEC_EXP_NOT_AUTH = '5.7.2'; {do not localize}
  267. //X.7.3 Security conversion required but not possible
  268. Id_EHR_SEC_CONV_REQ_NOT_POSSIBLE = '5.7.3'; {do not localize}
  269. //X.7.4 Security features not supported
  270. Id_EHR_SEC_NOT_SUPPORTED = '5.7.4'; {do not localize}
  271. //X.7.5 Cryptographic failure
  272. Id_EHR_SEC_CRYPT_FAILURE_TRANS = '4.7.5'; {do not localize}
  273. Id_EHR_SEC_CRYPT_FAILURE_PERM = '5.7.5'; {do not localize}
  274. //X.7.6 Cryptographic algorithm not supported
  275. Id_EHR_SEC_CRYPT_ALG_NOT_SUP_TRANS = '4.7.6'; {do not localize}
  276. Id_EHR_SEC_CRYPT_ALG_NOT_SUP_PERM = '5.7.6'; {do not localize}
  277. //X.7.7 Message integrity failure
  278. Id_EHR_SEC_INTEGRETIY_FAILED_WARN = '2.7.7'; {do not localize}
  279. Id_EHR_SEC_INTEGRETIY_FAILED_TRANS = '4.7.7'; {do not localize}
  280. implementation
  281. uses
  282. IdGlobalProtocols, IdResourceStringsProtocols, SysUtils;
  283. { TIdSMTPEnhancedCode }
  284. procedure TIdSMTPEnhancedCode.AssignTo(ADest: TPersistent);
  285. var
  286. LE : TIdSMTPEnhancedCode;
  287. begin
  288. if ADest is TIdSMTPEnhancedCode then
  289. begin
  290. LE := TIdSMTPEnhancedCode(ADest);
  291. LE.StatusClass := FStatusClass;
  292. LE.Subject := FSubject;
  293. LE.Details := FDetails;
  294. LE.Available := FAvailable;
  295. end else begin
  296. inherited AssignTo(ADest);
  297. end;
  298. end;
  299. constructor TIdSMTPEnhancedCode.Create;
  300. begin
  301. inherited Create;
  302. Clear;
  303. end;
  304. procedure TIdSMTPEnhancedCode.Clear;
  305. begin
  306. FStatusClass := CLASS_DEF;
  307. FSubject := NODETAILS;
  308. FDetails := NODETAILS;
  309. FAvailable := AVAIL_DEF;
  310. end;
  311. function TIdSMTPEnhancedCode.GetReplyAsStr: String;
  312. begin
  313. Result := '';
  314. if Available then begin
  315. Result := Copy(IntToStr(FStatusClass),1,1)+PARTSEP+
  316. Copy(IntToStr(FSubject),1,3)+PARTSEP+
  317. Copy(IntToStr(FDetails),1,3);
  318. end;
  319. end;
  320. function TIdSMTPEnhancedCode.IsValidReplyCode(const AText: String): Boolean;
  321. var
  322. LTmp, LBuf, LValidPart : String;
  323. begin
  324. Result := (Trim(AText) = '');
  325. if not Result then begin
  326. LTmp := AText;
  327. LBuf := Fetch(LTmp);
  328. //class
  329. LValidPart := Fetch(LBuf,PARTSEP);
  330. if CharIsInSet(LValidPart, 1, ValidClassChars) then begin
  331. //subject
  332. LValidPart := Fetch(LBuf,PARTSEP);
  333. if (LValidPart<>'') and IsNumeric(LValidPart) then begin
  334. //details
  335. Result := (LBuf<>'') and IsNumeric(LBuf);
  336. end;
  337. end;
  338. end;
  339. end;
  340. procedure TIdSMTPEnhancedCode.SetAvailable(const AValue: Boolean);
  341. begin
  342. if FAvailable <> AValue then
  343. begin
  344. FAvailable := AValue;
  345. if not AValue then
  346. begin
  347. FStatusClass := CLASS_DEF;
  348. FSubject := NODETAILS;
  349. FDetails := NODETAILS;
  350. end;
  351. end;
  352. end;
  353. procedure TIdSMTPEnhancedCode.SetReplyAsStr(const AText: String);
  354. var
  355. LTmp, LBuf: string;
  356. LValidPart: string;
  357. begin
  358. if not IsValidReplyCode(AText) then begin
  359. raise EIdSMTPReplyInvalidReplyString.Create(RSSMTPReplyInvalidReplyStr);
  360. end;
  361. LTmp := AText;
  362. LBuf := Fetch(LTmp);
  363. if LBuf <> '' then begin
  364. //class
  365. LValidPart := Fetch(LBuf, PARTSEP);
  366. FStatusClass := IndyStrToInt(LValidPart, 0);
  367. //subject
  368. LValidPart := Fetch(LBuf, PARTSEP);
  369. FSubject := IndyStrToInt(LValidPart,0);
  370. //details
  371. FDetails := IndyStrToInt(LBuf,0);
  372. FAvailable := True;
  373. end else begin
  374. FAvailable := False;
  375. end;
  376. end;
  377. procedure TIdSMTPEnhancedCode.SetStatusClass(const AValue: UInt32);
  378. begin
  379. if not (AValue in ValidClassVals) then begin
  380. raise EIdSMTPReplyInvalidClass.Create(RSSMTPReplyInvalidClass);
  381. end;
  382. FStatusClass := AValue;
  383. end;
  384. { TIdReplySMTP }
  385. procedure TIdReplySMTP.AssignTo(ADest: TPersistent);
  386. var
  387. LS : TIdReplySMTP;
  388. begin
  389. if ADest is TIdReplySMTP then begin
  390. LS := TIdReplySMTP(ADest);
  391. //set code first as it possibly clears the reply
  392. LS.Code := Code;
  393. LS.EnhancedCode := EnhancedCode;
  394. LS.Text.Assign(Text);
  395. end else begin
  396. inherited AssignTo(ADest);
  397. end;
  398. end;
  399. procedure TIdReplySMTP.Clear;
  400. begin
  401. inherited Clear;
  402. FEnhancedCode.Clear;
  403. end;
  404. constructor TIdReplySMTP.Create(ACollection: TCollection);
  405. begin
  406. inherited Create(ACollection);
  407. FEnhancedCode := TIdSMTPEnhancedCode.Create;
  408. end;
  409. constructor TIdReplySMTP.CreateWithReplyTexts(ACollection: TCollection; AReplyTexts: TIdReplies);
  410. begin
  411. inherited CreateWithReplyTexts(ACollection, AReplyTexts);
  412. FEnhancedCode := TIdSMTPEnhancedCode.Create;
  413. end;
  414. destructor TIdReplySMTP.Destroy;
  415. begin
  416. FreeAndNil(FEnhancedCode);
  417. inherited;
  418. end;
  419. function TIdReplySMTP.GetFormattedReply: TStrings;
  420. var
  421. i: Integer;
  422. LCode: String;
  423. begin
  424. Result := GetFormattedReplyStrings;
  425. { JP here read from Items and format according to the reply, in this case RFC
  426. and put it into FFormattedReply }
  427. if NumericCode > 0 then begin
  428. LCode := IntToStr(NumericCode);
  429. if FText.Count > 0 then begin
  430. for i := 0 to FText.Count - 1 do begin
  431. if i < FText.Count - 1 then begin
  432. if EnhancedCode.Available then begin
  433. Result.Add(LCode + '-' + EnhancedCode.ReplyAsStr + ' ' + FText[i]);
  434. end else begin
  435. Result.Add(LCode + '-' + FText[i]);
  436. end;
  437. end else begin
  438. if EnhancedCode.Available then begin
  439. Result.Add(LCode + ' ' + EnhancedCode.ReplyAsStr + ' ' + FText[i]);
  440. end else begin
  441. Result.Add(LCode + ' ' + FText[i]);
  442. end;
  443. end;
  444. end;
  445. end else begin
  446. if EnhancedCode.Available then begin
  447. Result.Add(LCode + ' ' + EnhancedCode.ReplyAsStr);
  448. end else begin
  449. Result.Add(LCode);
  450. end;
  451. end;
  452. end else if FText.Count > 0 then begin
  453. Result.AddStrings(FText);
  454. end;
  455. end;
  456. procedure TIdReplySMTP.RaiseReplyError;
  457. begin
  458. raise EIdSMTPReplyError.CreateError(NumericCode, FEnhancedCode, Text.Text);
  459. end;
  460. procedure TIdReplySMTP.SetEnhancedCode(AValue: TIdSMTPEnhancedCode);
  461. begin
  462. FEnhancedCode.Assign(AValue);
  463. end;
  464. procedure TIdReplySMTP.SetEnhReply(const ANumericCode: Integer;
  465. const AEnhReply, AText: String);
  466. begin
  467. inherited SetReply(ANumericCode, AText);
  468. FEnhancedCode.ReplyAsStr := AEnhReply;
  469. end;
  470. procedure TIdReplySMTP.SetFormattedReply(const AValue: TStrings);
  471. { in here just parse and put in items, no need to store after parse }
  472. var
  473. i: Integer;
  474. s: string;
  475. begin
  476. Clear;
  477. if AValue.Count > 0 then begin
  478. // Get 4 chars - for POP3
  479. s := Trim(Copy(AValue[0], 1, 4));
  480. if Length(s) = 4 then begin
  481. if s[4] = '-' then begin
  482. SetLength(s, 3);
  483. end;
  484. end;
  485. Code := s;
  486. for i := 0 to AValue.Count - 1 do begin
  487. s := Copy(AValue[i], 5, MaxInt);
  488. if FEnhancedCode.IsValidReplyCode(s) then begin
  489. FEnhancedCode.ReplyAsStr := Fetch(s);
  490. end;
  491. Text.Add(s);
  492. end;
  493. end;
  494. end;
  495. { TIdRepliesSMTP }
  496. constructor TIdRepliesSMTP.Create(AOwner: TPersistent);
  497. begin
  498. inherited Create(AOwner, TIdReplySMTP);
  499. end;
  500. { EIdSMTPReplyError }
  501. constructor EIdSMTPReplyError.CreateError(const AErrCode: Integer;
  502. AEnhanced: TIdSMTPEnhancedCode; const AReplyMessage: string);
  503. begin
  504. inherited CreateError(AErrCode,AReplyMessage);
  505. FEnhancedCode := TIdSMTPEnhancedCode.Create;
  506. FEnhancedCode.Assign(AEnhanced);
  507. end;
  508. destructor EIdSMTPReplyError.Destroy;
  509. begin
  510. FreeAndNil(FEnhancedCode);
  511. inherited Destroy;
  512. end;
  513. end.