<?php
/**
 * $Id: monwlogmatch.php,v 1.7 2011/08/19 08:29:39 hiroaki Exp $
 * 
 * monwlogmatch クラス定義. 
 *
 * @copyright	Copyright (c) 2010 - COMSQUARE Co.,Ltd, All Rights Reserved. 
 */
/** mondep クラス. */
require_once( 'group/mondep.php' );
/** PostSender クラス. */
require_once( 'net/PostSender.php' );
/** ClarisCipher クラス. */
require_once( 'claris/security/ClarisCipher.php' );

/**
 *  monwlogmatch は、Winログ詳細監視に依存する情報を管理するクラスです. 
 *
 * @package	model.group
 * @access		public
 *
 * @author		Comsquare Co.,LTD. 
 *
 * @version	$Revision: 1.7 $
 * @since		1.0
 */
class monwlogmatch extends mondep
{
// public methods. 
	/**
	 * 監視詳細設定変更画面で入力された各値のエラーチェックを行います. 
	 *
	 * @param	array		$indata	入力値リスト. 
	 * @param	boolean	$isnew		新規登録かどうかを示すフラグ. 
	 * @param	boolean	$chkmode	チェックモード. 
	 *
	 * @return	array
	 *	エラーが有った場合はエラー ID リスト、エラーが無かった場合は null
	 * を返します. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function &checkError( &$indata, $isnew = true, $chkmode = 0 )
	{
		$errors = array() ;
		if( $chkmode == 0) {
			$monitorInfo = &$this->model->getMonitorInfo() ;
			$lminfo = &$monitorInfo->getDependsInfo() ;
			if( !$lminfo['service_installed']) {
				$errors[] = 'error.logmatch_instsvc.noexec' ;
				return $errors ;
			}
			$context = &$this->model->getContext() ;
			$connection = &$context->getConnection() ;
			$statement = &$connection->prepareStatement( 'SELECT winlogmatch_ver FROM clm_system' ) ;
			$resultSet = &$statement->executeQuery() ;
			$ver = null ;
			if( $resultSet->next())
				$ver = $resultSet->getString( 1 ) ;
			$resultSet->close();
			$statement->close();
			if( $ver === null)
				trigger_error( 'unable to get winlogmatch version?', E_USER_ERROR );
			if( $indata['logmatch_ver'] != $ver) {
				$errors[] = 'error.logmatch_ver.changed' ;
				return $errors ;
			}
		}
		else if( $chkmode == 1) {
			if( ( ( $len = strlen( $indata['logmatch_pgname'] )) <= 0) || preg_match( '/\/$/', $indata['logmatch_pgname'] ))
				$errors[] = 'error.logmatch_pgname.empty' ;
			else if( $len > 255)
				$errors[] = 'error.logmatch_pgname.len' ;
			else {
				foreach( explode( '\\', $indata['logmatch_pgname'] ) as $p ) {
					if( preg_match( '/[^a-zA-Z0-9_\.-]/', $p )) {
						$errors[] = 'error.logmatch_pgname.invalid' ;
						break ;
					}
				}
			}
			if( ( $len = strlen( $indata['logmatch_ctrl_ip'] )) <= 0)
				$errors[] = 'error.logmatch_ctrl_ip.empty' ;
			else if( $len > 64)
				$errors[] = 'error.logmatch_ctrl_ip.len' ;
			else if( !$GLOBALS['_ip']->isv4( $indata['logmatch_ctrl_ip'] ) && !$GLOBALS['_ip']->isv6( $indata['logmatch_ctrl_ip'] ))
				$errors[] = 'error.logmatch_ctrl_ip.invalid' ;
			else if( $indata['logmatch_ctrl_ip'] == '127.0.0.1')
				$errors[] = 'error.logmatch_ctrl_ip.localhost' ;
			if( count( $errors ) <= 0)
				$errors = null ;
			return $errors ;
		}
		
		if( $chkmode != 3) {
			if( ( $len = strlen( $indata['logmatch_logname'] )) <= 0)
				$errors[] = 'error.logmatch_logname.empty' ;
			else {
				$fe = explode( ',', $indata['logmatch_logname'], 2 ) ;
				if( ( $fc = count( $fe )) <= 1) {
					if( ( $err = $this->check_fname( $indata['logmatch_logname'] )) != null)
						$errors[] = "error.logmatch_logname.$err" ;
				}
				else {
					$f1 = trim( $fe[0] ) ;
					if( ( $err = $this->check_fname( $f1 )) != null)
						$errors[] = "error.logmatch_logname.$err" ;
					else {
						$f2 = trim( $fe[1] ) ;
						if( ( $err = $this->check_fname( $f2 )) != null)
							$errors[] = "error.logmatch_logname2.$err" ;
						else
							$indata['logmatch_logname'] = $f1.','.$f2 ;
					}
				}
			}
		}
		
		$indata['logmatch_regex'] = '' ;
		if( ( $rlen = strlen( $indata['logmatch_regex_dsp'] )) > 0) {
			$enc = $this->getPHPEncoding( $indata['logmatch_regex_enc'] ) ;
			if( $indata['logmatch_regex_enc'] && ( $enc == null))
				$indata['logmatch_regex_enc'] = 0 ;
			require_once( WEBAPP_HOME.'_webapp/lib/mbcnv.php' ); $mbcnv = new mbcnv() ;
			$regex = array() ;
			$rs = preg_split( '/\r\n|\n/', $indata['logmatch_regex_dsp'] ) ;
			$rc = count( $rs ) ;
			for( $i = 0 ; $i < $rc ; $i++) {
				if( strlen( ( $r = trim( $rs[$i] )) ) <= 0)
					continue ;
				$rr = array( 'r' => null, 'e0' => '', 'e1' => '', 'e2' => '', 'regex' => '' ) ;
				$es = explode( ':', $r, 3 ) ;
				if( ( $ec = count( $es )) != 3) {
					$rr['r'] = 'invalid' ;
					for( $j = 0 ; $j < $ec ; $j++)
						$rr["e$j"] = trim( $es[$j] ) ;
				}
				else {
					$rr['e0'] = trim( $es[0] ) ; $rr['e1'] = trim( $es[1] ) ; $rr['e2'] = trim( $es[2] ) ;
					if( strlen( $rr['e0'] ) <= 0)
						$rr['r'] = 'type.empty' ;
					else if( ( $rr['e0'] != 'N') && ( $rr['e0'] != 'W') && ( $rr['e0'] != 'A'))
						$rr['r'] = 'type.invalid' ;
					else if( strlen( $rr['e1'] ) <= 0)
						$rr['r'] = 'tag.empty' ;
					else if( strlen( $rr['e2'] ) <= 0)
						$rr['r'] = 'regex.empty' ;
					else {
						$ascii_only = $mbcnv->ascii_only( $rr['e2'] ) ;
						if( !$ascii_only && !$indata['logmatch_regex_enc'])
							$rr['r'] = 'regex.mb' ;
						else {
							if( $ascii_only || !$indata['logmatch_regex_enc'])
								$rr['regex'] = $rr['e2'] ;
							else
								$rr['regex'] = $mbcnv->convert( $rr['e2'], $enc, false ) ;
							if( $this->check_regex( $rr['regex'], $errmsg ) != 1)
								$rr['r'] = ( 'regex.invalid.'.bin2hex( $errmsg )) ;
						}
					}
				}
				$regex[] = $rr ;
			}
			$lr = $ld = '' ;
			if( ( $rc = count( $regex )) > 0) {
				for( $i = 0 ; $i < $rc ; $i++) {
					if( $regex[$i]['r'] != null)
						$errors[] = 'error.logmatch_regex.'.($i+1).'.'.$regex[$i]['r'] ;
					if( $i > 0) {
						$lr .= "\n" ; $ld .= "\n" ;
					}
					$ld .= ( $regex[$i]['e0'].':'.$regex[$i]['e1'].':'.$regex[$i]['e2']) ;
					$lr .= ( $regex[$i]['e0'].':'.$regex[$i]['e1'].':'.$regex[$i]['regex']) ;
				}
			}
			else
				$rlen = 0 ;
			$indata['logmatch_regex'] = $lr ;
			$indata['logmatch_regex_dsp'] = $ld ;
		}
		
		if( $chkmode != 3) {
			if( ( $len = strlen( $indata['logmatch_wsize'] )) > 0) {
				if( preg_match( '/[^0-9]/', $indata['logmatch_wsize'] ))
					$errors[] = 'error.logmatch_wsize.invalid' ;
				else if( $len > 20)
					$errors[] = 'error.logmatch_wsize.size' ;
			}
			else
				$indata['logmatch_wsize'] = 0 ;
			if( ( $len = strlen( $indata['logmatch_asize'] )) > 0) {
				if( preg_match( '/[^0-9]/', $indata['logmatch_asize'] ))
					$errors[] = 'error.logmatch_asize.invalid' ;
				else if( $len > 20)
					$errors[] = 'error.logmatch_asize.size' ;
			}
			else
				$indata['logmatch_asize'] = 0 ;
		
			if( ( $len = strlen( $indata['logmatch_wline'] )) > 0) {
				if( preg_match( '/[^0-9]/', $indata['logmatch_wline'] ))
					$errors[] = 'error.logmatch_wline.invalid' ;
				else if( $len > 9)
					$errors[] = 'error.logmatch_wline.size' ;
			}
			else
				$indata['logmatch_wline'] = 0 ;
			if( ( $len = strlen( $indata['logmatch_aline'] )) > 0) {
				if( preg_match( '/[^0-9]/', $indata['logmatch_aline'] ))
					$errors[] = 'error.logmatch_aline.invalid' ;
				else if( $len > 9)
					$errors[] = 'error.logmatch_aline.size' ;
			}
			else
				$indata['logmatch_aline'] = 0 ;
			
			if( ( $indata['logmatch_incflg'] != 0) && ( $indata['logmatch_incflg'] != 1))
				$indata['logmatch_incflg'] = 0 ;
			
			if( $rlen <= 0) {
				if( ( ( $indata['logmatch_wline'] != 0) || ( $indata['logmatch_aline'] != 0)) ||
					( ( $indata['logmatch_incflg'] == 0) && ( $indata['logmatch_wsize'] == 0) && ( $indata['logmatch_asize'] == 0)))
					$errors[] = 'error.logmatch_regex.empty' ;
			}
		}
		
		if( $chkmode == 0) {
			$gerr = false ;
			if( ( $p1 = strlen( $indata['logmatch_g_p1'] )) <= 0) {
				$indata['logmatch_g_p1'] = 'ALL' ;
				$p1 = 3 ;
			}
			else if( strpos( $indata['logmatch_g_p1'], ':' ) !== false) {
				$errors[] = 'error.logmatch_g_p1.invalid' ;
				$gerr = true ;
			}
			if( ( $p2 = strlen( $indata['logmatch_g_p2'] )) <= 0) {
				$indata['logmatch_g_p2'] = 'N' ;
				$p2 = 1 ;
			}
			else if( strpos( $indata['logmatch_g_p2'], ':' ) !== false) {
				$errors[] = 'error.logmatch_g_p2.invalid' ;
				$gerr = true ;
			}
			if( ( $p3 = strlen( $indata['logmatch_g_p3'] )) <= 0) {
				$indata['logmatch_g_p3'] = 'W' ;
				$p3 = 1 ;
			}
			else if( strpos( $indata['logmatch_g_p3'], ':' ) !== false) {
				$errors[] = 'error.logmatch_g_p3.invalid' ;
				$gerr = true ;
			}
			if( ( $p4 = strlen( $indata['logmatch_g_p4'] )) <= 0) {
				$indata['logmatch_g_p4'] = 'A' ;
				$p4 = 1 ;
			}
			else if( strpos( $indata['logmatch_g_p4'], ':' ) !== false) {
				$errors[] = 'error.logmatch_g_p4.invalid' ;
				$gerr = true ;
			}
			if( !$gerr) {
				if( ( $p1 + $p2 + $p3 + $p4) > 252)
					$errors[] = 'error.logmatch_g.len' ;
			}
		}
		
		if( $chkmode != 3) {
			if( ( $len = strlen( $indata['logmatch_timeout'] )) <= 0)
				$errors[] = 'error.logmatch_timeout.empty' ;
			else if( preg_match( '/[^0-9]/', $indata['logmatch_timeout'] ))
				$errors[] = 'error.logmatch_timeout.invalid' ;
			else {
				$timeout = intval( $indata['logmatch_timeout'] ) ;
				if( ( $timeout < 5) || ( 20 < $timeout))
					$errors[] = 'error.logmatch_timeout.range' ;
				else
					$indata['logmatch_timeout'] = $timeout ;
			}
			
			if( ( $len = strlen( $indata['logmatch_lastsize'] )) > 0) {
				if( preg_match( '/[^0-9]/', $indata['logmatch_lastsize'] ))
					$errors[] = 'error.logmatch_lastsize.invalid' ;
				else if( $len > 20)
					$errors[] = 'error.logmatch_lastsize.size' ;
			}
			else
				$indata['logmatch_lastsize'] = 0 ;
			
			if( ( $len = strlen( $indata['logmatch_ctrl_ip'] )) <= 0)
				$errors[] = 'error.logmatch_ctrl_ip.empty' ;
			else if( $len > 64)
				$errors[] = 'error.logmatch_ctrl_ip.len' ;
			else if( !$GLOBALS['_ip']->isv4( $indata['logmatch_ctrl_ip'] ) && !$GLOBALS['_ip']->isv6( $indata['logmatch_ctrl_ip'] ))
				$errors[] = 'error.logmatch_ctrl_ip.invalid' ;
			else if( $indata['logmatch_ctrl_ip'] == '127.0.0.1')
				$errors[] = 'error.logmatch_ctrl_ip.localhost' ;
		}
		
		if( count( $errors ) <= 0)
			$errors = null ;
		return $errors ;
		
	}
	
	/**
	 *  監視詳細設定画面で入力された各値を取得し、リストに設定して返します. 
	 *
	 * @param	HttpRequest	$request	HttpRequest オブジェクト. 
	 * @param	boolean		$isnew		新規登録かどうかを示すフラグ. 
	 *
	 * @return	array	入力値リスト. 
	 *
	 * @access	private
	 * @since	1.0
	 */
	function &collectInputtedData( &$request, $isnew = true )
	{
		$indata = array() ;
		
		$indata['logmatch_logname'] = $request->getParameter( 'logmatch_logname' ) ;
		
		$indata['logmatch_regex_dsp'] = $request->getParameter( 'logmatch_regex_dsp' ) ;
		$indata['logmatch_regex_enc'] = $request->getParameter( 'logmatch_regex_enc' ) ;
		
		$indata['logmatch_wsize'] = $request->getParameter( 'logmatch_wsize' ) ;
		$indata['logmatch_asize'] = $request->getParameter( 'logmatch_asize' ) ;
		$indata['logmatch_wline'] = $request->getParameter( 'logmatch_wline' ) ;
		$indata['logmatch_aline'] = $request->getParameter( 'logmatch_aline' ) ;
		$indata['logmatch_incflg'] = $request->getParameter( 'logmatch_incflg' ) ;
		
		$indata['logmatch_rcvflg'] = intval( $request->getParameter( 'logmatch_rcvflg' ) ) ;
		
		$indata['logmatch_g_p1'] = $request->getParameter( 'logmatch_g_p1' ) ;
		$indata['logmatch_g_p2'] = $request->getParameter( 'logmatch_g_p2' ) ;
		$indata['logmatch_g_p3'] = $request->getParameter( 'logmatch_g_p3' ) ;
		$indata['logmatch_g_p4'] = $request->getParameter( 'logmatch_g_p4' ) ;
		
		$indata['logmatch_timeout'] = $request->getParameter( 'logmatch_timeout' ) ;
		
		$indata['logmatch_ctrl_ip'] = $request->getParameter( 'logmatch_ctrl_ip' ) ;
		
		$indata['logmatch_lastsize'] = $request->getParameter( 'logmatch_lastsize' ) ;
		
		$indata['logmatch_text'] = $request->getParameter( 'logmatch_text' ) ;
		
		$monitorInfo = &$this->model->getMonitorInfo() ;
		$lminfo = &$monitorInfo->getDependsInfo() ;
		$indata['logmatch_pgname'] = $lminfo['_logmatch_pgname'] ;
		$indata['logmatch_ver'] = $lminfo['logmatch_ver'] ;
		
		return $indata ;
		
	}
	
