From 161c28dffcab78da00b6b80693ef9423c4258248 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Sat, 05 Sep 2009 08:31:19 -0400
Subject: [PATCH] - Fix wrong headers for IE on servers without $_SERVER['HTTPS'] (#1485926) - Force IE style headers for attachments in non-HTTPS session, 'use_https' option (#1485655)

---
 program/lib/imap.inc |  582 ++++++++++++++++++++++-----------------------------------
 1 files changed, 223 insertions(+), 359 deletions(-)

diff --git a/program/lib/imap.inc b/program/lib/imap.inc
index 64f0325..02c9bd9 100644
--- a/program/lib/imap.inc
+++ b/program/lib/imap.inc
@@ -84,6 +84,7 @@
 		- handling connection startup response
 		- added UID EXPUNGE support
 		- fixed problem with double quotes and spaces in folder names in LIST and LSUB 
+		- rewritten iil_C_FetchHeaderIndex()
 
 ********************************************************/
 
@@ -99,15 +100,6 @@
 if (!isset($IMAP_USE_HEADER_DATE) || !$IMAP_USE_HEADER_DATE) {
     $IMAP_USE_INTERNAL_DATE = true;
 }
-
-/**
- * @todo Maybe use date() to generate this.
- */
-$GLOBALS['IMAP_MONTHS'] = array("Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4,
-    "May" => 5, "Jun" => 6, "Jul" => 7, "Aug" => 8, "Sep" => 9, "Oct" => 10,
-    "Nov" => 11, "Dec" => 12);
-
-$GLOBALS['IMAP_SERVER_TZ'] = date('Z');
 
 $GLOBALS['IMAP_FLAGS'] = array(
     'SEEN'     => '\\Seen',
@@ -205,7 +197,11 @@
 }
 
 function iil_PutLine($fp, $string, $endln=true) {
-//      console('C: '. rtrim($string));
+	global $my_prefs;
+	
+	if (!empty($my_prefs['debug_mode']))
+    		write_log('imap', 'C: '. rtrim($string));
+	
         return fputs($fp, $string . ($endln ? "\r\n" : ''));
 }
 
@@ -233,6 +229,8 @@
 }
 
 function iil_ReadLine($fp, $size=1024) {
+	global $my_prefs;
+	
 	$line = '';
 
 	if (!$fp) {
@@ -245,13 +243,15 @@
     
 	do {
     		$buffer = fgets($fp, $size);
+
     		if ($buffer === false) {
         		break;
     		}
-//		console('S: '. chop($buffer));
+		if (!empty($my_prefs['debug_mode']))
+			write_log('imap', 'S: '. chop($buffer));
     		$line .= $buffer;
 	} while ($buffer[strlen($buffer)-1] != "\n");
-	
+
 	return $line;
 }
 
@@ -268,36 +268,41 @@
 		}
 
 		$line = $a[1][0] . '"' . ($escape ? iil_Escape($out) : $out) . '"';
-//		console('[...] '. $out);
 	}
 	return $line;
 }
 
 function iil_ReadBytes($fp, $bytes) {
+	global $my_prefs;
 	$data = '';
 	$len  = 0;
 	do {
-    		$data .= fread($fp, $bytes-$len);
-		if ($len == strlen($data)) {
+		$d = fread($fp, $bytes-$len);
+		if (!empty($my_prefs['debug_mode']))
+			write_log('imap', 'S: '. $d);
+                $data .= $d;
+		$data_len = strlen($data);
+		if ($len == $data_len) {
     		        break; //nothing was read -> exit to avoid apache lockups
     		}
-    		$len = strlen($data);
+    		$len = $data_len;
 	} while ($len < $bytes);
 	
 	return $data;
 }
 
+// don't use it in loops, until you exactly know what you're doing
 function iil_ReadReply($fp) {
 	do {
 		$line = trim(iil_ReadLine($fp, 1024));
 	} while ($line[0] == '*');
-	
+
 	return $line;
 }
 
 function iil_ParseResult($string) {
-	$a = explode(' ', $string);
-	if (count($a) > 2) {
+	$a = explode(' ', trim($string));
+	if (count($a) >= 2) {
 		if (strcasecmp($a[1], 'OK') == 0) {
 			return 0;
 		} else if (strcasecmp($a[1], 'NO') == 0) {
@@ -306,7 +311,7 @@
 			return -2;
 		} else if (strcasecmp($a[1], 'BYE') == 0) {
 			return -3;
-    		}
+		}
 	}
 	return -4;
 }
@@ -326,7 +331,7 @@
 	return false;
 }
 
