<?
if(VALID_DOCUMENT != 1) die('what?');
function ErrorHandler($errno, $errstr, $errfile, $errline){
switch ($errno) {
case E_USER_ERROR:
$err_arr = unserialize($errstr);
//include(TMPLPATH."html_start.php");
$title = $err_arr['title'];
$message = $err_arr['error'].
"\n<br/><br/>\n".
'<code style="font-size: 80%">'.$err_arr['extra_error'].'</code>';
include(TMPLPATH.'html_start.php');
include(TMPLPATH.'error.php');
include(TMPLPATH.'html_end.php');
exit;
break;
case FATAL:
echo "<b>ERROR</b> [$errno] $errstr<br />\n";
echo " Fatal error in line $errline of file $errfile";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
echo "Aborting...<br />\n";
exit;
break;
case 8:case 2:case 2048:break;
default:
echo "<b>WARNING</b> [$errno] $errstr<br />\n";
echo " Warning in line $errline of file $errfile";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
break;
}
}
function throw_error($title,$err,$extra_err){
trigger_error(serialize(array('title'=>$title,'error'=>$err,'extra_error'=>$extra_err)),
E_USER_ERROR);
}
set_error_handler('ErrorHandler');
register_shutdown_function('closeResources');
//////////////////////////////////////
// closing all resources
// called in the end of each script
//////////////////////////////////////
function closeResources(){
if(function_exists('closeFTP'))
closeFTP();
if(function_exists('closeMP'))
closeMP();
TempFileManager::clean();
}
/////////////////////////////////////////////////////////
// There is registration of some session variables:
// session_user_logged : if user logged
// session_user_name : encoded username
// session_user_password : encoded user password
// session_preferences : MailerPreferences instance
// session_mboxes : MBoxes instance
// html : HTML instance
/////////////////////////////////////////////////////////
function register_session_vars($user_name,$user_password,$auto_id=false){
session_start();
// registering and initialization
$yp = yp_passwd($user_name);
$_SESSION['user_logged'] = "true";
$_SESSION['user_name'] = base64_encode($user_name);
$_SESSION['user_password'] = base64_encode($user_password);
$_SESSION['user_homedir'] = $yp[5];
$_SESSION['preferences'] = new MailerPreferences(PREFERENCES_FILE);
$_SESSION['procmail'] = new Procmail(PROCMAIL_FILE);
$_SESSION['newsrc'] = new Newsrc(NEWSRC_FILE);
$_SESSION['labels'] = new Labels(LABELS_FILE);
$_SESSION['addressbook'] = new AddressBook(ADDRESSBOOK_FILE);
$_SESSION['mboxes'] = new MBoxes;
$_SESSION['last_mailbox'] = '';
$_SESSION['last_mailkey'] = '';
$_SESSION['last_key'] = '';
if($auto_id) $_SESSION['auto-id'] = $auto_id;
unset($_SESSION['notice']);
}
////////////////////////////////
// Class for notice
////////////////////////////////
class Notice{
function set($notice){
if(is_array($notice))
$notice = implode('<br/>',$notice);
if(Notice::exists()){
if($_SESSION['notice'][strlen($_SESSION['notice'])-1] != "\n")
$_SESSION['notice'] .= "\n";
$_SESSION['notice'] .= $notice;
}
else
$_SESSION['notice'] = $notice;
}
function exists(){
return isset($_SESSION['notice']);
}
function erase(){
if(Notice::exists()){
$notice = $_SESSION['notice'];
unset($_SESSION['notice']);
return $notice;
}
return null;
}
}
////////////////////////////////
// Class for error
////////////////////////////////
class Error{
function set($error){
if(is_array($error))
$error = implode('<br/>',$error);
if(Error::exists()){
if($_SESSION['error'][strlen($_SESSION['error'])-1] != "\n")
$_SESSION['error'] .= "\n";
$_SESSION['error'] .= $error;
}
else
$_SESSION['error'] = $error;
}
function exists(){
return isset($_SESSION['error']);
}
function erase(){
if(Error::exists()){
$error = $_SESSION['error'];
unset($_SESSION['error']);
return $error;
}
return null;
}
}
///////////////////////////////
// Checking of authentication
//////////////////////////////
function check_www_authentication($continue=true){
if(isset($GLOBALS['__CHECK_WWW_AUTHENTICATION__']))
return $GLOBALS['__CHECK_WWW_AUTHENTICATION__'];
session_start();
if($_SESSION['user_logged'] != 'true'){
session_unset();
session_destroy();
if(isset($_COOKIE['auto-id'])){
$user_data = get_remembered_user($_COOKIE['auto-id']);
if(array_not_empty($user_data)){
$GLOBALS['MAIL_USER_NAME']=$user_data['user_name'];
$GLOBALS['MAIL_USER_PASSWORD']=$user_data['user_password'];
if(check_imap_login(false)){
register_session_vars($GLOBALS['MAIL_USER_NAME'],
$GLOBALS['MAIL_USER_PASSWORD'],
$_COOKIE['auto-id']);
$GLOBALS['__CHECK_WWW_AUTHENTICATION__'] = true;
}
else{
setcookie('auto-id','',time()-42000,'/');
}
}
}
if(!$GLOBALS['__CHECK_WWW_AUTHENTICATION__']){
$GLOBALS['__CHECK_WWW_AUTHENTICATION__'] = false;
if($continue) return false;
if(isset($_REQUEST[session_name()]))
error('Session Error',
'Your session life time is expired<br/>'.
'Try to login again.');
else
location_header();
return false;
}
}
$GLOBALS['MAIL_USER_NAME'] = base64_decode($_SESSION['user_name']);
$GLOBALS['MAIL_USER_PASSWORD'] = base64_decode($_SESSION['user_password']);
$GLOBALS['__CHECK_WWW_AUTHENTICATION__'] = true;
return true;
}
function remember_user($user_name,$user_password){
$id = sha1(uniqid($user_name,true));
file_put_contents(AUTOLOGIN_DIR.$id,serialize(array(base64_encode($user_name),
base64_encode($user_password))));
setcookie('auto-id',$id,time()+60*60*24*40);
$_SESSION['auto-id'] = $id;
return $id;
}
function get_remembered_user($id){
$data = @file_get_contents(AUTOLOGIN_DIR.$id);
if($data == '') return false;
$data = unserialize($data);
return array('user_name'=>base64_decode($data[0]),
'user_password'=>base64_decode($data[1]));
}
function remove_remembered_user($id){
return @unlink(AUTOLOGIN_DIR.$id);
}
// getting user local dir
function get_user_local_dir($username){
return LOCAL_STORAGE_DIR.$username.'/';
}
///////////////////////////////
// Checking IMAP server login
///////////////////////////////
function check_imap_login($continue=false){
$imap = getIMAP();
if($imap == false){
if($continue) return false;
error('Login Error',
'Login failed for some reason. Most likely your<br/>'.
'username or password was entered incorrectly.');
}
return true;
}
//////////////////////////////////////////
// like PHPSESSIONID=874RJ4NFG8FG9754THRM
//////////////////////////////////////////
function sid(){
return $_SESSION['user_logged']?session_name().'='.session_id():'';
}
//////////////////////////////////////////
// Gzip support
//////////////////////////////////////////
function gzip_supported(){
return ((isset($_SERVER['HTTP_ACCEPT_ENCODING']) && eregi('gzip',$_SERVER['HTTP_ACCEPT_ENCODING'])) ||
eregi('opera',$_SERVER['HTTP_USER_AGENT']) ||
(eregi('mozilla',$_SERVER['HTTP_USER_AGENT']) && !eregi('msie',$_SERVER['HTTP_USER_AGENT'])));
}
function start_gzip(){
if(gzip_supported())
ob_start('ob_gzhandler');
}
//////////////////////////////////////////
// Location: header with location
//////////////////////////////////////////
function location_header($href=false,$with_sid=true){
if(!$href){
$href = $_SERVER['PHP_SELF'];
}
if($with_sid && !ini_get('session.use_cookies') && sid())
$href .= (eregi("[?]",$href)?'&':'?').sid();
Header('Location: '.$href);
// nothing be done after this
exit;
}
//////////////////////////////////////////
// Content-type: header with some charset
//////////////////////////////////////////
function charset_header($charset=false,$mime_type='text/html'){
if(!$charset){
$charset = $GLOBALS['DEFAULT_CHARSET'];
}
if($GLOBALS['MOBILE'] && $mime_type == 'text/html')
$mime_type = 'application/xhtml+xml';
header('Content-Type: '.$mime_type.'; charset='.$charset);
}
// no cache !!!!!!!
function no_cache(){
header("Expires: Tue, 01 Jan 2005 00:00:00 GMT");
header("Last-Modified: ".gmstrftime('%a, %d %b %Y %H:%M:%S GMT'));
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
}
//////////////////////////////////////////////
// Getting post or get variable that can be
// HEX encripted (also removes \' \" \\)
/////////////////////////////////////////////
function get_var($name){
if(isset($_GET[$name]))
$x = &$_GET[$name];
else if(isset($_POST[$name]))
$x = &$_POST[$name];
else return null;
if(!is_array($x)){
if(eregi("(%[0-9A-F]{1,2})+",$x))
$x = urldecode($x);
if(get_magic_quotes_gpc()){
$x = str_replace('\\\\','\\',$x);
$x = str_replace('\\"','"',$x);
$x = str_replace("\\'","'",$x);
}
}
return $x;
}
function is_true($obj){
if(is_bool($obj) && !$obj)
return false;
else if(is_string($obj) && $obj == "")
return false;
else return true;
}
// print obj
function print_obj($o){
print '<pre style="border: 1px solid #666">';
print h(print_r($o,true));
print '</pre>';
flush();
}
// debug printing for test users
function debug($o){
if(is_test_user()) print_obj($o);
}
// alias to htmlspecialchars
function h($s){
return htmlspecialchars($s);
}
// alias to rawurlencode
function urle($s){
return rawurlencode($s);
}
// make link
function action_link($action,$text,$extra=''){
$href = $_SERVER['PHP_SELF'].'?action='.$action;
if($extra != '') $href .= '&'.$extra;
return '<a href="'.$href.'">'.$text.'</a>';
}
function action_confirm_link($action,$text,$confirm,$extra=''){
$href = $_SERVER['PHP_SELF'].'?action='.$action;
if($extra != '') $href .= '&'.$extra;
return '<a href="'.$href.'" title="'.$confirm.'" class="confirm">'.$text.'</a>';
}
// getting current user email address
function get_current_user_email(){
return $GLOBALS['MAIL_USER_NAME'].'@'.MAILSUFFIX;
}
################################################
# Converts bytes amount to KB, MB and GB string
################################################
function bytes2string($bytes,$approx='2'){
if($bytes >= 1073741824)
return sprintf('%.'.$approx.'fGb',$bytes/1073741824);
if($bytes >= 1048576)
return sprintf('%.'.$approx.'fMb',$bytes/1048576);
if($bytes >= 512)
return sprintf('%.'.$approx.'fK',$bytes/1024);
if($bytes > 0)
return $bytes."B";
return $bytes;
}
###################
# Useful regexps
###################
class MiscRegexps{
function MiscRegexps(){
$this->chrs = '[0-9a-z_-]+';
$this->user = '[0-9a-z_.-]+';
$this->complex = '[0-9a-z~?&%#;:\/._+=-]+';
$this->protocol = '((http|https|ftp|mms):\/\/)';
$this->userpass = '('.$this->user.'(:'.$this->complex.')?@)?';
$this->address = $this->chrs.'([.]'.$this->chrs.')*';
$this->dir = '(\/+'.$this->complex.')*\/*';
$this->link = '('.$this->protocol.$this->userpass.'('.$this->address.'(:[0-9]+)?'.$this->dir.'))';
$this->email = '('.$this->user.'@'.$this->address.')';
}
}
$misc_regexps = new MiscRegexps;
function is_email($email){
global $misc_regexps;
if(eregi('('.$misc_regexps->email.')',$email,$m))
if($m[1]!='')
return $m[1];
return false;
}
function is_http_link($link){
global $misc_regexps;
return eregi($misc_regexps->link,$link);
}
function match_links($str){
global $misc_regexps;
// $str = str_replace('>','>',str_replace('<','<',$str));
if($GLOBALS['MOBILE'])
$res = preg_replace('/'.$misc_regexps->link.'/ie',
'\'<a href="http://www.google.com/gwt/n?&mrestrict=xhtml&u=\'.urlencode(\'$1\').\'">$1</a>\'',$str);
else
$res = preg_replace('/'.$misc_regexps->link.'/i',
'<a href="${1}" target="_blank">${1}</a>',$str);
$res = preg_replace('/(^|[\s,.;"\'-])'.$misc_regexps->email.'/i',
'$1<a href="'.$_SERVER['PHP_SELF'].'?action=compose&to=$2&'.sid().
'" title="compose mail to $2">$2</a>',$res);
$str = str_replace('>','>',str_replace('<','<',$str));
return $res;
}
function htmlentitydecode($str){
return html_entity_decode($str,ENT_NOQUOTES,$GLOBALS['DEFAULT_CHARSET']);
}
// convert $str to DEFAULT_CHARSET from some charset
function to_default_charset($str,$charset_from){
$charset_from = strtolower($charset_from);
// some cases to return as is
if($charset_from == $GLOBALS['DEFAULT_CHARSET'] ||
// some outlook emails
$charset_from == 'visual')
return $str;
$res = iconv($charset_from,$GLOBALS['DEFAULT_CHARSET'],$str);
// some iconv error
if(!$res) return $str;
return $res;
}
/**
* Fixes newlines to \r\n
*/
function fix_newlines($str){
$res = '';
foreach(explode("\n",$str) as $line){
$res .= $line;
$length = strlen($line);
if($length > 0 && $line[$length-1] == "\r"){
$res .= "\n";
}
else{
$res .= "\r\n";
}
}
return $res;
}
/**
* Executes external command, write to stdin and takes its stdout/stderr
* @param string $command
* @param string $stdin
*/
function execute_process($command,$stdin){
$return_value = -1;
$stdout = '';
$stderr = '';
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$process = proc_open($command, $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0],$stdin);
fclose($pipes[0]);
while($buf = fread($pipes[1],2048)){ $stdout .= $buf; }
fclose($pipes[1]);
while($buf = fread($pipes[2],2048)){ $stderr .= $buf; }
fclose($pipes[2]);
// It is important that you close any pipes before calling
// proc_close in order to avoid a deadlock
$return_value = proc_close($process);
}
return array('return'=>$return_value,
'stdout'=>trim($stdout),
'stderr'=>trim($stderr));
}
function html2text($html,$width=-1,$with_links=false){
// $out = execute_process("lynx -stdin -dump -width=$width",$html);
// return $out['stdout'];
require_once(INCPATH.'html2text.php');
$html2text = new Html2Text;
$text = $html2text->parse($html,$width,$with_links);
// return wordwrap($text,$width);
return $text;
}
#
# MIME types matching
#
$primary_mime_types = array("TEXT","MULTIPART","MESSAGE","APPLICATION",
"AUDIO","IMAGE","VIDEO","OTHER");
function get_mime_type(&$structure){
global $primary_mime_types;
reset($primary_mime_types);
$ptype = $primary_mime_types[(int)$structure->type];
if($structure->subtype)
return $ptype."/".$structure->subtype;
return $ptype;
}
function get_primary_mime_type($type){
global $primary_mime_types;
reset($primary_mime_types);
while(list($index,$ptype) = each($primary_mime_types))
if(eregi($ptype,$type))
return $index;
return count($primary_mime_types)-1;
}
function get_file_extention($mime_type){
if(eregi("HTML",$mime_type))
return "html";
else if(eregi("TEXT",$mime_type))
return "txt";
else if(eregi("MSWORD",$mime_type))
return "doc";
else if(eregi("JPEG",$mime_type))
return "jpg";
else if(eregi("BMP",$mime_type))
return "bmp";
else if(eregi("GIF",$mime_type))
return "gif";
else if(eregi("PNG",$mime_type))
return "png";
else if(eregi("TIFF",$mime_type))
return "tiff";
else
return "dat";
}
function get_mime_icon($mime_type){
if(eregi("html",$mime_type))
return 'html.gif';
else if(eregi("text",$mime_type) || $mime_type === 'message/rfc822')
return 'text.gif';
else if(eregi("midi",$mime_type))
return 'midi.gif';
else if(eregi("audio",$mime_type))
return 'audio.gif';
else if(eregi("image",$mime_type))
return 'image.gif';
else if(eregi("video",$mime_type))
return 'movie.gif';
else if(eregi("pdf",$mime_type))
return 'pdf.gif';
else if(eregi("zip",$mime_type) || eregi("x-(compressed|jar|tar)",$mime_type))
return 'zip.gif';
else if(eregi("msword",$mime_type))
return 'word.gif';
else if(eregi("rtf",$mime_type))
return 'rtf.gif';
else if(eregi("excel",$mime_type))
return 'excel.gif';
else if(eregi("powerpoint",$mime_type))
return 'ppt.gif';
else if(eregi("postscript",$mime_type))
return 'ps.gif';
else if(eregi("x-dvi",$mime_type))
return 'dvi.gif';
else if(eregi("x-tex",$mime_type))
return 'tex.gif';
else if($mime_type == 'application/pgp-signature')
return 'pgp_signature.gif';
else if($mime_type == 'application/pgp-encrypted')
return 'pgp_encrypted.gif';
else if(eregi("octet-stream",$mime_type))
return 'binary.gif';
else
return 'unknown.gif';
}
// error
function error($title='Error',$message=''){
include(TMPLPATH."html_start.php");
include(TMPLPATH."error.php");
include(TMPLPATH."html_end.php");
exit;
}
// Random
function get_random(){
list($usec,$sec) = explode(' ',microtime());
srand($sec+($usec*100000));
return rand();
}
// Getting listing of directory.
// $readmode can be 'files' , 'dirs' or 'all'.
function readDirectory($dirname,$readmode="all"){
$files = array();
if($dir = opendir($dirname)){
while($file = readdir($dir)){
if($file != "." && $file != ".." &&
(($readmode == "files" && is_file($dirname."/".$file)) ||
($readmode == "dirs" && is_dir($dirname."/".$file)) ||
($readmode != "files" && $readmode != "dirs")))
$files[] = $file;
}
closedir($dir);
reset($files);
sort($files);
reset($files);
}
return $files;
}
# Browser detection
function detect_browser($query=false){
if(!$query) $query = $_SERVER['HTTP_USER_AGENT'];
// Browser
if(eregi("(opera)[ ]?([0-9]{1,2}.[0-9]{1,3}){0,1}",$query,$match) ||
eregi("(opera/)[ ]?([0-9]{1,2}.[0-9]{1,3}){0,1}",$query,$match)){
$BName = "Opera"; $BVersion=$match[2];
}
elseif(eregi("(konqueror)/([0-9]{1,2}.[0-9]{1,3})",$query,$match)){
$BName = "Konqueror"; $BVersion=$match[2];
}
elseif(eregi("(lynx)/([0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2})",$query,$match)){
$BName = "Lynx"; $BVersion=$match[2];
}
elseif(eregi("(links)[ ]?\(([0-9]{1,2}.[0-9]{1,3})",$query,$match)){
$BName = "Links"; $BVersion=$match[2];
}
elseif(eregi("(msie)[ ]?([0-9]{1,2}.[0-9]{1,3})",$query,$match)){
$BName = "IExplorer"; $BVersion=$match[2];
}
elseif(eregi("(netscape6)/(6.[0-9]{1,3})",$query,$match)){
$BName = "Netscape"; $BVersion=$match[2];
}
elseif(eregi("mozilla/5",$query)){
$BName = "Netscape"; $BVersion="5";
}
elseif(eregi("(mozilla)/([0-9]{1,2}.[0-9]{1,3})",$query,$match)){
$BName = "Netscape"; $BVersion=$match[2];
}
elseif(eregi("w3m",$query)){
$BName = "w3m"; $BVersion="Unknown";
}
elseif(eregi("(.*)/(.*)",$query,$match)){
$BName = $match[1]; $BVersion=$match[2];
}
else{
$BName = "Unknown"; $BVersion="Unknown";
}
// System
if(eregi("linux",$query)){
$BPlatform = "Linux";
}
elseif(eregi("win32",$query)){
$BPlatform = "Windows";
}
elseif((eregi("(win)([0-9]{2})",$query,$match)) ||
(eregi("(windows) ([0-9]{2}|ME|XP)",$query,$match))){
$BPlatform = "Windows $match[2]";
}
elseif(eregi("(winnt)([0-9]{1,2}.[0-9]{1,2}){0,1}",$query,$match)){
$BPlatform = "Windows NT $match[2]";
}
elseif(eregi("(windows nt)[ ]?([0-9]{1,2}.[0-9]{1,2}){0,1}",$query,$match)){
$BPlatform = "Windows NT $match[2]";
}
elseif(eregi("mac",$query)){
$BPlatform = "Macintosh";
}
elseif(eregi("(sunos)([0-9]{1,2}.[0-9]{1,2}){0,1}",$query,$match)){
$BPlatform = "SunOS $match[2]";
}
elseif(eregi("(beos)r([0-9]{1,2}.[0-9]{1,2}){0,1}",$query,$match)){
$BPlatform = "BeOS $match[2]";
}
elseif(eregi("freebsd",$query)){
$BPlatform = "FreeBSD";
}
elseif(eregi("openbsd",$query)){
$BPlatform = "OpenBSD";
}
elseif(eregi("irix",$query)){
$BPlatform = "IRIX";
}
elseif(eregi("os/2",$query)){
$BPlatform = "OS/2";
}
elseif(eregi("plan9",$query)){
$BPlatform = "Plan9";
}
elseif(eregi("unix",$query) || eregi("hp-ux",$query) || eregi("x11",$query)){
$BPlatform = "Unix";
}
elseif(eregi("osf",$query)){
$BPlatform = "OSF";
}
else{
$BPlatform = "Unknown";
}
return array('user_agent' => $query,
'browser' => $BName,
'version' => $BVersion,
'os' => $BPlatform);
}
function yp_passwd($user){
$res = array();
exec(escapeshellcmd("ypmatch $user passwd"),$res);
if(count($res) == 0 || eregi('no such key',$res[0]))
return false;
return split(":",$res[0]);
}
// is current use ris test user
function is_test_user(){
return in_array($GLOBALS['MAIL_USER_NAME'],array('diablo','ygleyzer'));
}
// check if string have some hebrew unicode chars
function is_hebrew($str){
return ereg(chr(215).'['.chr(144).'-'.chr(170).']',$str);
}
// if array and not empty
function array_not_empty($arr){
return is_array($arr) && count($arr)>0;
}
function in_array_recursive($v,$arr){
if(is_array($arr)){
foreach($arr as $a){
if(is_array($a) && in_array_recursive($v,$a))
return true;
else if($a == $v)
return true;
}
}
return false;
}
function js_string($str){
if(is_array($str)){
$values = array();
$key_values = array();
$assoc = false;
foreach($str as $k=>$v){
$values[] = js_string($v);
$key_values[] = js_string($k).':'.js_string($v);
if(!is_numeric($k)){
$assoc = true;
}
}
if($assoc)
return '{'.implode(',',$key_values).'}';
else
return '['.implode(',',$values).']';
}
else{
$str = str_replace('\\','\\\\',$str);
$str = str_replace('"','\\"',$str);
$str = str_replace("\n",'\\n',$str);
$str = str_replace("\r",'\\r',$str);
$str = str_replace("\t",'\\t',$str);
return '"'.$str.'"';
}
}
// split string by alpha chars, quoted parts are not splited
// string like: aa bb'dd dd' "cc cc" converted to array
// 'aa','bb','dd dd','cc cc'
function split_quoted_string($str){
$words = array();
$index = 0;
$len = strlen($str);
$was_double_quote=false;
$was_quote=false;
for($i=0;$i<$len;$i++){
if(!$was_quote && $str[$i] == '"'){
if($was_double_quote){
$was_double_quote=false;
}
else{
$was_double_quote=true;
}
if(isset($words[$index]))
$index++;
}
else if(!$was_double_quote && $str[$i] == "'"){
if($was_quote){
$was_quote=false;
}
else{
$was_quote=true;
}
if(isset($words[$index]))
$index++;
}
else if(!$was_quote && !$was_double_quote && ($str[$i] == " " || $str[$i] == "\t")){
if(isset($words[$index]))
$index++;
}
else{
$words[$index] .= $str[$i];
}
}
return $words;
}
?>