	/**
	 *  監視詳細設定画面を、指定の値で構成します. 
	 *
	 * @param	I18nSmarty	$smarty	I18nSmarty オブジェクト. 
	 * @param	array		$indata	入力データリスト. 
	 * @param	boolean	$isnew		新規登録かどうかを示すフラグ. 
	 *
	 * @return	string	View 名称を返します. 
	 *
	 * @access	private
	 * @since	1.0
	 */
	function compositeModifyView( &$smarty, &$indata, &$connection, $isnew = true )
	{
		$encodings = &$this->getEncodingList() ;
		$smarty->assign_by_ref( 'el', $encodings );
		$smarty->assign( 'ec', ( $ec = count( $encodings )) );
		
		$monitorInfo = &$this->model->getMonitorInfo() ;
		$lminfo = &$monitorInfo->getDependsInfo() ;
		
		switch( $this->lmop) {
		case 1 :
			if( $lminfo['service_installed'])
				$this->lmop = 0 ;
			break ;
		case 2 :
		case 3 :
			if( !$lminfo['service_installed'])
				$this->lmop = 0 ;
			break ;
		case 4 :
			break ;
		default :
			$this->lmop = 0 ;
		}
		$cerr = 0 ;
		if( $this->lmop) {
			if( $this->lmop == 1) { // install service.
				$ind = $indata ;
				$ind['logmatch_pgname'] = $this->request->getParameter( 'logmatch_pgname' ) ;
				$ind['logmatch_pgname'] = preg_replace( '/^\\\\+/', '', $ind['logmatch_pgname'] ) ;
				$ind['logmatch_pgname'] = preg_replace( '/\\\\+$/', '', $ind['logmatch_pgname'] ) ;
				while( ( $r = str_replace( '\\\\', '\\', $ind['logmatch_pgname'] )) != $ind['logmatch_pgname'])
					$ind['logmatch_pgname'] = $r ;
				$lminfo['_logmatch_pgname'] = $ind['logmatch_pgname'] ;
				$ind['logmatch_ctrl_ip'] = $this->request->getParameter( 'logmatch_ctrl_ip' ) ;
				if( ( $errors = &$this->checkError( $ind, $isnew, 1 )) != null) {
					$smarty->assign_by_ref( 'errors', $errors );
					$cerr = 1 ;
				}
				else {
					$lminfo['logmatch_ctrl_ip'] = $ind['logmatch_ctrl_ip'] ;
					if( ( $err = $this->install_service( $monitorInfo, $ind )) != null) {
						$smarty->assign( 'errors', array( $err ) );
						$cerr = 2 ;
					}
					else {
						$lminfo['service_installed'] = true ;
						$lminfo['logmatch_ver'] = $ind['logmatch_ver'] ;
						$lminfo['lmtest_done'] = $lminfo['updating'] = false ;
					}
				}
			}
			else {
				$ind = &$this->collectInputtedData( $this->request, $isnew ) ;
				if( $this->lmop == 2) { // uninstall service. 
					if( ( $err = $this->uninstall_service( $monitorInfo, $ind )) != null) {
						$smarty->assign( 'errors', array( $err ) );
						$cerr = 1 ;
					}
					else {
						$lminfo['service_installed'] = false ;
						$lminfo['lmtest_done'] = $lminfo['updating'] = false ;
						$lminfo['logmatch_ver'] = '' ;
						$ind['logmatch_lastsize'] = 0 ;
					}
				}
				else if( $this->lmop == 3) { // monitoring test. 
					if( ( $errors = &$this->checkError( $ind, $isnew, 2 )) != null) {
						$smarty->assign_by_ref( 'errors', $errors );
						$cerr = 1 ;
					}
					else {
						if( ( $err = $this->logmatch_test( $monitorInfo, $ind, $result )) != null) {
							$smarty->assign( 'errors', array( $err ) );
							if( $err == 'error.logmatch_test.exec')
								$cerr = 2 ;
							else
								$cerr = 3 ;
						}
						if( $cerr != 2) {
							$smarty->assign_by_ref( 'testr', $result );
							if( preg_match( '/^[0-9]+$/', $result['lastsize'] ))
								$ind['logmatch_lastsize'] = $result['lastsize'] ;
							$lminfo['lmtest_done'] = true ;
						}
					}
				}
				else /*if( $this->lmop == 4)*/ { // regexp test. 
					if( ( $errors = &$this->checkError( $ind, $isnew, 3 )) != null) {
						$re = false ;
						foreach( $errors as $e ) {
							if( preg_match( '/^error\.logmatch_regex\./', $e )) {
								$re = true ;
								break ;
							}
						}
						if( !$re)
							$errors = null ;
					}
					if( $errors != null)
						$smarty->assign_by_ref( 'errors', $errors );
					else {
						$enc = null ;
						for( $i = 0 ; $i < $ec ; $i++) {
							if( $encodings[$i]['id'] == $ind['logmatch_regex_enc']) {
								$enc = $encodings[$i]['enc'] ;
								break ;
							}
						}
						$rtestr = $this->test_regex( $ind['logmatch_regex'], $ind['logmatch_text'], $enc ) ;
						$smarty->assign_by_ref( 'rtestr', $rtestr );
						$smarty->assign( 'rtestc', count( $rtestr ) );
					}
				}
			}
			$smarty->assign( 'logmatch_logname', htmlspecialchars( $ind['logmatch_logname'] ) );
			$smarty->assign( 'logmatch_regex_dsp', htmlspecialchars( $ind['logmatch_regex_dsp'] ) );
			$smarty->assign( 'logmatch_regex_enc', htmlspecialchars( $ind['logmatch_regex_enc'] ) );
			$smarty->assign( 'logmatch_wsize', $ind['logmatch_wsize'] );
			$smarty->assign( 'logmatch_asize', $ind['logmatch_asize'] );
			$smarty->assign( 'logmatch_wline', $ind['logmatch_wline'] );
			$smarty->assign( 'logmatch_aline', $ind['logmatch_aline'] );
			$smarty->assign( 'logmatch_incflg', $ind['logmatch_incflg'] );
			$smarty->assign( 'logmatch_g_p1', htmlspecialchars( $ind['logmatch_g_p1'] ) );
			$smarty->assign( 'logmatch_g_p2', htmlspecialchars( $ind['logmatch_g_p2'] ) );
			$smarty->assign( 'logmatch_g_p3', htmlspecialchars( $ind['logmatch_g_p3'] ) );
			$smarty->assign( 'logmatch_g_p4', htmlspecialchars( $ind['logmatch_g_p4'] ) );
			$smarty->assign( 'logmatch_lastsize', $ind['logmatch_lastsize'] );
			$smarty->assign( 'logmatch_text', htmlspecialchars( $ind['logmatch_text'] ) );
			$smarty->assign( 'logmatch_pgname', htmlspecialchars( $ind['logmatch_pgname'] ) );
			$smarty->assign( 'logmatch_rcvflg', $ind['logmatch_rcvflg'] );
			$smarty->assign( 'logmatch_timeout', htmlspecialchars( $ind['logmatch_timeout'] ) );
			$smarty->assign( 'logmatch_ctrl_ip', htmlspecialchars( $ind['logmatch_ctrl_ip'] ) );
		}
		else {
			$smarty->assign( 'logmatch_logname', htmlspecialchars( $indata['logmatch_logname'] ) );
			$smarty->assign( 'logmatch_regex_dsp', htmlspecialchars( $indata['logmatch_regex_dsp'] ) );
			$smarty->assign( 'logmatch_regex_enc', $indata['logmatch_regex_enc'] );
			$smarty->assign( 'logmatch_wsize', $indata['logmatch_wsize'] );
			$smarty->assign( 'logmatch_asize', $indata['logmatch_asize'] );
			$smarty->assign( 'logmatch_wline', $indata['logmatch_wline'] );
			$smarty->assign( 'logmatch_aline', $indata['logmatch_aline'] );
			$smarty->assign( 'logmatch_incflg', $indata['logmatch_incflg'] );
			$smarty->assign( 'logmatch_g_p1', htmlspecialchars( $indata['logmatch_g_p1'] ) );
			$smarty->assign( 'logmatch_g_p2', htmlspecialchars( $indata['logmatch_g_p2'] ) );
			$smarty->assign( 'logmatch_g_p3', htmlspecialchars( $indata['logmatch_g_p3'] ) );
			$smarty->assign( 'logmatch_g_p4', htmlspecialchars( $indata['logmatch_g_p4'] ) );
			$smarty->assign( 'logmatch_lastsize', $indata['logmatch_lastsize'] );
			$smarty->assign( 'logmatch_text', htmlspecialchars( $indata['logmatch_text'] ) );
			$smarty->assign( 'logmatch_pgname', htmlspecialchars( $indata['logmatch_pgname'] ) );
			$smarty->assign( 'logmatch_rcvflg', $indata['logmatch_rcvflg'] );
			$smarty->assign( 'logmatch_timeout', htmlspecialchars( $indata['logmatch_timeout'] ) );
			if( ( strlen( $indata['logmatch_ctrl_ip'] ) <= 0) || ( $indata['logmatch_ctrl_ip'] == '127.0.0.1')) {
				$statement = &$connection->prepareStatement( 'SELECT ctrl_ip FROM clm_ctrl WHERE ctrl_id=?' ) ;
				$statement->setInt( 1, $monitorInfo->getControlId() );
				$resultSet = &$statement->executeQuery() ;
				$cip = null ;
				if( $resultSet->next())
					$cip = $resultSet->getIp( 1 ) ;
				$resultSet->close();
				$statement->close();
				if( $cip === null)
					trigger_error( $monitorInfo->getControlId().': unable to get control ip?', E_USER_ERROR );
				$indata['logmatch_ctrl_ip'] = $cip ;
			}
			$smarty->assign( 'logmatch_ctrl_ip', htmlspecialchars( $indata['logmatch_ctrl_ip'] ) );
		}
		$smarty->assign( 'lmop', $this->lmop );
		$smarty->assign( 'cerr', $cerr );
		
		$smarty->assign( 'service_installed', $lminfo['service_installed'] );
		$smarty->assign( 'lmtest_done', $lminfo['lmtest_done'] );
		$smarty->assign( 'logmatch_ver', $lminfo['logmatch_ver'] );
		
		$smarty->assign( 'now', ( $now = time()) );
		$smarty->assign( 'b1d', ( $now - ( 60 * 60 * 24)) );
		$smarty->assign( 'b1h', ( $now - ( 60 * 60)) );
		
		$smarty->assign( 'isnew', $isnew );
		return 'group/modmonwlogmatch.tpl' ;
		
	}
	
