PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/pop3/Pop3Client.cs

http://magas.codeplex.com
C# | 367 lines | 261 code | 77 blank | 29 comment | 21 complexity | 5a3b96174a190798ddba33eca0dc0384 MD5 | raw file
  1. using System;
  2. using System.Collections;
  3. using System.IO;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Threading;
  7. using System.Text;
  8. using System.Text.RegularExpressions;
  9. using System.Diagnostics;
  10. namespace Pop3
  11. {
  12. public class Pop3Client
  13. {
  14. private Pop3Credential m_credential;
  15. private const int m_pop3port = 110;
  16. private const int MAX_BUFFER_READ_SIZE = 256;
  17. private long m_inboxPosition = 0;
  18. private long m_directPosition = -1;
  19. private Socket m_socket = null;
  20. private Pop3Message m_pop3Message = null;
  21. public Pop3Credential UserDetails
  22. {
  23. set { m_credential = value; }
  24. get { return m_credential; }
  25. }
  26. public long InboxPosition
  27. {
  28. get
  29. {
  30. return this.m_pop3Message.InboxPosition;
  31. }
  32. }
  33. public string ContentType
  34. {
  35. get { return m_pop3Message.ContentType; }
  36. }
  37. public string From
  38. {
  39. get { return m_pop3Message.From; }
  40. }
  41. public string To
  42. {
  43. get { return m_pop3Message.To; }
  44. }
  45. public DateTime Date
  46. {
  47. get { return m_pop3Message.Date; }
  48. }
  49. public string Subject
  50. {
  51. get { return m_pop3Message.Subject; }
  52. }
  53. public string Body
  54. {
  55. get { return m_pop3Message.Body; }
  56. }
  57. public IEnumerator MultipartEnumerator
  58. {
  59. get { return m_pop3Message.MultipartEnumerator; }
  60. }
  61. public bool IsMultipart
  62. {
  63. get { return m_pop3Message.IsMultipart; }
  64. }
  65. public Pop3Client(string user, string pass, string server)
  66. {
  67. m_credential = new Pop3Credential(user,pass,server);
  68. }
  69. private Socket GetClientSocket()
  70. {
  71. Socket s = null;
  72. try
  73. {
  74. IPHostEntry hostEntry = null;
  75. // Get host related information.
  76. hostEntry = Dns.Resolve(m_credential.Server);
  77. // Loop through the AddressList to obtain the supported
  78. // AddressFamily. This is to avoid an exception that
  79. // occurs when the host IP Address is not compatible
  80. // with the address family
  81. // (typical in the IPv6 case).
  82. foreach(IPAddress address in hostEntry.AddressList)
  83. {
  84. IPEndPoint ipe = new IPEndPoint(address, m_pop3port);
  85. Socket tempSocket =
  86. new Socket(ipe.AddressFamily,
  87. SocketType.Stream, ProtocolType.Tcp);
  88. tempSocket.Connect(ipe);
  89. if(tempSocket.Connected)
  90. {
  91. // we have a connection.
  92. // return this socket ...
  93. s = tempSocket;
  94. break;
  95. }
  96. else
  97. {
  98. continue;
  99. }
  100. }
  101. }
  102. catch(Exception e)
  103. {
  104. throw new Pop3ConnectException(e.ToString());
  105. }
  106. // throw exception if can't connect ...
  107. if(s == null)
  108. {
  109. throw new Pop3ConnectException("Error : connecting to "
  110. +m_credential.Server);
  111. }
  112. return s;
  113. }
  114. //send the data to server
  115. private void Send(String data)
  116. {
  117. if(m_socket == null)
  118. {
  119. throw new Pop3MessageException("Pop3 connection is closed");
  120. }
  121. try
  122. {
  123. // Convert the string data to byte data
  124. // using ASCII encoding.
  125. byte[] byteData = Encoding.ASCII.GetBytes(data+"\r\n");
  126. // Begin sending the data to the remote device.
  127. m_socket.Send(byteData);
  128. }
  129. catch(Exception e)
  130. {
  131. throw new Pop3SendException(e.ToString());
  132. }
  133. }
  134. private string GetPop3String()
  135. {
  136. if(m_socket == null)
  137. {
  138. throw new
  139. Pop3MessageException("Connection to POP3 server is closed");
  140. }
  141. byte[] buffer = new byte[MAX_BUFFER_READ_SIZE];
  142. string line = null;
  143. try
  144. {
  145. int byteCount =
  146. m_socket.Receive(buffer,buffer.Length,0);
  147. line =
  148. Encoding.ASCII.GetString(buffer, 0, byteCount);
  149. }
  150. catch(Exception e)
  151. {
  152. throw new Pop3ReceiveException(e.ToString());
  153. }
  154. return line;
  155. }
  156. private void LoginToInbox()
  157. {
  158. string returned;
  159. // send username ...
  160. Send("user "+m_credential.User);
  161. // get response ...
  162. returned = GetPop3String();
  163. if( !returned.Substring(0,3).Equals("+OK") )
  164. {
  165. throw new Pop3LoginException("login not excepted");
  166. }
  167. // send password ...
  168. Send("pass "+m_credential.Pass);
  169. // get response ...
  170. returned = GetPop3String();
  171. if( !returned.Substring(0,3).Equals("+OK") )
  172. {
  173. throw new
  174. Pop3LoginException("login/password not accepted");
  175. }
  176. }
  177. public long MessageCount
  178. {
  179. get
  180. {
  181. long count = 0;
  182. if(m_socket==null)
  183. {
  184. throw new Pop3MessageException("Pop3 server not connected");
  185. }
  186. Send("stat");
  187. string returned = GetPop3String();
  188. // if values returned ...
  189. if( Regex.Match(returned,
  190. @"^.*\+OK[ | ]+([0-9]+)[ | ]+.*$").Success )
  191. {
  192. // get number of emails ...
  193. count = long.Parse( Regex
  194. .Replace(returned.Replace("\r\n","")
  195. , @"^.*\+OK[ | ]+([0-9]+)[ | ]+.*$" ,"$1") );
  196. }
  197. return(count);
  198. }
  199. }
  200. public void CloseConnection()
  201. {
  202. Send("quit");
  203. if (m_socket != null)
  204. {
  205. m_socket.Close();
  206. m_socket = null;
  207. }
  208. m_pop3Message = null;
  209. }
  210. public bool DeleteEmail()
  211. {
  212. bool ret = false;
  213. Send("dele "+m_inboxPosition);
  214. string returned = GetPop3String();
  215. if( Regex.Match(returned,
  216. @"^.*\+OK.*$").Success )
  217. {
  218. ret = true;
  219. }
  220. return ret;
  221. }
  222. public bool NextEmail(long directPosition)
  223. {
  224. bool ret;
  225. if( directPosition >= 0 )
  226. {
  227. m_directPosition = directPosition;
  228. ret = NextEmail();
  229. }
  230. else
  231. {
  232. throw new Pop3MessageException("Position less than zero");
  233. }
  234. return ret;
  235. }
  236. public bool NextEmail()
  237. {
  238. string returned;
  239. long pos;
  240. if(m_directPosition == -1)
  241. {
  242. if(m_inboxPosition == 0)
  243. {
  244. pos = 1;
  245. }
  246. else
  247. {
  248. pos = m_inboxPosition + 1;
  249. }
  250. }
  251. else
  252. {
  253. pos = m_directPosition+1;
  254. m_directPosition = -1;
  255. }
  256. // send username ...
  257. Send("list "+pos.ToString());
  258. // get response ...
  259. returned = GetPop3String();
  260. // if email does not exist at this position
  261. // then return false ...
  262. if( returned.Substring(0,4).Equals("-ERR") )
  263. {
  264. return false;
  265. }
  266. m_inboxPosition = pos;
  267. // strip out CRLF ...
  268. string[] noCr = returned.Split(new char[]{ '\r' });
  269. // get size ...
  270. string[] elements = noCr[0].Split(new char[]{ ' ' });
  271. long size = long.Parse(elements[2]);
  272. // ... else read email data
  273. m_pop3Message = new Pop3Message(m_inboxPosition,size,m_socket);
  274. return true;
  275. }
  276. public void OpenInbox()
  277. {
  278. // get a socket ...
  279. m_socket = GetClientSocket();
  280. // get initial header from POP3 server ...
  281. string header = GetPop3String();
  282. if( !header.Substring(0,3).Equals("+OK") )
  283. {
  284. throw new Exception("Invalid initial POP3 response");
  285. }
  286. // send login details ...
  287. LoginToInbox();
  288. }
  289. }
  290. }