#!/opt/Guardian/Admin/php/bin/php
<?php
/* --------------------------------------------------------
 * GUARDIANSUITE С GuardianWall(᡼)¦
 * κԤץȤǤ
 * 
 * ¸֡¸ǥ쥯ȥ¥˽ޤ
 * --------------------------------------------------------
 */

require_once "util.php";

function usage() {
	print "Usage: " . basename($_SERVER["PHP_SELF"]) . " [options] \n";
	print "  -f : config file path. \n";
	print "  -n : check only (display remove target file). \n";
	exit(1);
}
function err_exit($msg) {
	print $msg;
	exit(-1);
}

/* main */

$conf = null;
$check = false;

if (count($argv) == 1) usage();

array_shift($argv);
while(($opt = array_shift($argv)) != null) {
	if ($opt{0} != '-')
		break;
	switch($opt{1}) {
	case 'f':
		$conf = array_shift($argv);
		break;
	case 'n':
		$check = true;
		break;
	default:
		usage();
		break;
	}
}
/* new */

/* Ƹ */
if (!isValid($conf, &$err)) {
	err_exit($err);
}

/* Ƽ */
$opt = array(
  array('ƥ',         'SystemLog',    '',                    'system'),
  array('',             'DeliverLog',   'MaxDeliverLogSize',   'deliver'),
  array('󸡺',         'ScreeningLog', 'MaxScreeningLogSize', 'screening'),
  array('¸᡼븡ѥ', 'ArchiveLog',   'MaxArchiveLogSize',   'archive'),
  array('α᡼',   'ManagerLog',   'MaxManagerLogSize',   'manager'),
  array('¸᡼',   'ViewerLog',    'MaxViewerLogSize',    'viewer'));


// ǥ쥯ȥ
$dir = getConfValue($conf, 'Directories', 'LogDirectory', &$err);
if ($dir === false) err_exit($err);
if (!is_dir($dir)) err_exit("not directory($dir)");
if ($check) print "LogDirectory : $dir \n";

$sec = 'Expire';
foreach($opt as $list) {
	// ¸
	$days = getConfValue($conf, $sec, $list[1], &$err);
	if ($days === false) err_exit($err);

	// ¥
	if ($list[2] != '') {
		$max_size = getConfValue($conf, $sec, $list[2], &$err);
		if ($max_size === false) err_exit($err);
	} else {
		$max_size = 0;
	}	

	if ($check) {
		print $list[1]  . "\t" . $days . "days\t" . $max_size . "MB \n";
	}
	$logger = new Logger($list[0], $dir, $list[3], $days, $max_size, $check, &$err);
	if (!$logger->execute(&$err)) {
		err_exit($err);
	}
}
print "successful. \n";
exit(0);


// class  ______________________________________

/*
 * Class Logger
 */
class Logger {
	var $name;      // ̾
	var $check;		// åΤ
	var $dir;		// ¸ǥ쥯ȥ
	var $subdir;    // ֥ǥ쥯ȥ
	var	$days;		// ¸
	var $max_size;	// ¥ 
	var $DISK_FREE;
	var $DISK_USAGE;

	/* 󥹥ȥ饯 */
	function Logger($name, $dir, $subdir, $days, $max_size, $check) {
		$this->name = $name;
		if (!preg_match("/\/$/", $dir)) $dir .= "/";
		$this->dir = $dir;
		if (!preg_match("/\/$/", $subdir)) $subdir .= "/";
		$this->subdir = $subdir;
		$this->days = $days;
		$this->max_size = $max_size;
		$this->check = $check;

		$this->DISK_FREE =  GRDN_BASE . "local/bin/df -kP ";
		$this->DISK_USAGE = GRDN_BASE . "local/bin/du -ms ";

	}

	/*  */
	function execute($err) {

		/* Ķǥ쥯ȥκ */
		if ($this->days && $this->days > 0) {
			if (!$this->removeExpire(&$err)) {
				return false;
			}
		}

		/*
		 * ¥СΥǥ쥯ȥ
		 * ¥ʲˤʤޤǷ֤
		 */
		if ($this->max_size && $this->max_size > 0) {
			$du = $this->getDiskUsage(&$err);
			if (!$du) return false;

			if ($this->check) {
				if ($du > $this->max_size) {
					print "over MaxSize(now: $du MB). \n";
				} else {
					print "not over MaxSize(now: $du MB). \n";
				}
			} else {
				while ($du > $this->max_size) {
					$rtn = $this->removeOldestFile(&$err);
					if ($rtn === false && $err) {
						return false;
					} elseif ($rtn === false) {
						return true;
					}
					unset($df);
					unset($du);
					$du = $this->getDiskUsage(&$err);
					if (!$du && $err) {
						return false;
					} elseif (!$du) {
						break;
					}
				}
			}
		}
		return true;
	}