	/**
	 *  監視登録/更新画面を、指定の値で構成します. 
	 *
	 * @param	I18nSmarty		$smarty		I18nSmarty オブジェクト. 
	 * @param	MonitorInfo	$monitorInfo	監視情報. 
	 * @param	boolean		$isnew			新規登録かどうかを示すフラグ. 
	 *
	 * @return	string	View 名称を返します. 
	 *
	 * @access	private
	 * @since	1.0
	 */
	function compositeView( &$smarty, &$monitorInfo, $isnew = true )
	{
		$lminfo = &$monitorInfo->getDependsInfo() ;
		
		$smarty->assign( 'logmatch_logname', htmlspecialchars( $lminfo['logmatch_logname'] ) );
		$smarty->assign( 'logmatch_regex', htmlspecialchars( $lminfo['logmatch_regex'] ) );
		$smarty->assign( 'logmatch_regex_dsp', htmlspecialchars( $lminfo['logmatch_regex_dsp'] ) );
		
		$smarty->assign( 'logmatch_wsize', $lminfo['logmatch_wsize'] );
		$smarty->assign( 'logmatch_asize', $lminfo['logmatch_asize'] );
		$smarty->assign( 'logmatch_wline', $lminfo['logmatch_wline'] );
		$smarty->assign( 'logmatch_aline', $lminfo['logmatch_aline'] );
		
		$smarty->assign( 'logmatch_incflg', $lminfo['logmatch_incflg'] );
		
		$smarty->assign( 'logmatch_g_p1', htmlspecialchars( $lminfo['logmatch_g_p1'] ) );
		$smarty->assign( 'logmatch_g_p2', htmlspecialchars( $lminfo['logmatch_g_p2'] ) );
		$smarty->assign( 'logmatch_g_p3', htmlspecialchars( $lminfo['logmatch_g_p3'] ) );
		$smarty->assign( 'logmatch_g_p4', htmlspecialchars( $lminfo['logmatch_g_p4'] ) );
		
		$smarty->assign( 'logmatch_lastsize', $lminfo['logmatch_lastsize'] );
		$smarty->assign( 'logmatch_pgname', htmlspecialchars( $lminfo['logmatch_pgname'] ) );
		
		$smarty->assign( 'logmatch_rcvflg', $lminfo['logmatch_rcvflg'] );
		$smarty->assign( 'logmatch_timeout', $lminfo['logmatch_timeout'] );
		
		$smarty->assign( 'logmatch_ctrl_ip', $lminfo['logmatch_ctrl_ip'] );
		$smarty->assign( 'service_installed', $lminfo['service_installed'] );
		return 'group/monwlogmatch.tpl' ;
		
	}
	
