POP3

Mail_fetch/setup.php.

Defined (1)

The class is defined in the following location(s).

/wp-includes/class-pop3.php  
  1. class POP3 { 
  2. var $ERROR = ''; // Error string. 
  3.  
  4. var $TIMEOUT = 60; // Default timeout before giving up on a 
  5. // network operation. 
  6.  
  7. var $COUNT = -1; // Mailbox msg count 
  8.  
  9. var $BUFFER = 512; // Socket buffer for socket fgets() calls. 
  10. // Per RFC 1939 the returned line a POP3 
  11. // server can send is 512 bytes. 
  12.  
  13. var $FP = ''; // The connection to the server's 
  14. // file descriptor 
  15.  
  16. var $MAILSERVER = ''; // Set this to hard code the server name 
  17.  
  18. var $DEBUG = FALSE; // set to true to echo pop3 
  19. // commands and responses to error_log 
  20. // this WILL log passwords! 
  21.  
  22. var $BANNER = ''; // Holds the banner returned by the 
  23. // pop server - used for apop() 
  24.  
  25. var $ALLOWAPOP = FALSE; // Allow or disallow apop() 
  26. // This must be set to true 
  27. // manually 
  28.  
  29. /** 
  30. * PHP5 constructor. 
  31. */ 
  32. function __construct ( $server = '', $timeout = '' ) { 
  33. settype($this->BUFFER, "integer"); 
  34. if( !empty($server) ) { 
  35. // Do not allow programs to alter MAILSERVER 
  36. // if it is already specified. They can get around 
  37. // this if they -really- want to, so don't count on it. 
  38. if(empty($this->MAILSERVER)) 
  39. $this->MAILSERVER = $server; 
  40. if(!empty($timeout)) { 
  41. settype($timeout, "integer"); 
  42. $this->TIMEOUT = $timeout; 
  43. if (!ini_get('safe_mode')) 
  44. set_time_limit($timeout); 
  45. return true; 
  46.  
  47. /** 
  48. * PHP4 constructor. 
  49. */ 
  50. public function POP3( $server = '', $timeout = '' ) { 
  51. self::__construct( $server, $timeout ); 
  52.  
  53. function update_timer () { 
  54. if (!ini_get('safe_mode')) 
  55. set_time_limit($this->TIMEOUT); 
  56. return true; 
  57.  
  58. function connect ($server, $port = 110) { 
  59. // Opens a socket to the specified server. Unless overridden,  
  60. // port defaults to 110. Returns true on success, false on fail 
  61.  
  62. // If MAILSERVER is set, override $server with its value. 
  63.  
  64. if (!isset($port) || !$port) {$port = 110;} 
  65. if(!empty($this->MAILSERVER)) 
  66. $server = $this->MAILSERVER; 
  67.  
  68. if(empty($server)) { 
  69. $this->ERROR = "POP3 connect: " . _("No server specified"); 
  70. unset($this->FP); 
  71. return false; 
  72.  
  73. $fp = @fsockopen("$server", $port, $errno, $errstr); 
  74.  
  75. if(!$fp) { 
  76. $this->ERROR = "POP3 connect: " . _("Error ") . "[$errno] [$errstr]"; 
  77. unset($this->FP); 
  78. return false; 
  79.  
  80. socket_set_blocking($fp, -1); 
  81. $this->update_timer(); 
  82. $reply = fgets($fp, $this->BUFFER); 
  83. $reply = $this->strip_clf($reply); 
  84. if($this->DEBUG) 
  85. error_log("POP3 SEND [connect: $server] GOT [$reply]", 0); 
  86. if(!$this->is_ok($reply)) { 
  87. $this->ERROR = "POP3 connect: " . _("Error ") . "[$reply]"; 
  88. unset($this->FP); 
  89. return false; 
  90. $this->FP = $fp; 
  91. $this->BANNER = $this->parse_banner($reply); 
  92. return true; 
  93.  
  94. function user ($user = "") { 
  95. // Sends the USER command, returns true or false 
  96.  
  97. if( empty($user) ) { 
  98. $this->ERROR = "POP3 user: " . _("no login ID submitted"); 
  99. return false; 
  100. } elseif(!isset($this->FP)) { 
  101. $this->ERROR = "POP3 user: " . _("connection not established"); 
  102. return false; 
  103. } else { 
  104. $reply = $this->send_cmd("USER $user"); 
  105. if(!$this->is_ok($reply)) { 
  106. $this->ERROR = "POP3 user: " . _("Error ") . "[$reply]"; 
  107. return false; 
  108. } else 
  109. return true; 
  110.  
  111. function pass ($pass = "") { 
  112. // Sends the PASS command, returns # of msgs in mailbox,  
  113. // returns false (undef) on Auth failure 
  114.  
  115. if(empty($pass)) { 
  116. $this->ERROR = "POP3 pass: " . _("No password submitted"); 
  117. return false; 
  118. } elseif(!isset($this->FP)) { 
  119. $this->ERROR = "POP3 pass: " . _("connection not established"); 
  120. return false; 
  121. } else { 
  122. $reply = $this->send_cmd("PASS $pass"); 
  123. if(!$this->is_ok($reply)) { 
  124. $this->ERROR = "POP3 pass: " . _("Authentication failed") . " [$reply]"; 
  125. $this->quit(); 
  126. return false; 
  127. } else { 
  128. // Auth successful. 
  129. $count = $this->last("count"); 
  130. $this->COUNT = $count; 
  131. return $count; 
  132.  
  133. function apop ($login, $pass) { 
  134. // Attempts an APOP login. If this fails, it'll 
  135. // try a standard login. YOUR SERVER MUST SUPPORT 
  136. // THE USE OF THE APOP COMMAND! 
  137. // (apop is optional per rfc1939) 
  138.  
  139. if(!isset($this->FP)) { 
  140. $this->ERROR = "POP3 apop: " . _("No connection to server"); 
  141. return false; 
  142. } elseif(!$this->ALLOWAPOP) { 
  143. $retVal = $this->login($login, $pass); 
  144. return $retVal; 
  145. } elseif(empty($login)) { 
  146. $this->ERROR = "POP3 apop: " . _("No login ID submitted"); 
  147. return false; 
  148. } elseif(empty($pass)) { 
  149. $this->ERROR = "POP3 apop: " . _("No password submitted"); 
  150. return false; 
  151. } else { 
  152. $banner = $this->BANNER; 
  153. if( (!$banner) or (empty($banner)) ) { 
  154. $this->ERROR = "POP3 apop: " . _("No server banner") . ' - ' . _("abort"); 
  155. $retVal = $this->login($login, $pass); 
  156. return $retVal; 
  157. } else { 
  158. $AuthString = $banner; 
  159. $AuthString .= $pass; 
  160. $APOPString = md5($AuthString); 
  161. $cmd = "APOP $login $APOPString"; 
  162. $reply = $this->send_cmd($cmd); 
  163. if(!$this->is_ok($reply)) { 
  164. $this->ERROR = "POP3 apop: " . _("apop authentication failed") . ' - ' . _("abort"); 
  165. $retVal = $this->login($login, $pass); 
  166. return $retVal; 
  167. } else { 
  168. // Auth successful. 
  169. $count = $this->last("count"); 
  170. $this->COUNT = $count; 
  171. return $count; 
  172.  
  173. function login ($login = "", $pass = "") { 
  174. // Sends both user and pass. Returns # of msgs in mailbox or 
  175. // false on failure (or -1, if the error occurs while getting 
  176. // the number of messages.) 
  177.  
  178. if( !isset($this->FP) ) { 
  179. $this->ERROR = "POP3 login: " . _("No connection to server"); 
  180. return false; 
  181. } else { 
  182. $fp = $this->FP; 
  183. if( !$this->user( $login ) ) { 
  184. // Preserve the error generated by user() 
  185. return false; 
  186. } else { 
  187. $count = $this->pass($pass); 
  188. if( (!$count) || ($count == -1) ) { 
  189. // Preserve the error generated by last() and pass() 
  190. return false; 
  191. } else 
  192. return $count; 
  193.  
  194. function top ($msgNum, $numLines = "0") { 
  195. // Gets the header and first $numLines of the msg body 
  196. // returns data in an array with each returned line being 
  197. // an array element. If $numLines is empty, returns 
  198. // only the header information, and none of the body. 
  199.  
  200. if(!isset($this->FP)) { 
  201. $this->ERROR = "POP3 top: " . _("No connection to server"); 
  202. return false; 
  203. $this->update_timer(); 
  204.  
  205. $fp = $this->FP; 
  206. $buffer = $this->BUFFER; 
  207. $cmd = "TOP $msgNum $numLines"; 
  208. fwrite($fp, "TOP $msgNum $numLines\r\n"); 
  209. $reply = fgets($fp, $buffer); 
  210. $reply = $this->strip_clf($reply); 
  211. if($this->DEBUG) { 
  212. @error_log("POP3 SEND [$cmd] GOT [$reply]", 0); 
  213. if(!$this->is_ok($reply)) 
  214. $this->ERROR = "POP3 top: " . _("Error ") . "[$reply]"; 
  215. return false; 
  216.  
  217. $count = 0; 
  218. $MsgArray = array(); 
  219.  
  220. $line = fgets($fp, $buffer); 
  221. while ( !preg_match('/^\.\r\n/', $line)) 
  222. $MsgArray[$count] = $line; 
  223. $count++; 
  224. $line = fgets($fp, $buffer); 
  225. if(empty($line)) { break; } 
  226.  
  227. return $MsgArray; 
  228.  
  229. function pop_list ($msgNum = "") { 
  230. // If called with an argument, returns that msgs' size in octets 
  231. // No argument returns an associative array of undeleted 
  232. // msg numbers and their sizes in octets 
  233.  
  234. if(!isset($this->FP)) 
  235. $this->ERROR = "POP3 pop_list: " . _("No connection to server"); 
  236. return false; 
  237. $fp = $this->FP; 
  238. $Total = $this->COUNT; 
  239. if( (!$Total) or ($Total == -1) ) 
  240. return false; 
  241. if($Total == 0) 
  242. return array("0", "0"); 
  243. // return -1; // mailbox empty 
  244.  
  245. $this->update_timer(); 
  246.  
  247. if(!empty($msgNum)) 
  248. $cmd = "LIST $msgNum"; 
  249. fwrite($fp, "$cmd\r\n"); 
  250. $reply = fgets($fp, $this->BUFFER); 
  251. $reply = $this->strip_clf($reply); 
  252. if($this->DEBUG) { 
  253. @error_log("POP3 SEND [$cmd] GOT [$reply]", 0); 
  254. if(!$this->is_ok($reply)) 
  255. $this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]"; 
  256. return false; 
  257. list($junk, $num, $size) = preg_split('/\s+/', $reply); 
  258. return $size; 
  259. $cmd = "LIST"; 
  260. $reply = $this->send_cmd($cmd); 
  261. if(!$this->is_ok($reply)) 
  262. $reply = $this->strip_clf($reply); 
  263. $this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]"; 
  264. return false; 
  265. $MsgArray = array(); 
  266. $MsgArray[0] = $Total; 
  267. for($msgC=1;$msgC <= $Total; $msgC++) 
  268. if($msgC > $Total) { break; } 
  269. $line = fgets($fp, $this->BUFFER); 
  270. $line = $this->strip_clf($line); 
  271. if(strpos($line, '.') === 0) 
  272. $this->ERROR = "POP3 pop_list: " . _("Premature end of list"); 
  273. return false; 
  274. list($thisMsg, $msgSize) = preg_split('/\s+/', $line); 
  275. settype($thisMsg, "integer"); 
  276. if($thisMsg != $msgC) 
  277. $MsgArray[$msgC] = "deleted"; 
  278. else 
  279. $MsgArray[$msgC] = $msgSize; 
  280. return $MsgArray; 
  281.  
  282. function get ($msgNum) { 
  283. // Retrieve the specified msg number. Returns an array 
  284. // where each line of the msg is an array element. 
  285.  
  286. if(!isset($this->FP)) 
  287. $this->ERROR = "POP3 get: " . _("No connection to server"); 
  288. return false; 
  289.  
  290. $this->update_timer(); 
  291.  
  292. $fp = $this->FP; 
  293. $buffer = $this->BUFFER; 
  294. $cmd = "RETR $msgNum"; 
  295. $reply = $this->send_cmd($cmd); 
  296.  
  297. if(!$this->is_ok($reply)) 
  298. $this->ERROR = "POP3 get: " . _("Error ") . "[$reply]"; 
  299. return false; 
  300.  
  301. $count = 0; 
  302. $MsgArray = array(); 
  303.  
  304. $line = fgets($fp, $buffer); 
  305. while ( !preg_match('/^\.\r\n/', $line)) 
  306. if ( $line{0} == '.' ) { $line = substr($line, 1); } 
  307. $MsgArray[$count] = $line; 
  308. $count++; 
  309. $line = fgets($fp, $buffer); 
  310. if(empty($line)) { break; } 
  311. return $MsgArray; 
  312.  
  313. function last ( $type = "count" ) { 
  314. // Returns the highest msg number in the mailbox. 
  315. // returns -1 on error, 0+ on success, if type != count 
  316. // results in a popstat() call (2 element array returned) 
  317.  
  318. $last = -1; 
  319. if(!isset($this->FP)) 
  320. $this->ERROR = "POP3 last: " . _("No connection to server"); 
  321. return $last; 
  322.  
  323. $reply = $this->send_cmd("STAT"); 
  324. if(!$this->is_ok($reply)) 
  325. $this->ERROR = "POP3 last: " . _("Error ") . "[$reply]"; 
  326. return $last; 
  327.  
  328. $Vars = preg_split('/\s+/', $reply); 
  329. $count = $Vars[1]; 
  330. $size = $Vars[2]; 
  331. settype($count, "integer"); 
  332. settype($size, "integer"); 
  333. if($type != "count") 
  334. return array($count, $size); 
  335. return $count; 
  336.  
  337. function reset () { 
  338. // Resets the status of the remote server. This includes 
  339. // resetting the status of ALL msgs to not be deleted. 
  340. // This method automatically closes the connection to the server. 
  341.  
  342. if(!isset($this->FP)) 
  343. $this->ERROR = "POP3 reset: " . _("No connection to server"); 
  344. return false; 
  345. $reply = $this->send_cmd("RSET"); 
  346. if(!$this->is_ok($reply)) 
  347. // The POP3 RSET command -never- gives a -ERR 
  348. // response - if it ever does, something truly 
  349. // wild is going on. 
  350.  
  351. $this->ERROR = "POP3 reset: " . _("Error ") . "[$reply]"; 
  352. @error_log("POP3 reset: ERROR [$reply]", 0); 
  353. $this->quit(); 
  354. return true; 
  355.  
  356. function send_cmd ( $cmd = "" ) 
  357. // Sends a user defined command string to the 
  358. // POP server and returns the results. Useful for 
  359. // non-compliant or custom POP servers. 
  360. // Do NOT includ the \r\n as part of your command 
  361. // string - it will be appended automatically. 
  362.  
  363. // The return value is a standard fgets() call, which 
  364. // will read up to $this->BUFFER bytes of data, until it 
  365. // encounters a new line, or EOF, whichever happens first. 
  366.  
  367. // This method works best if $cmd responds with only 
  368. // one line of data. 
  369.  
  370. if(!isset($this->FP)) 
  371. $this->ERROR = "POP3 send_cmd: " . _("No connection to server"); 
  372. return false; 
  373.  
  374. if(empty($cmd)) 
  375. $this->ERROR = "POP3 send_cmd: " . _("Empty command string"); 
  376. return ""; 
  377.  
  378. $fp = $this->FP; 
  379. $buffer = $this->BUFFER; 
  380. $this->update_timer(); 
  381. fwrite($fp, "$cmd\r\n"); 
  382. $reply = fgets($fp, $buffer); 
  383. $reply = $this->strip_clf($reply); 
  384. if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]", 0); } 
  385. return $reply; 
  386.  
  387. function quit() { 
  388. // Closes the connection to the POP3 server, deleting 
  389. // any msgs marked as deleted. 
  390.  
  391. if(!isset($this->FP)) 
  392. $this->ERROR = "POP3 quit: " . _("connection does not exist"); 
  393. return false; 
  394. $fp = $this->FP; 
  395. $cmd = "QUIT"; 
  396. fwrite($fp, "$cmd\r\n"); 
  397. $reply = fgets($fp, $this->BUFFER); 
  398. $reply = $this->strip_clf($reply); 
  399. if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]", 0); } 
  400. fclose($fp); 
  401. unset($this->FP); 
  402. return true; 
  403.  
  404. function popstat () { 
  405. // Returns an array of 2 elements. The number of undeleted 
  406. // msgs in the mailbox, and the size of the mbox in octets. 
  407.  
  408. $PopArray = $this->last("array"); 
  409.  
  410. if($PopArray == -1) { return false; } 
  411.  
  412. if( (!$PopArray) or (empty($PopArray)) ) 
  413. return false; 
  414. return $PopArray; 
  415.  
  416. function uidl ($msgNum = "") 
  417. // Returns the UIDL of the msg specified. If called with 
  418. // no arguments, returns an associative array where each 
  419. // undeleted msg num is a key, and the msg's uidl is the element 
  420. // Array element 0 will contain the total number of msgs 
  421.  
  422. if(!isset($this->FP)) { 
  423. $this->ERROR = "POP3 uidl: " . _("No connection to server"); 
  424. return false; 
  425.  
  426. $fp = $this->FP; 
  427. $buffer = $this->BUFFER; 
  428.  
  429. if(!empty($msgNum)) { 
  430. $cmd = "UIDL $msgNum"; 
  431. $reply = $this->send_cmd($cmd); 
  432. if(!$this->is_ok($reply)) 
  433. $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]"; 
  434. return false; 
  435. list ($ok, $num, $myUidl) = preg_split('/\s+/', $reply); 
  436. return $myUidl; 
  437. } else { 
  438. $this->update_timer(); 
  439.  
  440. $UIDLArray = array(); 
  441. $Total = $this->COUNT; 
  442. $UIDLArray[0] = $Total; 
  443.  
  444. if ($Total < 1) 
  445. return $UIDLArray; 
  446. $cmd = "UIDL"; 
  447. fwrite($fp, "UIDL\r\n"); 
  448. $reply = fgets($fp, $buffer); 
  449. $reply = $this->strip_clf($reply); 
  450. if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]", 0); } 
  451. if(!$this->is_ok($reply)) 
  452. $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]"; 
  453. return false; 
  454.  
  455. $line = ""; 
  456. $count = 1; 
  457. $line = fgets($fp, $buffer); 
  458. while ( !preg_match('/^\.\r\n/', $line)) { 
  459. list ($msg, $msgUidl) = preg_split('/\s+/', $line); 
  460. $msgUidl = $this->strip_clf($msgUidl); 
  461. if($count == $msg) { 
  462. $UIDLArray[$msg] = $msgUidl; 
  463. else 
  464. $UIDLArray[$count] = 'deleted'; 
  465. $count++; 
  466. $line = fgets($fp, $buffer); 
  467. return $UIDLArray; 
  468.  
  469. function delete ($msgNum = "") { 
  470. // Flags a specified msg as deleted. The msg will not 
  471. // be deleted until a quit() method is called. 
  472.  
  473. if(!isset($this->FP)) 
  474. $this->ERROR = "POP3 delete: " . _("No connection to server"); 
  475. return false; 
  476. if(empty($msgNum)) 
  477. $this->ERROR = "POP3 delete: " . _("No msg number submitted"); 
  478. return false; 
  479. $reply = $this->send_cmd("DELE $msgNum"); 
  480. if(!$this->is_ok($reply)) 
  481. $this->ERROR = "POP3 delete: " . _("Command failed ") . "[$reply]"; 
  482. return false; 
  483. return true; 
  484.  
  485. // ********************************************************* 
  486.  
  487. // The following methods are internal to the class. 
  488.  
  489. function is_ok ($cmd = "") { 
  490. // Return true or false on +OK or -ERR 
  491.  
  492. if( empty($cmd) ) 
  493. return false; 
  494. else 
  495. return( stripos($cmd, '+OK') !== false ); 
  496.  
  497. function strip_clf ($text = "") { 
  498. // Strips \r\n from server responses 
  499.  
  500. if(empty($text)) 
  501. return $text; 
  502. else { 
  503. $stripped = str_replace(array("\r", "\n"), '', $text); 
  504. return $stripped; 
  505.  
  506. function parse_banner ( $server_text ) { 
  507. $outside = true; 
  508. $banner = ""; 
  509. $length = strlen($server_text); 
  510. for($count =0; $count < $length; $count++) 
  511. $digit = substr($server_text, $count, 1); 
  512. if(!empty($digit)) { 
  513. if( (!$outside) && ($digit != '<') && ($digit != '>') ) 
  514. $banner .= $digit; 
  515. if ($digit == '<') 
  516. $outside = false; 
  517. if($digit == '>') 
  518. $outside = true; 
  519. $banner = $this->strip_clf($banner); // Just in case 
  520. return "<$banner>"; 
  521.  
  522. } // End class