Location: PHPKode > projects > Laikwan WMC > wmc_20070325/hail/HTTPMail.class.php
<?

/*
 * Hail is a PHP-Hotmail gateway. It will allow you to
 * check your hotmail account via any webserver with PHP.
 *
 * Created by: Craig Marshall <hide@address.com> and
 * Justin Carlson <hide@address.com>, 30-May-2003
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

class HTTPMail
{
	var $user;
	var $pass;

	var $login_response;
	var $last_auth_response;

	var $cnonce = "f0ecf39d64caeed767075abcc6bec8bz";// This string should be auto-generated
	var $method = "PROPFIND";
	
	var $nc;
	var $nonce;
	var $realm;
	var $qop;
	var $uri;
	
	var $digest;
	var $auth;

	function HTTPMail($user, $pass)
	{
		$this->user = $user;
		$this->pass = $pass;
	}

	function delete_mail($mail_url)
	{
		
		//Grab the $host and $path from the $msgroot
		preg_match("/^(.*:\/\/)?([^:\/]+):?([0-9]+)?(.*)/", $mail_url, $matches);
		list(,,$host,,$path) = $matches;

		//Remove extra newlines from host and path
		$path = preg_replace("/(\r|\n)/", "", $path);
		$host = preg_replace("/(\r|\n)/", "", $host);
		
		$end_pos = strrpos($mail_url, "/");  // Find the last slash in mail_url
		$start_pos = strrpos(substr($mail_url, 0, $end_pos), "/") + 1; // Find the second last slash
		$find = substr($mail_url, $start_pos, $end_pos - $start_pos); // Get the text between these two slashes
		$dest = substr_replace($mail_url, "trAsH", $start_pos, $end_pos-$start_pos); // replace that with trash folder name..

		/*
		MOVE /cgi-bin/hmdata/hide@address.com/folders/ACTIVE/MSG1057229617.75 HTTP/1.1
		Destination: http://bay8.oe.hotmail.com/cgi-bin/hmdata/hide@address.com/folders/trAsH/MSG1057229617.75
		Allow-Rename: t
		User-Agent: Outlook-Express/6.0 (MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; TmstmpExt)
		Host: bay8.oe.hotmail.com
		Content-Length: 0
		Connection: Keep-Alive
		Cache-Control: no-cache
		Cookie: MSPAuth=4Hg24CyhDDvUQV%2aPSZapxKuHeNnLBnK7k2lzYXodexSR75QYXOtIeYikal6d%2auIaZbSF5dyncH98Evy%21RnQsKIGg%24%24; MSPProf=4ljMr6SKtEhrKBUy7tk7LL5ZCtLNLNkJPYacnGnPQ5uCrIJ%2aB%2aPPat9VUKaClueK%2acNLFtgzt%212g9wIzzavEUFAHpGZzI61zdtVjXxSMUAdHLea6VI%2aZPFmGZ5ACxhjmYdsd72XCsIGfpB3T591OxER%2a7ihyfZ%2acqRKrsiBz6bbJdAbwJNfqZsXvdW0T7QMaesVNPZBtynq8Vhrd6dF%219d1w%24%24; HMSatchmo=0; HMSC0899=227mrcraigmarshall%40hotmail%2ecomBjcQE9CjxFSkRCQycI9p34oaODur5CNLISvoT7Z07deIIoMt%2aVlhaMvyIMgAdJyS51Q9sum3qON%2a6gzumK74Rl35CclXMcyHP5e3%21Zon8g%21166kgqic8GInORu%21aQvNOOn2hNaTWjnvjpU98QhXkGwhgDhWMJzyimnD1I7CS9TAzAXdmyXJSDoDES8Hlsg8BCUVHu338UV7ty9lxXt0u5Zk1eNwysrerSSg4EFwhOLAbcoclPF7OQRh6RwbAvg04AOUwicyv0QzQm2cRyVnD0kqomlKYHie8%21bp74xQNlWPCoJj%2a0ycqG%2apkMjNZv%21xP2bTKLH7%2aKHx2p%2arVNsUdZGDrrQ5g0j4ffDBOh3L5kIJst8tcOmE0SP0yXxMfYxe2A3YFoRNLAyeiwBMZtC2hShPxULeQKhL18ANjJSN%219co%24; HMSatchmo=0; HMMS2954=40ECB06078A51BC4452D437972F42DE7C5A3AF9AC355E263D29B9B63D09CF096625C625AA77DE8AE; OE_Usermrcraigmarshall_hotmail.com=1057477228
		Authorization: Digest username="hide@address.com", realm="hotmail.com", qop="auth", algorithm="MD5", uri="/cgi-bin/hmdata/hide@address.com/folders/ACTIVE/MSG1057229617.75", nonce="MTA1NzM5MDgyNjoxZGNiYWNjODFlNGVlOWY4NTRmMjcyNmYwOWEwMzM5Yw==", nc=00000008, cnonce="9a053cfe44796fa92352634adf4e7819", response="8b6724ded832f869e1be49860c241a38"
		*/
		

		$request = "MOVE $path HTTP/1.1\r\n";
		$request .= "Destination: $dest\r\n";
		$request .= "Allow-Rename: t\r\n";
		$request .= "User-Agent: Outlook-Express/6.0 (MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; TmstmpExt)\r\n";
		$request .= "Host: $host\r\n";
		$request .= "Content-Length: 0\r\n";
		$request .= "Connection: Keep-Alive\r\n";
		$request .= "Cache-Control: no-cache\r\n";
		$request .= "\r\n";

		//Authorise
		$this->nc = "00000001"; // TODO: Implement auto increment (Does it matter to the server???)

		$cookies = $this->get_cookies($this->login_response);
		$this->set_request_cookies($request, $cookies);

		$this->get_auth_vars();
		$this->realm = "hotmail.com";
		$this->uri = $this->remove_querystring($path);
		$this->method = "MOVE";

		$this->create_digest();
		$this->create_auth($request);

		//Reset it here 'cause we don't set it elsewhere (normally just stays on PROPFIND)
		$this->method = "PROPFIND";

		$response = "";
		$status = "";

		//This should print our response out to html comment.
		$this->send_http_request($host, $request, $response, $status);

		return 1;
	}

	function get_folders()
	{
		//Initialise array to return
		$mail_folders = Array();

		//Get the message root
		$msgroot = $this->get_msgroot();

		//print "MSGROOT: $msgroot<br>\n";

		//Grab the $host and $path from the $msgroot
		preg_match("/^(.*:\/\/)?([^:\/]+):?([0-9]+)?(.*)/", $msgroot, $matches);
		list(,,$host,,$path) = $matches;

		//Remove extra newlines from host and path
		$path = preg_replace("/(\r|\n)/", "", $path);
		$host = preg_replace("/(\r|\n)/", "", $host);

		//print "PATH: $path<br>\n";
		//print "HOST: $host<br>\n";

		$request = "PROPFIND $path HTTP/1.1\r\n";
		$request .= "Depth: 1,noroot\r\n";
		$request .= "Content-Type: text/xml\r\n";
		$request .= "Brief: t\r\n";
		$request .= "X-Timestamp: folders=,ACTIVE=\r\n";
		$request .= "Accept-CharSet: Windows-1252\r\n";
		$request .= "User-Agent: Outlook-Express/6.0 (MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; TmstmpExt)\r\n";
		$request .= "Host: $host\r\n";
		$request .= "Content-Length: 235\r\n"; // was 265
		$request .= "Connection: Keep-Alive\r\n";
		$request .= "Cache-Control: no-cache\r\n";
		$request .= "\r\n";
		$request .= "<?xml version='1.0'?>\r\n";
		$request .= "<D:propfind xmlns:D='DAV:' xmlns:hm='urn:schemas:httpmail:'>\r\n";
		$request .= "<D:prop>\r\n";
		$request .= "<D:isfolder/>\r\n";
		$request .= "<D:displayname/>\r\n";
		$request .= "<hm:special/>\r\n";
		$request .= "<D:hassubs/>\r\n";
		$request .= "<D:nosubs/>\r\n";
		$request .= "<hm:unreadcount/>\r\n";
		$request .= "<D:visiblecount/>\r\n";
		$request .= "<hm:special/>\r\n";
		$request .= "</D:prop>\r\n";
		$request .= "</D:propfind>\r\n";

		//Authorise
		$this->nc = "00000003"; // TODO: Implement auto increment (Does it matter to the server???)

		$cookies = $this->get_cookies($this->login_response);
		$this->set_request_cookies($request, $cookies);

		$this->get_auth_vars();
		$this->realm = "hotmail.com";
		$this->uri = $this->remove_querystring($path);

		$this->create_digest();
		$this->create_auth($request);

		$response = "";
		$status = "";

		$this->send_http_request($host, $request, $response, $status);

		/*
		$preg_match = "<D:response>";
		//$preg_match.= "(.*?<D:displayname>(.*?)<\/D:displayname>)?";
		$preg_match.= ".*?<hm:special>(.*?)<\/hm:special>";
		$preg_match.= ".*?<hm:unreadcount>(.*?)<\/hm:unreadcount>";
		$preg_match.= ".*?<D:visiblecount>(.*?)<\/D:visiblecount>";
		$preg_match.= ".*?<\/D:response>";

		preg_match_all("/$preg_match/s", $response, $matches);

		for($i=0;$i<count($matches[1]);$i++){
			if($matches[0][$i]!=''){
				$displayname = $matches[0][$i];
				$name = $matches[1][$i];
				$unread = $matches[2][$i];
				$visible = $matches[3][$i]; // total number of mail items

				print ("<!-- Extracted this info: displayname: $displayname, name: $name, unread: $unread, visible: $visible -->\n");

				$temp_folder = new MailFolder($name, $unread, $visible);

				array_push($mail_folders, $temp_folder);
			}
		}
		*/

		//Couldn't get a single regex to work with the *optional* <D:displayname> element
		//I tried the (<node>.*?</node)? method with a ? quantifier (0 or 1 matches), but 
		//I can't get it to work? Feel free to optimise this bit. It should be quicker in one 
		//regex, no?

		$preg_match = "<D:response>(.*?)<\/D:response>";

		preg_match_all("/$preg_match/s", $response, $matches);

		for($i=0; $i<count($matches[1]); $i++)
		{
			$response = $matches[1][$i];

			preg_match("/<D:displayname>(.*?)<\/D:displayname>/", $response, $m);
			$displayname = $m[1];

			preg_match("/<hm:special>(.*?)<\/hm:special>/", $response, $m);
			$name = $m[1];

			preg_match("/<hm:unreadcount>(.*?)<\/hm:unreadcount>/", $response, $m);
			$unread = $m[1];

			preg_match("/<D:visiblecount>(.*?)<\/D:visiblecount>/", $response, $m);
			$visible = $m[1];
	
			//print ("<!-- Extracted this info: displayname: $displayname, name: $name, unread: $unread, visible: $visible -->\n");

			if ($name == "" && $displayname != "")
				$name = $displayname;

			if($name == "msnpromo")
				$unread = "N/A";

			$temp_folder = new MailFolder($name, $unread, $visible);

			array_push($mail_folders, $temp_folder);
		}

		return $mail_folders;
	}

	function send_email($to,$cc,$bcc,$subject,$message)
	{

		$send_url = str_replace("folders", "sendmsg", $this->get_msgroot());

		//Grab the $host and $path from the $msgroot
		preg_match("/^(.*:\/\/)?([^:\/]+):?([0-9]+)?(.*)/", $send_url, $matches);
		list(,,$host,,$path) = $matches;

		//Remove extra newlines from host and path
		$path = preg_replace("/(\r|\n)/", "", $path);
		$host = preg_replace("/(\r|\n)/", "", $host);

		$body = "";
		$body .= "MAIL FROM:<".$this->user.">\r\n";

		$to = split(";", $to); // turn semicolon delimited string into array
		$cc = split(";", $cc); // turn semicolon delimited string into array
		$bcc = split(";", $bcc); // turn semicolon delimited string into array

		foreach($to as $x)
			if($x) $body.= "RCPT TO:<$x>\r\n";

		foreach($cc as $x)
			if($x) $body.= "RCPT TO:<$x>\r\n";

		foreach($bcc as $x)
			if($x) $body.= "RCPT TO:<$x>\r\n";

		$body.= "\r\n";
		$body.= "From: ".$this->user."\r\n";
		foreach($to as $x)
			if($x) $body.= "To:<$x>\r\n";

		foreach($cc as $x)
			if($x) $body.= "Cc:<$x>\r\n";

		foreach($bcc as $x)
			if($x) $body.= "Bcc:<$x>\r\n";
			
		$body.= "Subject: $subject\r\n";
		//$body.= "Fri, 6 Jun 2003 18:40:36 +0100\r\n";
		$body.= "MIME-Version: 1.0\r\n";
		$body.= "Content-Type: text/plain; charset=\"iso-8859-1\"\r\n";
		$body.= "Content-Transfer-Encoding: 7bit\r\n";
		$body.= "X-Priority: 3\r\n";
		$body.= "X-MSMail-Priority: Normal\r\n";
		$body.= "X-Mailer: Microsoft Outlook Express 6.00.2600.0000\r\n";
		$body.= "X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000\r\n";
		$body.= "\r\n$message\r\n";
		
		$length = strlen($body);
		
		$request = "POST $path HTTP/1.1\r\n";
		$request .= "Translate: t\r\n";
		$request .= "Content-Type: message/rfc821\r\n";
		$request .= "SAVEINSENT: t\r\n";
		$request .= "User-Agent: Outlook-Express/6.0 (MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; TmstmpExt)\r\n";
		$request .= "Host: $host\r\n";
		$request .= "Content-Length: $length\r\n"; // was 265
		$request .= "Connection: Keep-Alive\r\n";
		$request .= "Cache-Control: no-cache\r\n";
		$request .= "\r\n";
		$request .= $body;

		$cookies = $this->get_cookies($this->login_response);
		$this->set_request_cookies($request, $cookies);

		$this->send_http_request($host, $request, $response, $status);
	}

	function get_folder_items_raw($folder)
	{
		$mail_folder_items = Array();

		//Get the message root
		$msgroot = $this->get_msgroot();

		//print "MSGROOT: $msgroot<br>\n";

		//Grab the $host and $path from the $msgroot
		preg_match("/^(.*:\/\/)?([^:\/]+):?([0-9]+)?(.*)/", $msgroot, $matches);
		list(,,$host,,$path) = $matches;

		//Remove extra newlines from host and path


		$path = preg_replace("/(\r|\n)/", "", $path);
		$host = preg_replace("/(\r|\n)/", "", $host);

		// Translate the named folders into the real folder name
		$tmp = $this->get_realfolder($folder);
		
		if($tmp != "")
			$folder = $tmp;
				
		// Add the foldername to the path
		$path = $path.$folder.'/';

		$request = "PROPFIND $path HTTP/1.1\r\n";
		$request .= "Depth: 1,noroot\r\n";
		$request .= "Content-Type: text/xml\r\n";
		$request .= "Brief: t\r\n";
		$request .= "X-Timestamp: folders=,ACTIVE=\r\n";
		$request .= "Accept-CharSet: Windows-1252\r\n";
		$request .= "User-Agent: Outlook-Express/6.0 (MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; TmstmpExt)\r\n";
		$request .= "Host: $host\r\n";
		$request .= "Content-Length: 270\r\n"; // was 265
		$request .= "Connection: Keep-Alive\r\n";
		$request .= "Cache-Control: no-cache\r\n";
		$request .= "\r\n";
		$request .= "<?xml version='1.0'?>\r\n"; //23
		$request .= "<D:propfind xmlns:D='DAV:' xmlns:hm='urn:schemas:httpmail:' xmlns:m='urn:schemas:mailheader:'>\r\n"; //96
			$request .= "<D:prop>\r\n"; //10
				$request .= "<D:isfolder/>\r\n"; //15
				$request .= "<hm:read/>\r\n"; //12
				$request .= "<hm:hasattachment/>\r\n"; //20 - corrected by laikwan on 4/2/2006 (m to hm NS)
//				$request .= "<hm:to/>\r\n"; //9 - corrected by laikwan on 4/2/2006 
				$request .= "<m:from/>\r\n"; //11
				$request .= "<m:subject/>\r\n"; //14
				$request .= "<m:date/>\r\n"; //11
				$request .= "<D:getcontentlength/>\r\n"; //23
			$request .= "</D:prop>\r\n"; //11
		$request .= "</D:propfind>\r\n"; //15

		//Authorise
		$this->nc = "00000004"; // TODO: Implement auto increment (Does it matter to the server???)

		$cookies = $this->get_cookies($this->login_response);
		$this->set_request_cookies($request, $cookies);

		$this->get_auth_vars();
		$this->realm = "hotmail.com";
		$this->uri = $this->remove_querystring($path);

		$this->create_digest();
		$this->create_auth($request);

		$response = "";
		$status = "";

		//This should print our response out to html comment.
		$this->send_http_request($host, $request, $response, $status);

		return $response;
	}

	function get_folder_items($folder)
	{
		$mail_folder_items = Array();

		//Get the message root
		$msgroot = $this->get_msgroot();

		//print "MSGROOT: $msgroot<br>\n";

		//Grab the $host and $path from the $msgroot
		preg_match("/^(.*:\/\/)?([^:\/]+):?([0-9]+)?(.*)/", $msgroot, $matches);
		list(,,$host,,$path) = $matches;

		//Remove extra newlines from host and path


		$path = preg_replace("/(\r|\n)/", "", $path);
		$host = preg_replace("/(\r|\n)/", "", $host);

		// Translate the named folders into the real folder name
		$tmp = $this->get_realfolder($folder);
		
		if($tmp != "")
			$folder = $tmp;
				
		// Add the foldername to the path
		$path = $path.$folder.'/';

		$request = "PROPFIND $path HTTP/1.1\r\n";
		$request .= "Depth: 1,noroot\r\n";
		$request .= "Content-Type: text/xml\r\n";
		$request .= "Brief: t\r\n";
		$request .= "X-Timestamp: folders=,ACTIVE=\r\n";
		$request .= "Accept-CharSet: Windows-1252\r\n";
		$request .= "User-Agent: Outlook-Express/6.0 (MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; TmstmpExt)\r\n";
		$request .= "Host: $host\r\n";
		$request .= "Content-Length: 270\r\n"; // was 265
		$request .= "Connection: Keep-Alive\r\n";
		$request .= "Cache-Control: no-cache\r\n";
		$request .= "\r\n";
		$request .= "<?xml version='1.0'?>\r\n"; //23
		$request .= "<D:propfind xmlns:D='DAV:' xmlns:hm='urn:schemas:httpmail:' xmlns:m='urn:schemas:mailheader:'>\r\n"; //96
		$request .= "<D:prop>\r\n"; //10
		$request .= "<D:isfolder/>\r\n"; //15
		$request .= "<hm:read/>\r\n"; //12

		// corrected by laikwan on 4/2/2006 (m to hm NS)
		// see http://msdn.microsoft.com/library/en-us/cdosys/html/9ff28aa3-fb60-490a-a358-d05849a3de94.asp?frame=true
		$request .= "<hm:hasattachment/>\r\n"; //20
		
		$request .= "<m:to/>\r\n"; //9 
		$request .= "<m:from/>\r\n"; //11
		$request .= "<m:subject/>\r\n"; //14
		$request .= "<m:date/>\r\n"; //11
		$request .= "<D:getcontentlength/>\r\n"; //23
		$request .= "</D:prop>\r\n"; //11
		$request .= "</D:propfind>\r\n"; //15


		//Authorise
		$this->nc = "00000004"; // TODO: Implement auto increment (Does it matter to the server???)

		$cookies = $this->get_cookies($this->login_response);
		$this->set_request_cookies($request, $cookies);

		$this->get_auth_vars();
		$this->realm = "hotmail.com";
		$this->uri = $this->remove_querystring($path);

		$this->create_digest();
		$this->create_auth($request);

		$response = "";
		$status = "";

		//This should print our response out to html comment.
		$this->send_http_request($host, $request, $response, $status);

		// Build preg_match for this query
		$preg_match = "";
		$preg_match.= "<D:response>";
		$preg_match.= ".*?<D:href>(.*?)<\/D:href>";
		$preg_match.= ".*?<hm:read>(.*?)<\/hm:read>";
		$preg_match.= ".*?<hm:hasattachment>(.*?)<\/hm:hasattachment>";
		$preg_match.= ".*?(?:<m:to>(.*?)<\/m:to>|<m:to\/>)";
		$preg_match.= ".*?(?:<m:from>(.*?)<\/m:from>|<m:from\/>)";
		$preg_match.= ".*?<m:subject>(.*?)<\/m:subject>";

		//print $folder."\n";
		// need a nice way to get "sAVeD" back from "sentitems"
		if($folder != 'msnpromo' && $folder != 'sAVeD')
		        $preg_match .= ".*?<m:date>(.*?)<\/m:date>";

		$preg_match.= ".*?<D:getcontentlength>(.*?)<\/D:getcontentlength>";

		$preg_match.= ".*?<\/D:response>";

		// Grab data from the response
		preg_match_all("/$preg_match/s", $response, $matches);

		//print $preg_match."\n";
		//print "Found ".count($matches[1])." matches in the response XML<br>\n";

		for($i=0;$i<count($matches[1]);$i++)
		{
			if($matches[1][$i]!=''){

				$new = !$matches[2][$i];
				$url = $matches[1][$i];

				// index 3+ mod by laikwan on 4/2/2006 (for hasattachement)
				$hasattachment = $matches[3][$i];	
				$to = $matches[4][$i];
				$from = $matches[5][$i];
				$subject = $matches[6][$i];
				
				$j = 7;
				//date and size need if statements to accomodate "msnpromo" and "sentitems"
				if($folder != 'msnpromo' && $folder != 'sAVeD'){
//				    $date = $this->get_nice_date($matches[$j++][$i]);
				    $date = preg_replace("/T/", " ", $matches[$j++][$i]);
				}else{
				    $date = "";
				}

//				$size = $this->get_nice_size($matches[$j][$i]);
				$size = $matches[$j][$i];

				array_unshift($mail_folder_items, new MailFolderItem($new, $url, $to, $from, $subject, $date, $size, $hasattachment));
			}
		}

		return $mail_folder_items;
	}
	
	function get_nice_size($s)
	{
		$k = 1024;
		$m = $k * $k;

		if($s<$k)
			return $s."b";
		else if($s<$m)
			return round($s/$k, 2)."k";
		else
			return round($s/$m, 2)."m";
	}

	function get_nice_date($date)
	{
		//$date = "2003-06-05T20:27:28";

		preg_match("/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/", $date, $matches);
		
		$year = $matches[1];
		$month = $matches[2];
		$day = $matches[3];
		$hour = $matches[4];
		$minute = $matches[5];
		$second = $matches[6];

		//mktime(hour, minute, second, month, day, year)

		return date ("jS F @ g:i a", mktime($hour,$minute,$second,$month,$day,$year));
	}

	function get_email($mail_url)
	{

		//print "MAIL URL: $mail_url<br>\n";

		//Grab the $host and $path from the $msgroot
		preg_match("/^(.*:\/\/)?([^:\/]+):?([0-9]+)?(.*)/", $mail_url, $matches);
		list(,,$host,,$path) = $matches;

		//Remove extra newlines from host and path
		$path = preg_replace("/(\r|\n)/", "", $path);
		$host = preg_replace("/(\r|\n)/", "", $host);

		$request = "GET $path HTTP/1.1\r\n";
		$request .= "Accept: message/rfc82 */*\r\n";
		$request .= "Translate: f\r\n";
		$request .= "User-Agent: Outlook-Express/6.0 (MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; TmstmpExt)\r\n";
		$request .= "Host: $host\r\n";
		$request .= "Connection: Keep-Alive\r\n";
		$request .= "Cache-Control: no-cache\r\n";
		$request .= "\r\n";

		//Authorise
		$this->nc = "00000005"; // TODO: Implement auto increment (Does it matter to the server???)

		$cookies = $this->get_cookies($this->login_response);
		$this->set_request_cookies($request, $cookies);

		$this->get_auth_vars();
		$this->realm = "hotmail.com";
		$this->uri = $this->remove_querystring($path);
		$this->method = "GET";

		$this->create_digest();
		$this->create_auth($request);

		//Reset it here 'cause we don't set it elsewhere (normally just stays on PROPFIND)
		$this->method = "PROPFIND";

		$response = "";
		$status = "";

		//This should print our response out to html comment.
		$this->send_http_request($host, $request, $response, $status);

		//there's a double newline to seperate the response from the email header
		//then there's another double newline to seperateusername the email header from the
		//email body, we want the content type of the email here.
//		preg_match("/\n\n.*?Content-Type: (.*?)\n/", $response, $matches);
		//$content_type = $matches[1];

// 		preg_match("/(Received|From): .*/s", $response, $matches);
//		$email = $matches[0];
		
		//update_read($mail_url, 1);

		// added by laikwan 3/26/2006
		// the email can be parsed by pear's "Mail/mimeDecode.php"
		// known variants: 		
		//	X-Message-Info 
		//	X-Message-Status

 		preg_match("/X-Message.*/s", $response, $matches);
		$email = $matches[0];

		return $email;
	}

	function update_read($mail_url, $read)
	{
	
		//Grab the $host and $path from the $msgroot
		preg_match("/^(.*:\/\/)?([^:\/]+):?([0-9]+)?(.*)/", $mail_url, $matches);
		list(,,$host,,$path) = $matches;

		//Remove extra newlines from host and path
		$path = preg_replace("/(\r|\n)/", "", $path);
		$host = preg_replace("/(\r|\n)/", "", $host);

		$request = "PROPPATCH $path HTTP/1.1\r\n";
		$request .= "Content-Type: text/xml\r\n";
		$request .= "Brief: t\r\n";
		$request .= "User-Agent: Outlook-Express/6.0 (MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; TmstmpExt)\r\n";
		$request .= "Host: $host\r\n";
		$request .= "Content-Length: 181\r\n";
		$request .= "Connection: Keep-Alive\r\n";
		$request .= "Cache-Control: no-cache\r\n";
		$request .= "\r\n";
		$request .= "<?xml version=\"1.0\"?>\r\n";
		$request .= "<D:propertyupdate xmlns:D=\"DAV:\" xmlns:hm=\"urn:schemas:httpmail:\">\r\n";
		$request .= "\t<D:set>\r\n";
		$request .= "\t\t<D:prop>\r\n";
		$request .= "\t\t\t<hm:read>$read</hm:read>\r\n";
		$request .= "\t\t</D:prop>\r\n";
		$request .= "\t</D:set>\r\n";
		$request .= "</D:propertyupdate>\r\n";


		//Authorise
		$this->nc = "00000005"; // TODO: Implement auto increment (Does it matter to the server???)

		$cookies = $this->get_cookies($this->login_response);
		$this->set_request_cookies($request, $cookies);

		$this->get_auth_vars();
		$this->realm = "hotmail.com";
		$this->uri = $this->remove_querystring($path);
		$this->method = "PROPPATCH";

		$this->create_digest();
		$this->create_auth($request);

		//Reset it here 'cause we don't set it elsewhere (normally just stays on PROPFIND)
		$this->method = "PROPFIND";

		$response = "";
		$status = "";

		//This should print our response out to html comment.
		$this->send_http_request($host, $request, $response, $status);

		return 1;

	}

	function login()
	{
		$MAX_REQUESTS = 20; // it's normally less than 10, this should do for now
		$request_count = 0;
		$status = "";

		while(1)
		{
			switch($status)
			{
			case "":
				//First time we enter the loop
				$host = "services.msn.com";

				$request = "PROPFIND /svcs/hotmail/httpmail.asp HTTP/1.1\r\n";
				$request .= "Depth: 0\r\n";
				$request .= "Content-Type: text/xml\r\n";
				$request .= "Brief: t\r\n";
				$request .= "User-Agent: Outlook-Express/6.0 (MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; TmstmpExt)\r\n";
				$request .= "Host: services.msn.com\r\n";
				$request .= "Content-Length: 357\r\n";
				$request .= "Connection: Keep-Alive\r\n";
				$request .= "Cache-Control: no-cache\r\n";
				$request .= "\r\n";
				$request .= "<?xml version=\"1.0\"?>\r\n";
				$request .= "<D:propfind xmlns:D=\"DAV:\" xmlns:h=\"http://schemas.microsoft.com/hotmail/\" xmlns:hm=\"urn:schemas:httpmail:\">\r\n";
				$request .= "\t<D:prop>\r\n";
				$request .= "\t\t<h:adbar/>\r\n";
				$request .= "\t\t<hm:contacts/>\r\n";
				$request .= "\t\t<hm:inbox/>\r\n";
				$request .= "\t\t<hm:outbox/>\r\n";
				$request .= "\t\t<hm:sendmsg/>\r\n";
				$request .= "\t\t<hm:sentitems/>\r\n";
				$request .= "\t\t<hm:deleteditems/>\r\n";
				$request .= "\t\t<hm:drafts/>\r\n";
				$request .= "\t\t<hm:msgfolderroot/>\r\n";
				$request .= "\t\t<h:maxpoll/>\r\n";
				$request .= "\t\t<h:sig/>\r\n";
				$request .= "\t</D:prop>\r\n";
				$request .= "</D:propfind>\r\n";
				//Do nothing
				break;

			case "207": // Multi-status
				$this->login_response = $response;
				return 1;

			case "302": // Object moved
				$cookies = $this->get_cookies($response);
				$host = $this->get_location_host($response);
				$path = $this->get_location_path($response);
				$this->set_request_path($request, $path);
				$this->set_request_host($request, $host);
				$this->remove_auth_line($request);
				$this->set_request_cookies($request, $cookies);
				break;

			case "401": // Unauthorised
				$this->last_auth_response = $response;

				$this->nc = "00000001"; // TODO: Implement auto increment (Doesn't matter to server???)
				$this->get_auth_vars();
				$this->uri = $this->remove_querystring($path);
				$this->create_digest();
				$this->create_auth($request);
				break;

			case "403": // Forbidden
				$this->last_error = "Error 403: Request was forbidden";
				return 0;

			case "503": // Service Unavailable
				$this->last_error = "Error 503: Service is unavailable";
				return 0;

			default:
				$this->last_error = "Error: Unrecognised HTTP status was recieved: $status";
				return 0;
			}

			$this->send_http_request($host, $request, $response, $status);

			//This stops us looping and requesting forever
			if(++$request_count >= $MAX_REQUESTS)
			{
				$this->last_error = "Error: Had to make $request_count requests, check username and password or increase request count limit";
				return 0;
			}
		}
	}

	function get_msgroot()
	{
		preg_match("/<(hm:msgfolderroot)>(.*?)<\/\\1>/", $this->login_response, $matches);
		return $matches[2];
	}

	function send_http_request($host, $request, &$response, &$status)
	{
		$port = 80;
		$timeout = 30;
		$errno = 0;
		$errstr = "";
		$response = "";
		$status = "";

		if(!$host)
		{
			$this->last_error = "Error: No host was passed to send_http_request<br>\n";
			return 0;
		}

		//print("\n<!-- REQUESTING FROM HOST: '$host'\n".$this->remove_comments($request)."\n -->\n");
		flush();

		//Open the socket to the server
		$handle = fsockopen($host, $port, $errno, $errstr, $timeout);

		if(!$handle)
		{
			$this->last_error = "Error: fsockopen() failed. Error no: $errno. Error string $errstr<br>\n";
			return 0;
		}

		//Send the request data to the socket
		fputs($handle, $request);

		//Read the entire response from the socket
	
		while (!feof($handle)){
			$response .= fgets($handle,1024);
		}
	
		//Close the resource we opened
		fclose($handle);

		//Get the HTTP status code
		preg_match("/\s+(\d+)\s+/", $response, $matches);
		$status = $matches[1];

		//print("\n<!-- RESPONSE $status \n".$this->remove_comments($response)."\n-->\n");
		flush();
	}

	function remove_comments(&$string)
	{
		return preg_replace("/<!--.*?-->/s", "", $string);
	}

	function remove_auth_line(&$request)
	{
		$request = preg_replace("/(\r|\n)+Authorization:.*?(\r|\n)+/i", "\r\n", $request);
	}

	function get_cookies($response)
	{
		preg_match_all("/Set-Cookie: (.*?);/", $response, $matches);
		return "Cookie: ".join('; ', $matches[1]);
	}

	function get_auth_vars()
	{
		$r = $this->last_auth_response;

		preg_match("/realm=\"(.*?)\"/", $r, $matches);
		$this->realm = $matches[1];

		preg_match("/qop=\"(.*?)\"/", $r, $matches);
		$this->qop = $matches[1];

		preg_match("/nonce=\"(.*?)\"/", $r, $matches);
		$this->nonce = $matches[1];
	}

	// Looks for a "Location: " header, and extracts the hostname from it
	function get_location_host($response)
	{
		//match the new location
		preg_match("/Location: (.*?)\n/", $response, $matches);
		$location = $matches[1];

		//look for the host
		preg_match("/^(.*:\/\/)?([^:\/]+):?([0-9]+)?(.*)/", $location, $matches);
		list(,$proto, $hostname, $new_port, $path) = $matches;

		$hostname = preg_replace("/(\r|\n)/", "", $hostname);

		return $hostname;
	}

	// Looks for a "Location: " header, and extracts the path from it
	function get_location_path($response)
	{
		//match the new location
		preg_match("/Location: (.*?)\n/", $response, $matches);
		$location = $matches[1];

		//look for the host
		preg_match("/^(.*:\/\/)?([^:\/]+):?([0-9]+)?(.*)/", $location, $matches);
		list(,$proto, $hostname, $new_port, $path) = $matches;

		$path = preg_replace("/(\r|\n)/", "", $path);

		return $path;
	}

	function set_request_path(&$request, $file)
	{
		$request = preg_replace("/(PROPFIND|GET|PROPPATCH|POST|MOVE) .*? HTTP/i", "\\1 $file HTTP", $request);
	}

	function set_request_host(&$request, $host)
	{
		$request = preg_replace("/Host: .*?\r/i", "Host: $host\r", $request);
	}

	function create_digest()
	{
		$u = $this->user;
		$r = $this->realm;
		$p = $this->pass;
		$n = $this->nonce;
		$c = $this->nc;
		$o = $this->cnonce;
		$q = $this->qop;
		$m = $this->method;
		$i = $this->uri;

		$this->digest = md5(md5("$u:$r:$p").":$n:$c:$o:$q:".md5("$m:$i"));
	}

	function create_auth(&$request)
	{
		$u = $this->user;
		$r = $this->realm;
		$q = $this->qop;
		$i = $this->uri;
		$n = $this->nonce;
		$c = $this->nc;
		$o = $this->cnonce;
		$d = $this->digest;

		$this->auth = "Authorization: Digest username=\"$u\", realm=\"$r\", qop=\"$q\", algorithm=\"MD5\", uri=\"$i\", nonce=\"$n\", nc=$c, cnonce=\"$o\", response=\"$d\"";
		$this->auth = preg_replace("/[\n\r]+/", "", $this->auth);
		$request = preg_replace("/^((PROPFIND|GET|PROPPATCH|POST|MOVE).*?\n)/i", "\\1".$this->auth."\r\n", $request);
	}

	function set_request_cookies(&$request, $cookies)
	{
		$cookies = preg_replace("/[\n\r]+/", "", $cookies);
		$request = preg_replace("/^((PROPFIND|GET|PROPPATCH|POST|MOVE).*?\n)/i", "\\1$cookies\r\n", $request);
	}

	function remove_querystring($uri)
	{
		return preg_replace("/\?.*/", "", $uri);
	}

	function get_realfolder($folder)
	{
		if(strtolower($folder)=='inbox') return 'ACTIVE';
        if(strtolower($folder)=='sentitems') return 'sAVeD';
        if(strtolower($folder)=='deleteditems') return 'trAsH';
        if(strtolower($folder)=='bulkmail') return 'HM_BuLkMail_';
	}

}
?>
Return current item: Laikwan WMC