squirrelmail-webmail  1.4.22
About: SquirrelMail is a standards-based webmail package with strong MIME support, address books, and folder manipulation (written in PHP4).
  Fossies Dox: squirrelmail-webmail-1.4.22.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

imap_general.php
Go to the documentation of this file.
1 <?php
2 
16 require_once(SM_PATH . 'functions/page_header.php');
17 require_once(SM_PATH . 'functions/auth.php');
18 
19 
26 function sqimap_session_id($unique_id = FALSE) {
27  static $sqimap_session_id = 1;
28 
29  if (!$unique_id) {
30  return( sprintf("A%03d", $sqimap_session_id++) );
31  } else {
32  return( sprintf("A%03d", $sqimap_session_id++) . ' UID' );
33  }
34 }
35 
40 function sqimap_run_command_list ($imap_stream, $query, $handle_errors, &$response, &$message, $unique_id = false) {
41  if ($imap_stream) {
42  $sid = sqimap_session_id($unique_id);
43  fputs ($imap_stream, $sid . ' ' . $query . "\r\n");
44  $read = sqimap_read_data_list ($imap_stream, $sid, $handle_errors, $response, $message, $query );
45  return $read;
46  } else {
49  require_once(SM_PATH . 'functions/display_messages.php');
50  $string = "<b><font color=\"$color[2]\">\n" .
51  _("ERROR: No available IMAP stream.") .
52  "</b></font>\n";
53  error_box($string,$color);
54  return false;
55  }
56 }
57 
58 function sqimap_run_command ($imap_stream, $query, $handle_errors, &$response,
59  &$message, $unique_id = false,$filter=false,
60  $outputstream=false,$no_return=false) {
61  if ($imap_stream) {
62  $sid = sqimap_session_id($unique_id);
63  fputs ($imap_stream, $sid . ' ' . $query . "\r\n");
64  $read = sqimap_read_data ($imap_stream, $sid, $handle_errors, $response,
65  $message, $query,$filter,$outputstream,$no_return);
66  return $read;
67  } else {
70  require_once(SM_PATH . 'functions/display_messages.php');
71  $string = "<b><font color=\"$color[2]\">\n" .
72  _("ERROR: No available IMAP stream.") .
73  "</b></font>\n";
74  error_box($string,$color);
75  return false;
76  }
77 }
78 
79 function sqimap_run_literal_command($imap_stream, $query, $handle_errors, &$response, &$message, $unique_id = false) {
80  if ($imap_stream) {
81  $sid = sqimap_session_id($unique_id);
82  $command = sprintf("%s {%d}\r\n", $query['command'], strlen($query['literal_args'][0]));
83  fputs($imap_stream, $sid . ' ' . $command);
84 
85  // TODO: Put in error handling here //
86  $read = sqimap_read_data($imap_stream, $sid, $handle_errors, $response, $message, $query['command']);
87 
88  $i = 0;
89  $cnt = count($query['literal_args']);
90  while( $i < $cnt ) {
91  if (($cnt > 1) && ($i < ($cnt - 1))) {
92  $command = sprintf("%s {%d}\r\n", $query['literal_args'][$i], strlen($query['literal_args'][$i+1]));
93  } else {
94  $command = sprintf("%s\r\n", $query['literal_args'][$i]);
95  }
96 
97  fputs($imap_stream, $command);
98  $read = sqimap_read_data($imap_stream, $sid, $handle_errors, $response, $message, $query['command']);
99 
100  $i++;
101 
102  }
103  return $read;
104  } else {
107  require_once(SM_PATH . 'functions/display_messages.php');
108  $string = "<b><font color=\"$color[2]\">\n" .
109  _("ERROR: No available IMAP stream.") .
110  "</b></font>\n";
111  error_box($string,$color);
112  return false;
113  }
114 }
115 
116 
124  $read = '';
125  $buffer = 4096;
126  $results = '';
127  $offset = 0;
128  while (strpos($results, "\r\n", $offset) === false) {
129  if (!($read = fgets($imap_stream, $buffer))) {
130  /* this happens in case of an error */
131  /* reset $results because it's useless */
132  $results = false;
133  break;
134  }
135  if ( $results != '' ) {
136  $offset = strlen($results) - 1;
137  }
138  $results .= $read;
139  }
140  return $results;
141 }
142 
143 function sqimap_fread($imap_stream,$iSize,$filter=false,
144  $outputstream=false, $no_return=false) {
145  if (!$filter || !$outputstream) {
146  $iBufferSize = $iSize;
147  } else {
148  // see php bug 24033. They changed fread behaviour %$^&$%
149  $iBufferSize = 7800; // multiple of 78 in case of base64 decoding.
150  }
151  if ($iSize < $iBufferSize) {
152  $iBufferSize = $iSize;
153  }
154 
155  $iRetrieved = 0;
156  $results = '';
157  $sRead = $sReadRem = '';
158  // NB: fread can also stop at end of a packet on sockets.
159  while ($iRetrieved < $iSize) {
160  $sRead = fread($imap_stream,$iBufferSize);
161  $iLength = strlen($sRead);
162  $iRetrieved += $iLength ;
163  $iRemaining = $iSize - $iRetrieved;
164  if ($iRemaining < $iBufferSize) {
165  $iBufferSize = $iRemaining;
166  }
167  if ($sRead == '') {
168  $results = false;
169  break;
170  }
171  if ($sReadRem != '') {
172  $sRead = $sReadRem . $sRead;
173  $sReadRem = '';
174  }
175 
176  if ($filter && $sRead != '') {
177  // in case the filter is base64 decoding we return a remainder
178  $sReadRem = $filter($sRead);
179  }
180  if ($outputstream && $sRead != '') {
181  if (is_resource($outputstream)) {
182  fwrite($outputstream,$sRead);
183  } else if ($outputstream == 'php://stdout') {
184  echo $sRead;
185  }
186  }
187  if ($no_return) {
188  $sRead = '';
189  } else {
190  $results .= $sRead;
191  }
192  }
193  return $results;
194 }
195 
201 function sqimap_read_data_list ($imap_stream, $tag_uid, $handle_errors,
202  &$response, &$message, $query = '',
203  $filter = false, $outputstream = false, $no_return = false) {
205  $read = '';
206  $tag_uid_a = explode(' ',trim($tag_uid));
207  $tag = $tag_uid_a[0];
208  $resultlist = array();
209  $data = array();
211 
212  $i = 0;
213  while ($read) {
214  $char = $read{0};
215  switch ($char)
216  {
217  case '+':
218  {
219  $response = 'OK';
220  break 2;
221  }
222  default:
224  break;
225 
226  case $tag{0}:
227  {
228  /* get the command */
229  $arg = '';
230  $i = strlen($tag)+1;
231  $s = substr($read,$i);
232  if (($j = strpos($s,' ')) || ($j = strpos($s,"\n"))) {
233  $arg = substr($s,0,$j);
234  }
235  $found_tag = substr($read,0,$i-1);
236  if ($arg && $found_tag==$tag) {
237  switch ($arg)
238  {
239  case 'OK':
240  case 'BAD':
241  case 'NO':
242  case 'BYE':
243  case 'PREAUTH':
244  $response = $arg;
245  $message = trim(substr($read,$i+strlen($arg)));
246  break 3; /* switch switch while */
247  default:
248  /* this shouldn't happen */
249  $response = $arg;
250  $message = trim(substr($read,$i+strlen($arg)));
251  break 3; /* switch switch while */
252  }
253  } elseif($found_tag !== $tag) {
254  /* reset data array because we do not need this reponse */
255  $data = array();
257  break;
258  }
259  } // end case $tag{0}
260 
261  case '*':
262  {
263  if (preg_match('/^\*\s\d+\sFETCH/',$read)) {
264  /* check for literal */
265  $s = substr($read,-3);
266  $fetch_data = array();
267  do { /* outer loop, continue until next untagged fetch
268  or tagged reponse */
269  do { /* innerloop for fetching literals. with this loop
270  we prohibid that literal responses appear in the
271  outer loop so we can trust the untagged and
272  tagged info provided by $read */
273  $read_literal = false;
274  if ($s === "}\r\n") {
275  $j = strrpos($read,'{');
276  $iLit = substr($read,$j+1,-3);
277  $fetch_data[] = $read;
278  $sLiteral = sqimap_fread($imap_stream,$iLit,$filter,$outputstream,$no_return);
279  if ($sLiteral === false) { /* error */
280  break 4; /* while while switch while */
281  }
282  /* backwards compattibility */
283  $aLiteral = explode("\n", $sLiteral);
284  /* release not neaded data */
285  unset($sLiteral);
286  foreach ($aLiteral as $line) {
287  $fetch_data[] = $line ."\n";
288  }
289  /* release not neaded data */
290  unset($aLiteral);
291  /* next fgets belongs to this fetch because
292  we just got the exact literalsize and there
293  must follow data to complete the response */
295  if ($read === false) { /* error */
296  break 4; /* while while switch while */
297  }
298  $s = substr($read,-3);
299  $read_literal = true;
300  continue;
301  } else {
302  $fetch_data[] = $read;
303  }
304  /* retrieve next line and check in the while
305  statements if it belongs to this fetch response */
307  if ($read === false) { /* error */
308  break 4; /* while while switch while */
309  }
310  /* check for next untagged reponse and break */
311  if ($read{0} == '*') break 2;
312  $s = substr($read,-3);
313  } while ($s === "}\r\n" || $read_literal);
314  $s = substr($read,-3);
315  } while ($read{0} !== '*' &&
316  substr($read,0,strlen($tag)) !== $tag);
317  $resultlist[] = $fetch_data;
318  /* release not neaded data */
319  unset ($fetch_data);
320  } else {
321  $s = substr($read,-3);
322  do {
323  if ($s === "}\r\n") {
324  $j = strrpos($read,'{');
325  $iLit = substr($read,$j+1,-3);
326  // check for numeric value to avoid that untagged responses like:
327  // * OK [PARSE] Unexpected characters at end of address: {SET:debug=51}
328  // will trigger literal fetching ({SET:debug=51} !== int )
329  if (is_numeric($iLit)) {
330  $data[] = $read;
331  $sLiteral = fread($imap_stream,$iLit);
332  if ($sLiteral === false) { /* error */
333  $read = false;
334  break 3; /* while switch while */
335  }
336  $data[] = $sLiteral;
338  } else {
339  $data[] = $read;
340  }
341  } else {
342  $data[] = $read;
343  }
345  if ($read === false) {
346  break 3; /* while switch while */
347  } else if ($read{0} == '*') {
348  break;
349  }
350  $s = substr($read,-3);
351  } while ($s === "}\r\n");
352  break 1;
353  }
354  break;
355  } // end case '*'
356  } // end switch
357  } // end while
358 
359  /* error processing in case $read is false */
360  if ($read === false) {
361  unset($data);
363  require_once(SM_PATH . 'functions/display_messages.php');
364  $string = "<b><font color=\"$color[2]\">\n" .
365  _("ERROR: Connection dropped by IMAP server.") .
366  "</b><br />\n";
367  $cmd = explode(' ',$query);
368  $cmd = strtolower($cmd[0]);
369  if ($query != '' && $cmd != 'login') {
370  $string .= ("Query:") . ' '. htmlspecialchars($query)
371  . '<br />' . "</font><br />\n";
372  }
373  error_box($string,$color);
374  exit;
375  }
376 
377  /* Set $resultlist array */
378  if (!empty($data)) {
379  $resultlist[] = $data;
380  }
381  elseif (empty($resultlist)) {
382  $resultlist[] = array();
383  }
384 
385  /* Return result or handle errors */
386  if ($handle_errors == false) {
387  return( $resultlist );
388  }
389  switch ($response) {
390  case 'OK':
391  return $resultlist;
392  break;
393  case 'NO':
394  /* ignore this error from M$ exchange, it is not fatal (aka bug) */
395  if (strstr($message, 'command resulted in') === false) {
397  require_once(SM_PATH . 'functions/display_messages.php');
398  $string = "<b><font color=\"$color[2]\">\n" .
399  _("ERROR: Could not complete request.") .
400  "</b><br />\n" .
401  _("Query:") . ' ' .
402  htmlspecialchars($query) . '<br />' .
403  _("Reason Given:") . ' ' .
404  htmlspecialchars($message) . "</font><br />\n";
405  error_box($string,$color);
406  echo '</body></html>';
407  exit;
408  }
409  break;
410  case 'BAD':
412  require_once(SM_PATH . 'functions/display_messages.php');
413  $string = "<b><font color=\"$color[2]\">\n" .
414  _("ERROR: Bad or malformed request.") .
415  "</b><br />\n" .
416  _("Query:") . ' '.
417  htmlspecialchars($query) . '<br />' .
418  _("Server responded:") . ' ' .
419  htmlspecialchars($message) . "</font><br />\n";
420  error_box($string,$color);
421  echo '</body></html>';
422  exit;
423  case 'BYE':
425  require_once(SM_PATH . 'functions/display_messages.php');
426  $string = "<b><font color=\"$color[2]\">\n" .
427  _("ERROR: IMAP server closed the connection.") .
428  "</b><br />\n" .
429  _("Query:") . ' '.
430  htmlspecialchars($query) . '<br />' .
431  _("Server responded:") . ' ' .
432  htmlspecialchars($message) . "</font><br />\n";
433  error_box($string,$color);
434  echo '</body></html>';
435  exit;
436  default:
438  require_once(SM_PATH . 'functions/display_messages.php');
439  $string = "<b><font color=\"$color[2]\">\n" .
440  _("ERROR: Unknown IMAP response.") .
441  "</b><br />\n" .
442  _("Query:") . ' '.
443  htmlspecialchars($query) . '<br />' .
444  _("Server responded:") . ' ' .
445  htmlspecialchars($message) . "</font><br />\n";
446  error_box($string,$color);
447  /* the error is displayed but because we don't know the reponse we
448  return the result anyway */
449  return $resultlist;
450  break;
451  }
452 }
453 
454 function sqimap_read_data ($imap_stream, $tag_uid, $handle_errors,
455  &$response, &$message, $query = '',
456  $filter=false,$outputstream=false,$no_return=false) {
457 
458  $res = sqimap_read_data_list($imap_stream, $tag_uid, $handle_errors,
459  $response, $message, $query,$filter,$outputstream,$no_return);
460  /* sqimap_read_data should be called for one response
461  but since it just calls sqimap_read_data_list which
462  handles multiple responses we need to check for that
463  and merge the $res array IF they are seperated and
464  IF it was a FETCH response. */
465 
466 // if (isset($res[1]) && is_array($res[1]) && isset($res[1][0])
467 // && preg_match('/^\* \d+ FETCH/', $res[1][0])) {
468 // $result = array();
469 // foreach($res as $index=>$value) {
470 // $result = array_merge($result, $res["$index"]);
471 // }
472 // }
473 
474  return $res[0];
475 }
476 
481 function sqimap_login ($username, $password, $imap_server_address, $imap_port, $hide) {
483 
484  if (!isset($onetimepad) || empty($onetimepad)) {
485  sqgetglobalvar('onetimepad' , $onetimepad , SQ_SESSION );
486  }
487  $imap_server_address = sqimap_get_user_server($imap_server_address, $username);
488  $host=$imap_server_address;
489 
490  if (($use_imap_tls == true) and (check_php_version(4,3)) and (extension_loaded('openssl'))) {
491  /* Use TLS by prefixing "tls://" to the hostname */
492  $imap_server_address = 'tls://' . $imap_server_address;
493  }
494 
495  $imap_stream = @fsockopen($imap_server_address, $imap_port, $error_number, $error_string, 15);
496 
497  /* Do some error correction */
498  if (!$imap_stream) {
499  if (!$hide) {
501  require_once(SM_PATH . 'functions/display_messages.php');
502  logout_error( sprintf(_("Error connecting to IMAP server: %s."), $imap_server_address).
503  "<br />\r\n$error_number : $error_string<br />\r\n",
504  sprintf(_("Error connecting to IMAP server: %s."), $imap_server_address) );
505  }
506  exit;
507  }
508 
509  $server_info = fgets ($imap_stream, 1024);
510 
511  /* Decrypt the password */
512  $password = OneTimePadDecrypt($password, $onetimepad);
513 
514  if (($imap_auth_mech == 'cram-md5') OR ($imap_auth_mech == 'digest-md5')) {
515  // We're using some sort of authentication OTHER than plain or login
516  $tag=sqimap_session_id(false);
517  if ($imap_auth_mech == 'digest-md5') {
518  $query = $tag . " AUTHENTICATE DIGEST-MD5\r\n";
519  } elseif ($imap_auth_mech == 'cram-md5') {
520  $query = $tag . " AUTHENTICATE CRAM-MD5\r\n";
521  }
522  fputs($imap_stream,$query);
523  $answer=sqimap_fgets($imap_stream);
524  // Trim the "+ " off the front
525  $response=explode(" ",$answer,3);
526  if ($response[0] == '+') {
527  // Got a challenge back
528  $challenge=$response[1];
529  if ($imap_auth_mech == 'digest-md5') {
530  $reply = digest_md5_response($username,$password,$challenge,'imap',$host);
531  } elseif ($imap_auth_mech == 'cram-md5') {
532  $reply = cram_md5_response($username,$password,$challenge);
533  }
534  fputs($imap_stream,$reply);
536  if ($imap_auth_mech == 'digest-md5') {
537  // DIGEST-MD5 has an extra step..
538  if (substr($read,0,1) == '+') { // OK so far..
539  fputs($imap_stream,"\r\n");
541  }
542  }
543  $results=explode(" ",$read,3);
544  $response=$results[1];
545  $message=$results[2];
546  } else {
547  // Fake the response, so the error trap at the bottom will work
548  $response="BAD";
549  $message='IMAP server does not appear to support the authentication method selected.';
550  $message .= ' Please contact your system administrator.';
551  }
552  } elseif ($imap_auth_mech == 'login') {
553  // this is a workaround to alert users of LOGINDISABLED, which is done "right" in
554  // devel but requires functions not available in stable. RFC requires us to
555  // not send LOGIN when LOGINDISABLED is advertised.
556  if(stristr($server_info, 'LOGINDISABLED')) {
557  $response = 'BAD';
558  $message = _("The IMAP server is reporting that plain text logins are disabled.").' '.
559  _("Using CRAM-MD5 or DIGEST-MD5 authentication instead may work.").' ';
560  if (!$use_imap_tls) {
561  $message .= _("Also, the use of TLS may allow SquirrelMail to login.").' ';
562  }
563  $message .= _("Please contact your system administrator and report this error.");
564  } else {
565  // Original IMAP login code
566  if(sq_is8bit($username) || sq_is8bit($password)) {
567  $query['command'] = 'LOGIN';
568  $query['literal_args'][0] = $username;
569  $query['literal_args'][1] = $password;
570  $read = sqimap_run_literal_command($imap_stream, $query, false, $response, $message);
571  } else {
572  $query = 'LOGIN "' . quoteimap($username) . '"'
573  . ' "' . quoteimap($password) . '"';
574  $read = sqimap_run_command ($imap_stream, $query, false, $response, $message);
575  }
576  }
577  } elseif ($imap_auth_mech == 'plain') {
578  /* Replace this with SASL PLAIN if it ever gets implemented */
579  $response="BAD";
580  $message='SquirrelMail does not support SASL PLAIN yet. Rerun conf.pl and use login instead.';
581  } else {
582  $response="BAD";
583  $message="Internal SquirrelMail error - unknown IMAP authentication method chosen. Please contact the developers.";
584  }
585 
586  /* If the connection was not successful, lets see why */
587  if ($response != 'OK') {
588  if (!$hide) {
589  if ($response != 'NO') {
590  /* "BAD" and anything else gets reported here. */
591  $message = htmlspecialchars($message);
593  require_once(SM_PATH . 'functions/display_messages.php');
594  if ($response == 'BAD') {
595  $string = sprintf (_("Bad request: %s")."<br />\r\n", $message);
596  } else {
597  $string = sprintf (_("Unknown error: %s") . "<br />\n", $message);
598  }
599  if (isset($read) && is_array($read)) {
600  $string .= '<br />' . _("Read data:") . "<br />\n";
601  foreach ($read as $line) {
602  $string .= htmlspecialchars($line) . "<br />\n";
603  }
604  }
605  error_box($string,$color);
606  exit;
607  } else {
608  /*
609  * If the user does not log in with the correct
610  * username and password it is not possible to get the
611  * correct locale from the user's preferences.
612  * Therefore, apply the same hack as on the login
613  * screen.
614  *
615  * $squirrelmail_language is set by a cookie when
616  * the user selects language and logs out
617  */
618 
620  include_once(SM_PATH . 'functions/display_messages.php' );
622  /* terminate the session nicely */
624  logout_error( _("Unknown user or password incorrect.") );
625  exit;
626  }
627  } else {
628  exit;
629  }
630  }
631  return $imap_stream;
632 }
633 
640  /* Logout is not valid until the server returns 'BYE'
641  * If we don't have an imap_stream we're already logged out */
642  if(isset($imap_stream) && $imap_stream)
643  sqimap_run_command($imap_stream, 'LOGOUT', false, $response, $message);
644 }
645 
651 function sqimap_capability($imap_stream, $capability='') {
652  global $sqimap_capabilities;
653  if (!is_array($sqimap_capabilities)) {
654  $read = sqimap_run_command($imap_stream, 'CAPABILITY', true, $a, $b);
655 
656  $c = explode(' ', $read[0]);
657  for ($i=2; $i < count($c); $i++) {
658  $cap_list = explode('=', $c[$i]);
659  if (isset($cap_list[1])) {
660  // FIX ME. capabilities can occure multiple times.
661  // THREAD=REFERENCES THREAD=ORDEREDSUBJECT
662  $sqimap_capabilities[$cap_list[0]] = $cap_list[1];
663  } else {
664  $sqimap_capabilities[$cap_list[0]] = TRUE;
665  }
666  }
667  }
668  if ($capability) {
669  if (isset($sqimap_capabilities[$capability])) {
670  return $sqimap_capabilities[$capability];
671  } else {
672  return false;
673  }
674  }
675  return $sqimap_capabilities;
676 }
677 
681 function sqimap_get_delimiter ($imap_stream = false) {
682  global $sqimap_delimiter, $optional_delimiter;
683 
684  /* Use configured delimiter if set */
685  if((!empty($optional_delimiter)) && $optional_delimiter != 'detect') {
686  return $optional_delimiter;
687  }
688 
689  /* Do some caching here */
690  if (!$sqimap_delimiter) {
691  if (sqimap_capability($imap_stream, 'NAMESPACE')) {
692  /*
693  * According to something that I can't find, this is supposed to work on all systems
694  * OS: This won't work in Courier IMAP.
695  * OS: According to rfc2342 response from NAMESPACE command is:
696  * OS: * NAMESPACE (PERSONAL NAMESPACES) (OTHER_USERS NAMESPACE) (SHARED NAMESPACES)
697  * OS: We want to lookup all personal NAMESPACES...
698  */
699  $read = sqimap_run_command($imap_stream, 'NAMESPACE', true, $a, $b);
700  if (preg_match('/\* NAMESPACE +(\( *\(.+\) *\)|NIL) +(\( *\(.+\) *\)|NIL) +(\( *\(.+\) *\)|NIL)/i', $read[0], $data)) {
701  if (preg_match('/^\( *\((.*)\) *\)/', $data[1], $data2)) {
702  $pn = $data2[1];
703  }
704  $pna = explode(')(', $pn);
705  while (list($k, $v) = each($pna)) {
706  $lst = explode('"', $v);
707  if (isset($lst[3])) {
708  $pn[$lst[1]] = $lst[3];
709  } else {
710  $pn[$lst[1]] = '';
711  }
712  }
713  }
714  $sqimap_delimiter = $pn[0];
715  } else {
716  fputs ($imap_stream, ". LIST \"INBOX\" \"\"\r\n");
717  $read = sqimap_read_data($imap_stream, '.', true, $a, $b);
718  $quote_position = strpos ($read[0], '"');
719  $sqimap_delimiter = substr ($read[0], $quote_position+1, 1);
720  }
721  }
722  return $sqimap_delimiter;
723 }
724 
725 
730  $read_ary = sqimap_run_command ($imap_stream, "EXAMINE \"$mailbox\"", false, $result, $message);
731  for ($i = 0; $i < count($read_ary); $i++) {
732  if (preg_match('/[^ ]+ +([^ ]+) +EXISTS/', $read_ary[$i], $regs)) {
733  return $regs[1];
734  }
735  }
736  return false; //"BUG! Couldn't get number of messages in $mailbox!";
737 }
738 
756 function parseAddress($address, $max=0) {
757  $aTokens = array();
758  $aAddress = array();
759  $iCnt = strlen($address);
760  $aSpecials = array('(' ,'<' ,',' ,';' ,':');
761  $aReplace = array(' (',' <',' ,',' ;',' :');
762  $address = str_replace($aSpecials,$aReplace,$address);
763  $i = 0;
764  while ($i < $iCnt) {
765  $cChar = $address{$i};
766  switch($cChar)
767  {
768  case '<':
769  $iEnd = strpos($address,'>',$i+1);
770  if (!$iEnd) {
771  $sToken = substr($address,$i);
772  $i = $iCnt;
773  } else {
774  $sToken = substr($address,$i,$iEnd - $i +1);
775  $i = $iEnd;
776  }
777  $sToken = str_replace($aReplace, $aSpecials,$sToken);
778  $aTokens[] = $sToken;
779  break;
780  case '"':
781  $iEnd = strpos($address,$cChar,$i+1);
782  if ($iEnd) {
783  // skip escaped quotes
784  $prev_char = $address{$iEnd-1};
785  while ($prev_char === '\\' && substr($address,$iEnd-2,2) !== '\\\\') {
786  $iEnd = strpos($address,$cChar,$iEnd+1);
787  if ($iEnd) {
788  $prev_char = $address{$iEnd-1};
789  } else {
790  $prev_char = false;
791  }
792  }
793  }
794  if (!$iEnd) {
795  $sToken = substr($address,$i);
796  $i = $iCnt;
797  } else {
798  // also remove the surrounding quotes
799  $sToken = substr($address,$i+1,$iEnd - $i -1);
800  $i = $iEnd;
801  }
802  $sToken = str_replace($aReplace, $aSpecials,$sToken);
803  if ($sToken) $aTokens[] = $sToken;
804  break;
805  case '(':
806  $iEnd = strrpos($address,')');
807  if (!$iEnd || $iEnd < $i) {
808  $sToken = substr($address,$i);
809  $i = $iCnt;
810  } else {
811  $sToken = substr($address,$i,$iEnd - $i + 1);
812  $i = $iEnd;
813  }
814  $sToken = str_replace($aReplace, $aSpecials,$sToken);
815  $aTokens[] = $sToken;
816  break;
817  case ',':
818  case ';':
819  case ';':
820  case ' ':
821  $aTokens[] = $cChar;
822  break;
823  default:
824  $iEnd = strpos($address,' ',$i+1);
825  if ($iEnd) {
826  $sToken = trim(substr($address,$i,$iEnd - $i));
827  $i = $iEnd-1;
828  } else {
829  $sToken = trim(substr($address,$i));
830  $i = $iCnt;
831  }
832  if ($sToken) $aTokens[] = $sToken;
833  }
834  ++$i;
835  }
836  $sPersonal = $sEmail = $sComment = $sGroup = '';
837  $aStack = $aComment = array();
838  foreach ($aTokens as $sToken) {
839  if ($max && $max == count($aAddress)) {
840  return $aAddress;
841  }
842  $cChar = $sToken{0};
843  switch ($cChar)
844  {
845  case '=':
846  case '"':
847  case ' ':
848  $aStack[] = $sToken;
849  break;
850  case '(':
851  $aComment[] = substr($sToken,1,-1);
852  break;
853  case ';':
854  if ($sGroup) {
855  $sEmail = trim(implode(' ',$aStack));
856  $aAddress[] = array($sGroup,$sEmail);
857  $aStack = $aComment = array();
858  $sGroup = '';
859  break;
860  }
861  case ',':
862  if (!$sEmail) {
863  while (count($aStack) && !$sEmail) {
864  $sEmail = trim(array_pop($aStack));
865  }
866  }
867  if (count($aStack)) {
868  $sPersonal = trim(implode('',$aStack));
869  } else {
870  $sPersonal = '';
871  }
872  if (!$sPersonal && count($aComment)) {
873  $sComment = implode(' ',$aComment);
874  $sPersonal .= $sComment;
875  }
876  $aAddress[] = array($sEmail,$sPersonal);
877  $sPersonal = $sComment = $sEmail = '';
878  $aStack = $aComment = array();
879  break;
880  case ':':
881  $sGroup = implode(' ',$aStack); break;
882  $aStack = array();
883  break;
884  case '<':
885  $sEmail = trim(substr($sToken,1,-1));
886  break;
887  case '>':
888  /* skip */
889  break;
890  default: $aStack[] = $sToken; break;
891  }
892  }
893  /* now do the action again for the last address */
894  if (!$sEmail) {
895  while (count($aStack) && !$sEmail) {
896  $sEmail = trim(array_pop($aStack));
897  }
898  }
899  if (count($aStack)) {
900  $sPersonal = trim(implode('',$aStack));
901  } else {
902  $sPersonal = '';
903  }
904  if (!$sPersonal && count($aComment)) {
905  $sComment = implode(' ',$aComment);
906  $sPersonal .= $sComment;
907  }
908  $aAddress[] = array($sEmail,$sPersonal);
909  return $aAddress;
910 }
911 
912 
917  $read_ary = sqimap_run_command ($imap_stream, "STATUS \"$mailbox\" (UNSEEN)", false, $result, $message);
918  $i = 0;
919  $regs = array(false, false);
920  while (isset($read_ary[$i])) {
921  if (preg_match('/UNSEEN\s+([0-9]+)/i', $read_ary[$i], $regs)) {
922  break;
923  }
924  $i++;
925  }
926  return $regs[1];
927 }
928 
933  $read_ary = sqimap_run_command ($imap_stream, "STATUS \"$mailbox\" (MESSAGES UNSEEN RECENT)", false, $result, $message);
934  $i = 0;
935  $messages = $unseen = $recent = false;
936  $regs = array(false,false);
937  while (isset($read_ary[$i])) {
938  if (preg_match('/UNSEEN\s+([0-9]+)/i', $read_ary[$i], $regs)) {
939  $unseen = $regs[1];
940  }
941  if (preg_match('/MESSAGES\s+([0-9]+)/i', $read_ary[$i], $regs)) {
942  $messages = $regs[1];
943  }
944  if (preg_match('/RECENT\s+([0-9]+)/i', $read_ary[$i], $regs)) {
945  $recent = $regs[1];
946  }
947  $i++;
948  }
949  return array('MESSAGES' => $messages, 'UNSEEN'=>$unseen, 'RECENT' => $recent);
950 }
951 
952 
957  fputs ($imap_stream, sqimap_session_id() . " APPEND \"$sent_folder\" (\\Seen) {".$length."}\r\n");
958  $tmp = fgets ($imap_stream, 1024);
960 }
961 
962 function sqimap_append_done ($imap_stream, $folder='') {
963  fputs ($imap_stream, "\r\n");
964  $tmp = fgets ($imap_stream, 1024);
965  sqimap_append_checkresponse($tmp, $folder);
966 }
967 
968 function sqimap_append_checkresponse($response, $folder) {
969 
970  if (preg_match("/(.*)(BAD|NO)(.*)$/", $response, $regs)) {
973  require_once(SM_PATH . 'functions/display_messages.php');
974 
975  $reason = $regs[3];
976  if ($regs[2] == 'NO') {
977  $string = "<b><font color=\"$color[2]\">\n" .
978  _("ERROR: Could not append message to") ." $folder." .
979  "</b><br />\n" .
980  _("Server responded:") . ' ' .
981  $reason . "<br />\n";
982  if (preg_match("/(.*)(quota)(.*)$/i", $reason, $regs)) {
983  $string .= _("Solution:") . ' ' .
984  _("Remove unneccessary messages from your folders. Start with your Trash folder.")
985  ."<br />\n";
986  }
987  $string .= "</font>\n";
988  error_box($string,$color);
989  } else {
990  $string = "<b><font color=\"$color[2]\">\n" .
991  _("ERROR: Bad or malformed request.") .
992  "</b><br />\n" .
993  _("Server responded:") . ' ' .
994  $reason . "</font><br />\n";
995  error_box($string,$color);
996  exit;
997  }
998  }
999 }
1000 
1001 function sqimap_get_user_server ($imap_server, $username) {
1002  if (substr($imap_server, 0, 4) != "map:") {
1003  return $imap_server;
1004  }
1005  $function = substr($imap_server, 4);
1006  return $function($username);
1007 }
1008 
1016  $safe_username = escapeshellarg($username);
1017  $yp = `ypmatch $safe_username aliases`;
1018  return chop(substr($yp, strlen($username)+1));
1019 }
1020 
elseif
if(! sqgetGlobalVar('sound', $sound, SQ_GET)) elseif($sound=='(none)')
Definition: testsound.php:25
$cnt
$cnt
Definition: options_identities.php:86
sqimap_append_checkresponse
sqimap_append_checkresponse($response, $folder)
Definition: imap_general.php:968
sqimap_session_id
sqimap_session_id($unique_id=FALSE)
Definition: imap_general.php:26
sqimap_login
sqimap_login($username, $password, $imap_server_address, $imap_port, $hide)
Definition: imap_general.php:481
$imap_auth_mech
$imap_auth_mech
Definition: config_default.php:285
SQ_SESSION
const SQ_SESSION
Definition: global.php:18
$imap_stream
$imap_stream
Definition: bug_report.php:119
$mailbox
$mailbox
Definition: options.php:28
sqimap_append_done
sqimap_append_done($imap_stream, $folder='')
Definition: imap_general.php:962
sprintf
powered by Systran sprintf(_("Number of supported language pairs: %s"), '36').' '
Definition: options.php:107
sqsession_destroy
sqsession_destroy()
Definition: global.php:399
$use_imap_tls
$use_imap_tls
Definition: config_default.php:240
OneTimePadDecrypt
OneTimePadDecrypt($string, $epad)
Definition: strings.php:460
$username
global $username
Definition: validate.php:55
$sqimap_capabilities
if(sqgetGlobalVar('passed_id', $temp)) if(sqgetGlobalVar('sort', $temp)) if(sqgetGlobalVar('startMessage', $temp)) global $sqimap_capabilities
Definition: read_body.php:767
sqimap_read_data_list
sqimap_read_data_list($imap_stream, $tag_uid, $handle_errors, &$response, &$message, $query='', $filter=false, $outputstream=false, $no_return=false)
Definition: imap_general.php:201
sq_is8bit
sq_is8bit($string, $charset='')
Definition: strings.php:784
$message
$message
Definition: download.php:54
logout_error
logout_error( $errString, $errTitle='')
Definition: display_messages.php:44
set_up_language
set_up_language($sm_language, $do_search=false, $default=false)
Definition: i18n.php:330
sqimap_get_user_server
sqimap_get_user_server($imap_server, $username)
Definition: imap_general.php:1001
$sent_folder
$sent_folder
Definition: config_default.php:395
map_yp_alias
map_yp_alias($username)
Definition: imap_general.php:1015
sqimap_logout
sqimap_logout($imap_stream)
Definition: imap_general.php:639
sqimap_fgets
sqimap_fgets($imap_stream)
Definition: imap_general.php:123
sqimap_run_literal_command
sqimap_run_literal_command($imap_stream, $query, $handle_errors, &$response, &$message, $unique_id=false)
Definition: imap_general.php:79
check_php_version
if(function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc()) check_php_version($a='0', $b='0', $c='0')
Definition: global.php:194
sqimap_append
sqimap_append($imap_stream, $sent_folder, $length)
Definition: imap_general.php:956
$optional_delimiter
$optional_delimiter
Definition: config_default.php:300
$j
for($i=0; $i< $numboxes; $i++) $j
Definition: empty_trash.php:72
sqimap_run_command_list
sqimap_run_command_list($imap_stream, $query, $handle_errors, &$response, &$message, $unique_id=false)
Definition: imap_general.php:40
quoteimap
quoteimap($str)
Definition: strings.php:646
sqimap_read_data
sqimap_read_data($imap_stream, $tag_uid, $handle_errors, &$response, &$message, $query='', $filter=false, $outputstream=false, $no_return=false)
Definition: imap_general.php:454
sqimap_get_num_messages
sqimap_get_num_messages($imap_stream, $mailbox)
Definition: imap_general.php:729
$data
$data
Definition: mailto.php:83
exit
exit
Definition: help.php:128
SM_PATH
const SM_PATH
Definition: decrypt_headers.php:16
sqimap_status_messages
sqimap_status_messages($imap_stream, $mailbox)
Definition: imap_general.php:932
_
_($str)
Definition: gettext.php:160
$read
$read
Definition: message_details_bottom.php:75
sqimap_run_command
sqimap_run_command($imap_stream, $query, $handle_errors, &$response, &$message, $unique_id=false, $filter=false, $outputstream=false, $no_return=false)
Definition: imap_general.php:58
$server_info
$server_info
Definition: bug_report.php:120
$color
$color
Definition: load_prefs.php:28
$squirrelmail_language
global $squirrelmail_language
Definition: i18n.php:774
sqimap_unseen_messages
sqimap_unseen_messages($imap_stream, $mailbox)
Definition: imap_general.php:916
sqimap_fread
sqimap_fread($imap_stream, $iSize, $filter=false, $outputstream=false, $no_return=false)
Definition: imap_general.php:143
cram_md5_response
cram_md5_response($username, $password, $challenge)
Definition: auth.php:141
parseAddress
parseAddress($address, $max=0)
Definition: imap_general.php:756
sqimap_get_delimiter
sqimap_get_delimiter($imap_stream=false)
Definition: imap_general.php:681
digest_md5_response
digest_md5_response($username, $password, $challenge, $service, $host)
Definition: auth.php:163
sqimap_capability
sqimap_capability($imap_stream, $capability='')
Definition: imap_general.php:651
error_box
error_box($string, $color)
Definition: display_messages.php:116