-function iil_StartsWithI($string, $match, $bye=false) {
+function iil_StartsWithI($string, $match, $error=false) {
 	$len = strlen($match);
 	if ($len == 0) {
 		return false;
@@ -334,7 +339,7 @@
 	if (strncasecmp($string, $match, $len) == 0) {
 		return true;
 	}
-	if ($bye && strncmp($string, '* BYE ', 6) == 0) {
+	if ($error && preg_match('/^\* (BYE|BAD) /i', $string)) {
 		return true;
 
 	}
@@ -439,13 +444,8 @@
 
     iil_PutLine($conn->fp, 'a001 LOGIN "'.iil_Escape($user).'" "'.iil_Escape($password).'"');
 
-    do {
-        $line = iil_ReadReply($conn->fp);
-        if ($line === false) {
-            break;
-        }
-    } while (!iil_StartsWith($line, 'a001 ', true));
-    
+    $line = iil_ReadReply($conn->fp);
+
     // process result
     $result = iil_ParseResult($line);
 
@@ -560,6 +560,8 @@
     				$my_prefs['rootdir'] = $optval;
 			} else if ($optkey == 'delimiter') {
     				$my_prefs['delimiter'] = $optval;
+			} else if ($optkey == 'debug_mode') {
+    				$my_prefs['debug_mode'] = $optval;
 			}
 		}
 	}
@@ -584,7 +586,6 @@
 	} else if ($my_prefs['sort_field'] == 'DATE') {
     		$IMAP_USE_INTERNAL_DATE = false;
 	}
-	//echo '<!-- conn sort_field: '.$my_prefs['sort_field'].' //-->';
 	
 	//check input
 	if (empty($host)) {
@@ -619,7 +620,10 @@
 	}
 
 	stream_set_timeout($conn->fp, 10);
-	$line = stream_get_line($conn->fp, 8192, "\r\n");
+	$line = stream_get_line($conn->fp, 8192, "\n");
+
+	if ($my_prefs['debug_mode'] && $line)
+		write_log('imap', 'S: '. $line);
 
 	// Connected to wrong port or connection error?
 	if (!preg_match('/^\* (OK|PREAUTH)/i', $line)) {
@@ -630,7 +634,7 @@
 	        $iil_errornum = -2;
 	        return false;
 	}
-	
+
 	// RFC3501 [7.1] optional CAPABILITY response
 	if (preg_match('/\[CAPABILITY ([^]]+)\]/i', $line, $matches)) {
 		$conn->capability = explode(' ', strtoupper($matches[1]));
@@ -787,7 +791,7 @@
 				if (strcasecmp($a[2], 'EXISTS') == 0) {
 					$conn->exists = (int) $a[1];
 				}
-				if (strcasecmp($a[2], 'RECENT') == 0) {
+				else if (strcasecmp($a[2], 'RECENT') == 0) {
 					$conn->recent = (int) $a[1];
 				}
 			}
@@ -840,46 +844,23 @@
 	return $string;
 }
 
