PageRenderTime 44ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/ProSnooperFx_src/indy10.0.52_source/Protocols/IdIMAP4.pas

http://github.com/lookias/ProSnooper
Pascal | 6600 lines | 4687 code | 264 blank | 1649 comment | 708 complexity | ec27c6e2f5e54696e1225257f3a7e214 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. { $HDR$}
  2. {**********************************************************************}
  3. { Unit archived using Team Coherence }
  4. { Team Coherence is Copyright 2002 by Quality Software Components }
  5. { }
  6. { For further information / comments, visit our WEB site at }
  7. { http://www.TeamCoherence.com }
  8. {**********************************************************************}
  9. {}
  10. { $Log: 11627: IdIMAP4.pas
  11. {
  12. Rev 1.57 11/8/2004 8:39:00 AM DSiders
  13. Removed comment in TIdIMAP4.SearchMailBox implementation that caused DOM
  14. problem when locating the symbol id.
  15. }
  16. {
  17. { Rev 1.56 10/26/2004 10:19:58 PM JPMugaas
  18. { Updated refs.
  19. }
  20. {
  21. { Rev 1.55 2004.10.26 2:19:56 PM czhower
  22. { Resolved alias conflict.
  23. }
  24. {
  25. Rev 1.54 6/11/2004 9:36:34 AM DSiders
  26. Added "Do not Localize" comments.
  27. }
  28. {
  29. { Rev 1.53 6/4/04 12:48:12 PM RLebeau
  30. { ContentTransferEncoding bug fix
  31. }
  32. {
  33. { Rev 1.52 01/06/2004 19:03:46 CCostelloe
  34. { .NET bug fix
  35. }
  36. {
  37. { Rev 1.51 01/06/2004 01:16:18 CCostelloe
  38. { Various improvements
  39. }
  40. {
  41. { Rev 1.50 20/05/2004 22:04:14 CCostelloe
  42. { IdStreamVCL changes
  43. }
  44. {
  45. { Rev 1.49 20/05/2004 08:43:12 CCostelloe
  46. { IdStream change
  47. }
  48. {
  49. { Rev 1.48 16/05/2004 20:40:46 CCostelloe
  50. { New TIdText/TIdAttachment processing
  51. }
  52. {
  53. { Rev 1.47 24/04/2004 23:54:42 CCostelloe
  54. { IMAP-style UTF-7 encoding/decoding of mailbox names added
  55. }
  56. {
  57. { Rev 1.46 13/04/2004 22:24:28 CCostelloe
  58. { Bug fix (FCapabilities not created if not DOTNET)
  59. }
  60. {
  61. { Rev 1.45 3/18/2004 2:32:40 AM JPMugaas
  62. { Should compile under D8 properly.
  63. }
  64. {
  65. { Rev 1.44 3/8/2004 10:10:32 AM JPMugaas
  66. { IMAP4 should now have SASLMechanisms again. Those work in DotNET now.
  67. { SSL abstraction is now supported even in DotNET so that should not be
  68. { IFDEF'ed out.
  69. }
  70. {
  71. { Rev 1.43 07/03/2004 17:55:16 CCostelloe
  72. { Updates to cover changes in other units
  73. }
  74. {
  75. { Rev 1.42 2/4/2004 2:36:58 AM JPMugaas
  76. { Moved more units down to the implementation clause in the units to make them
  77. { easier to compile.
  78. }
  79. {
  80. { Rev 1.41 2/3/2004 4:12:50 PM JPMugaas
  81. { Fixed up units so they should compile.
  82. }
  83. {
  84. { Rev 1.40 2004.02.03 5:43:48 PM czhower
  85. { Name changes
  86. }
  87. {
  88. { Rev 1.39 2004.02.03 2:12:10 PM czhower
  89. { $I path change
  90. }
  91. {
  92. { Rev 1.38 1/27/2004 4:01:12 PM SPerry
  93. { StringStream ->IdStringStream
  94. }
  95. {
  96. { Rev 1.37 1/25/2004 3:11:12 PM JPMugaas
  97. { SASL Interface reworked to make it easier for developers to use.
  98. { SSL and SASL reenabled components.
  99. }
  100. {
  101. { Rev 1.36 23/01/2004 01:48:28 CCostelloe
  102. { Added BinHex4.0 encoding support for parts
  103. }
  104. {
  105. { Rev 1.35 1/21/2004 3:10:40 PM JPMugaas
  106. { InitComponent
  107. }
  108. {
  109. { Rev 1.34 31/12/2003 09:40:32 CCostelloe
  110. { ChangeReplyClass removed, replaced AnsiSameText with TextIsSame, stream code
  111. { not tested.
  112. }
  113. { Rev 1.33 28/12/2003 23:48:18 CCostelloe
  114. { More TEMPORARY fixes to get it to compile under D7 and D8 .NET
  115. }
  116. {
  117. { Rev 1.32 22/12/2003 01:20:20 CCostelloe
  118. { .NET fixes. This is a TEMPORARY combined Indy9/10/.NET master file.
  119. }
  120. {
  121. { Rev 1.31 14/12/2003 21:03:16 CCostelloe
  122. { First version for .NET
  123. }
  124. {
  125. { Rev 1.30 10/17/2003 12:11:06 AM DSiders
  126. { Added localization comments.
  127. { Added resource strings for exception messages.
  128. }
  129. {
  130. { Rev 1.29 2003.10.12 3:53:10 PM czhower
  131. { compile todos
  132. }
  133. {
  134. { Rev 1.28 10/12/2003 1:49:50 PM BGooijen
  135. { Changed comment of last checkin
  136. }
  137. {
  138. { Rev 1.27 10/12/2003 1:43:34 PM BGooijen
  139. { Changed IdCompilerDefines.inc to Core\IdCompilerDefines.inc
  140. }
  141. {
  142. { Rev 1.26 20/09/2003 15:38:38 CCostelloe
  143. { More patches added for different IMAP servers
  144. }
  145. {
  146. { Rev 1.25 12/08/2003 01:17:38 CCostelloe
  147. { Retrieve and AppendMsg updated to suit changes made to attachment encoding
  148. { changes in other units
  149. }
  150. {
  151. { Rev 1.24 21/07/2003 01:22:24 CCostelloe
  152. { Added CopyMsg and UIDCopyMsgs. (UID)Receive(Peek) rewritten. AppendMsg
  153. { still buggy with attachments. Public variable FGreetingBanner added. Added
  154. { "if Connected then " to Destroy. Attachment filenames now decoded if
  155. { necessary. Added support for multisection parts. Resolved issue of some
  156. { servers leaving out the trailing "NIL NIL NIL" at the end of some body
  157. { structures. UIDRetrieveAllHeaders removed
  158. }
  159. {
  160. { Rev 1.23 18/06/2003 21:53:36 CCostelloe
  161. { Rewrote GetResponse from scratch. Restored Capabilities for login. Compiles
  162. { and runs properly (may be a couple of minor bugs not yet discovered).
  163. }
  164. {
  165. { Rev 1.22 6/16/2003 11:48:18 PM JPMugaas
  166. { Capabilities has to be restored for SASL and SSL support.
  167. }
  168. {
  169. { Rev 1.21 17/06/2003 01:33:46 CCostelloe
  170. { Updated to support new LoginSASL. Compiles OK, may not yet run OK.
  171. }
  172. {
  173. { Rev 1.20 12/06/2003 10:17:54 CCostelloe
  174. { Partial update for Indy 10's new Reply structure. Compiles but does not run
  175. { correctly. Checked in to show problem with Get/SetNumericCode in IdReplyIMAP.
  176. }
  177. {
  178. { Rev 1.19 04/06/2003 02:33:44 CCostelloe
  179. { Compiles under Indy 10 with the revised Indy 10 structure, but does not yet
  180. { work properly due to some of the changes. Will be fixed by me in a later
  181. { check-in.
  182. }
  183. {
  184. { Rev 1.18 14/05/2003 01:55:50 CCostelloe
  185. { This version (with the extra IMAP functionality recently added) now compiles
  186. { on Indy 10 and works in a real application.
  187. }
  188. {
  189. { Rev 1.17 5/12/2003 02:19:56 AM JPMugaas
  190. { Now should work properly again. I also removed all warnings and errors in
  191. { Indy 10.
  192. }
  193. {
  194. { Rev 1.16 5/11/2003 07:35:44 PM JPMugaas
  195. }
  196. {
  197. { Rev 1.15 5/11/2003 07:11:06 PM JPMugaas
  198. { Fixed to eliminate some warnings and compile errors in Indy 10.
  199. }
  200. {
  201. { Rev 1.14 11/05/2003 23:53:52 CCostelloe
  202. { Bug fix due to Windows 98 / 2000 discrepancies
  203. }
  204. {
  205. { Rev 1.13 11/05/2003 23:08:36 CCostelloe
  206. { Lots more bug fixes, plus IMAP code moved up from IdRFCReply
  207. }
  208. {
  209. { Rev 1.12 5/10/2003 07:31:22 PM JPMugaas
  210. { Updated with some bug fixes and some cleanups.
  211. }
  212. {
  213. { Rev 1.11 5/9/2003 10:51:26 AM JPMugaas
  214. { Bug fixes. Now works as it should. Verified.
  215. }
  216. {
  217. { Rev 1.9 5/9/2003 03:49:44 AM JPMugaas
  218. { IMAP4 now supports SASL. Merged some code from Ciaran which handles the +
  219. { SASL continue reply in IMAP4 and makes a few improvements. Verified to work
  220. { on two servers.
  221. }
  222. {
  223. { Rev 1.8 5/8/2003 05:41:48 PM JPMugaas
  224. { Added constant for SASL continuation.
  225. }
  226. {
  227. { Rev 1.7 5/8/2003 03:17:50 PM JPMugaas
  228. { Flattened ou the SASL authentication API, made a custom descendant of SASL
  229. { enabled TIdMessageClient classes.
  230. }
  231. {
  232. { Rev 1.6 5/8/2003 11:27:52 AM JPMugaas
  233. { Moved feature negoation properties down to the ExplicitTLSClient level as
  234. { feature negotiation goes hand in hand with explicit TLS support.
  235. }
  236. {
  237. { Rev 1.5 5/8/2003 02:17:44 AM JPMugaas
  238. { Fixed an AV in IdPOP3 with SASL list on forms. Made exceptions for SASL
  239. { mechanisms missing more consistant, made IdPOP3 support feature feature
  240. { negotiation, and consolidated some duplicate code.
  241. }
  242. {
  243. { Rev 1.4 5/7/2003 10:20:32 PM JPMugaas
  244. }
  245. {
  246. { Rev 1.3 5/7/2003 04:35:30 AM JPMugaas
  247. { IMAP4 should now compile. Started on prelimary SSL support (not finished
  248. { yet).
  249. }
  250. {
  251. { Rev 1.2 15/04/2003 00:57:08 CCostelloe
  252. }
  253. {
  254. { Rev 1.1 2/24/2003 09:03:06 PM JPMugaas
  255. }
  256. {
  257. { Rev 1.0 11/13/2002 07:54:50 AM JPMugaas
  258. }
  259. unit IdIMAP4;
  260. {*
  261. IMAP 4 (Internet Message Access Protocol - Version 4 Rev 1)
  262. By Idan Cohen i_cohen@yahoo.com
  263. 2001-FEB-27 IC: First version most of the IMAP features are implemented and
  264. the core IdPOP3 features are implemented to allow a seamless
  265. switch.
  266. The unit is currently oriented to a session connection and not
  267. to constant connection, because of that server events that are
  268. raised from another user actions are not supported.
  269. 2001-APR-18 IC: Added support for the session's connection state with a
  270. special exception for commands preformed in wrong connection
  271. states. Exceptions were also added for response errors.
  272. 2001-MAY-05 IC:
  273. 2001-Mar-13 DS: Fixed Bug # 494813 in CheckMsgSeen where LastCmdResult.Text
  274. was not using the Ln index variable to access server
  275. responses.
  276. 2002-Apr-12 DS: fixed bug # 506026 in TIdIMAP4.ListSubscribedMailBoxes. Call
  277. ParseLSubResut instead of ParseListResult.
  278. 2003-Mar-31 CC: Added GetUID and UIDSearchMailBox, sorted out some bugs (details
  279. shown in comments in those functions which start with "CC:").
  280. 2003-Apr-15 CC2:Sorted out some more bugs (details shown in comments in those
  281. functions which start with "CC2:"). Set FMailBoxSeparator
  282. in ParseListResult and ParseLSubResult.
  283. Some IMAP servers generally return "OK completed" even if they
  284. returned no data, such as passing a non-existent message
  285. number to them: they possibly should return NO or BAD; the
  286. functions here have been changed to return FALSE unless they
  287. get good data back, even if the server answers OK. Similar
  288. change made for other functions.
  289. There are a few exceptions, e.g. ListMailBoxes may only return
  290. "OK completed" if the user has no mailboxes, these are noted.
  291. Also, RetrieveStructure(), UIDRetrieveStructure, RetrievePart,
  292. UIDRetrievePart, RetrievePartPeek and UIDRetrievePartPeek
  293. added to allow user to find the structure of a message and
  294. just retrieve the part or parts he needs.
  295. 2003-Apr-30 CC3:Added functionality to retrieve the text of a message (only)
  296. via RetrieveText / UIDRetrieveText / RetrieveTextPeek /
  297. UIDRetrieveTextPeek.
  298. Return codes now generally reflect if the function succeeded
  299. instead of returning True even though function fails.
  300. 2003-May-15 CC4:Added functionality to retrieve individual parts of a message
  301. to a file, including the decoding of those parts.
  302. 2003-May-29 CC5:Response of some servers to UID version of commands varies,
  303. code changed to deal with those (UID position varies).
  304. Some servers return NO such as when you request an envelope
  305. for a message number that does not exist: functions return
  306. False instead of throwing an exception, as was done for other
  307. servers. The general logic is that if a valid result is
  308. returned from the IMAP server, return True; if there is no
  309. result (but the command is validly structured), return FALSE;
  310. if the command is badly structured or if it gives a response
  311. that this code does not expect, throw an exception (typically
  312. when we get a BAD response instead of OK or NO).
  313. Added IsNumberValid, IsUIDValid to prevent rubbishy parameters
  314. being passed through to IMAP functions.
  315. Sender field now filled in correctly in ParseEnvelope
  316. functions.
  317. All fields in ParseEnvelopeAddress are cleared out first,
  318. avoids an unwitting error where some entries, such as CC list,
  319. will append entries to existing entries.
  320. Full test script now used that tests every TIdIMAP command,
  321. more bugs eradicated.
  322. First version to pass testing against both CommuniGate and
  323. Cyrus IMAP servers.
  324. Not tested against Microsoft Exchange, don't have an Exchange
  325. account to test it against.
  326. 2003-Jun-10 CC6:Added (UID)RetrieveEnvelopeRaw, in case the user wants to do
  327. their own envelope parsing.
  328. Code in RetrievePart altered to make it more consistent.
  329. Altered to incorporate Indy 10's use of IdReplyIMAP4 (not
  330. complete at this stage).
  331. ReceiveBody added to IdIMAP4, due to the response of some
  332. servers, which gets (UID)Receive(Peek) functions to work on
  333. more servers.
  334. 2003-Jun-20 CC7:ReceiveBody altered to work with Indy 10. Made changes due to
  335. LoginSASL moving from TIdMessageSASLClient to TIdSASLList.
  336. Public variable FGreetingBanner added to help user identify
  337. the IMAP server he is connected to (may help him decide the
  338. best strategy). Made AppendMsg work a bit better (now uses
  339. platform-independent EOL and supports ExtraHeaders field).
  340. Added 2nd version of AppendMsg. Added "if Connected then "
  341. to Destroy. Attachment filenames now decoded if necessary.
  342. Added support for multisection parts.
  343. 2003-Jul-16 CC8:Added RemoveAnyAdditionalResponses. Resolved issue of some
  344. servers leaving out the trailing "NIL NIL NIL" at the end of
  345. some body structures. (UID)Retrieve(Peek) functions
  346. integrated via InternalRetrieve, new method of implementing
  347. these functions (all variations of Retrieve) added for Indy
  348. 10 based on getting message by the byte-count and then feeding
  349. it into the standard message parser.
  350. UIDRetrieveAllHeaders removed: it was never implemented anyway
  351. but it makes no sense to retrieve a non-contiguous list which
  352. would have gaps due to missing UIDs.
  353. In the Indy 10 version, AppendMsg functions were altered to
  354. support the sending of attachments (attachments had never
  355. been supported in AppendMsg prior to this).
  356. Added CopyMsg and UIDCopyMsgs to complete the command set.
  357. 2003-Jul-30 CC9:Removed wDoublePoint so that the code is compliant with
  358. the guidelines. Allowed for servers that don't implement
  359. search commands in Indy 9 (OK in 10). InternalRetrieve
  360. altered to (hopefully) deal with optional "FLAGS (\Seen)"
  361. in response.
  362. 2003-Aug-22 CCA:Yet another IMAP oddity - a server returns NIL for the
  363. mailbox separator, ParseListResult modified. Added "Length
  364. (LLine) > 0)" test to stop GPF on empty line in ReceiveBody.
  365. 2003-Sep-26 CCB:Changed SendCmd altered to try to remove anything that may
  366. be unprocessed from a previous (probably failed) command.
  367. This uses the property FMilliSecsToWaitToClearBuffer, which
  368. defaults to 10ms.
  369. Added EIdDisconnectedProbablyIdledOut, trapped in
  370. GetInternalResponse.
  371. Unsolicited responses now filtered out (they are now transferred
  372. from FLastCmdResult.Text to a new field, FLastCmdResult.Extra,
  373. leaving just the responses we want to our command in
  374. FLastCmdResult.Text).
  375. 2003-Oct-21 CCC:Original GetLineResponse merged with GetResponse to reduce
  376. complexity and to add filtering unsolicited responses when
  377. we are looking for single-line responses (which GetLineResponse
  378. did), removed/coded-out much of these functions to make the
  379. code much simpler.
  380. Removed RemoveAnyAdditionalResponses, no longer needed.
  381. Parsing of body structure reworked to support ParentPart concept
  382. allowing parsing of indefinitely-nested MIME parts. Note that
  383. a`MIME "alternative" message with a plain-text and a html part
  384. will have part[0] marked "alternative" with size 0 and ImapPartNumber
  385. of 1, a part[1] of type text/plain with a ParentPart of 0 and an
  386. ImapPartNumber of 1.1, and finally a part[2] of type text/html
  387. again with a ParentPart of 0 and an ImapPartNumber of 1.2.
  388. Imap part number changed from an integer to string, allowing
  389. retrieval of IMAP sub-parts, e.g. part '3.2' is the 2nd subpart
  390. of part 3.
  391. 2003-Nov-20 CCD:Added UIDRetrievePartHeader & RetrievePartHeader. Started to
  392. use an abstracted parsing method for the command response in
  393. UIDRetrieveFlags. Added function FindHowServerCreatesFolders.
  394. 2003-Dec-04 CCE:Copied DotNet connection changes from IdSMTP to tempoarily bypass
  395. the SASL authentications until they are ported.
  396. 2004-Jan-23 CCF:Finished .NET port, added BinHex4.0 encoding.
  397. 2004-Apr-16 CCG:Added UTF-7 decoding/encoding code kindly written and submitted by
  398. Roman Puls for encoding/decoding mailbox names. IMAP does not use
  399. standard UTF-7 code (what's new?!) so these routines are localised
  400. to this unit.
  401. *}
  402. { Todo -oIC :
  403. Change the mailbox list commands so that they receive TMailBoxTree
  404. structures and so they can store in them the mailbox name and it's attributes. }
  405. { Todo -oIC :
  406. Add support for \* special flag in messages, and check for \Recent
  407. flag in STORE command because it cant be stored (will get no reply!!!) }
  408. { Todo -oIC :
  409. 5.1.2. Mailbox Namespace Naming Convention
  410. By convention, the first hierarchical element of any mailbox name
  411. which begins with "#" identifies the "namespace" of the remainder of
  412. the name. This makes it possible to disambiguate between different
  413. types of mailbox stores, each of which have their own namespaces.
  414. For example, implementations which offer access to USENET
  415. newsgroups MAY use the "#news" namespace to partition the USENET
  416. newsgroup namespace from that of other mailboxes. Thus, the
  417. comp.mail.misc newsgroup would have an mailbox name of
  418. "#news.comp.mail.misc", and the name "comp.mail.misc" could refer
  419. to a different object (e.g. a user's private mailbox). } {Do not Localize}
  420. { TO BE CONSIDERED -CC :
  421. Double-quotes in mailbox names can cause major but subtle failures. Maybe
  422. add the automatic stripping of double-quotes if passed in mailbox names,
  423. to avoid ending up with ""INBOX""
  424. }
  425. interface
  426. {CC3: WARNING - if the following gives a "File not found" error on compilation,
  427. you need to add the path "C:\Program Files\Borland\Delphi7\Source\Indy" in
  428. Project -> Options -> Directories/Conditionals -> Search Path}
  429. {$I IdCompilerDefines.inc}
  430. uses
  431. IdMessage,
  432. Classes,
  433. IdAssignedNumbers,
  434. IdMailBox,
  435. IdException,
  436. IdGlobal,
  437. IdMessageParts,
  438. IdMessageClient,
  439. IdReply,
  440. IdComponent, {CC6: Now needed for ReceiveBody}
  441. IdMessageCoder, {CC2: Now needed for parsing BODYSTRUCTURE}
  442. IdHeaderList, {CC7: Added for 2nd version of AppendMsg}
  443. IdCoderHeader, {CC7: Needed for decoding filenames}
  444. IdCoderMIME,
  445. IdCoderQuotedPrintable,
  446. IdCoderBinHex4,
  447. IdSASLCollection, {JPM - SASL authentication for IMAP4 in Indy 10}
  448. IdTStrings,
  449. IdMessageCollection;
  450. { MUTF7 }
  451. type
  452. EmUTF7Encode = class(EIdSilentException);
  453. EmUTF7Decode = class(EIdSilentException);
  454. const
  455. b64Chars : array[0..63] of char =
  456. 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,'; {Do not Localize}
  457. b64Index : array [0..127] of integer = (
  458. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 16
  459. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 32
  460. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,63,-1,-1,-1, // 48
  461. 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, // 64
  462. -1,00,01,02,03,04,05,06,07,08,09,10,11,12,13,14, // 80
  463. 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, // 96
  464. -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, // 112
  465. 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1 // 128
  466. );
  467. b64Table : array[0..127] of integer = (
  468. $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, // 16
  469. $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, // 32
  470. $20,$21,$22,$23, $24,$25,$FF,$27, $28,$29,$2A,$2B, $2C,$2D,$2E,$2F, // 48
  471. $30,$31,$32,$33, $34,$35,$36,$37, $38,$39,$3A,$3B, $3C,$3D,$3E,$3F, // 64
  472. $40,$41,$42,$43, $44,$45,$46,$47, $48,$49,$4A,$4B, $4C,$4D,$4E,$4F, // 80
  473. $50,$51,$52,$53, $54,$55,$56,$57, $58,$59,$5A,$5B, $5C,$5D,$5E,$5F, // 96
  474. $60,$61,$62,$63, $64,$65,$66,$67, $68,$69,$6A,$6B, $6C,$6D,$6E,$6F, // 112
  475. $70,$71,$72,$73, $74,$75,$76,$77, $78,$79,$7A,$7B, $7C,$7D,$7E,$FF);// 128
  476. type
  477. TIdMUTF7 = class(TObject)
  478. public
  479. function Encode(aString : string):string;
  480. function Decode(aString : string):string;
  481. function Valid(aMUTF7String : string):boolean;
  482. function Append(const aMUTF7String, aAnsiStr : string):string;
  483. end;
  484. { TIdIMAP4 }
  485. const
  486. wsOk = 1;
  487. wsNo = 2;
  488. wsBad = 3;
  489. wsPreAuth = 4;
  490. wsBye = 5;
  491. wsContinue = 6;
  492. type
  493. TIdIMAP4FolderTreatment = ( //Result codes from FindHowServerCreatesFolders
  494. ftAllowsTopLevelCreation, //Folders can be created at the same level as Inbox (the top level)
  495. ftFoldersMustBeUnderInbox, //Folders must be created under INBOX, such as INBOX.Sent
  496. ftDoesNotAllowFolderCreation, //Wont allow you create folders at top level or under Inbox (may be read-only connection)
  497. ftCannotTestBecauseHasNoInbox, //Wont allow top-level creation but cannot test creation under Inbox because it does not exist
  498. ftCannotRetrieveAnyFolders //No folders present for that user, cannot be determined
  499. );
  500. type
  501. TIdIMAP4AuthenticationType = (atUserPass, atSASL);
  502. const
  503. DEF_IMAP4_AUTH = atUserPass;
  504. IDF_DEFAULT_MS_TO_WAIT_TO_CLEAR_BUFFER = 10;
  505. {CC3: TIdImapMessagePart and TIdImapMessageParts added for retrieving
  506. individual parts of a message via IMAP, because IMAP uses some additional
  507. terms.
  508. Note that (rarely) an IMAP can have two sub-"parts" in the one part -
  509. they are sent in the one part by the server, typically a plain-text and
  510. html version with a boundary at the start, in between, and at the end.
  511. TIdIMAP fills in the boundary in that case, and the FSubpart holds the
  512. info on the second part. I call these multisection parts.}
  513. type
  514. TIdImapMessagePart = class(TCollectionItem)
  515. protected
  516. FBodyType: string;
  517. FBodySubType: string;
  518. FFileName: string;
  519. FDescription: string;
  520. FEncoding: TIdMessageEncoding;
  521. FContentTransferEncoding: string;
  522. FSize: integer;
  523. FUnparsedEntry: string; {Text returned from server: useful for debugging or workarounds}
  524. FBoundary: string; {Only used for multisection parts}
  525. FParentPart: Integer;
  526. FImapPartNumber: string;
  527. public
  528. property BodyType : String read FBodyType write FBodyType;
  529. property BodySubType : String read FBodySubType write FBodySubType;
  530. property FileName : String read FFileName write FFileName;
  531. property Description : String read FDescription write FDescription;
  532. property Encoding: TIdMessageEncoding read FEncoding write FEncoding;
  533. property ContentTransferEncoding : String read FContentTransferEncoding write FContentTransferEncoding;
  534. property Size : integer read FSize write FSize;
  535. property UnparsedEntry : string read FUnparsedEntry write FUnparsedEntry;
  536. property Boundary : string read FBoundary write FBoundary;
  537. property ParentPart: integer read FParentPart write FParentPart;
  538. property ImapPartNumber: string read FImapPartNumber write FImapPartNumber;
  539. constructor Create(Collection: TCollection); override;
  540. end;
  541. type
  542. {CC3: Added for validating message number}
  543. EIdNumberInvalid = class(EIdException);
  544. {CCB: Added for server disconnecting you if idle too long...}
  545. EIdDisconnectedProbablyIdledOut = class(EIdException);
  546. TIdImapMessageParts = class(TOwnedCollection)
  547. protected
  548. function GetItem(Index: Integer): TIdImapMessagePart;
  549. procedure SetItem(Index: Integer; const Value: TIdImapMessagePart);
  550. public
  551. function Add: TIdImapMessagePart;
  552. property Items[Index: Integer]: TIdImapMessagePart read GetItem write SetItem; default;
  553. end;
  554. {CCD: Added to parse out responses, because the order in which the responses appear
  555. varies between servers. A typical line that gets parsed into this is:
  556. * 9 FETCH (UID 1234 FLAGS (\Seen \Deleted))
  557. }
  558. TIdIMAPLineStruct = class(TObject)
  559. protected
  560. HasStar: Boolean; //Line starts with a '*'
  561. MessageNumber: string; //Line has a message number (after the *)
  562. Command: string; //IMAP servers send back the command they are responding to, e.g. FETCH
  563. UID: string; //Sometimes the UID is echoed back
  564. Flags: TIdMessageFlagsSet; //Sometimes the FLAGS are echoed back
  565. Complete: Boolean; //If false, line has no closing bracket (response continues on following line(s))
  566. ByteCount: integer; //The value in a trailing byte count like {123}, -1 means not present
  567. IMAPFunction: string; //E.g. FLAGS
  568. IMAPValue: string; //E.g. '(\Seen \Deleted)'
  569. end;
  570. type
  571. TIdIMAP4Commands =
  572. ( cmdCAPABILITY,
  573. cmdNOOP,
  574. cmdLOGOUT,
  575. cmdAUTHENTICATE,
  576. cmdLOGIN,
  577. cmdSELECT,
  578. cmdEXAMINE,
  579. cmdCREATE,
  580. cmdDELETE,
  581. cmdRENAME,
  582. cmdSUBSCRIBE,
  583. cmdUNSUBSCRIBE,
  584. cmdLIST,
  585. cmdLSUB,
  586. cmdSTATUS,
  587. cmdAPPEND,
  588. cmdCHECK,
  589. cmdCLOSE,
  590. cmdEXPUNGE,
  591. cmdSEARCH,
  592. cmdFETCH,
  593. cmdSTORE,
  594. cmdCOPY,
  595. cmdUID,
  596. cmdXCmd );
  597. {CC3: Add csUnexpectedlyDisconnected for when we receive "Connection reset by peer"}
  598. TIdIMAP4ConnectionState = ( csAny, csNonAuthenticated, csAuthenticated, csSelected , csUnexpectedlyDisconnected );
  599. {****************************************************************************
  600. Universal commands CAPABILITY, NOOP, and LOGOUT
  601. Authenticated state commands SELECT, EXAMINE, CREATE, DELETE, RENAME,
  602. SUBSCRIBE, UNSUBSCRIBE, LIST, LSUB, STATUS, and APPEND
  603. Selected state commands CHECK, CLOSE, EXPUNGE, SEARCH, FETCH, STORE, COPY, and UID
  604. *****************************************************************************}
  605. TIdIMAP4SearchKey =
  606. ( skAll, //All messages in the mailbox; the default initial key for ANDing.
  607. skAnswered, //Messages with the \Answered flag set.
  608. skBcc, //Messages that contain the specified string in the envelope structure's BCC field.
  609. skBefore, //Messages whose internal date is earlier than the specified date.
  610. skBody, //Messages that contain the specified string in the body of the message.
  611. skCc, //Messages that contain the specified string in the envelope structure's CC field.
  612. skDeleted, //Messages with the \Deleted flag set.
  613. skDraft, //Messages with the \Draft flag set.
  614. skFlagged, //Messages with the \Flagged flag set.
  615. skFrom, //Messages that contain the specified string in the envelope structure's FROM field.
  616. skHeader, //Messages that have a header with the specified field-name (as defined in [RFC-822])
  617. //and that contains the specified string in the [RFC-822] field-body.
  618. skKeyword, //Messages with the specified keyword set.
  619. skLarger, //Messages with an [RFC-822] size larger than the specified number of octets.
  620. skNew, //Messages that have the \Recent flag set but not the \Seen flag.
  621. //This is functionally equivalent to "(RECENT UNSEEN)".
  622. skNot, //Messages that do not match the specified search key.
  623. skOld, //Messages that do not have the \Recent flag set. This is functionally
  624. //equivalent to "NOT RECENT" (as opposed to "NOT NEW").
  625. skOn, //Messages whose internal date is within the specified date.
  626. skOr, //Messages that match either search key.
  627. skRecent, //Messages that have the \Recent flag set.
  628. skSeen, //Messages that have the \Seen flag set.
  629. skSentBefore,//Messages whose [RFC-822] Date: header is earlier than the specified date.
  630. skSentOn, //Messages whose [RFC-822] Date: header is within the specified date.
  631. skSentSince, //Messages whose [RFC-822] Date: header is within or later than the specified date.
  632. skSince, //Messages whose internal date is within or later than the specified date.
  633. skSmaller, //Messages with an [RFC-822] size smaller than the specified number of octets.
  634. skSubject, //Messages that contain the specified string in the envelope structure's SUBJECT field.
  635. skText, //Messages that contain the specified string in the header or body of the message.
  636. skTo, //Messages that contain the specified string in the envelope structure's TO field.
  637. skUID, //Messages with unique identifiers corresponding to the specified unique identifier set.
  638. skUnanswered,//Messages that do not have the \Answered flag set.
  639. skUndeleted, //Messages that do not have the \Deleted flag set.
  640. skUndraft, //Messages that do not have the \Draft flag set.
  641. skUnflagged, //Messages that do not have the \Flagged flag set.
  642. skUnKeyWord, //Messages that do not have the specified keyword set.
  643. skUnseen );
  644. TIdIMAP4SearchKeyArray = array of TIdIMAP4SearchKey;
  645. TIdIMAP4SearchRec = record
  646. Date: TDateTime;
  647. Size: Integer;
  648. Text: String;
  649. SearchKey : TIdIMAP4SearchKey;
  650. end;
  651. TIdIMAP4SearchRecArray = array of TIdIMAP4SearchRec;
  652. TIdIMAP4StatusDataItem = ( mdMessages, mdRecent, mdUIDNext, mdUIDValidity, mdUnseen );
  653. TIdIMAP4StoreDataItem = ( sdReplace, sdReplaceSilent, sdAdd, sdAddSilent, sdRemove, sdRemoveSilent );
  654. TIdRetrieveOnSelect = ( rsDisabled, rsHeaders, rsMessages );
  655. TIdAlertEvent = procedure(ASender: TObject; const AAlertMsg: String) of object;
  656. TIdIMAP4 = class(TIdMessageClient)
  657. private
  658. procedure SetMailBox(const Value: TIdMailBox);
  659. protected
  660. FCmdCounter : Integer;
  661. FConnectionState : TIdIMAP4ConnectionState;
  662. FMailBox : TIdMailBox;
  663. FMailBoxSeparator: Char;
  664. FOnAlert: TIdAlertEvent;
  665. FRetrieveOnSelect: TIdRetrieveOnSelect;
  666. FMilliSecsToWaitToClearBuffer: integer;
  667. FMUTF7: TIdMUTF7;
  668. FOnWorkForPart: TWorkEvent;
  669. FOnWorkBeginForPart: TWorkBeginEvent;
  670. FOnWorkEndForPart: TWorkEndEvent;
  671. FGreetingBanner : String; {CC7: Added because it may help identify the server}
  672. FHasCapa : Boolean;
  673. {CC7: FSASLMechanisms and FAuthType added when LoginSASL moved from TIdMessageSASLClient to TIdSASLList...}
  674. FSASLMechanisms : TIdSASLEntries;
  675. FAuthType : TIdIMAP4AuthenticationType;
  676. FCapabilities: TIdStringList;
  677. FLineStruct: TIdIMAPLineStruct;
  678. function GetReplyClass:TIdReplyClass; override;
  679. //The following call FMUTF7 but do exception-handling on invalid strings...
  680. function DoMUTFEncode(aString : string):string;
  681. function DoMUTFDecode(aString : string):string;
  682. function GetCmdCounter: String;
  683. function GetConnectionStateName: String;
  684. function GetNewCmdCounter: String;
  685. property LastCmdCounter: String read GetCmdCounter;
  686. property NewCmdCounter: String read GetNewCmdCounter;
  687. { General Functions }
  688. function ArrayToNumberStr (const AMsgNumList: array of Integer): String;
  689. function MessageFlagSetToStr (const AFlags: TIdMessageFlagsSet): String;
  690. //This function is needed because when using the regular DateToStr with dd/MMM/yyyy
  691. //(which is the IMAP needed convension) may give the month as the local language
  692. //three letter month instead of the English month needed.
  693. function DateToIMAPDateStr (const ADate: TDateTime): String;
  694. procedure StripCRLFs(var AText: string); overload; virtual; //Allow users to optimise
  695. procedure StripCRLFs(ASourceStream, ADestStream: TStringStream); overload;
  696. { General Functions }
  697. { Parser Functions }
  698. {CCC: new attempt...}
  699. procedure ParseImapPart(ABodyStructure: string;
  700. AImapParts: TIdImapMessageParts; AThisImapPart: TIdImapMessagePart; AParentImapPart: TIdImapMessagePart;
  701. APartNumber: integer);
  702. procedure ParseMessagePart(ABodyStructure: string;
  703. AMessageParts: TIdMessageParts; AThisMessagePart: TIdMessagePart; AParentMessagePart: TIdMessagePart;
  704. APartNumber: integer);
  705. {CC2: ParseBodyStructureResult added to support individual part retreival...}
  706. procedure ParseBodyStructureResult(ABodyStructure: string; ATheParts: TIdMessageParts; AImapParts: TIdImapMessageParts);
  707. {CC3: ParseBodyStructurePart added to support individual part retreival...}
  708. {CC7: TIdImapSubSection added to ParseBodyStructurePart to support multisection parts...}
  709. procedure ParseBodyStructurePart(APartString: string; AThePart: TIdMessagePart; AImapPart: TIdImapMessagePart{; AImapSubSection: TIdImapSubSection});
  710. procedure ParseTheLine(ALine: string; APartsList: TIdStringList);
  711. procedure ParseIntoParts(APartString: string; AParams: TIdStringList);
  712. procedure ParseIntoBrackettedQuotedAndUnquotedParts(APartString: string; AParams: TIdStringList; AKeepBrackets: Boolean);
  713. procedure BreakApartParamsInQuotes(const AParam: string; var AParsedList: TIdStringList);
  714. function GetNextWord(AParam: string): string;
  715. function GetNextQuotedParam(AParam: string; ARemoveQuotes: Boolean): string;
  716. procedure ParseExpungeResult (AMB: TIdMailBox; ACmdResultDetails: TIdStrings);
  717. procedure ParseListResult (AMBList: TIdStringList; ACmdResultDetails: TIdStrings);
  718. procedure ParseLSubResult(AMBList: TIdStringList; ACmdResultDetails: TIdStrings);
  719. {CCA: InternalParseListResult added to resolve NIL mailbox separator and
  720. rationalise code between ParseLisTresult and ParseLSubResult}
  721. procedure InternalParseListResult(ACmd: string; AMBList: TIdStringList; ACmdResultDetails: TIdStrings);
  722. procedure ParseMailBoxAttributeString(AAttributesList: String; var AAttributes: TIdMailBoxAttributesSet);
  723. procedure ParseMessageFlagString (AFlagsList: String; var AFlags: TIdMessageFlagsSet);
  724. procedure ParseSelectResult (AMB: TIdMailBox; ACmdResultDetails: TIdStrings);
  725. procedure ParseStatusResult (AMB: TIdMailBox; ACmdResultDetails: TIdStrings);
  726. procedure ParseSearchResult (AMB: TIdMailBox; ACmdResultDetails: TIdStrings);
  727. procedure ParseEnvelopeResult (AMsg: TIdMessage; ACmdResultStr: String);
  728. function ParseLastCmdResult(ALine: string; AExpectedCommand: string; AExpectedIMAPFunction: array of string): Boolean;
  729. procedure ParseLastCmdResultButAppendInfo(ALine: string);
  730. {CC8: Following added to combine the (UID)Retrieve(Peek) functions...}
  731. function InternalRetrieve(const AMsgNum: Integer; AUseUID: Boolean; AUsePeek: Boolean; ANoDecode: Boolean; AMsg: TIdMessage): Boolean;
  732. {CC2: Following added for retrieving individual parts of a message...}
  733. function InternalRetrievePart(const AMsgNum: Integer; const APartNum: {Integer} string;
  734. AUseUID: Boolean; AUsePeek: Boolean;
  735. {$IFDEF DOTNET}
  736. var ABuffer: TIdBytes;
  737. {$ELSE}
  738. var ABuffer: PChar;
  739. {$ENDIF}
  740. var ABufferLength: Integer; {NOTE: var args cannot have default params}
  741. ADestFileNameAndPath: string = ''; {Do not Localize}
  742. AContentTransferEncoding: string = 'text'): Boolean; {Do not Localize}
  743. function ParseBodyStructureSectionAsEquates(AParam: string): string;
  744. function ParseBodyStructureSectionAsEquates2(AParam: string): string;
  745. {CC3: Following added for retrieving the text-only part of a message...}
  746. function InternalRetrieveText(const AMsgNum: Integer; var AText: string;
  747. AUseUID: Boolean; AUsePeek: Boolean; AUseFirstPartInsteadOfText: Boolean): Boolean;
  748. {CC3: Following added for TLS support..}
  749. function IsCapabilityListed(ACapability: string):Boolean;
  750. {CC6: Added to support RetrieveEnvelopeRaw...}
  751. function InternalRetrieveEnvelope(const AMsgNum: Integer; AMsg: TIdMessage; ADestList: TIdStringList): Boolean;
  752. {CC6: Added to support UIDRetrieveEnvelopeRaw...}
  753. function UIDInternalRetrieveEnvelope(const AMsgUID: String; AMsg: TIdMessage; ADestList: TIdStringList): Boolean;
  754. {CCD: For getting the header of a part...}
  755. function InternalRetrievePartHeader(const AMsgNum: Integer; const APartNum: string; const AUseUID: Boolean; AHeaders: TIdHeaderList): Boolean;
  756. {CC: ReceiveHeader in IdMessageClient seems to have a very rare bug, maybe it
  757. is missing the end marker occassionally. Moved up to here to add
  758. debugging code, plus it can be converted to an IMAP byte-count retrieval
  759. method if necessary.}
  760. function ReceiveHeader(AMsg: TIdMessage; const AAltTerm: string = ''): string; override;
  761. {CC3: Need to validate message numbers (relative and UIDs) and part numbers, because otherwise
  762. the routines wait for a response that never arrives and so functions never return.
  763. Also used for validating part numbers.}
  764. function IsNumberValid(const ANumber: Integer): Boolean;
  765. function IsUIDValid(const AUID: string): Boolean;
  766. function IsImapPartNumberValid(const AUID: string): Boolean;
  767. function IsItDigitsAndOptionallyPeriod(const AStr: string; AAllowPeriod: Boolean): Boolean;
  768. {CC6: Override IdMessageClient's ReceiveBody due to the responses from some
  769. servers...}
  770. procedure ReceiveBody(AMsg: TIdMessage; const ADelim: string = '.'); override; {Do not Localize}
  771. procedure InitComponent; override;
  772. public
  773. { TIdIMAP4 Commands }
  774. //Requests a listing of capabilities that the server supports.
  775. function Capability(ASlCapability: TIdStrings): Boolean; overload;
  776. function FindHowServerCreatesFolders: TIdIMAP4FolderTreatment;
  777. procedure DoAlert (const AMsg: String);
  778. property ConnectionState: TIdIMAP4ConnectionState read FConnectionState;
  779. property MailBox: TIdMailBox read FMailBox write SetMailBox;
  780. {CC7: Two versions of AppendMsg are provided. The first is the normal one you
  781. would use. The second allows you to specify an alternative header list which
  782. will be used in place of AMsg.Headers.
  783. An email client may need the second type if it sends an email via IdSMTP and wants
  784. to copy it to a "Sent" IMAP folder. In Indy 9, IdSMTP internally generates and
  785. transmits the headers but does not keep them, so what you may need to do is to
  786. subclass IdSMTP, override SendHeader so that the TIdHeaderList is returned (and
  787. also override both SendMsg and Send to get it back to you), then use the
  788. second version of AppendMsg to use the returned TIdHeaderList. In Indy 10,
  789. IdSMTP puts the generated headers in the LastGeneratedHeaders field, so you
  790. can use the second version of AppendMsg, passing it AMsg.LastGeneratedHeaders as
  791. the AAlternativeHeaders field. Note that IdSMTP puts both the Headers and
  792. the ExtraHeaders fields in LastGeneratedHeaders.}
  793. function AppendMsg (const AMBName: String; AMsg: TIdMessage; const AFlags: TIdMessageFlagsSet = []): Boolean; overload;
  794. function AppendMsg (const AMBName: String; AMsg: TIdMessage; AAlternativeHeaders: TIdHeaderList; const AFlags: TIdMessageFlagsSet = []): Boolean; overload;
  795. function AppendMsgNoEncodeFromFile (const AMBName: String; ASourceFile: string; const AFlags: TIdMessageFlagsSet = []): Boolean;
  796. function AppendMsgNoEncodeFromStream (const AMBName: String; AStream: TStream; const AFlags: TIdMessageFlagsSet = []): Boolean;
  797. //The following are used for raw (unparsed) messages in a file or stream...
  798. //Requests a checkpoint of the currently selected mailbox. Does NOTHING on most servers.
  799. function CheckMailBox: Boolean;
  800. //Checks if the message was read or not.
  801. function CheckMsgSeen (const AMsgNum: Integer): Boolean;
  802. //Method for logging in manually if you didn't login at connect
  803. procedure Login; virtual;
  804. //Connects and logins to the IMAP4 account.
  805. procedure Connect(const AAndLogin: boolean = true); reintroduce; virtual;
  806. //Closes the current selected mailbox in the account. {Do not Localize}
  807. function CloseMailBox: Boolean;
  808. //Creates a new mailbox with the specified name in the account. {Do not Localize}
  809. function CreateMailBox (const AMBName: String): Boolean;
  810. //Deletes the specified mailbox from the account. {Do not Localize}
  811. function DeleteMailBox (const AMBName: String): Boolean;
  812. //Marks messages for deletion, it will be deleted when the mailbox will be purged.
  813. function DeleteMsgs(const AMsgNumList: array of Integer): Boolean;
  814. destructor Destroy; override;
  815. //Logouts and disconnects from the IMAP account.
  816. procedure Disconnect; overload;
  817. //Disconnect with a parameter for raising a Not Connected exception
  818. procedure Disconnect(AImmediate: Boolean; const ARaiseExceptionIfNotCon : Boolean); reintroduce; overload;
  819. //Examines the specified mailbox and inserts the results to the TIdMailBox provided. {Do not Localize}
  820. function ExamineMailBox (const AMBName: String; AMB: TIdMailBox): Boolean;
  821. //Expunges (deletes the marked files) the current selected mailbox in the account. {Do not Localize}
  822. function ExpungeMailBox: Boolean;
  823. //Sends a NOOP (No Operation) to keep the account connection with the server alive.
  824. procedure KeepAlive;
  825. //Returns a list of all the child mailboxes (one level down) to the mailbox supplied.
  826. //This should be used when you fear that there are too many mailboxes and the listing of
  827. //all of them could be time consuming, so this should be used to retrieve specific mailboxes.
  828. function ListInferiorMailBoxes (AMailBoxList, AInferiorMailBoxList: TIdStringList): Boolean;
  829. //Returns a list of all the mailboxes in the user account.
  830. function ListMailBoxes (AMailBoxList: TIdStringList): Boolean;
  831. //Returns a list of all the subscribed mailboxes in the user account.
  832. function ListSubscribedMailBoxes (AMailBoxList: TIdStringList): Boolean;
  833. //Renames the specified mailbox in the account. {Do not Localize}
  834. function RenameMailBox (const AOldMBName, ANewMBName: String): Boolean;
  835. //Searches the current selected mailbox for messages matching the SearchRec and
  836. //returnes the results to the mailbox SearchResults array.
  837. function SearchMailBox (const ASearchInfo: array of TIdIMAP4SearchRec): Boolean;
  838. //Selects the current a mailbox in the account. {Do not Localize}
  839. function SelectMailBox (const AMBName: String): Boolean;
  840. //Retrieves the status of the indicated mailbox.
  841. {CC2: It is pointless calling StatusMailBox with AStatusDataItems set to []
  842. because you are asking the IMAP server to update none of the status flags.
  843. Instead, if called with no AStatusDataItems specified, use the standard flags
  844. returned by SelectMailBox, which allows the user to easily check if the mailbox
  845. has changed. Overload the functions, since AStatusDataItems cannot be set
  846. to nil.}
  847. function StatusMailBox (const AMBName: String; AMB: TIdMailBox): Boolean; overload;
  848. function StatusMailBox (const AMBName: String; AMB: TIdMailBox; const AStatusDataItems: array of TIdIMAP4StatusDataItem): Boolean; overload;
  849. //Changes (adds or removes) message flags.
  850. function StoreFlags (const AMsgNumList: array of Integer;
  851. const AStoreMethod: TIdIMAP4StoreDataItem; const AFlags: TIdMessageFlagsSet): Boolean;
  852. //Adds the specified mailbox name to the server's set of "active" or "subscribed" {Do not Localize}
  853. //mailboxes as returned by the LSUB command.
  854. function SubscribeMailBox (const AMBName: String): Boolean;
  855. {CC8: Added CopyMsg, should have always been there...}
  856. function CopyMsg (const AMsgNum: Integer; const AMBName: String): Boolean;
  857. //Copies a message from the current selected mailbox to the specified mailbox. {Do not Localize}
  858. function CopyMsgs (const AMsgNumList: array of Integer; const AMBName: String): Boolean;
  859. //Retrieves a whole message while marking it read.
  860. function Retrieve (const AMsgNum: Integer; AMsg: TIdMessage): Boolean;
  861. //Retrieves a whole message "raw" and saves it to file, while marking it read.
  862. function RetrieveNoDecodeToFile (const AMsgNum: Integer; ADestFile: string): Boolean;
  863. function RetrieveNoDecodeToStream (const AMsgNum: Integer; AStream: TStream): Boolean;
  864. //Retrieves all envelope of the selected mailbox to the specified TIdMessageCollection.
  865. function RetrieveAllEnvelopes (AMsgList: TIdMessageCollection): Boolean;
  866. //Retrieves all headers of the selected mailbox to the specified TIdMessageCollection.
  867. function RetrieveAllHeaders (AMsgList: TIdMessageCollection): Boolean;
  868. //Retrieves all messages of the selected mailbox to the specified TIdMessageCollection.
  869. function RetrieveAllMsgs (AMsgList: TIdMessageCollection): Boolean;
  870. //Retrieves the message envelope, parses it, and discards the envelope.
  871. function RetrieveEnvelope (const AMsgNum: Integer; AMsg: TIdMessage): Boolean;
  872. //Retrieves the message envelope into a TIdStringList but does NOT parse it.
  873. function RetrieveEnvelopeRaw(const AMsgNum: Integer; ADestList: TIdStringList): Boolean;
  874. //Returnes the message flag values.
  875. function RetrieveFlags (const AMsgNum: Integer; var AFlags: TIdMessageFlagsSet): Boolean;
  876. {CC2: Following added for retrieving individual parts of a message...}
  877. function InternalRetrieveStructure(const AMsgNum: Integer; AMsg: TIdMessage; AParts: TIdImapMessageParts): Boolean;
  878. //Retrieve only the message structure (this tells you what parts are in the message).
  879. function RetrieveStructure(const AMsgNum: Integer; AMsg: TIdMessage): Boolean; overload;
  880. function RetrieveStructure(const AMsgNum: Integer; AParts: TIdImapMessageParts): Boolean; overload;
  881. {CC2: Following added for retrieving individual parts of a message...}
  882. {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...}
  883. function RetrievePart(const AMsgNum: Integer; const APartNum: Integer;
  884. {$IFDEF DOTNET}
  885. var ABuffer: TIdBytes;
  886. {$ELSE}
  887. var ABuffer: PChar;
  888. {$ENDIF}
  889. var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize}
  890. {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...}
  891. function RetrievePart(const AMsgNum: Integer; const APartNum: string;
  892. {$IFDEF DOTNET}
  893. var ABuffer: TIdBytes;
  894. {$ELSE}
  895. var ABuffer: PChar;
  896. {$ENDIF}
  897. var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize}
  898. {CC2: Following added for retrieving individual parts of a message...}
  899. {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...}
  900. function RetrievePartPeek(const AMsgNum: Integer; const APartNum: Integer;
  901. {$IFDEF DOTNET}
  902. var ABuffer: TIdBytes;
  903. {$ELSE}
  904. var ABuffer: PChar;
  905. {$ENDIF}
  906. var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize}
  907. {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...}
  908. function RetrievePartPeek(const AMsgNum: Integer; const APartNum: string;
  909. {$IFDEF DOTNET}
  910. var ABuffer: TIdBytes;
  911. {$ELSE}
  912. var ABuffer: PChar;
  913. {$ENDIF}
  914. var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize}
  915. {CC2: Following added for retrieving individual parts of a message...}
  916. {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...}
  917. function RetrievePartToFile(const AMsgNum: Integer; const APartNum: Integer;
  918. ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload;
  919. {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...}
  920. function RetrievePartToFile(const AMsgNum: Integer; const APartNum: string;
  921. ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload;
  922. {CC2: Following added for retrieving individual parts of a message...}
  923. {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...}
  924. function RetrievePartToFilePeek(const AMsgNum: Integer; const APartNum: Integer;
  925. ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload;
  926. {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...}
  927. function RetrievePartToFilePeek(const AMsgNum: Integer; const APartNum: string;
  928. ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload;
  929. {CC3: Following added for retrieving the text-only part of a message...}
  930. function RetrieveText(const AMsgNum: Integer; var AText: string): Boolean;
  931. {CC4: An alternative for retrieving the text-only part of a message which
  932. may give a better response from some IMAP implementations...}
  933. function RetrieveText2(const AMsgNum: Integer; var AText: string): Boolean;
  934. {CC3: Following added for retrieving the text-only part of a message...}
  935. function RetrieveTextPeek(const AMsgNum: Integer; var AText: string): Boolean;
  936. function RetrieveTextPeek2(const AMsgNum: Integer; var AText: string): Boolean;
  937. //Retrieves only the message header.
  938. function RetrieveHeader (const AMsgNum: Integer; AMsg: TIdMessage): Boolean;
  939. //CCD: Retrieve the header for a particular part...
  940. function RetrievePartHeader(const AMsgNum: Integer; const APartNum: string…

Large files files are truncated, but you can click here to view the full file