	/**
	 *  監視依存データを新規作成します. 
	 *
	 * @param	Connection		$connection	データベースコネクションオブジェクト. 
	 * @param	MonitorInfo	$monitorInfo	監視情報. 
	 * @param	integer		$updater		登録処理を行っているユーザのユーザ ID. 
	 *
	 * @return	boolean
	 *	登録処理が正常終了した場合は true、エラーが発生した場合は false を返します. 
	 *
	 * @throws	E_USER_ERROR	データベースアクセスエラーが発生した場合. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function createDependsData( &$connection, &$monitorInfo, $updater )
	{
		$moduleInfo = &$monitorInfo->getModuleInfo() ;
		$lminfo = &$monitorInfo->getDependsInfo() ;
		
		$now = new Date() ;
		$statement = &$connection->prepareStatement(
			'INSERT INTO ?(cltmon_id,wsize,asize,wline,aline,lastsize,incflg,logname,regex,regex_dsp,regex_enc,g_unit,pgname,rcvflg,ver,timeout,create_date,create_userid,update_date,update_userid,ctrl_ip)' .
			' VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'
		) ;
		
		$statement->setString( 1, $moduleInfo->getDbName(), false );
		$statement->setInt( 2, $monitorInfo->getId() );
		$statement->setString( 3, $lminfo['logmatch_wsize'], false );
		$statement->setString( 4, $lminfo['logmatch_asize'], false );
		$statement->setInt( 5, $lminfo['logmatch_wline'] );
		$statement->setInt( 6, $lminfo['logmatch_aline'] );
		$statement->setString( 7, $lminfo['logmatch_lastsize'], false );
		$statement->setInt( 8, $lminfo['logmatch_incflg'] );
		$statement->setString( 9, $lminfo['logmatch_logname'] );
		$statement->setString( 10, $lminfo['logmatch_regex'] );
		$statement->setString( 11, $lminfo['logmatch_regex_dsp'] );
		$statement->setInt( 12, $lminfo['logmatch_regex_enc'] );
		$statement->setString( 13, $lminfo['logmatch_g_p1'].':'.$lminfo['logmatch_g_p2'].':'.$lminfo['logmatch_g_p3'].':'.$lminfo['logmatch_g_p4'] );
		$statement->setString( 14, 'C:\\'.$lminfo['logmatch_pgname'].'.exe' );
		$statement->setInt( 15, ( $lminfo['logmatch_rcvflg']? 1 : 0) );
		$statement->setString( 16, $lminfo['logmatch_ver'] );
		$statement->setInt( 17, $lminfo['logmatch_timeout'] );
		$statement->setDate( 18, $now );
		$statement->setInt( 19, $updater );
		$statement->setDate( 20, $now );
		$statement->setInt( 21, $updater );
		$statement->setString( 22, $lminfo['logmatch_ctrl_ip'] );
		$result = ( $statement->executeUpdate() > 0) ;
		
		$statement->close();
		return $result ;
		
	}
	
	/**
	 *  監視依存データを削除します. 
	 *
	 * @param	Connection		$connection	データベースコネクションオブジェクト. 
	 * @param	MonitorInfo	$monitorInfo	監視情報. 
	 * @param	integer		$updater		削除処理を行っているユーザのユーザ ID. 
	 *
	 * @return	boolean
	 *	削除処理が正常終了した場合は true、エラーが発生した場合は false を返します. 
	 *
	 * @throws	E_USER_ERROR	データベースアクセスエラーが発生した場合. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function deleteDependsData( &$connection, &$monitorInfo, $updater )
	{
		if( ( $result = parent::deleteDependsData( $connection, $monitorInfo, $updater ))) {
			$lminfo = &$monitorInfo->getDependsInfo() ;
			if( $lminfo['service_installed']) {
				$indata = $this->mon2indat( $monitorInfo ) ;
				/* try to uninstall service... */
				if( ( $err = $this->uninstall_service( $monitorInfo, $indata )) != null) {
					if( preg_match( '/^error\.logmatch_uninstsvc\.(.+)$/', $err, $e ))
						$err = pack( 'H*', $e[1] ) ;
					$this->model->error( $err );
				}
			}
		}
		return $result ;
		
	}
	
	/**
	 *  監視依存データクラスの初期化処理を行います. 
	 *
	 * @param	ClarisModel	$model		ClarisModel オブジェクト. 
	 * @param	HttpRequest	$request	HttpRequest オブジェクト. 
	 * @param	boolean		$isnew		新規登録かどうかを示すフラグ. 
	 *
	 * @throws	E_USER_ERROR	初期化処理エラーが発生した場合. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function init( &$model, &$request, $isnew = true )
	{
		parent::init( $model, $request, $isnew );
		if( $request->getParameter( 'md' ) == 'chkenc')
			$this->lmop = intval( $request->getParameter( 'logmatch_op' ) ) ;
		
	}
	
	/**
	 *  監視依存データをデータベースから読み込み、、監視情報オブジェクトに
	 * 設定します. 
	 *
	 * @param	Connection		$connection	データベースコネクションオブジェクト. 
	 * @param	MonitorInfo	$monitorInfo	監視情報. 
	 *
	 * @throws	E_USER_ERROR	データベースアクセスエラーが発生した場合. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function loadDependsData( &$connection, &$monitorInfo )
	{
		$lminfo = null ;
		
		$moduleInfo = &$monitorInfo->getModuleInfo() ;
		
		$statement = &$connection->prepareStatement(
			'SELECT wsize,asize,wline,aline,lastsize,incflg,logname,regex,regex_dsp,regex_enc,g_unit,pgname,rcvflg,ver,timeout,ctrl_ip FROM ? WHERE cltmon_id=?'
		) ;
		$statement->setString( 1, $moduleInfo->getDbName(), false );
		$statement->setInt( 2, $monitorInfo->getId() );
		$resultSet = &$statement->executeQuery() ;
		if( $resultSet->next()) {
			if( strlen( ( $gunit = $resultSet->getString( 11 )) ) <= 0) {
				$g_p1 = 'ALL' ; $g_p2 = 'N' ; $g_p3 = 'W' ; $g_p4 = 'A' ;
			} else {
				list( $g_p1, $g_p2, $g_p3, $g_p4 ) = @explode( ':', $gunit, 4 ) ;
			}
			$pgname = $resultSet->getString( 12 ) ;
			if( preg_match( '/^[Cc]:\\\\(.+)\.[Ee][Xx][Ee]$/', $pgname, $pn ))
				$pgname = $pn[1] ;
			if( $this->cpnew) {
				$pelm = explode( '\\', $pgname ) ;
				$pgname = '' ;
				if( ( $pc = count( $pelm )) > 1) {
					for( $i = 0 ; $i < $pc - 1 ; $i++)
						$pgname .= ( $pelm[$i].'\\') ;
				}
				$coninfo = &$this->getConnectionInfo() ;
				$pgname .= $this->make_svcname( $coninfo ) ;
			}
			$lminfo = array(
				'logmatch_wsize' => $resultSet->getString( 1 ),
				'logmatch_asize' => $resultSet->getString( 2 ),
				'logmatch_wline' => $resultSet->getInt( 3 ),
				'logmatch_aline' => $resultSet->getInt( 4 ),
				'logmatch_lastsize' => ( $this->cpnew? 0 : $resultSet->getString( 5 )),
				'logmatch_incflg' => $resultSet->getInt( 6 ),
				'logmatch_logname' => $resultSet->getString( 7 ),
				'logmatch_regex' => $resultSet->getString( 8 ),
				'logmatch_regex_dsp' => $resultSet->getString( 9 ),
				'logmatch_regex_enc' => $resultSet->getInt( 10 ),
				'logmatch_g_p1' => $g_p1,
				'logmatch_g_p2' => $g_p2,
				'logmatch_g_p3' => $g_p3,
				'logmatch_g_p4' => $g_p4,
				'logmatch_pgname' => $pgname,
				'_logmatch_pgname' => $pgname,
				'logmatch_rcvflg' => $resultSet->getInt( 13 ),
				'logmatch_ver' => ( $this->cpnew? '' : $resultSet->getString( 14 )),
				'logmatch_timeout' => $resultSet->getInt( 15 ),
				'logmatch_ctrl_ip' => $resultSet->getString( 16 ),
				'logmatch_text' => '',
				'service_installed' => !$this->cpnew,
				'lmtest_done' => false,
				'updating' => false,
			) ;
			if( strlen( $lminfo['logmatch_ver'] ) <= 0)
				$lminfo['updating'] = true ;
		}
		$resultSet->close();
		$statement->close();
		
		if( $lminfo == null)
			trigger_error( 'unable to find winlogmatch monitor data: cltmon_id '.$monitorInfo->getId(), E_USER_ERROR );
		
		$monitorInfo->setDependsInfo( $lminfo );
		
	}
	
	/**
	 *  現在の監視情報から監視モジュール簡易説明テキストを生成し、監視情報オブジェクト
	 * へ設定します. 
	 *
	 * @param	MonitorInfo	$monitorInfo	監視情報. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function makeAlt( &$monitorInfo )
	{
		$lminfo = &$monitorInfo->getDependsInfo() ;
		$ls = @explode( ',', $lminfo['logmatch_logname'], 2 ) ;
		if( is_array( $ls ) && ( count( $ls ) > 1))
			$lname = $ls[0] ;
		else
			$lname = $lminfo['logmatch_logname'] ;
		if( ( $ip = $monitorInfo->getAltIP()) && ( strlen( $ip ) > 0))
			$monip = $ip ;
		else
			$monip = long2ip( $monitorInfo->getDeviceId() ) ;
		$alt = 'LOG=>'.$monip.'# '.$lname ;
		$monitorInfo->setAlt( $alt );
		
	}
	
	/**
	 *  現在の監視情報から、監視モジュールシングルリアル実行時のコマンドラインパラメータ
	 * を生成し、HEX コードに変換して監視情報オブジェクトへ設定します. 
	 *
	 * @param	MonitorInfo	$monitorInfo	監視情報. 
	 * @param	array			$indata
	 *	入力データからパラメータを生成する場合は入力データリスト、そうでない場合
	 * は null を指定します. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function makeCommandLineParameter( &$monitorInfo, &$indata )
	{
		if( $indata != null) {
			$pelm = explode( '\\', $indata['logmatch_pgname'] ) ;
			$cip  = $indata['logmatch_ctrl_ip'] ;
		}
		else {
			$lminfo = &$monitorInfo->getDependsInfo() ;
			$pelm = explode( '\\', $lminfo['logmatch_pgname'] ) ;
			$cip  = $lminfo['logmatch_ctrl_ip'] ;
		}
		$svcname = $pelm[count($pelm)-1] ;
		
		$cipher = new ClarisCipher() ;
		$param = $cipher->encrypt( $monitorInfo->getId().','.$cip ) ;
		$monitorInfo->setCommandLineParameter( $svcname.':'.$param );
		
	}
	
	/**
	 *  監視情報から、監視詳細設定画面入力データリストを生成します. 
	 *
	 * @param	MonitorInfo	$monitorInfo	監視情報. 
	 *
	 * @return	array	入力データリストを返します. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function &mon2indat( &$monitorInfo )
	{
		$lminfo = &$monitorInfo->getDependsInfo() ;
		$indata = array(
			'logmatch_logname' => $lminfo['logmatch_logname'],
			'logmatch_regex' => $lminfo['logmatch_regex'],
			'logmatch_regex_dsp' => $lminfo['logmatch_regex_dsp'],
			'logmatch_regex_enc' => $lminfo['logmatch_regex_enc'],
			'logmatch_wsize' => $lminfo['logmatch_wsize'],
			'logmatch_asize' => $lminfo['logmatch_asize'],
			'logmatch_wline' => $lminfo['logmatch_wline'],
			'logmatch_aline' => $lminfo['logmatch_aline'],
			'logmatch_incflg' => $lminfo['logmatch_incflg'],
			'logmatch_g_p1' => $lminfo['logmatch_g_p1'],
			'logmatch_g_p2' => $lminfo['logmatch_g_p2'],
			'logmatch_g_p3' => $lminfo['logmatch_g_p3'],
			'logmatch_g_p4' => $lminfo['logmatch_g_p4'],
			'logmatch_lastsize' => $lminfo['logmatch_lastsize'],
			'logmatch_pgname' => $lminfo['logmatch_pgname'],
			'logmatch_rcvflg' => $lminfo['logmatch_rcvflg'],
			'logmatch_timeout' => $lminfo['logmatch_timeout'],
			'logmatch_ctrl_ip' => $lminfo['logmatch_ctrl_ip'],
			'logmatch_ver' => $lminfo['logmatch_ver'],
			'logmatch_text' => $lminfo['logmatch_text'],
		) ;
		return $indata ;
		
	}
	
	/**
	 *  監視テンプレート用に、監視依存情報をシリアライズします. 
	 *
	 * @param	array		$mondep			監視依存情報. 
	 *
	 * @return	string	シリアライズされた監視依存情報. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function serialize( &$mondep )
	{
		$minfo =  'f:'.bin2hex( $mondep['logmatch_logname'] )."\n"
				 .'ws:'.$mondep['logmatch_wsize']."\n"
				 .'as:'.$mondep['logmatch_asize']."\n"
				 .'wl:'.$mondep['logmatch_wline']."\n"
				 .'al:'.$mondep['logmatch_aline']."\n"
				 .'if:'.$mondep['logmatch_incflg']."\n"
				 .'r:'.bin2hex( $mondep['logmatch_regex'] )."\n"
				 .'d:'.bin2hex( $mondep['logmatch_regex_dsp'] )."\n"
				 .'e:'.$mondep['logmatch_regex_enc']."\n"
				 .'g:'.bin2hex( $mondep['logmatch_g_p1'].':'.$mondep['logmatch_g_p2'].':'.$mondep['logmatch_g_p3'].':'.$mondep['logmatch_g_p4'] )."\n"
				 .'pn:'.bin2hex( $mondep['logmatch_pgname'] )."\n"
				 .'rf:'.$mondep['logmatch_rcvflg']."\n"
				 .'t:'.$mondep['logmatch_timeout']."\n"
				 .'c:'.bin2hex( $mondep['logmatch_ctrl_ip'] )."\n"
				 ;
		return $minfo ;
		
	}
	
	/**
	 *  監視テンプレート用にシリアライズされた監視依存情報（配列）から、
	 * 監視依存情報を設定します. 
	 *
	 * @param	array	$mondep	シリアライズされた監視依存情報（配列）. 
	 *
	 * @return	array	監視依存情報を返します. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function &unserialize( &$mondep )
	{
		$gunit = pack( 'H*', $mondep['g'] ) ;
		list( $g_p1, $g_p2, $g_p3, $g_p4 ) = @explode( ':', $gunit, 4 ) ;
		$minfo = array(
			'logmatch_logname' => pack( 'H*', $mondep['f'] ),
			'logmatch_wsize' => $mondep['ws'],
			'logmatch_asize' => $mondep['as'],
			'logmatch_wline' => $mondep['wl'],
			'logmatch_aline' => $mondep['al'],
			'logmatch_incflg' => $mondep['if'],
			'logmatch_regex' => pack( 'H*', $mondep['r'] ),
			'logmatch_regex_dsp' => pack( 'H*', $mondep['d'] ),
			'logmatch_regex_enc' => $mondep['e'],
			'logmatch_g_p1' => $g_p1,
			'logmatch_g_p2' => $g_p2,
			'logmatch_g_p3' => $g_p3,
			'logmatch_g_p4' => $g_p4,
			'logmatch_lastsize' => 0,
			'logmatch_pgname' => '',//pack( 'H*', $mondep['pn'] ),
			'logmatch_rcvflg' => $mondep['rf'],
			'logmatch_timeout' => $mondep['t'],
			'logmatch_ctrl_ip' => pack( 'H*', $mondep['c'] ),
			'service_installed' => false,
			'lmtest_done' => false,
			'updating' => false,
			'logmatch_text' => '',
			'logmatch_ver' => '',
		) ;
		$pgname = pack( 'H*', $mondep['pn'] ) ;
		if( preg_match( '/^[Cc]:\\\\(.+)\.[Ee][Xx][Ee]$/', $pgname, $pn ))
			$pgname = $pn[1] ;
		$pelm = explode( '\\', $pgname ) ;
		$pgname = '' ;
		if( ( $pc = count( $pelm )) > 1) {
			for( $i = 0 ; $i < $pc - 1 ; $i++)
				$pgname .= ( $pelm[$i].'\\') ;
		}
		$coninfo = &$this->getConnectionInfo() ;
		$pgname .= $this->make_svcname( $coninfo ) ;
		$minfo['logmatch_pgname'] = $minfo['_logmatch_pgname'] = $pgname ;
		return $minfo ;
		
	}
	
	/**
	 *  デフォルトの監視依存データを、監視情報オブジェクトに設定します. 
	 *
	 * @param	MonitorInfo	$monitorInfo	監視情報. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function setDefault( &$monitorInfo )
	{
		$coninfo = &$this->getConnectionInfo() ;
		$lminfo = array(
			'logmatch_logname' => '',
			'logmatch_regex' => '',
			'logmatch_regex_dsp' => '',
			'logmatch_regex_enc' => 0,
			'logmatch_wsize' => '',
			'logmatch_asize' => '',
			'logmatch_wline' => '',
			'logmatch_aline' => '',
			'logmatch_incflg' => 0,
			'logmatch_g_p1' => 'ALL',
			'logmatch_g_p2' => 'N',
			'logmatch_g_p3' => 'W',
			'logmatch_g_p4' => 'A',
			'logmatch_lastsize' => '0',
			'logmatch_pgname' => $this->make_svcname( $coninfo ),
			'logmatch_rcvflg' => 1,
			'logmatch_timeout' => 10,
			'logmatch_ver' => '',
			'logmatch_text' => '',
			'logmatch_ctrl_ip' => '',
			'service_installed' => false,
			'lmtest_done' => false,
			'updating' => false,
		) ;
		$lminfo['_logmatch_pgname'] = $lminfo['logmatch_pgname'] ;
		$monitorInfo->setDependsInfo( $lminfo );
		
	}
	
	/**
	 *  監視詳細情報設定画面で入力された各値を監視情報に設定します. 
	 *
	 * @param	array			$indata		入力値リスト. 
	 * @param	MonitorInfo	$monitorInfo	監視情報オブジェクト. 
	 * @param	boolean		$isnew			新規登録かどうかを示すフラグ. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function setInputtedData( &$indata, &$monitorInfo, $isnew = true )
	{
		$lminfo = &$monitorInfo->getDependsInfo() ;
		$lminfo['logmatch_logname'] = $indata['logmatch_logname'] ;
		$lminfo['logmatch_regex'] = $indata['logmatch_regex'] ;
		$lminfo['logmatch_regex_dsp'] = $indata['logmatch_regex_dsp'] ;
		$lminfo['logmatch_regex_enc'] = $indata['logmatch_regex_enc'] ;
		$lminfo['logmatch_wsize'] = $indata['logmatch_wsize'] ;
		$lminfo['logmatch_asize'] = $indata['logmatch_asize'] ;
		$lminfo['logmatch_wline'] = $indata['logmatch_wline'] ;
		$lminfo['logmatch_aline'] = $indata['logmatch_aline'] ;
		$lminfo['logmatch_incflg'] = $indata['logmatch_incflg'] ;
		$lminfo['logmatch_g_p1'] = $indata['logmatch_g_p1'] ;
		$lminfo['logmatch_g_p2'] = $indata['logmatch_g_p2'] ;
		$lminfo['logmatch_g_p3'] = $indata['logmatch_g_p3'] ;
		$lminfo['logmatch_g_p4'] = $indata['logmatch_g_p4'] ;
		$lminfo['logmatch_lastsize'] = $indata['logmatch_lastsize'] ;
		$lminfo['logmatch_rcvflg'] = $indata['logmatch_rcvflg'] ;
		$lminfo['logmatch_timeout'] = $indata['logmatch_timeout'] ;
		$lminfo['logmatch_ctrl_ip'] = $indata['logmatch_ctrl_ip'] ;
		$lminfo['logmatch_pgname'] = $lminfo['_logmatch_pgname'] = $indata['logmatch_pgname'] ;
		$lminfo['logmatch_ver'] = $indata['logmatch_ver'] ;
		$lminfo['logmatch_text'] = $indata['logmatch_text'] ;
		
	}
	
	/**
	 *  現在の設定情報で、シングルリアルタイム実行を試します. 
	 *
	 * @param	MonitorInfo	$monitorInfo	監視情報. 
	 * @param	array			$indata		入力データリスト. 
	 * @param	boolean		$isnew			新規登録処理中かどうかを示すフラグ. 
	 *
	 * @return	array
	 *	シングルリアルタイム実行が正常終了した場合は null、失敗した場合はエラー ID
	 * リストを返します. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function &test( &$monitorInfo, &$indata, $isnew = true )
	{
		$errors = array() ;
		return $errors ;
		
	}
	
	
	/**
	 *  監視依存データを更新します. 
	 *
	 * @param	Connection		$connection	データベースコネクションオブジェクト. 
	 * @param	MonitorInfo	$monitorInfo	監視情報. 
	 * @param	integer		$updater		更新処理を行っているユーザのユーザ ID. 
	 *
	 * @return	boolean
	 *	更新処理が正常終了した場合は true、エラーが発生した場合は false を返します. 
	 *
	 * @throws	E_USER_ERROR	データベースアクセスエラーが発生した場合. 
	 *
	 * @access	public
	 * @since	1.0
	 */
	function updateDependsData( &$connection, &$monitorInfo, $updater )
	{
		$moduleInfo = &$monitorInfo->getModuleInfo() ;
		$lminfo = &$monitorInfo->getDependsInfo() ;
		
		$now = new Date() ;
		$statement = &$connection->prepareStatement(
			'UPDATE ? SET wsize=?,asize=?,wline=?,aline=?,lastsize=?,incflg=?,logname=?,regex=?,regex_dsp=?,regex_enc=?,g_unit=?,pgname=?,rcvflg=?,update_date=?,update_userid=?,timeout=?,ver=?,ctrl_ip=?' .
			' WHERE cltmon_id=?'
		) ;
		$statement->setString( 1, $moduleInfo->getDbName(), false );
		$statement->setString( 2, $lminfo['logmatch_wsize'], false );
		$statement->setString( 3, $lminfo['logmatch_asize'], false );
		$statement->setInt( 4, $lminfo['logmatch_wline'] );
		$statement->setInt( 5, $lminfo['logmatch_aline'] );
		$statement->setString( 6, $lminfo['logmatch_lastsize'], false );
		$statement->setInt( 7, $lminfo['logmatch_incflg'] );
		$statement->setString( 8, $lminfo['logmatch_logname'] );
		$statement->setString( 9, $lminfo['logmatch_regex'] );
		$statement->setString( 10, $lminfo['logmatch_regex_dsp'] );
		$statement->setInt( 11, $lminfo['logmatch_regex_enc'] );
		$statement->setString( 12, $lminfo['logmatch_g_p1'].':'.$lminfo['logmatch_g_p2'].':'.$lminfo['logmatch_g_p3'].':'.$lminfo['logmatch_g_p4'] );
		$statement->setString( 13, 'C:\\'.$lminfo['logmatch_pgname'].'.exe' );
		$statement->setInt( 14, ( $lminfo['logmatch_rcvflg']? 1 : 0) );
		$statement->setDate( 15, $now );
		$statement->setInt( 16, $updater );
		$statement->setInt( 17, $lminfo['logmatch_timeout'] );
		$statement->setString( 18, $lminfo['logmatch_ver'] );
		$statement->setString( 19, $lminfo['logmatch_ctrl_ip'] );
		$statement->setInt( 20, $monitorInfo->getId() );
		$result = ( $statement->executeUpdate() >= 0) ;
		
		$statement->close();
		return $result ;
		
	}
	