-function iil_StrToTime($str) {
-	$IMAP_MONTHS    = $GLOBALS['IMAP_MONTHS'];
-	$IMAP_SERVER_TZ = $GLOBALS['IMAP_SERVER_TZ'];
-		
-	if ($str) {
-    	    $time1 = strtotime($str);
-	}
-	if ($time1 && $time1 != -1) {
-	    return $time1-$IMAP_SERVER_TZ;
-	}
-	//echo '<!--'.$str.'//-->';
-	
-	//replace double spaces with single space
-	$str = trim($str);
-	$str = str_replace('  ', ' ', $str);
-	
-	//strip off day of week
-	$pos = strpos($str, ' ');
-	if (!is_numeric(substr($str, 0, $pos))) {
-	    $str = substr($str, $pos+1);
-	}
-	//explode, take good parts
-	$a = explode(' ', $str);
+function iil_StrToTime($date) {
 
-	$month_str = $a[1];
-	$month     = $IMAP_MONTHS[$month_str];
-	$day       = (int)$a[0];
-	$year      = (int)$a[2];
-	$time      = $a[3];
-	$tz_str    = $a[4];
-	$tz        = substr($tz_str, 0, 3);
-	$ta        = explode(':', $time);
-	$hour      = (int)$ta[0]-(int)$tz;
-	$minute    = (int)$ta[1];
-	$second    = (int)$ta[2];
-	
-	//make UNIX timestamp
-	$time2 = mktime($hour, $minute, $second, $month, $day, $year);
-	//echo '<!--'.$time1.' '.$time2.' //-->'."\n";
-	return $time2;
+	// support non-standard "GMTXXXX" literal
+	$date = preg_replace('/GMT\s*([+-][0-9]+)/', '\\1', $date);
+        // if date parsing fails, we have a date in non-rfc format.
+	// remove token from the end and try again
+	while ((($ts = @strtotime($date))===false) || ($ts < 0))
+	{
+	        $d = explode(' ', $date);
+		array_pop($d);
+		if (!$d) break;
+		$date = implode(' ', $d);
+	}
+
+	$ts = (int) $ts;
+
+	return $ts < 0 ? 0 : $ts;	
 }
 
 function iil_C_Sort(&$conn, $mailbox, $field, $add='', $is_uid=FALSE,
@@ -911,14 +892,14 @@
 	$command  = 's ' . $is_uid . 'SORT (' . $field . ') ';
 	$command .= $encoding . ' ALL' . $add;
 	$line     = $data = '';
-	
+
 	if (!iil_PutLineC($conn->fp, $command)) {
 	    return false;
 	}
 	do {
-		$line = chop(iil_ReadLine($conn->fp, 1024));
+		$line = chop(iil_ReadLine($conn->fp));
 		if (iil_StartsWith($line, '* SORT')) {
-			$data .= ($data ? ' ' : '') . substr($line, 7);
+			$data .= substr($line, 7);
     		} else if (preg_match('/^[0-9 ]+$/', $line)) {
 			$data .= $line;
 		}
@@ -931,32 +912,21 @@
                 return false;
 	}
 	
-	$out = explode(' ',$data);
-	return $out;
+	return preg_split('/\s+/', $data, -1, PREG_SPLIT_NO_EMPTY);
 }
 
-function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field,
-    $normalize=true) {
-	global $IMAP_USE_INTERNAL_DATE;
-	
-	$c=0;
-	$result=array();
-	$fp = $conn->fp;
-		
-	if (empty($index_field)) {
-	    $index_field = 'DATE';
-	}
-	$index_field = strtoupper($index_field);
-	
+function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field='', $skip_deleted=true) {
+
 	list($from_idx, $to_idx) = explode(':', $message_set);
-	if (empty($message_set) || (isset($to_idx)
-    	    && (int)$from_idx > (int)$to_idx)) {
+	if (empty($message_set) ||
+		(isset($to_idx) && $to_idx != '*' && (int)$from_idx > (int)$to_idx)) {
 		return false;
 	}
+
+	$index_field = empty($index_field) ? 'DATE' : strtoupper($index_field);
 	
-	//$fields_a['DATE'] = ($IMAP_USE_INTERNAL_DATE?6:1);
 	$fields_a['DATE']         = 1;
-	$fields_a['INTERNALDATE'] = 6;
+	$fields_a['INTERNALDATE'] = 4;
 	$fields_a['FROM']         = 1;
 	$fields_a['REPLY-TO']     = 1;
 	$fields_a['SENDER']       = 1;
@@ -965,178 +935,107 @@
 	$fields_a['UID']          = 2;
 	$fields_a['SIZE']         = 2;
 	$fields_a['SEEN']         = 3;
-	$fields_a['RECENT']       = 4;
-	$fields_a['DELETED']      = 5;
-	
-	$mode=$fields_a[$index_field];
-	if (!($mode > 0)) {
-	    return false;
+	$fields_a['RECENT']       = 3;
+	$fields_a['DELETED']      = 3;
+
+	if (!($mode = $fields_a[$index_field])) {
+		return false;
 	}
-    
+
 	/*  Do "SELECT" command */
 	if (!iil_C_Select($conn, $mailbox)) {
-	    return false;
+		return false;
 	}
-    
-	/* FETCH date,from,subject headers */
-	if ($mode == 1) {
-		$key     = 'fhi' . ($c++);
-		$request = $key . " FETCH $message_set (BODY.PEEK[HEADER.FIELDS ($index_field)])";
-		if (!iil_PutLine($fp, $request)) {
-		    return false;
-    		}
-		do {
-			
-			$line=chop(iil_ReadLine($fp, 200));
-			$a=explode(' ', $line);
-			if (($line[0] == '*') && ($a[2] == 'FETCH')
-            		    && ($line[strlen($line)-1] != ')')) {
-				$id=$a[1];
+	
+	// build FETCH command string
+	$key     = 'fhi0';
+	$deleted = $skip_deleted ? ' FLAGS' : '';
 
-				$str=$line=chop(iil_ReadLine($fp, 300));
+	if ($mode == 1)
+		$request = " FETCH $message_set (BODY.PEEK[HEADER.FIELDS ($index_field)]$deleted)";
+	else if ($mode == 2) {
+		if ($index_field == 'SIZE')
+			$request = " FETCH $message_set (RFC822.SIZE$deleted)";
+		else
+			$request = " FETCH $message_set ($index_field$deleted)";
+	} else if ($mode == 3)
+		$request = " FETCH $message_set (FLAGS)";
+	else // 4
+		$request = " FETCH $message_set (INTERNALDATE$deleted)";
 
-				while ($line[0] != ')') {					//caution, this line works only in this particular case
-					$line=chop(iil_ReadLine($fp, 300));
-					if ($line[0] != ')') {
-						if (ord($line[0]) <= 32) {			//continuation from previous header line
-							$str.= ' ' . trim($line);
-						}
-						if ((ord($line[0]) > 32) || (strlen($line[0]) == 0)) {
-							list($field, $string) = iil_SplitHeaderLine($str);
-							if (strcasecmp($field, 'date') == 0) {
-								$result[$id] = iil_StrToTime($string);
-							} else {
-								$result[$id] = str_replace('"', '', $string);
-								if ($normalize) {
-								    $result[$id] = strtoupper($result[$id]);
-                            					}
-							}
-							$str=$line;
-						}
-					}
-				}
-			}
-			/*
-			$end_pos = strlen($line)-1;
-			if (($line[0]=="*") && ($a[2]=="FETCH") && ($line[$end_pos]=="}")) {
-				$id = $a[1];
-				$pos = strrpos($line, "{")+1;
-				$bytes = (int)substr($line, $pos, $end_pos-$pos);
-				$received = 0;
-				do {
-					$line      = iil_ReadLine($fp, 0);
-					$received += strlen($line);
-					$line      = chop($line);
+	$request = $key . $request;
+
+	if (!iil_PutLine($conn->fp, $request))
+		return false;
+
+	$result = array();
+
+	do {
+		$line = chop(iil_ReadLine($conn->fp, 200));
+		$line = iil_MultLine($conn->fp, $line);
+
+		if (preg_match('/^\* ([0-9]+) FETCH/', $line, $m)) {
+
+            		$id = $m[1];
+			$flags = NULL;
 					
-					if ($received>$bytes) {
-                    				break;
-					} else if (!$line) {
-                    				continue;
+			if ($skip_deleted && preg_match('/FLAGS \(([^)]+)\)/', $line, $matches)) {
+				$flags = explode(' ', strtoupper($matches[1]));
+				if (in_array('\\DELETED', $flags)) {
+					$deleted[$id] = $id;
+					continue;
+				}
+			}
+
+			if ($mode == 1) {
+				if (preg_match('/BODY\[HEADER\.FIELDS \("?(DATE|FROM|REPLY-TO|SENDER|TO|SUBJECT)"?\)\] (.*)/', $line, $matches)) {
+					$value = preg_replace(array('/^"*[a-z]+:/i', '/\s+$/sm'), array('', ''), $matches[2]);
+					$value = trim($value);
+					if ($index_field == 'DATE') {
+						$result[$id] = iil_StrToTime($value);
+					} else {
+						$result[$id] = $value;
 					}
-
-					list($field, $string) = explode(': ', $line);
-					
-					if (strcasecmp($field, 'date') == 0) {
-						$result[$id] = iil_StrToTime($string);
-					} else if ($index_field != 'DATE') {
-						$result[$id]=strtoupper(str_replace('"', '', $string));
-                			}
-				} while ($line[0] != ')');
-			} else {
-				//one line response, not expected so ignore				
-			}
-			*/
-		} while (!iil_StartsWith($line, $key, true));
-
-	}else if ($mode == 6) {
-
-		$key     = 'fhi' . ($c++);
-		$request = $key . " FETCH $message_set (INTERNALDATE)";
-		if (!iil_PutLine($fp, $request)) {
-		    return false;
-    		}
-		do {
-			$line=chop(iil_ReadLine($fp, 200));
-			if ($line[0] == '*') {
-				/*
-				 * original:
-				 * "* 10 FETCH (INTERNALDATE "31-Jul-2002 09:18:02 -0500")"
-				 */
-				$paren_pos = strpos($line, '(');
-				$foo       = substr($line, 0, $paren_pos);
-				$a         = explode(' ', $foo);
-				$id        = $a[1];
-				
-				$open_pos  = strpos($line, '"') + 1;
-				$close_pos = strrpos($line, '"');
-				if ($open_pos && $close_pos) {
-					$len         = $close_pos - $open_pos;
-					$time_str    = substr($line, $open_pos, $len);
-					$result[$id] = strtotime($time_str);
-				}
-			} else {
-				$a = explode(' ', $line);
-			}
-		} while (!iil_StartsWith($a[0], $key, true));
-	} else {
-		if ($mode >= 3) {
-		    $field_name = 'FLAGS';
-		} else if ($index_field == 'SIZE') {
-		    $field_name = 'RFC822.SIZE';
-		} else {
-		    $field_name = $index_field;
-    		}
-        
-		/* 			FETCH uid, size, flags		*/
-		$key     = 'fhi' .($c++);
-		$request = $key . " FETCH $message_set ($field_name)";
-
-		if (!iil_PutLine($fp, $request)) {
-		    return false;
-    		}
-		do {
-			$line=chop(iil_ReadLine($fp, 200));
-			$a = explode(' ', $line);
-			if (($line[0] == '*') && ($a[2] == 'FETCH')) {
-				$line = str_replace('(', '', $line);
-				$line = str_replace(')', '', $line);
-				$a    = explode(' ', $line);
-				
-				$id = $a[1];
-
-				if (isset($result[$id])) {
-				    continue; //if we already got the data, skip forward
-				}
-            			if ($a[3]!=$field_name) {
-                			continue;  //make sure it's returning what we requested
-				}
-                
-				/*  Caution, bad assumptions, next several lines */
-				if ($mode == 2) {
-				    $result[$id] = $a[4];
 				} else {
-					$haystack    = strtoupper($line);
-					$result[$id] = (strpos($haystack, $index_field) > 0 ? "F" : "N");
+					$result[$id] = '';
+				}
+			} else if ($mode == 2) {
+				if (preg_match('/\((UID|RFC822\.SIZE) ([0-9]+)/', $line, $matches)) {
+					$result[$id] = trim($matches[2]);
+				} else {
+					$result[$id] = 0;
+				}
+			} else if ($mode == 3) {
+				if (!$flags && preg_match('/FLAGS \(([^)]+)\)/', $line, $matches)) {
+					$flags = explode(' ', $matches[1]);
+				}
+				$result[$id] = in_array('\\'.$index_field, $flags) ? 1 : 0;
+			} else if ($mode == 4) {
+				if (preg_match('/INTERNALDATE "([^"]+)"/', $line, $matches)) {
+					$result[$id] = iil_StrToTime($matches[1]);
+				} else {
+					$result[$id] = 0;
 				}
 			}
-		} while (!iil_StartsWith($line, $key, true));
-	}
+		}
+	} while (!iil_StartsWith($line, $key, true));
 
+/*
 	//check number of elements...
-	list($start_mid, $end_mid) = explode(':', $message_set);
-	if (is_numeric($start_mid) && is_numeric($end_mid)) {
+	if (is_numeric($from_idx) && is_numeric($to_idx)) {
 		//count how many we should have
-		$should_have = $end_mid - $start_mid +1;
+		$should_have = $to_idx - $from_idx + 1;
 		
 		//if we have less, try and fill in the "gaps"
 		if (count($result) < $should_have) {
-			for ($i=$start_mid; $i<=$end_mid; $i++) {
+			for ($i=$from_idx; $i<=$to_idx; $i++) {
 				if (!isset($result[$i])) {
 			    		$result[$i] = '';
             			}
         		}
 		}
 	}
+*/
 	return $result;	
 }
 