	/* Ķǥ쥯ȥκ */
	function removeExpire($err) {
		// ƥб 2005.09.05
		if (is_dir($this->dir)  && $this->subdir == 'system/') {
			foreach(glob($this->dir . "log\.*") as $filename) {
				if (preg_match("/^.*(\d{4})(\d{2})(\d{2})$/", $filename, $v)) {
					$ymd = $v[1] . $v[2] . $v[3];
				} else {
					continue;
				}
				// о
				if ($this->isRemoveDir($ymd)) {
					if (!$this->check) {
						if (!$this->removeFile($filename, &$err)) {
							return false;
						}
						print "removed(old) " . $filename . ".\n";
					} else {
						print "Remove Target : $filename \n";
					}
				}
			}
		} elseif (!is_dir($this->dir . $this->subdir)) {
			return true;
		}
		foreach(glob($this->dir . $this->subdir . "*/*/*") as $dirname) {
			if (preg_match("/^.*(\d{4})\/(\d{2})\/(\d{2})$/", $dirname, $v)) {
				$ymd = $v[1] . $v[2] . $v[3];
			} else {
				continue;
			}
			// о
			if ($this->isRemoveDir($ymd)) {
				if (!$this->check) {
					if (!$this->removeFile($dirname, &$err)) {
						return false;
					}
					print "removed(old) " . $dirname . ".\n";
				} else {
					print "Remove Target : $dirname \n";
				}
			}
		}
		return true;
	}

	/*
	 * ǥ쥯ȥΰָŤեեޤ
	 * return : false - ǥ쥯ȥ꤬ʤե뤬ʤ
	 */
	function removeOldestFile($err) {
		$dirlist;
		if (!is_dir($this->dir . $this->subdir)) {
			return false;
		}
		foreach(glob($this->dir . $this->subdir . "*/*/*") as $file) {
			if (!preg_match("/^.*(\d{4})\/(\d{2})\/(\d{2})$/", $file, $v)) {
				continue;
			}
			$dirlist[] = $file;
		}
		if (count($dirlist) > 0) {
			sort($dirlist);
			$file = array_shift($dirlist);
			$rtn = $this->removeFile($file, &$err);	
			print "removed(max) " . $file . ".\n";
			return $rtn;
		} else {
			print "Over dir size, But not oldest file. \n";
			return false;
		}
		return true;
	}

	/* եե */
	function removeFile($file, $err) {
		if (!su_rm($file)) {
			$err = "failed remove file ($file).";
			return false;
		}
		// ƥǥ쥯ȥ()⤬ˤʤäϿƥǥ쥯ȥ
		$parent = dirname($file);
		if ($this->isEmptyDir($parent)) {
			rmdir_tree($parent, true);
		}
		// ƥǥ쥯ȥ(ǯ)⤬ˤʤäϿƥǥ쥯ȥ
		$gparent = dirname($parent);
		if ($this->isEmptyDir($gparent)) {
			rmdir_tree($gparent, true);
		}
		return true;
	}

	/* ǥ쥯ȥ꤬Ǥ뤫ɤȽ */
	function isEmptyDir($path) {
		if ($path == '' || !is_dir($path)) {
			return false;
		}
		$rtn = true;
		$df = opendir($path);
		if (!$df) {
			print "error open dir ($path). \n";
			return false;
		}
		while($file = readdir($df)) {
			if ($file != "." && $file != "..") {
				$rtn = false;
				break;
			}
		}
		closedir($df);
		return $rtn;
	}

	/* ǥ̤μ(%) */
	function getDiskFree($err) {
		$cmd = $this->DISK_FREE . $this->dir . $this->subdir;
		exec($cmd, $out, $rtn);
		if ($rtn != 0) {
			$err = "exec error ($cmd).";
			return false;
		}
		$v = preg_split("/\s+/", $out[1]);
		return substr(trim($v[4]), 0, strlen(trim($v[4])) - 1);
	}

	/* ǥ̤μ(MB) */
	function getDiskUsage($err) {
		$cmd = $this->DISK_USAGE . $this->dir . $this->subdir;
		exec($cmd, $out, $rtn);
		if ($rtn != 0) {
			$err = "exec error ($cmd).";
			return false;
		}
		$v = preg_split("/\t+/", $out[0]);
		return trim($v[0]);
	}

	/* ¸Ķκоݥǥ쥯ȥ꤫ɤȽ */
	function isRemoveDir($ymd) {
		if (!$ymd || strlen($ymd) != 8) {
			return false;
		}
		$y = substr($ymd, 0, 4);
		$m = substr($ymd, 4, 2);
		$d = substr($ymd, 6, 2);

		$ymd_t = mktime(0, 0, 0, $m, $d, $y);
		$chk_t = $this->days * 24 * 60 * 60;

        $now_y = date("Y", time());
        $now_m = date("m", time());
        $now_d = date("d", time());
        $now_t = mktime(0, 0, 0, $now_m, $now_d, $now_y);

		return ($now_t - $ymd_t > $chk_t);
	}
}

// function ______________________________________

/* ϥå */
function isValid($conf, $err) {
	// ե̵ͭ
	if (!file_exists($conf)) {
		$err = "file not exits ($conf) .";
		return false;
	}
	return true;
}
/* ͼ */
function getConfValue($conf, $sec, $key, $err) {
	$cmd = GS_ADMINCONF_C . ' -f ' . $conf . ' -l -s ' . $sec . ' -k ' . $key;
	exec($cmd, $out, $rtn);
	if ($rtn != 0) {
		$err = "faild exec($cmd) \n";
		return false;
	}
	$v = preg_split("/:/", $out[0]);
	return trim($v[1]);
}


?>