// public attributes. 
	/**
	 * エラーメッセージ表示用 View 名称. 
	 * @var	string
	 * @access	public
	 * @since	1.0
	 */
	var $errorView = 'group/monwlogmatcherr.tpl' ;
	
// private methods.
	function install_service( &$monitorInfo, &$indata )
	{
		$coninfo = &$this->getConnectionInfo() ;
		if( ( $ip = $monitorInfo->getAltIP()) && ( strlen( $ip ) > 0))
			$monip = $ip ;
		else
			$monip = long2ip( $coninfo['dev_ip'] ) ;
		$uinfo = $coninfo['login_user'] ;
		if( strlen( $coninfo['login_pass'] ) > 0)
			$uinfo .= ( '%'.$coninfo['login_pass']) ;
		$pelm = explode( '\\', $indata['logmatch_pgname'] ) ;
		$svcname = $pelm[count($pelm)-1] ;
		
		$param = "install $monip '$uinfo' $svcname @HOME@etc/winlogmatch.exe 'C:\\{$indata['logmatch_pgname']}.exe' 'PatrolClarice Log Matcher($svcname)'" ;
		$cipher = new ClarisCipher() ;
		$postdata = 'param='.$cipher->encrypt( $param ).
					'&op='.urlencode( $cipher->onetime_pass() ) ;
		
		$url = 'http://'.$indata['logmatch_ctrl_ip'].'/clif.php/winlog.winsvc' ;
		$sender = new PostSender( $url, 30 ) ;
		if( ( $result = &$sender->sendRequest( $postdata )) == null) {
			$this->model->error( "$url: unable to connect clarice I/F." ) ;
			return 'error.logmatch_instsvc.'.bin2hex( 'unable to connect clarice I/F.' ) ;
		}
		else if( $result['response-code'] != '200') {
			$this->model->error( $url.': '.$result['response-code'].': clarice I/F error.' );
			return 'error.logmatch_instsvc.'.bin2hex( $result['response-code'].': clarice I/F error.' ) ;
		}
		else if( !preg_match( '/^(-?[0-9]+)\n(.*)$/', $result['response-body'], $r )) {
			$this->model->error( $url.': '.$result['response-body'].': malformed clarice I/F response.' );
			return 'error.logmatch_instsvc.'.bin2hex( 'malformed clarice I/F response.' ) ;
		}
		if( $r[1] == '0') {
			$this->model->info( "$svcname@$monip: service installed." );
			$context = &$this->model->getContext() ;
			$connection = &$context->getConnection() ;
			$statement = &$connection->createStatement() ;
			$resultSet = &$statement->executeQuery( 'SELECT winlogmatch_ver FROM clm_system' ) ;
			if( $resultSet->next())
				$indata['logmatch_ver'] = $resultSet->getString( 1 ) ;
			$resultSet->close();
			$statement->close();
			return null ;
		}
		return 'error.logmatch_instsvc.'.bin2hex( $r[2] ) ;
		
	}
	
	function uninstall_service( &$monitorInfo, &$indata )
	{
		$coninfo = &$this->getConnectionInfo() ;
		if( ( $ip = $monitorInfo->getAltIP()) && ( strlen( $ip ) > 0))
			$monip = $ip ;
		else
			$monip = long2ip( $coninfo['dev_ip'] ) ;
		$uinfo = $coninfo['login_user'] ;
		if( strlen( $coninfo['login_pass'] ) > 0)
			$uinfo .= ( '%'.$coninfo['login_pass']) ;
		$pelm = explode( '\\', $indata['logmatch_pgname'] ) ;
		$svcname = $pelm[count($pelm)-1] ;
		
		$param = "uninstall $monip '$uinfo' $svcname" ;
		
		$cipher = new ClarisCipher() ;
		$postdata = 'param='.$cipher->encrypt( $param ).
					'&op='.urlencode( $cipher->onetime_pass() ) ;
		
		$url = 'http://'.$indata['logmatch_ctrl_ip'].'/clif.php/winlog.winsvc' ;
		$sender = new PostSender( $url, 30 ) ;
		if( ( $result = &$sender->sendRequest( $postdata )) == null) {
			$this->model->error( "$url: unable to connect clarice I/F." ) ;
			return 'error.logmatch_uninstsvc.'.bin2hex( 'unable to connect clarice I/F.' ) ;
		}
		else if( $result['response-code'] != '200') {
			$this->model->error( $url.': '.$result['response-code'].': clarice I/F error.' );
			return 'error.logmatch_uninstsvc.'.bin2hex( $result['response-code'].': clarice I/F error.' ) ;
		}
		else if( !preg_match( '/^(-?[0-9]+)\n(.*)$/', $result['response-body'], $r )) {
			$this->model->error( $url.': '.$result['response-body'].': malformed clarice I/F response.' );
			return 'error.logmatch_uninstsvc.'.bin2hex( 'malformed clarice I/F response.' ) ;
		}
		if( $r[1] == '0') {
			$this->model->info( "$svcname@$monip: service uninstalled." );
			$ind['logmatch_ver'] = '' ;
			return null ;
		}
		return 'error.logmatch_uninstsvc.'.bin2hex( $r[2] ) ;
		
	}
	
	function logmatch_test( &$monitorInfo, &$indata, &$result )
	{
		$result = array(
			'retcd' => null,
			'mcnt' => 0, 'lastsize' => 0, 'p1' => '', 'p2' => '', 'p3' => '', 'p4' => '',
			'enc' => null,
			'rc' => 0, 'rs' => array(),
			'err' => null, 'errno' => null, 'errmsg' => null,
		) ;
		
		$context = &$this->model->getContext() ;
		$connection = &$context->getConnection() ;
		
		$statement = &$connection->prepareStatement(
			'INSERT INTO clw_wmon_logmatch(cltmon_id,wsize,asize,wline,aline,lastsize,incflg,logname,regex,regex_enc,timeout,create_date,create_userid,ctrl_ip)'.
			' VALUES (0,?,?,?,?,?,?,?,?,?,?,SYSDATE(),?,?)'
		) ;
		$statement->setString( 1, $indata['logmatch_wsize'], false );
		$statement->setString( 2, $indata['logmatch_asize'], false );
		$statement->setInt( 3, $indata['logmatch_wline'] );
		$statement->setInt( 4, $indata['logmatch_aline'] );
		$statement->setString( 5, $indata['logmatch_lastsize'], false );
		$statement->setInt( 6, $indata['logmatch_incflg'] );
		$statement->setString( 7, $indata['logmatch_logname'] );
		$statement->setString( 8, $indata['logmatch_regex'] );
		$statement->setInt( 9, $indata['logmatch_regex_enc'] );
		$statement->setInt( 10, $indata['logmatch_timeout'] );
		$me = &$this->model->getUserInfo() ;
		$statement->setInt( 11, $me->getId() );
		$statement->setString( 12, $indata['logmatch_ctrl_ip'] );
		if( $statement->executeUpdate() <= 0)
			trigger_error( 'unable to create winlogmatch temporary data.', E_USER_ERROR );
		$cltmon_id = $statement->getLastInsertId() ;
		$statement->close();
		
		$pelm = explode( '\\', $indata['logmatch_pgname'] ) ;
		$svcname = $pelm[count($pelm)-1] ;
		
		$coninfo = &$this->getConnectionInfo() ;
		if( ( $ip = $monitorInfo->getAltIP()) && ( strlen( $ip ) > 0))
			$monip = $ip ;
		else
			$monip = long2ip( $coninfo['dev_ip'] ) ;
		$cipher = new ClarisCipher() ;
		$param = $monip.','.$coninfo['login_user'].','.$coninfo['enc_pass'].','.$indata['logmatch_timeout'].','.
				 'g:-'.$cltmon_id.':'.$svcname.':'.$cipher->encrypt( '-'.$cltmon_id.','.$indata['logmatch_ctrl_ip'] ) ;
		
		$command = new ClarisCommand( $monitorInfo->getControlId() ) ;
		$command->exec( 'chkwin -R '.bin2hex( $param ), $response, $exit_code, '-z' );
		
		$statement = &$connection->prepareStatement( 'DELETE FROM clw_wmon_logmatch WHERE cltmon_id=?' ) ;
		$statement->setInt( 1, $cltmon_id );
		$statement->executeUpdate();
		$statement->close();
		
		if( is_array( $response ) && ( ( $rcnt = count( $response )) > 0)) {
			for( $i = 0 ; $i < $rcnt ; $i++) {
				if( !preg_match( '/^<--(3011|0000)\.-?[1-9][0-9]*-->\s*(.+)$/', $response[$i], $r ))
					continue ;
				$line = trim( $r[2] ) ;
				if( preg_match( '/^_3011_\s*(-?[0-9]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+(.+)$/', $line, $r )) {
					$result['retcd'] = intval( $r[1] ) ;
					$result['mcnt'] = $r[2] ;
					$result['lastsize'] = $r[3] ;
					$result['p1'] = $r[4] ;
					$result['p2'] = $r[5] ;
					$result['p3'] = $r[6] ;
					$result['p4'] = $r[7] ;
					if( $r[8] == 'sjis')
						$result['enc'] = $this->getPHPEncoding( 20 ) ;
					else if( $r[8] == 'euc')
						$result['enc'] = $this->getPHPEncoding( 19 ) ;
				}
				else if( preg_match( '/^err=(.+)$/', $line, $r ))
					$result['err'] = $r[1] ;
				else if( preg_match( '/^errno=(.+)$/', $line, $r ))
					$result['errno'] = $r[1] ;
				else if( preg_match( '/^errmsg=(.+)$/', $line, $r ))
					$result['errmsg'] = $r[1] ;
				else {
					$rs = @explode( ':', $line, 3 ) ;
					if( is_array( $rs ) && ( count( $rs ) == 3)) {
						$tag = $rs[1] ;
						if( $result['enc'])
							$tag = @mb_convert_encoding( $tag, 'utf-8', $result['enc'] ) ;
						$r = array(
							'snip' => false,
							'type' => $rs[0],
							'tag' => htmlspecialchars( $tag ),
							'mlog' => $rs[2],
						) ;
					}
					else {
						$r = array(
							'snip' => true,
							'mlog' => $line,
						) ;
					}
					if( $result['enc'])
						$r['mlog'] = @mb_convert_encoding( $r['mlog'], 'utf-8', $result['enc'] ) ;
					$r['mlog'] = htmlspecialchars( $r['mlog'] ) ;
					$result['rs'][] = $r ;
					$result['rc']++ ;
				}
			}
		}
		if( $result['retcd'] === null)
			return 'error.logmatch_test.exec' ;
		else if( $result['retcd'] != 0)
			return 'error.logmatch_test.'.bin2hex( $this->getErrorMessage( $result['retcd'], $monitorInfo ) ) ;
		return null ;
		
	}
	
	function check_regex( $regex, &$errmsg )
	{
		$cmd = WEBAPP_HOME.'bin/exprchk2 -s -e '.escapeshellarg( $regex ).';echo $? >&3' ;
		$descriptorspec = array( 1 => array( 'pipe', 'w' ), 3 => array( 'pipe', 'w' ) ) ;
		$exitcode = -99 ;
		if( ( $fp = @proc_open( $cmd, $descriptorspec, $pipes ))) {
			$stdout = '' ;
			if( !@feof( $pipes[1] ))
				$stdout = trim( @fgets( $pipes[1], 4096 ) ) ;
			@fclose( $pipes[1] );
			$exitcode = -1 ;
			if( !@feof( $pipes[3] ))
				$exitcode = intval( trim( @fgets( $pipes[3] ) ) ) ;
			@fclose( $pipes[3] );
			@proc_close( $fp );
			if( $exitcode == 0) {
				if( strlen( $stdout ) > 0) {
					if( preg_match( '/^(-?[0-9]+):(.*)$/', $stdout, $e )) {
						$errmsg = $e[2] ;
						return ( ( ( $e[1] == '0') || ( $e[1] == '1'))? 1 : 0) ;
					}
					$errmsg = $stdout ;
					return -1 ;
				}
				else
					$exitcode = -9 ;
			}
		}
		$errmsg = "$exitcode: unable to execute exprchk2." ;
		return -1 ;
		
	}
	
	function test_regex( $regex_list, $tstr, $enc )
	{
		if( $enc != null)
			$tstr = @mb_convert_encoding( $tstr, $enc, 'utf-8' ) ;
		$locale = @setlocale( LC_ALL, '0' ) ; @setlocale( LC_ALL, 'en_US.iso88591' ) ;
		$cmd = WEBAPP_HOME.'bin/exprchk2 -s -l '.escapeshellarg( $tstr ) ;
		if( $locale !== false)
			@setlocale( LC_ALL, $locale );
		$descriptorspec = array( 1 => array( 'pipe', 'w' ), 3 => array( 'pipe', 'w' ) ) ;
		
		$rtestr = array() ;
		foreach( preg_split( '/\r\n|\n/', $regex_list ) as $regex) {
			if( ( strlen( ( $regex = trim( $regex )) ) <= 0) ||
				!is_array( ( $elm = explode( ':', $regex, 3 )) ) ||
				( count( $elm ) != 3))
				continue ;
			$rr = array(
				'type' => trim( $elm[0] ),
				'tag' => trim( $elm[1] ),
				'regex' => trim( $elm[2] ),
				'r' => '-',
				'P1' => null, 'P2' => null, 'P3' => null, 'P4' => null,
			) ;
			$exitcode = -99 ;
			if( ( $fp = @proc_open( $cmd.' -e '.escapeshellarg( $rr['regex'] ).';echo $? >&3', $descriptorspec, $pipes ))) {
				$stdout = null ;
				while( !@feof( $pipes[1] )) {
					if( strlen( ( $line = trim( @fgets( $pipes[1] ) )) ) > 0) {
						if( $stdout === null)
							$stdout = array() ;
						$stdout[] = $line ;
					}
				}
				@fclose( $pipes[1] );
				$exitcode = -1 ;
				if( !@feof( $pipes[3] ))
					$exitcode = intval( trim( @fgets( $pipes[3] ) ) ) ;
				@fclose( $pipes[3] );
				@proc_close( $fp );
				if( $exitcode == 0) {
					if( ( $stdout !== null) && ( ( $sc = count( $stdout )) >= 1)) {
						if( preg_match( '/^(-?[0-9]+):(.*)$/', $stdout[0], $e )) {
							$rr['r'] = intval( $e[1] ) ;
							if( $rr['r'] == 1) {
								for( $i = 1 ; $i < $sc ; $i++) {
									if( preg_match( '/^P'.$i.'=(.+)$/', $stdout[$i], $pn ))
										$rr["P$i"] = trim( $pn[1] ) ;
								}
							}
							else if( $rr['r'] != 0)
								$rr['r'] = $e[2] ;
						}
					}
					else
						$exitcode = -9 ;
				}
			}
			if( $exitcode != 0)
				$rr['r'] = "exprchk error($exitcode)" ;
			$rtestr[] = $rr ;
		}
		return $rtestr ;
		
	}
	
	function make_svcname( &$coninfo )
	{
		$prefix = long2ip( $coninfo['dev_ip'] ).'_'.$coninfo['login_user'].'_'.date( 'YmdHis', time() ).'_'.mt_rand() ;
		return substr( md5( uniqid( $prefix ) ), 0, 8 ) ;
		
	}
	
	function check_fname( &$f )
	{
		$path = array() ; $pc = 0 ;
		$pelm = explode( '\\', $f ) ;
		if( ( $ec = count( $pelm )) > 0) {
			for( $i = 0 ; $i < $ec ; $i++) {
				if( strlen( ( $p = trim( $pelm[$i] )) ) <= 0)
					continue ;
				if( strpos( $p, ':' ) !== false) {
					if( ( $pc > 0) || !preg_match( '/^[a-z]:$/i', $p ))
						return 'invalid' ;
				}
				else if( preg_match( '/[\\\\\/,;\"<>\|]/', $p ))
					return 'invalid' ;
				$path[] = $p ;
				$pc++ ;
			}
			if( $pc > 0) {
				$f = implode( '\\', $path ) ;
				return null ;
			}
		}
		return 'empty' ;
	}
	
// private attributes. 
	/**
	 * 処理モードモードフラグ. 
	 * @var	integer
	 * @access	private
	 * @since	1.0
	 */
	var $lmop = 0 ;
	
}
?>