@@ -1520,17 +1419,13 @@
 	$result = array();
 	$fp     = $conn->fp;
 	
-	list($from_idx, $to_idx) = explode(':', $message_set);
-	if (empty($message_set) || (isset($to_idx)
-		&& (int)$from_idx > (int)$to_idx)) {
-		return false;
-	}
-		
 	/*  Do "SELECT" command */
 	if (!iil_C_Select($conn, $mailbox)) {
 		$conn->error = "Couldn't select $mailbox";
 		return false;
 	}
+
+	$message_set = iil_CompressMessageSet($message_set);
 
 	if ($add)
 		$add = ' '.strtoupper(trim($add));
@@ -1597,25 +1492,8 @@
 					// if time is gmt...
 		                        $time_str = str_replace('GMT','+0000',$time_str);
 					
-					//get timezone
-					$time_str      = substr($time_str, 0, -1);
-					$time_zone_str = substr($time_str, -5); // extract timezone
-					$time_str      = substr($time_str, 0, -5); // remove timezone
-					$time_zone     = (float)substr($time_zone_str, 1, 2); // get first two digits
-			
-					if ($time_zone_str[3] != '0') {
-					         $time_zone += 0.5;  //handle half hour offset
-					}
-					if ($time_zone_str[0] == '-') {
-					        $time_zone = $time_zone * -1.0; //minus?
-					}
-					
-					//calculate timestamp
-                                        $timestamp     = strtotime($time_str); //return's server's time
-					$timestamp    -= $time_zone * 3600; //compensate for tz, get GMT
-
 					$result[$id]->internaldate = $time_str;
