POPLevel.cpp
上传用户:liuzhunlcd
上传日期:2007-01-12
资源大小:54k
文件大小:11k
源码类别:

Email客户端

开发平台:

Visual C++

  1. // POPLevel.cpp : Implementation of CPOPLevel
  2. #include "stdafx.h"
  3. #include "Pophandler.h"
  4. #include "POPLevel.h"
  5. #include "SmartWSA.h"
  6. /////////////////////////////////////////////////////////////////////////////
  7. // CPOPLevel
  8. HRESULT CPOPLevel::FinalConstruct()
  9. {
  10. m_pcSmartWSA = new CSmartWSA;
  11. ATLASSERT(m_pcSmartWSA);
  12. m_pcPOP3 = new CPop3Connection;
  13. ATLASSERT(m_pcPOP3);
  14. return S_OK;
  15. }
  16. void CPOPLevel::FinalRelease()
  17. {
  18. delete m_pcPOP3;
  19. delete m_pcSmartWSA;
  20. }
  21. STDMETHODIMP CPOPLevel::InterfaceSupportsErrorInfo(REFIID riid)
  22. {
  23. static const IID* arr[] = 
  24. {
  25. &IID_IPOPLevel
  26. };
  27. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  28. {
  29. if (InlineIsEqualGUID(*arr[i], riid))
  30. return S_OK;
  31. }
  32. return S_FALSE;
  33. }
  34. STDMETHODIMP CPOPLevel::get_Host(BSTR *pVal)
  35. {
  36. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  37. ATLASSERT(pVal);
  38. try
  39. {
  40. *pVal = m_bstHost.copy();
  41. }
  42. catch(...)
  43. {
  44. return E_FAIL;
  45. }
  46. return S_OK;
  47. }
  48. STDMETHODIMP CPOPLevel::put_Host(BSTR newVal)
  49. {
  50. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  51. try
  52. {
  53. m_bstHost = newVal;
  54. }
  55. catch(...)
  56. {
  57. return E_FAIL;
  58. }
  59. return S_OK;
  60. }
  61. STDMETHODIMP CPOPLevel::get_Port(long *pVal)
  62. {
  63. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  64. ATLASSERT(pVal);
  65. *pVal = (LONG)m_dwPort;
  66. return S_OK;
  67. }
  68. STDMETHODIMP CPOPLevel::put_Port(long newVal)
  69. {
  70. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  71. m_dwPort = (DWORD) newVal;
  72. return S_OK;
  73. }
  74. STDMETHODIMP CPOPLevel::get_User(BSTR *pVal)
  75. {
  76. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  77. ATLASSERT(pVal);
  78. try
  79. {
  80. *pVal = m_bstUser.copy();
  81. }
  82. catch(...)
  83. {
  84. return E_FAIL;
  85. }
  86. return S_OK;
  87. }
  88. STDMETHODIMP CPOPLevel::put_User(BSTR newVal)
  89. {
  90. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  91. try
  92. {
  93. m_bstUser = newVal;
  94. }
  95. catch(...)
  96. {
  97. return E_FAIL;
  98. }
  99. return S_OK;
  100. }
  101. STDMETHODIMP CPOPLevel::get_Password(BSTR *pVal)
  102. {
  103. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  104. ATLASSERT(pVal);
  105. try
  106. {
  107. *pVal = m_bstPassword.copy();
  108. }
  109. catch(...)
  110. {
  111. return E_FAIL;
  112. }
  113. return S_OK;
  114. }
  115. STDMETHODIMP CPOPLevel::put_Password(BSTR newVal)
  116. {
  117. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  118. try
  119. {
  120. m_bstPassword = newVal;
  121. }
  122. catch(...)
  123. {
  124. return E_FAIL;
  125. }
  126. return S_OK;
  127. }
  128. STDMETHODIMP CPOPLevel::get_Timeout(long *pVal)
  129. {
  130. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  131. ATLASSERT(pVal);
  132. *pVal = (LONG)m_pcPOP3->GetTimeout();
  133. return S_OK;
  134. }
  135. STDMETHODIMP CPOPLevel::put_Timeout(long newVal)
  136. {
  137. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  138. m_pcPOP3->SetTimeout(newVal);
  139. return S_OK;
  140. }
  141. STDMETHODIMP CPOPLevel::Connect()
  142. {
  143. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  144. BOOL blRet = m_pcPOP3->Connect(m_bstHost, m_bstUser, m_bstPassword, m_dwPort);
  145. if(blRet == false)
  146. return E_FAIL;
  147. //return E_FAIL;
  148. return S_OK;
  149. }
  150. STDMETHODIMP CPOPLevel::Disconnect()
  151. {
  152. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  153. BOOL blRet = m_pcPOP3->Disconnect();
  154. if(blRet == false)
  155. return E_FAIL;
  156. return S_OK;
  157. }
  158. STDMETHODIMP CPOPLevel::GetMailCount(long *a_plCount)
  159. {
  160. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  161. ATLASSERT(a_plCount);
  162. INT iSize;
  163. INT iCount;
  164. BOOL blRet = m_pcPOP3->Statistics(iCount, iSize);
  165. if(blRet == false)
  166. return E_FAIL;
  167. *a_plCount = iCount;
  168. return S_OK;
  169. }
  170. STDMETHODIMP CPOPLevel::GetMail(long a_lMailNum, long a_lDelete)
  171. {
  172. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  173. FILE* pfTemp = NULL;
  174. FILE* pfAttach = NULL;
  175. try
  176. {
  177. // clear attached files
  178. m_bstAttachedFiles = "";
  179. // clear body
  180. m_bstBody = "";
  181. // get mail message
  182. BOOL blRet = m_pcPOP3->Retrieve(a_lMailNum, m_cMessage);
  183. if(blRet == false)
  184. return E_FAIL;
  185. if(a_lDelete > 0)
  186. {
  187. // mark message as del
  188. m_pcPOP3->Delete(a_lMailNum);
  189. }
  190. // write raw body to the file
  191. pfTemp = fopen("temp.mme", "w+b");
  192. ATLASSERT(pfTemp);
  193. CString sRawBody = m_cMessage.GetRawBody();
  194. fputs(sRawBody, pfTemp);
  195. fclose(pfTemp);
  196. pfTemp = NULL;
  197. // get boundary
  198. CString sBoundary = m_cMessage.GetBoundary();
  199. // open file
  200. pfTemp = fopen("temp.mme", "rb");
  201. ATLASSERT(pfTemp);
  202. CHAR text[1024] = "";
  203. bool blIsBodyEmpty = false;
  204. // store position for the empty body
  205. LONG lPos = ftell(pfTemp);
  206. // get opening boundary string
  207. if(sBoundary.GetLength() != 0)
  208. {
  209. while(fgets(text, sizeof(text) - 1, pfTemp))
  210. {
  211. if( !strncmp(text, "--", 2) && !strncmp(text + 2, sBoundary, strlen(sBoundary)))
  212. break;
  213. }
  214. // local headers   
  215. // get header out of the way
  216. while(fgets(text, sizeof(text) - 1, pfTemp))
  217. {
  218. if((*text == 'n') || (*text == 'r') || !*text)
  219. break;
  220. if(strncmp(text, "Content-Disposition: attachment", strlen("Content-Disposition: attachment")) == 0)
  221. {
  222. blIsBodyEmpty = true;
  223. }
  224. }
  225. }
  226. // read body
  227. CString sBody;
  228. if(blIsBodyEmpty == false)
  229. {
  230. memset(text, 0, sizeof(text));
  231. while(fgets(text, sizeof(text) - 1, pfTemp))
  232. {
  233. if(sBoundary.GetLength() != 0)
  234. {
  235. if(!strncmp(text, "--", 2) && !strncmp(text + 2, sBoundary, strlen(sBoundary)))
  236. break;
  237. }
  238. sBody += text;
  239. if(strlen(text) >= 2)
  240. {
  241. if( (text[strlen(text) - 2] == 0x0d) && ((text[strlen(text) - 1] == 0x0a) ) )
  242. {
  243. sBody = sBody.Left(sBody.GetLength() - 2);
  244. sBody += "n";
  245. }
  246. }
  247. }
  248. }
  249. // check is it multipart
  250. CString sContentType = m_cMessage.GetContentType();
  251. if(sContentType.Compare("multipart/mixed") != 0)
  252. {
  253. m_bstBody = sBody;
  254. fclose(pfTemp);
  255. pfTemp = NULL;
  256. remove("temp.mme");
  257. return S_OK;
  258. }
  259. if(sBody.GetLength() > 2)
  260. sBody = sBody.Left(sBody.GetLength() - 2);
  261. m_bstBody = sBody;
  262. if(blIsBodyEmpty == false)
  263. // store new position
  264. lPos = ftell(pfTemp);
  265. // now parse attached files
  266. fseek(pfTemp, lPos, SEEK_SET);
  267. CHAR* pszStr = NULL;
  268. while(true)
  269. {
  270. // local headers   
  271. // get header out of the way
  272. while( (pszStr = fgets(text, sizeof(text) - 1, pfTemp)) )
  273. {
  274. if((*text == 'n') || (*text == 'r') || !*text)
  275. break;
  276. // try to get filename
  277. // Content-Disposition: attachment; filename="New Text Document.txt"
  278. if(strncmp(text, "Content-Disposition: attachment; filename=", strlen("Content-Disposition: attachment; filename=")) == 0)
  279. {
  280. CString sFileName = text + strlen("Content-Disposition: attachment; filename=") + 1;
  281. if(sFileName.GetLength() <= 3)
  282. {
  283. fclose(pfTemp);
  284. pfTemp = NULL;
  285. remove("temp.mme");
  286. return E_FAIL;
  287. }
  288. sFileName = sFileName.Left(sFileName.GetLength() - 3);
  289. // try to open file
  290. pfAttach = fopen(sFileName, "w+b");
  291. ATLASSERT(pfAttach);
  292. m_bstAttachedFiles += (LPCTSTR)sFileName;
  293. m_bstAttachedFiles += "n";
  294. }
  295. }
  296. // read current attachment
  297. memset(text, 0, sizeof(text));
  298. while( (pszStr = fgets(text, sizeof(text) - 1, pfTemp)) )
  299. {
  300. if(!strncmp(text, "--", 2) && !strncmp(text + 2, sBoundary, strlen(sBoundary)))
  301. break;      
  302. LONG x = 0;
  303. LONG triplet = 0; 
  304. LONG qpos = 0;
  305. LONG equals = 0;
  306. while(text[x])
  307. {
  308. if(base64_valid(text[x]))
  309. {
  310. if(text[x] == '=')
  311. {
  312. equals++;
  313. }
  314. else
  315. triplet |= (base64_get_value(text[x]) << ((3 - qpos) * 6));
  316. qpos++;
  317. }
  318. if(qpos == 4)
  319. {
  320. fputc((triplet & 0xFF0000) >> 16, pfAttach);
  321. if(equals < 2)
  322. fputc((triplet & 0xFF00) >> 8, pfAttach);
  323. if(!equals)
  324. fputc((triplet & 0xFF), pfAttach);
  325. triplet = 0;
  326. qpos = 0;
  327. }
  328. x ++;
  329. }
  330. memset(text, 0, sizeof(text));
  331. }
  332. if(pfAttach)
  333. {
  334. fclose(pfAttach);
  335. pfAttach = NULL;
  336. }
  337. if(pszStr == NULL)
  338. {
  339. // eof, stopping
  340. break;
  341. }
  342. }
  343. fclose(pfTemp);
  344. remove("temp.mme");
  345. }
  346. catch (...) 
  347. {
  348. if(pfTemp)
  349. fclose(pfTemp);
  350. if(pfAttach)
  351. fclose(pfAttach);
  352. remove("temp.mme");
  353. return E_FAIL;
  354. }
  355. return S_OK;
  356. }
  357. STDMETHODIMP CPOPLevel::get_From(BSTR *pVal)
  358. {
  359. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  360. ATLASSERT(pVal);
  361. try
  362. {
  363. bstr_t bstFrom;
  364. bstFrom = m_cMessage.GetFrom();
  365. *pVal = bstFrom.copy();
  366. }
  367. catch(...)
  368. {
  369. return E_FAIL;
  370. }
  371. return S_OK;
  372. }
  373. STDMETHODIMP CPOPLevel::get_To(BSTR *pVal)
  374. {
  375. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  376. ATLASSERT(pVal);
  377. try
  378. {
  379. bstr_t bstTo;
  380. bstTo = m_cMessage.GetTo();
  381. *pVal = bstTo.copy();
  382. }
  383. catch(...)
  384. {
  385. return E_FAIL;
  386. }
  387. return S_OK;
  388. }
  389. STDMETHODIMP CPOPLevel::get_CC(BSTR *pVal)
  390. {
  391. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  392. ATLASSERT(pVal);
  393. try
  394. {
  395. bstr_t bstCC;
  396. bstCC = m_cMessage.GetCC();
  397. *pVal = bstCC.copy();
  398. }
  399. catch(...)
  400. {
  401. return E_FAIL;
  402. }
  403. return S_OK;
  404. }
  405. STDMETHODIMP CPOPLevel::get_Date(BSTR *pVal)
  406. {
  407. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  408. ATLASSERT(pVal);
  409. try
  410. {
  411. bstr_t bstDate;
  412. bstDate = m_cMessage.GetDate();
  413. *pVal = bstDate.copy();
  414. }
  415. catch(...)
  416. {
  417. return E_FAIL;
  418. }
  419. return S_OK;
  420. }
  421. STDMETHODIMP CPOPLevel::get_Header(BSTR *pVal)
  422. {
  423. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  424. ATLASSERT(pVal);
  425. try
  426. {
  427. bstr_t bstHeader;
  428. bstHeader = m_cMessage.GetHeader();
  429. *pVal = bstHeader.copy();
  430. }
  431. catch(...)
  432. {
  433. return E_FAIL;
  434. }
  435. return S_OK;
  436. }
  437. STDMETHODIMP CPOPLevel::get_Subject(BSTR *pVal)
  438. {
  439. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  440. ATLASSERT(pVal);
  441. try
  442. {
  443. bstr_t bstSubject;
  444. bstSubject = m_cMessage.GetSubject();
  445. *pVal = bstSubject.copy();
  446. }
  447. catch(...)
  448. {
  449. return E_FAIL;
  450. }
  451. return S_OK;
  452. }
  453. STDMETHODIMP CPOPLevel::get_AttachedFiles(BSTR* pVal)
  454. {
  455. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  456. ATLASSERT(pVal);
  457. try
  458. {
  459. *pVal = m_bstAttachedFiles.copy();
  460. }
  461. catch(...)
  462. {
  463. return E_FAIL;
  464. }
  465. return S_OK;
  466. }
  467. STDMETHODIMP CPOPLevel::get_Body(BSTR *pVal)
  468. {
  469. AFX_MANAGE_STATE(AfxGetStaticModuleState())
  470. ATLASSERT(pVal);
  471. try
  472. {
  473. *pVal = m_bstBody.copy();
  474. }
  475. catch(...)
  476. {
  477. return E_FAIL;
  478. }
  479. return S_OK;
  480. }
  481. /*
  482.  * Eucalyptus
  483.  * by Paul A. Schifferer
  484.  *
  485.  * Module: base64.c
  486.  *     Base64 related functions
  487.  *
  488.  * Copyright