<?php
/**
* @file
* @brief pukiwiki バックアップフィルタ
*
* $id:$
*/

mb_internal_encoding('utf-8');
mb_http_input('pass');
mb_http_output('pass');

if (!defined('DS')) {
	define('DS', DIRECTORY_SEPARATOR);
}
// ページ名をディレクトリ構造に変換する際の文字コード (for mbstring)
define('PLUGIN_DUMP_FILENAME_ENCORDING', 'sjis');

exit(main($argc, $argv));

function main($argc, $argv)
{
	list($scriptname, $fromdir, $todir, $filter) = $argv;
	$fromdir = trim($fromdir);
	$todir = trim($todir);
	
	if($argc < 4){
		die("php -q $scriptname [from dir]  [to dir] [#filter regex#i]");
	}
	
	if(!is_dir($fromdir)){
		die("isn't dir. $fromdir");
	}
	
	if($fromdir == $todir){
		die("same dir.");
	}

	copyto($fromdir . DS . 'wiki', $todir, $filter);
	copyto($fromdir . DS . 'attach', $todir, $filter);
}

function copyto($fromdir, $todir, $filter)
{
	$fromdir = preg_replace('#([\\\/]+)$#', '', $fromdir);
	$todir = preg_replace('#([\\\/]+)$#', '', $todir);
	
	$info_from = pathinfo($fromdir);

	$handle = null;
	if (!$handle = opendir($fromdir)) {
		echo "Can't open dir : $fromdir<br />\n";
		return;
	}

	$count = 0;
	while (false !== ($file = readdir($handle))) {
		if( $file == '.' ||  $file == '..' ) continue;

		$fullpath = $fromdir . DS . $file;
		$from_stat = stat($fullpath);
		if($from_stat['size'] <= 0) continue;
		
		$filename = '';
		if (preg_match("/^((?:[0-9A-F]{2})+)_((?:[0-9A-F]{2})+)/", $file, $matches)) {
			// attachファイル名
			$filename = decode($matches[1]) . '/' . decode($matches[2]);
		} else {
			$pattern = '^((?:[0-9A-F]{2})+)((\.txt|\.gz)*)$';
			if (preg_match("/$pattern/", $file, $matches)) {
				$filename = decode($matches[1]) . $matches[2];

				// 危ないコードは置換しておく
				$filename = str_replace(':',  '_', $filename);
				$filename = str_replace('\\', '_', $filename);
			}
		}

		// フィルタ
		if (function_exists('mb_convert_encoding')){
			$tmp = mb_convert_encoding($filename, mb_internal_encoding(), 'eucjp');
			if(!preg_match($filter, $tmp)){
				continue;
			}
		}

		// attach/ バックアップをコピーしない
		if(preg_match('#\.\d+$|\.log$#i', $file)){
			continue;
		}

		// ファイル名の文字コードを変換
		$print_filename = '';
		if (function_exists('mb_convert_encoding')){
			$print_filename = mb_convert_encoding($filename, PLUGIN_DUMP_FILENAME_ENCORDING, 'eucjp');
		}

		if(!is_dir($todir)){
			mkdir($todir, 0777);
		}
		$to_fullpath = $todir . DS . $info_from['basename'];
		if(!is_dir($to_fullpath)){
			mkdir($to_fullpath, 0777);
		}
		$to_fullpath .= DS . $file;

		if ( is_file($fullpath) ){
			if (copy($fullpath, $to_fullpath)) {
				echo "COPY to [{$todir}/{$info_from['basename']}/{$print_filename}]...\n";
			}else{
				fwrite(STDERR, "failed to copy [$fullpath] to [$to_fullpath]...\n");
			}
		}else if( is_dir($fullpath) ){
		}
		$count++;
	}
}

////////////////////////////////////////////////////////////////////////////////
// func.php
////////////////////////////////////////////////////////////////////////////////
// Encode page-name
function encode($key)
{
	return ($key == '') ? '' : strtoupper(bin2hex($key));
	// Equal to strtoupper(join('', unpack('H*0', $key)));
	// But PHP 4.3.10 says 'Warning: unpack(): Type H: outside of string in ...'
}

// Decode page name
function decode($key)
{
	return hex2bin($key);
}

// Inversion of bin2hex()
function hex2bin($hex_string)
{
	// preg_match : Avoid warning : pack(): Type H: illegal hex digit ...
	// (string)   : Always treat as string (not int etc). See BugTrack2/31
	return preg_match('/^[0-9a-f]+$/i', $hex_string) ?
		pack('H*', (string)$hex_string) : $hex_string;
}