-					$result[$id]->timestamp = $timestamp;
+					$result[$id]->timestamp = iil_StrToTime($time_str);
 					$result[$id]->date = $time_str;
 				}
 
@@ -1623,7 +1501,7 @@
 				if($bodystr) {
 					while (!preg_match('/ BODYSTRUCTURE (.*) BODY\[HEADER.FIELDS/s', $line, $m)) {
 						$line2 = iil_ReadLine($fp, 1024);
-						$line .= iil_MultLine($fp, $line2);
+						$line .= iil_MultLine($fp, $line2, true);
 					}
 					$result[$id]->body_structure = $m[1];
 				}
@@ -1834,8 +1712,8 @@
 		while (list($key, $val)=each($a)) {
 
 			if ($field == 'timestamp') {
-				$data = @strtotime($val->date);
-				if ($data == false) {
+				$data = iil_StrToTime($val->date);
+				if (!$data) {
 					$data = $val->timestamp;
             			}
 			} else {
@@ -1935,14 +1813,6 @@
 	return iil_C_ModFlag($conn, $mailbox, $messages, 'DELETED', '+');
 }
 
-function iil_C_Undelete(&$conn, $mailbox, $messages) {
-	return iil_C_ModFlag($conn, $mailbox, $messages, 'DELETED', '-');
-}
-
-function iil_C_Unseen(&$conn, $mailbox, $messages) {
-	return iil_C_ModFlag($conn, $mailbox, $messages, 'SEEN', '-');
-}
-
 function iil_C_Copy(&$conn, $messages, $from, $to) {
 	$fp = $conn->fp;
 
@@ -1954,27 +1824,18 @@
 		$c=0;
 		
 		iil_PutLine($fp, "cpy1 UID COPY $messages \"".iil_Escape($to)."\"");
-		$line=iil_ReadReply($fp);
+		$line = iil_ReadReply($fp);
 		return iil_ParseResult($line);
 	} else {
 		return -1;
 	}
 }
 
-function iil_FormatSearchDate($month, $day, $year) {
-	$month  = (int) $month;
-	$months = $GLOBALS['IMAP_MONTHS'];
-	return $day . '-' . $months[$month] . '-' . $year;
-}
-
 function iil_C_CountUnseen(&$conn, $folder) {
-	$index = iil_C_Search($conn, $folder, 'ALL UNSEEN');
-	if (is_array($index)) {
-		if (($cnt = count($index)) && $index[0] != '') {
-			return $cnt;
-		}
-	}
-	return false;
+        $index = iil_C_Search($conn, $folder, 'ALL UNSEEN');
+        if (is_array($index))
+                return count($index);
+        return false;
 }
 
 function iil_C_UID2ID(&$conn, $folder, $uid) {
@@ -1988,45 +1849,46 @@
 }
 
 function iil_C_ID2UID(&$conn, $folder, $id) {
-	$fp = $conn->fp;
+
 	if ($id == 0) {
 	    return 	-1;
 	}
 	$result = -1;
 	if (iil_C_Select($conn, $folder)) {
-		$key = 'FUID';
-		if (iil_PutLine($fp, "$key FETCH $id (UID)")) {
+		$key = 'fuid';
+		if (iil_PutLine($conn->fp, "$key FETCH $id (UID)")) {
 			do {
-				$line=chop(iil_ReadLine($fp, 1024));
+				$line = chop(iil_ReadLine($conn->fp, 1024));
 				if (preg_match("/^\* $id FETCH \(UID (.*)\)/i", $line, $r)) {
 					$result = $r[1];
 				}
-			} while (!preg_match("/^$key/", $line));
+			} while (!iil_StartsWith($line, $key, true));
 		}
 	}
 	return $result;
 }
 
 function iil_C_Search(&$conn, $folder, $criteria) {
-	$fp = $conn->fp;
+
 	if (iil_C_Select($conn, $folder)) {
-		$c = 0;
+		$data = '';
 		
 		$query = 'srch1 SEARCH ' . chop($criteria);
-		if (!iil_PutLineC($fp, $query)) {
+		if (!iil_PutLineC($conn->fp, $query)) {
 			return false;
 		}
 		do {
-			$line=trim(iil_ReadLine($fp, 10000));
-			if (preg_match('/^\* SEARCH/i', $line)) {
-				$str = trim(substr($line, 8));
-				$messages = explode(' ', $str);
+			$line = trim(iil_ReadLine($conn->fp));
+			if (iil_StartsWith($line, '* SEARCH')) {
+				$data .= substr($line, 8);
+    			} else if (preg_match('/^[0-9 ]+$/', $line)) {
+				$data .= $line;
 			}
 		} while (!iil_StartsWith($line, 'srch1', true));
 
 		$result_code = iil_ParseResult($line);
 		if ($result_code == 0) {
-		    return $messages;
+		    return preg_split('/\s+/', $data, -1, PREG_SPLIT_NO_EMPTY);
 		}
 		$conn->error = 'iil_C_Search: ' . $line . "\n";
 		return false;	
@@ -2263,8 +2125,8 @@
 	$query = 'sub1 SUBSCRIBE "' . iil_Escape($folder). '"';
 	iil_PutLine($fp, $query);
 
-	$line = trim(iil_ReadLine($fp, 10000));
-	return iil_ParseResult($line);
+	$line = trim(iil_ReadLine($fp, 512));
+	return (iil_ParseResult($line) == 0);
 }
 
 function iil_C_UnSubscribe(&$conn, $folder) {
@@ -2273,8 +2135,8 @@
 	$query = 'usub1 UNSUBSCRIBE "' . iil_Escape($folder) . '"';
 	iil_PutLine($fp, $query);
     
-	$line = trim(iil_ReadLine($fp, 10000));
-	return iil_ParseResult($line);
+	$line = trim(iil_ReadLine($fp, 512));
+	return (iil_ParseResult($line) == 0);
 }
 
 function iil_C_FetchMIMEHeaders(&$conn, $mailbox, $id, $parts) {
@@ -2317,14 +2179,14 @@
 	return $result;
 }
 
-function iil_C_FetchPartHeader(&$conn, $mailbox, $id, $part) {
+function iil_C_FetchPartHeader(&$conn, $mailbox, $id, $is_uid=false, $part=NULL) {
 
 	$part = empty($part) ? 'HEADER' : $part.'.MIME';
 
-        return iil_C_HandlePartBody($conn, $mailbox, $id, $part);
+        return iil_C_HandlePartBody($conn, $mailbox, $id, $is_uid, $part);
 }
 
-function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part='', $encoding=NULL, $print=NULL, $file=NULL) {
+function iil_C_HandlePartBody(&$conn, $mailbox, $id, $is_uid=false, $part='', $encoding=NULL, $print=NULL, $file=NULL) {
 	
 	$fp     = $conn->fp;
 	$result = false;
@@ -2351,7 +2213,7 @@
 
     		// format request
 		$key     = 'ftch0';
-		$request = $key . " FETCH $id (BODY.PEEK[$part])";
+		$request = $key . ($is_uid ? ' UID' : '') . " FETCH $id (BODY.PEEK[$part])";
     		// send request
 		if (!iil_PutLine($fp, $request)) {
 		    return false;
@@ -2376,7 +2238,7 @@
 		        	$len  = $to - $from;
 				$result = substr($line, $from, $len);
 			}
-	    
+
         		if ($mode == 1)
 				$result = base64_decode($result);
 			else if ($mode == 2)
@@ -2399,8 +2261,9 @@
                 
 		                if ($len > $bytes) {
             			        $line = substr($line, 0, $bytes);
+					$len = strlen($line);
 		                }
-            			$bytes -= strlen($line);
+            			$bytes -= $len;
 
 		                if ($mode == 1) {
 					$line = rtrim($line, "\t\r\n\0\x0B");
@@ -2456,7 +2319,7 @@
 			do {
         			$line = iil_ReadLine($fp, 1024);
 			} while (!iil_StartsWith($line, $key, true));
-        
+
     		if ($result) {
 	    		$result = rtrim($result, "\t\r\n\0\x0B");
 			if ($file) {
@@ -2465,20 +2328,12 @@
 				echo $result;
 			} else
 				return $result; // substr($result, 0, strlen($result)-1);
+
+			return true;
     		}
-    		
-		return true;
 	}
     
 	return false;
-}
-
-function iil_C_FetchPartBody(&$conn, $mailbox, $id, $part, $file=NULL) {
-	return iil_C_HandlePartBody($conn, $mailbox, $id, $part, NULL, NULL, $file);
-}
-
-function iil_C_PrintPartBody(&$conn, $mailbox, $id, $part) {
-	iil_C_HandlePartBody($conn, $mailbox, $id, $part, NULL, true, NULL);
 }
 
 function iil_C_CreateFolder(&$conn, $folder) {
@@ -2486,8 +2341,7 @@
 	if (iil_PutLine($fp, 'c CREATE "' . iil_Escape($folder) . '"')) {
 		do {
 			$line=iil_ReadLine($fp, 300);
-		} while ($line[0] != 'c');
-        $conn->error = $line;
+		} while (!iil_StartsWith($line, 'c ', true));
 		return (iil_ParseResult($line) == 0);
 	}
 	return false;
@@ -2498,7 +2352,7 @@
 	if (iil_PutLine($fp, 'r RENAME "' . iil_Escape($from) . '" "' . iil_Escape($to) . '"')) {
 		do {
 			$line = iil_ReadLine($fp, 300);
-		} while ($line[0] != 'r');
+		} while (!iil_StartsWith($line, 'r ', true));
 		return (iil_ParseResult($line) == 0);
 	}
 	return false;
@@ -2509,40 +2363,47 @@
 	if (iil_PutLine($fp, 'd DELETE "' . iil_Escape($folder). '"')) {
 		do {
 			$line=iil_ReadLine($fp, 300);
-		} while ($line[0] != 'd');
+		} while (!iil_StartsWith($line, 'd ', true));
 		return (iil_ParseResult($line) == 0);
 	}
-	$conn->error = "Couldn't send command\n";
 	return false;
 }
 
 function iil_C_Append(&$conn, $folder, &$message) {
 	if (!$folder) {
-    		return false;
+		return false;
 	}
 	$fp = $conn->fp;
 
 	$message = str_replace("\r", '', $message);
-	$message = str_replace("\n", "\r\n", $message);		
+	$message = str_replace("\n", "\r\n", $message);
 
 	$len = strlen($message);
 	if (!$len) {
-    		return false;
+		return false;
 	}
 
-	$request = 'A APPEND "' . iil_Escape($folder) .'" (\\Seen) {' . $len . '}';
-    
+	$request = 'a APPEND "' . iil_Escape($folder) .'" (\\Seen) {' . $len . '}';
+
 	if (iil_PutLine($fp, $request)) {
-		$line=iil_ReadLine($fp, 100);		
-		$sent = fwrite($fp, $message."\r\n");
+		$line = iil_ReadLine($fp, 512);
+
+		if ($line[0] != '+') {
+			// $errornum = iil_ParseResult($line);
+			$conn->error .= "Cannot write to folder: $line\n";
+			return false;
+		}
+
+		iil_PutLine($fp, $message);
+
 		do {
-			$line=iil_ReadLine($fp, 1000);
-		} while ($line[0] != 'A');
+			$line = iil_ReadLine($fp);
+		} while (!iil_StartsWith($line, 'a ', true));
 	
 		$result = (iil_ParseResult($line) == 0);
 		if (!$result) {
 		    $conn->error .= $line . "\n";
-    		}
+		}
 		return $result;
 	}
 
@@ -2556,7 +2417,7 @@
 	}
     
 	//open message file
-	$in_fp = false;				
+	$in_fp = false;
 	if (file_exists(realpath($path))) {
 		$in_fp = fopen($path, 'r');
 	}
@@ -2572,31 +2433,35 @@
 	}
     
 	//send APPEND command
-	$request    = 'A APPEND "' . iil_Escape($folder) . '" (\\Seen) {' . $len . '}';
-	$bytes_sent = 0;
+	$request    = 'a APPEND "' . iil_Escape($folder) . '" (\\Seen) {' . $len . '}';
 	if (iil_PutLine($fp, $request)) {
-		$line = iil_ReadLine($fp, 100);
-				
+		$line = iil_ReadLine($fp, 512);
+
+		if ($line[0] != '+') {
+			//$errornum = iil_ParseResult($line);
+			$conn->error .= "Cannot write to folder: $line\n";
+			return false;
+		}
+
 		//send file
 		while (!feof($in_fp)) {
 			$buffer      = fgets($in_fp, 4096);
-			$bytes_sent += strlen($buffer);
 			iil_PutLine($fp, $buffer, false);
 		}
 		fclose($in_fp);
 
-		iil_PutLine($fp, '');
+		iil_PutLine($fp, ''); // \r\n
 
 		//read response
 		do {
-			$line = iil_ReadLine($fp, 1000);
-		} while ($line[0] != 'A');
-			
+			$line = iil_ReadLine($fp);
+		} while (!iil_StartsWith($line, 'a ', true));
+
 		$result = (iil_ParseResult($line) == 0);
 		if (!$result) {
 		    $conn->error .= $line . "\n";
 		}
-        
+
 		return $result;
 	}
 	
@@ -2604,23 +2469,22 @@
 	return false;
 }
 
-function iil_C_FetchStructureString(&$conn, $folder, $id) {
+function iil_C_FetchStructureString(&$conn, $folder, $id, $is_uid=false) {
 	$fp     = $conn->fp;
 	$result = false;
 	
 	if (iil_C_Select($conn, $folder)) {
 		$key = 'F1247';
 
-		if (iil_PutLine($fp, "$key FETCH $id (BODYSTRUCTURE)")) {
+		if (iil_PutLine($fp, $key . ($is_uid ? ' UID' : '') ." FETCH $id (BODYSTRUCTURE)")) {
 			do {
 				$line = iil_ReadLine($fp, 5000);
-				$line = iil_MultLine($fp, $line);
-				list(, $index, $cmd, $rest) = explode(' ', $line);
-				if ($cmd != 'FETCH' || $index == $id || preg_match("/^$key/", $line))
+				$line = iil_MultLine($fp, $line, true);
+				if (!preg_match("/^$key/", $line))
 					$result .= $line;
-			} while (!preg_match("/^$key/", $line));
+			} while (!iil_StartsWith($line, $key, true));
 
-			$result = trim(substr($result, strpos($result, 'BODYSTRUCTURE')+13, -(strlen($result)-strrpos($result, $key)+1)));
+			$result = trim(substr($result, strpos($result, 'BODYSTRUCTURE')+13, -1));
 		}
 	}
 	return $result;

--
Gitblit v1.9.1