Url();}, $Servers)); switch ($view) { case 'login': { if (defined('ZM_OPT_USE_GOOG_RECAPTCHA') && defined('ZM_OPT_GOOG_RECAPTCHA_SITEKEY') && defined('ZM_OPT_GOOG_RECAPTCHA_SECRETKEY') && ZM_OPT_USE_GOOG_RECAPTCHA && ZM_OPT_GOOG_RECAPTCHA_SITEKEY && ZM_OPT_GOOG_RECAPTCHA_SECRETKEY) { $additionalScriptSrc .= ' https://www.google.com'; } // fall through } case 'bandwidth': case 'blank': case 'console': case 'controlcap': case 'cycle': case 'donate': case 'download': case 'error': case 'events': case 'export': case 'frame': case 'function': case 'log': case 'logout': case 'optionhelp': case 'options': case 'plugin': case 'postlogin': case 'privacy': case 'server': case 'state': case 'status': case 'storage': case 'version': { // Enforce script-src on pages where inline scripts and event handlers have been fixed. // 'unsafe-inline' is only for backwards compatibility with browsers which // only support CSP 1 (with no nonce-* support). header("Content-Security-Policy: script-src 'unsafe-inline' 'self' 'nonce-$nonce' $additionalScriptSrc"); break; } default: { // Use Report-Only mode on all other pages. header("Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'self' 'nonce-$nonce' $additionalScriptSrc;". (ZM_CSP_REPORT_URI ? ' report-uri '.ZM_CSP_REPORT_URI : '' ) ); break; } } } function CORSHeaders() { if ( isset($_SERVER['HTTP_ORIGIN']) ) { # The following is left for future reference/use. $valid = false; global $Servers; if ( ! $Servers ) $Servers = ZM\Server::find(); if ( sizeof($Servers) < 1 ) { # Only need CORSHeaders in the event that there are multiple servers in use. # ICON: Might not be true. multi-port? if ( ZM_MIN_STREAMING_PORT ) { ZM\Logger::Debug('Setting default Access-Control-Allow-Origin from ' . $_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Headers: x-requested-with,x-request'); } return; } foreach ( $Servers as $Server ) { if ( preg_match('/^(https?:\/\/)?'.preg_quote($Server->Hostname(),'/').'/i', $_SERVER['HTTP_ORIGIN']) or preg_match('/^(https?:\/\/)?'.preg_quote($Server->Name(),'/').'/i', $_SERVER['HTTP_ORIGIN']) ) { $valid = true; ZM\Logger::Debug('Setting Access-Control-Allow-Origin from '.$_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Headers: x-requested-with,x-request'); break; } } if ( !$valid ) { ZM\Warning($_SERVER['HTTP_ORIGIN'] . ' is not found in servers list.'); } } } function getMimeType( $file ) { if ( function_exists('mime_content_type') ) { return mime_content_type($file); } elseif ( function_exists('finfo_file') ) { $finfo = finfo_open(FILEINFO_MIME); $mimeType = finfo_file($finfo, $file); finfo_close($finfo); return $mimeType; } return trim(exec('file -bi '.escapeshellarg($file).' 2>/dev/null')); } function outputVideoStream($id, $src, $width, $height, $format, $title='') { echo getVideoStreamHTML($id, $src, $width, $height, $format, $title); } function getVideoStreamHTML($id, $src, $width, $height, $format, $title='') { $html = ''; $width = validInt($width); $height = validInt($height); $title = validHtmlStr($title); if ( file_exists($src) ) { $mimeType = getMimeType($src); } else { switch( $format ) { case 'asf' : $mimeType = 'video/x-ms-asf'; break; case 'avi' : case 'wmv' : $mimeType = 'video/x-msvideo'; break; case 'mov' : $mimeType = 'video/quicktime'; break; case 'mpg' : case 'mpeg' : $mimeType = 'video/mpeg'; break; case 'swf' : $mimeType = 'application/x-shockwave-flash'; break; case '3gp' : $mimeType = 'video/3gpp'; break; default : $mimeType = "video/$format"; break; } } if ( !$mimeType || ($mimeType == 'application/octet-stream') ) $mimeType = 'video/'.$format; if ( ZM_WEB_USE_OBJECT_TAGS ) { switch( $mimeType ) { case 'video/x-ms-asf' : case 'video/x-msvideo' : case 'video/mp4' : if ( isWindows() ) { return ''; } case 'video/quicktime' : return ''; case 'application/x-shockwave-flash' : return ''; } # end switch } # end if use object tags return ''; } function outputImageStream( $id, $src, $width, $height, $title='' ) { echo getImageStreamHTML( $id, $src, $width, $height, $title ); } // width and height MUST be valid and include the px function getImageStreamHTML( $id, $src, $width, $height, $title='' ) { if ( canStreamIframe() ) { return ''; } else { return ''; } } function outputControlStream($src, $width, $height, $monitor, $scale, $target) { ?>
'; } function outputImageStill($id, $src, $width, $height, $title='') { echo getImageStill($id, $src, $width, $height, $title=''); } function getImageStill($id, $src, $width, $height, $title='') { return ''; } function getWebSiteUrl($id, $src, $width, $height, $title='') { # Prevent unsightly warnings when php cannot verify the ssl certificate stream_context_set_default( [ 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); # The End User can turn off the following warning under Options -> Web if ( ZM_WEB_XFRAME_WARN ) { $header = get_headers($src, 1); # If the target website has set X-Frame-Options, check it for "sameorigin" and warn the end user if ( array_key_exists('X-Frame-Options', $header) ) { $header = $header['X-Frame-Options']; if ( stripos($header, 'sameorigin') === 0 ) ZM\Warning("Web site $src has X-Frame-Options set to sameorigin. An X-Frame-Options browser plugin is required to display this site."); } } return ''; } function outputControlStill($src, $width, $height, $monitor, $scale, $target) { ?> getStreamSrc(array('mode'=>'mpeg', 'format'=>'h264')); } function deletePath( $path ) { ZM\Logger::Debug("Deleting $path"); if ( is_dir($path) ) { system(escapeshellcmd('rm -rf '.$path)); } else if ( file_exists($path) ) { unlink($path); } } function deleteEvent($event) { if ( empty($event) ) { ZM\Error('Empty event passed to deleteEvent.'); return; } if ( gettype($event) != 'array' ) { # $event could be an eid, so turn it into an event hash $event = new ZM\Event($event); } else { ZM\Logger::Debug("Event type: " . gettype($event)); } global $user; if ( $event->Archived() ) { ZM\Info('Cannot delete Archived event.'); return; } # end if Archived if ( $user['Events'] == 'Edit' ) { $event->delete(); } # CAN EDIT } function makeLink($url, $label, $condition=1, $options='') { $string = ''; if ( $condition ) { $string .= ''; } $string .= $label; if ( $condition ) { $string .= ''; } return $string; } /** * $label must be already escaped. It can't be done here since it sometimes contains HTML tags. */ function makePopupLink($url, $winName, $winSize, $label, $condition=1, $options='') { // Avoid double-encoding since some consumers incorrectly pass a pre-escaped URL. $string = ''; } else { $string .= '>'; } $string .= $label; $string .= ''; return $string; } function makePopupButton($url, $winName, $winSize, $buttonValue, $condition=1, $options='') { $string = ''; return $string; } function htmlSelect($name, $contents, $values, $behaviours=false) { $behaviourText = ''; if ( !empty($behaviours) ) { if ( is_array($behaviours) ) { foreach ( $behaviours as $event=>$action ) { $behaviourText .= ' '.$event.'="'.$action.'"'; } } else { $behaviourText = ' onchange="'.$behaviours.'"'; } } return "'; } function htmlOptions($contents, $values) { $options_html = ''; foreach ( $contents as $value=>$option ) { $disabled = 0; $text = ''; if ( is_array($option) ) { if ( isset($option['Name']) ) $text = $option['Name']; else if ( isset($option['text']) ) $text = $option['text']; if ( isset($option['disabled']) ) { $disabled = $option['disabled']; } } else if ( is_object($option) ) { $text = $option->Name(); } else { $text = $option; } $selected = is_array($values) ? in_array($value, $values) : !strcmp($value, $values); $options_html .= ' '; } return $options_html; } function truncText($text, $length, $deslash=1) { return preg_replace('/^(.{'.$length.',}?)\b.*$/', '\\1…', ($deslash?stripslashes($text):$text)); } function buildSelect($name, $contents, $behaviours=false) { $value = ''; if ( preg_match('/^\s*(\w+)\s*(\[.*\])?\s*$/', $name, $matches) && (count($matches) > 2) ) { $arr = $matches[1]; if ( isset($GLOBALS[$arr]) ) $value = $GLOBALS[$arr]; elseif ( isset($_REQUEST[$arr]) ) $value = $_REQUEST[$arr]; if ( !preg_match_all('/\[\s*[\'"]?(\w+)["\']?\s*\]/', $matches[2], $matches) ) { ZM\Fatal("Can't parse selector '$name'"); } for ( $i = 0; $i < count($matches[1]); $i++ ) { $idx = $matches[1][$i]; $value = isset($value[$idx])?$value[$idx]:false; } } else { if ( isset($GLOBALS[$name]) ) $value = $GLOBALS[$name]; elseif ( isset($_REQUEST[$name]) ) $value = $_REQUEST[$name]; } ob_start(); $behaviourText = ''; if ( !empty($behaviours) ) { if ( is_array($behaviours) ) { foreach ( $behaviours as $event=>$action ) { $behaviourText .= ' '.$event.'="'.$action.'"'; } } else { $behaviourText = ' onchange="'.$behaviours.'"'; } } ?> $value ) { if ( $columns && !isset($columns[$key]) ) continue; if ( !isset($types[$key]) ) $types[$key] = false; switch( $types[$key] ) { case 'set' : if ( is_array($newValues[$key]) ) { if ( (!isset($values[$key])) or ( join(',',$newValues[$key]) != $values[$key] ) ) { $changes[$key] = "`$key` = ".dbEscape(join(',',$newValues[$key])); } } else if ( (!isset($values[$key])) or $values[$key] ) { $changes[$key] = "`$key` = ''"; } break; case 'image' : if ( is_array( $newValues[$key] ) ) { $imageData = getimagesize( $newValues[$key]['tmp_name'] ); $changes[$key.'Width'] = $key.'Width = '.$imageData[0]; $changes[$key.'Height'] = $key.'Height = '.$imageData[1]; $changes[$key.'Type'] = $key."Type = '".$newValues[$key]['type']."'"; $changes[$key.'Size'] = $key.'Size = '.$newValues[$key]['size']; ob_start(); readfile( $newValues[$key]['tmp_name'] ); $changes[$key] = $key." = ".dbEscape( ob_get_contents() ); ob_end_clean(); } else { $changes[$key] = "$key = ".dbEscape($value); } break; case 'document' : if ( is_array( $newValues[$key] ) ) { $imageData = getimagesize( $newValues[$key]['tmp_name'] ); $changes[$key.'Type'] = $key."Type = '".$newValues[$key]['type']."'"; $changes[$key.'Size'] = $key.'Size = '.$newValues[$key]['size']; ob_start(); readfile( $newValues[$key]['tmp_name'] ); $changes[$key] = $key.' = '.dbEscape( ob_get_contents() ); ob_end_clean(); } else { $changes[$key] = $key . ' = '.dbEscape($value); } break; case 'file' : $changes[$key.'Type'] = $key.'Type = '.dbEscape($newValues[$key]['type']); $changes[$key.'Size'] = $key.'Size = '.dbEscape($newValues[$key]['size']); ob_start(); readfile( $newValues[$key]['tmp_name'] ); $changes[$key] = $key." = '".dbEscape( ob_get_contents() )."'"; ob_end_clean(); break; case 'raw' : if ( (!isset($values[$key])) or ($values[$key] != $value) ) { $changes[$key] = $key . ' = '.dbEscape($value); } break; case 'toggle' : if ( (!isset($values[$key])) or $values[$key] != $value ) { if ( empty($value) ) { $changes[$key] = "$key = 0"; } else { $changes[$key] = "$key = 1"; //$changes[$key] = $key . ' = '.dbEscape(trim($value)); } } break; case 'integer' : if ( (!isset($values[$key])) or $values[$key] != $value ) { $changes[$key] = $key . ' = '.intval($value); } break; default : if ( !isset($values[$key]) || ($values[$key] != $value) ) { if ( ! isset($value) || $value == '' ) { $changes[$key] = "`$key` = NULL"; } else { $changes[$key] = "`$key` = ".dbEscape(trim($value)); } } break; } // end switch } // end foreach newvalues foreach ( $values as $key=>$value ) { if ( !empty($columns[$key]) ) { if ( !empty($types[$key]) ) { if ( $types[$key] == 'toggle' ) { if ( !isset($newValues[$key]) && !empty($value) ) { $changes[$key] = "$key = 0"; } } else if ( $types[$key] == 'set' ) { $changes[$key] = "$key = ''"; } } } } return $changes; } function getBrowser(&$browser, &$version) { if ( isset($_SESSION['browser']) ) { $browser = $_SESSION['browser']; $version = $_SESSION['version']; } else { if ( ( preg_match('/MSIE (.*?);/', $_SERVER['HTTP_USER_AGENT'], $logVersion)) || ( preg_match('/.*Trident.*rv:(.*?)(;|\))/', $_SERVER['HTTP_USER_AGENT'], $logVersion)) ) { $version = $logVersion[1]; $browser = 'ie'; } else if ( preg_match('/Chrome\/([0-9.]+)/', $_SERVER['HTTP_USER_AGENT'], $logVersion) ) { $version = $logVersion[1]; // Check for old version of Chrome with bug 5876 if ( $version < 7 ) { $browser = 'oldchrome'; } else { $browser = 'chrome'; } } else if ( preg_match('/Safari\/([0-9.]+)/', $_SERVER['HTTP_USER_AGENT'], $logVersion) ) { $version = $logVersion[1]; $browser = 'safari'; } else if ( preg_match('/Opera[ \/]([0-9].[0-9]{1,2})/', $_SERVER['HTTP_USER_AGENT'], $logVersion) ) { $version = $logVersion[1]; $browser = 'opera'; } else if ( preg_match('/Konqueror\/([0-9.]+)/', $_SERVER['HTTP_USER_AGENT'], $logVersion) ) { $version = $logVersion[1]; $browser = 'konqueror'; } else if ( preg_match('/Mozilla\/([0-9].[0-9]{1,2})/', $_SERVER['HTTP_USER_AGENT'], $logVersion) ) { $version = $logVersion[1]; $browser = 'mozilla'; } else { $version = 0; $browser = 'unknown'; } $_SESSION['browser'] = $browser; $_SESSION['version'] = $version; } } function isMozilla() { getBrowser($browser, $version); return $browser == 'mozilla'; } function isKonqueror() { getBrowser($browser, $version); return $browser == 'konqueror'; } function isInternetExplorer() { getBrowser($browser, $version); return $browser == 'ie'; } function isOldChrome() { getBrowser($browser, $version); return $browser == 'oldchrome'; } function isChrome() { getBrowser($browser, $version); return $browser == 'chrome'; } function isOpera() { getBrowser($browser, $version); return $browser == 'opera'; } function isSafari() { getBrowser($browser, $version); return $browser == 'safari'; } function isWindows() { return preg_match('/Win/', $_SERVER['HTTP_USER_AGENT']); } function canStreamIframe() { return isKonqueror(); } function canStreamNative() { // Old versions of Chrome can display the stream, but then it blocks everything else (Chrome bug 5876) return ( ZM_WEB_CAN_STREAM == 'yes' || ( ZM_WEB_CAN_STREAM == 'auto' && (!isInternetExplorer() && !isOldChrome()) ) ); } function canStreamApplet() { if ( (ZM_OPT_CAMBOZOLA && !file_exists( ZM_PATH_WEB.'/'.ZM_PATH_CAMBOZOLA )) ) { ZM\Warning('ZM_OPT_CAMBOZOLA is enabled, but the system cannot find '.ZM_PATH_WEB.'/'.ZM_PATH_CAMBOZOLA); } return (ZM_OPT_CAMBOZOLA && file_exists(ZM_PATH_WEB.'/'.ZM_PATH_CAMBOZOLA)); } function canStream() { return canStreamNative() | canStreamApplet(); } function packageControl($command) { $string = ZM_PATH_BIN.'/zmpkg.pl '.escapeshellarg($command); $string .= ' 2>/dev/null >&- <&- >/dev/null'; exec($string); } function daemonControl($command, $daemon=false, $args=false) { $string = escapeshellcmd(ZM_PATH_BIN).'/zmdc.pl '.$command; if ( $daemon ) { $string .= ' ' . $daemon; if ( $args ) { $string .= ' ' . $args; } } $string = escapeshellcmd($string); #$string .= ' 2>/dev/null >&- <&- >/dev/null'; ZM\Logger::Debug("daemonControl $string"); exec($string); } function zmcControl($monitor, $mode=false) { $Monitor = new ZM\Monitor($monitor); return $Monitor->zmcControl($mode); } function zmaControl($monitor, $mode=false) { $Monitor = new ZM\Monitor($monitor); return $Monitor->zmaControl($mode); } function initDaemonStatus() { global $daemon_status; if ( !isset($daemon_status) ) { if ( daemonCheck() ) { $string = ZM_PATH_BIN.'/zmdc.pl status'; $daemon_status = shell_exec($string); } else { $daemon_status = ''; } } } function daemonStatus($daemon, $args=false) { global $daemon_status; initDaemonStatus(); $string = $daemon; if ( $args ) { if ( is_array($args) ) { $string .= join(' ', $args); ZM\Warning("daemonStatus args: $string"); } else { $string .= ' ' . $args; } } return ( strpos($daemon_status, "'$string' running") !== false ); } function zmcStatus($monitor) { if ( $monitor['Type'] == 'Local' ) { $zmcArgs = '-d '.$monitor['Device']; } else { $zmcArgs = '-m '.$monitor['Id']; } return daemonStatus('zmc', $zmcArgs); } function zmaStatus($monitor) { if ( is_array($monitor) ) { $monitor = $monitor['Id']; } return daemonStatus('zma', "-m $monitor"); } function daemonCheck($daemon=false, $args=false) { $string = ZM_PATH_BIN.'/zmdc.pl check'; if ( $daemon ) { $string .= ' ' . $daemon; if ( $args ) $string .= ' '. $args; } $string = escapeshellcmd($string); $result = exec($string); return preg_match('/running/', $result); } function zmcCheck($monitor) { if ( $monitor['Type'] == 'Local' ) { $zmcArgs = '-d '.$monitor['Device']; } else { $zmcArgs = '-m '.$monitor['Id']; } return daemonCheck('zmc', $zmcArgs); } function zmaCheck($monitor) { if ( is_array($monitor) ) { $monitor = $monitor['Id']; } return daemonCheck('zma', "-m $monitor"); } function getImageSrc($event, $frame, $scale=SCALE_BASE, $captureOnly=false, $overwrite=false) { $Event = new ZM\Event($event); return $Event->getImageSrc($frame, $scale, $captureOnly, $overwrite); } function viewImagePath($path, $querySep='&') { return '?view=image'.$querySep.'path='.$path; } function createListThumbnail($event, $overwrite=false) { # Load the frame with the highest score to use as a thumbnail if ( !($frame = dbFetchOne('SELECT * FROM Frames WHERE EventId=? AND Score=? ORDER BY FrameId LIMIT 1', NULL, array($event['Id'], $event['MaxScore']) )) ) return false; $frameId = $frame['FrameId']; if ( ZM_WEB_LIST_THUMB_WIDTH ) { $thumbWidth = ZM_WEB_LIST_THUMB_WIDTH; $scale = (SCALE_BASE*ZM_WEB_LIST_THUMB_WIDTH)/$event['Width']; $thumbHeight = reScale($event['Height'], $scale); } elseif ( ZM_WEB_LIST_THUMB_HEIGHT ) { $thumbHeight = ZM_WEB_LIST_THUMB_HEIGHT; $scale = (SCALE_BASE*ZM_WEB_LIST_THUMB_HEIGHT)/$event['Height']; $thumbWidth = reScale($event['Width'], $scale); } else { ZM\Fatal('No thumbnail width or height specified, please check in Options->Web'); } $imageData = getImageSrc($event, $frame, $scale, false, $overwrite); if ( !$imageData ) { return false; } $thumbData = $frame; $thumbData['Path'] = $imageData['thumbPath']; $thumbData['Width'] = (int)$thumbWidth; $thumbData['Height'] = (int)$thumbHeight; return $thumbData; } function createVideo($event, $format, $rate, $scale, $overwrite=false) { $command = ZM_PATH_BIN.'/zmvideo.pl -e '.$event['Id'].' -f '.$format.' -r '.sprintf('%.2F', ($rate/RATE_BASE)); if ( preg_match('/\d+x\d+/', $scale) ) $command .= ' -S '.$scale; else if ( version_compare(phpversion(), '4.3.10', '>=') ) $command .= ' -s '.sprintf('%.2F', ($scale/SCALE_BASE)); else $command .= ' -s '.sprintf('%.2f', ($scale/SCALE_BASE)); if ( $overwrite ) $command .= ' -o'; $command = escapeshellcmd($command); $result = exec($command, $output, $status); ZM\Logger::Debug("generating Video $command: result($result outptu:(".implode("\n", $output )." status($status"); return $status ? '' : rtrim($result); } # This takes more than one scale amount, so it runs through each and alters dimension. # I can't imagine why you would want to do that. function reScale($dimension, $dummy) { $new_dimension = $dimension; for ( $i = 1; $i < func_num_args(); $i++ ) { $scale = func_get_arg($i); if ( !empty($scale) && ($scale != '0') && ($scale != 'auto') && ($scale != SCALE_BASE) ) $new_dimension = (int)(($new_dimension*$scale)/SCALE_BASE); } return $new_dimension; } function deScale($dimension, $dummy) { $new_dimension = $dimension; for ( $i = 1; $i < func_num_args(); $i++ ) { $scale = func_get_arg($i); if ( !empty($scale) && $scale != SCALE_BASE ) $new_dimension = (int)(($new_dimension*SCALE_BASE)/$scale); } return $new_dimension; } function monitorLimitSql() { global $user; if ( !empty($user['MonitorIds']) ) $midSql = ' AND MonitorId IN ('.join(',', preg_split('/["\'\s]*,["\'\s]*/', $user['MonitorIds'])).')'; else $midSql = ''; return $midSql; } function parseSort($saveToSession=false, $querySep='&') { global $sortQuery, $sortColumn, $sortOrder, $limitQuery; // Outputs if ( isset($_REQUEST['filter']['Query']['sort_field']) ) { //Handle both new and legacy filter passing $_REQUEST['sort_field'] = $_REQUEST['filter']['Query']['sort_field']; } if ( isset($_REQUEST['filter']['Query']['sort_asc']) ) { $_REQUEST['sort_asc'] = $_REQUEST['filter']['Query']['sort_asc']; } if ( isset($_REQUEST['filter']['Query']['limit']) ) { $_REQUEST['limit'] = $_REQUEST['filter']['Query']['limit']; } if ( empty($_REQUEST['sort_field']) ) { $_REQUEST['sort_field'] = ZM_WEB_EVENT_SORT_FIELD; $_REQUEST['sort_asc'] = (ZM_WEB_EVENT_SORT_ORDER == 'asc'); } switch( $_REQUEST['sort_field'] ) { case 'Id' : $sortColumn = 'E.Id'; break; case 'MonitorName' : $sortColumn = 'M.Name'; break; case 'Name' : $sortColumn = 'E.Name'; break; case 'Cause' : $sortColumn = 'E.Cause'; break; case 'DateTime' : $sortColumn = 'E.StartTime'; $_REQUEST['sort_field'] = 'StartTime'; break; case 'DiskSpace' : $sortColumn = 'E.DiskSpace'; break; case 'StartTime' : $sortColumn = 'E.StartTime'; break; case 'StartDateTime' : $sortColumn = 'E.StartTime'; break; case 'EndTime' : $sortColumn = 'E.EndTime'; break; case 'EndDateTime' : $sortColumn = 'E.EndTime'; break; case 'Length' : $sortColumn = 'E.Length'; break; case 'Frames' : $sortColumn = 'E.Frames'; break; case 'AlarmFrames' : $sortColumn = 'E.AlarmFrames'; break; case 'TotScore' : $sortColumn = 'E.TotScore'; break; case 'AvgScore' : $sortColumn = 'E.AvgScore'; break; case 'MaxScore' : $sortColumn = 'E.MaxScore'; break; case 'FramesFrameId' : $sortColumn = 'F.FrameId'; break; case 'FramesType' : $sortColumn = 'F.Type'; break; case 'FramesTimeStamp' : $sortColumn = 'F.TimeStamp'; break; case 'FramesDelta' : $sortColumn = 'F.Delta'; break; case 'FramesScore' : $sortColumn = 'F.Score'; break; default: $sortColumn = 'E.StartTime'; break; } if ( !isset($_REQUEST['sort_asc']) ) $_REQUEST['sort_asc'] = 0; $sortOrder = $_REQUEST['sort_asc'] ? 'asc' : 'desc'; $sortQuery = $querySep.'sort_field='.validHtmlStr($_REQUEST['sort_field']).$querySep.'sort_asc='.validHtmlStr($_REQUEST['sort_asc']); if ( !isset($_REQUEST['limit']) ) $_REQUEST['limit'] = ''; if ( $saveToSession ) { $_SESSION['sort_field'] = validHtmlStr($_REQUEST['sort_field']); $_SESSION['sort_asc'] = validHtmlStr($_REQUEST['sort_asc']); } if ($_REQUEST['limit'] != '') { $limitQuery = '&limit='.validInt($_REQUEST['limit']); } } function getFilterQueryConjunctionTypes() { return array( 'and' => translate('ConjAnd'), 'or' => translate('ConjOr') ); } function parseFilter(&$filter, $saveToSession=false, $querySep='&') { $filter['query'] = ''; $filter['sql'] = ''; $filter['fields'] = ''; $validQueryConjunctionTypes = getFilterQueryConjunctionTypes(); $StorageArea = NULL; # It is not possible to pass an empty array in the url, so we have to deal with there not being a terms field. $terms = (isset($filter['Query']) and isset($filter['Query']['terms']) and is_array($filter['Query']['terms'])) ? $filter['Query']['terms'] : array(); if ( count($terms) ) { for ( $i = 0; $i < count($terms); $i++ ) { $term = $terms[$i]; if ( isset($term['cnj']) && array_key_exists($term['cnj'], $validQueryConjunctionTypes) ) { $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cnj]").'='.urlencode($term['cnj']); $filter['sql'] .= ' '.$term['cnj'].' '; $filter['fields'] .= "\n"; } if ( isset($term['obr']) && (string)(int)$term['obr'] == $term['obr'] ) { $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][obr]").'='.urlencode($term['obr']); $filter['sql'] .= ' '.str_repeat('(', $term['obr']).' '; $filter['fields'] .= "\n"; } if ( isset($term['attr']) ) { $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][attr]").'='.urlencode($term['attr']); $filter['fields'] .= "\n"; switch ( $term['attr'] ) { case 'AlarmedZoneId': $term['op'] = 'EXISTS'; break; case 'MonitorName': $filter['sql'] .= 'M.Name'; break; case 'ServerId': case 'MonitorServerId': $filter['sql'] .= 'M.ServerId'; break; case 'StorageServerId': $filter['sql'] .= 'S.ServerId'; break; case 'FilterServerId': $filter['sql'] .= ZM_SERVER_ID; break; # Unspecified start or end, so assume start, this is to support legacy filters case 'DateTime': $filter['sql'] .= 'E.StartTime'; break; case 'Date': $filter['sql'] .= 'to_days(E.StartTime)'; break; case 'Time': $filter['sql'] .= 'extract(hour_second FROM E.StartTime)'; break; case 'Weekday': $filter['sql'] .= 'weekday(E.StartTime)'; break; # Starting Time case 'StartDateTime': $filter['sql'] .= 'E.StartTime'; break; case 'FramesEventId': $filter['sql'] .= 'F.EventId'; break; case 'StartDate': $filter['sql'] .= 'to_days(E.StartTime)'; break; case 'StartTime': $filter['sql'] .= 'extract(hour_second FROM E.StartTime)'; break; case 'StartWeekday': $filter['sql'] .= 'weekday(E.StartTime)'; break; # Ending Time case 'EndDateTime': $filter['sql'] .= 'E.EndTime'; break; case 'EndDate': $filter['sql'] .= 'to_days(E.EndTime)'; break; case 'EndTime': $filter['sql'] .= 'extract(hour_second FROM E.EndTime)'; break; case 'EndWeekday': $filter['sql'] .= 'weekday(E.EndTime)'; break; case 'Id': case 'Name': case 'DiskSpace': case 'MonitorId': case 'StorageId': case 'SecondaryStorageId': case 'Length': case 'Frames': case 'AlarmFrames': case 'TotScore': case 'AvgScore': case 'MaxScore': case 'Cause': case 'Notes': case 'StateId': case 'Archived': $filter['sql'] .= 'E.'.$term['attr']; break; case 'DiskPercent': // Need to specify a storage area, so need to look through other terms looking for a storage area, else we default to ZM_EVENTS_PATH if ( ! $StorageArea ) { for ( $j = 0; $j < count($terms); $j++ ) { if ( isset($terms[$j]['attr']) and ($terms[$j]['attr'] == 'StorageId') and isset($terms[$j]['val']) ) { $StorageArea = ZM\Storage::find_one(array('Id'=>$terms[$j]['val'])); break; } } // end foreach remaining term if ( ! $StorageArea ) $StorageArea = new ZM\Storage(); } // end no StorageArea found yet $filter['sql'] .= getDiskPercent($StorageArea->Path()); break; case 'DiskBlocks': // Need to specify a storage area, so need to look through other terms looking for a storage area, else we default to ZM_EVENTS_PATH if ( ! $StorageArea ) { for ( $j = $i; $j < count($terms); $j++ ) { if ( isset($terms[$j]['attr']) and ($terms[$j]['attr'] == 'StorageId') and isset($terms[$j]['val']) ) { $StorageArea = ZM\Storage::find_one(array('Id'=>$terms[$j]['val'])); } } // end foreach remaining term } // end no StorageArea found yet $filter['sql'] .= getDiskBlocks( $StorageArea ); break; case 'SystemLoad': $filter['sql'] .= getLoad(); break; } $valueList = array(); if ( !isset($term['val']) ) $term['val'] = ''; foreach ( preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $term['val'])) as $value ) { switch ( $term['attr'] ) { case 'AlarmedZoneId': $value = '(SELECT * FROM Stats WHERE EventId=E.Id AND ZoneId='.$value.')'; break; case 'MonitorName': case 'Name': case 'Cause': case 'Notes': if ( $term['op'] == 'LIKE' || $term['op'] == 'NOT LIKE' ) { $value = '%'.$value.'%'; } $value = dbEscape($value); break; case 'MonitorServerId': case 'FilterServerId': case 'StorageServerId': case 'ServerId': if ( $value == 'ZM_SERVER_ID' ) { $value = ZM_SERVER_ID; } else if ( $value == 'NULL' ) { } else { $value = dbEscape($value); } break; case 'StorageId': $StorageArea = ZM\Storage::find_one(array('Id'=>$value)); if ( $value != 'NULL' ) $value = dbEscape($value); break; case 'DateTime': case 'StartDateTime': case 'EndDateTime': if ( $value != 'NULL' ) $value = '\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\''; break; case 'Date': case 'StartDate': case 'EndDate': if ( $value == 'CURDATE()' or $value == 'NOW()' ) { $value = 'to_days('.$value.')'; } else if ( $value != 'NULL' ) { $value = 'to_days(\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')'; } break; case 'Time': case 'StartTime': case 'EndTime': if ( $value != 'NULL' ) $value = 'extract(hour_second from \''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')'; break; default : if ( $value != 'NULL' ) $value = dbEscape($value); break; } $valueList[] = $value; } // end foreach value switch ( $term['op'] ) { case '=' : case '!=' : case '>=' : case '>' : case '<' : case '<=' : case 'LIKE' : case 'NOT LIKE': $filter['sql'] .= ' '.$term['op'].' '. $value; break; case '=~' : $filter['sql'] .= ' regexp '.$value; break; case '!~' : $filter['sql'] .= ' not regexp '.$value; break; case '=[]' : case 'IN' : $filter['sql'] .= ' IN ('.join(',', $valueList).')'; break; case '![]' : $filter['sql'] .= ' not in ('.join(',', $valueList).')'; break; case 'EXISTS' : $filter['sql'] .= ' EXISTS ' .$value; break; case 'IS' : if ( $value == 'Odd' ) { $filter['sql'] .= ' % 2 = 1'; } else if ( $value == 'Even' ) { $filter['sql'] .= ' % 2 = 0'; } else { $filter['sql'] .= " IS $value"; } break; case 'IS NOT' : $filter['sql'] .= " IS NOT $value"; break; default: ZM\Warning('Invalid operator in filter: ' . print_r($term['op'], true)); } // end switch op $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][op]").'='.urlencode($term['op']); $filter['fields'] .= "\n"; if ( isset($term['val']) ) { $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][val]").'='.urlencode($term['val']); $filter['fields'] .= "\n"; } } // end if isset($term['attr']) if ( isset($term['cbr']) && (string)(int)$term['cbr'] == $term['cbr'] ) { $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cbr]").'='.urlencode($term['cbr']); $filter['sql'] .= ' '.str_repeat(')', $term['cbr']); $filter['fields'] .= "\n"; } } // end foreach term if ( $filter['sql'] ) $filter['sql'] = ' AND ( '.$filter['sql'].' )'; if ( $saveToSession ) { $_SESSION['filter'] = $filter; } } else { $filter['query'] = $querySep; #.urlencode('filter[Query][terms]=[]'); } // end if terms #if ( 0 ) { #// ICON I feel like these should be here, but not yet #if ( isset($filter['Query']['sort_field']) ) { #$filter['sql'] .= ' ORDER BY ' . $filter['Query']['sort_field'] . ( #( $filter['Query']['sort_asc'] ? ' ASC' : ' DESC' ) ); #} #if ( $filter['Query']['limit'] ) { #$filter['sql'] .= ' LIMIT ' . validInt($filter['Query']['limit']); #} #} } // end function parseFilter(&$filter, $saveToSession=false, $querySep='&') // Please note that the filter is passed in by copy, so you need to use the return value from this function. // function addFilterTerm($filter, $position, $term=false) { if ( $position < 0 ) $position = 0; if ( !isset($filter['Query']['terms']) ) $filter['Query']['terms'] = array(); else if ( $position > count($filter['Query']['terms']) ) $position = count($filter['Query']['terms']); if ( $term && $position == 0 ) unset($term['cnj']); array_splice($filter['Query']['terms'], $position, 0, array($term ? $term : array())); return $filter; } function delFilterTerm($filter, $position) { if ( $position < 0 ) $position = 0; else if ( $position >= count($filter['Query']['terms']) ) $position = count($filter['Query']['terms']); array_splice($filter['Query']['terms'], $position, 1); return $filter; } function getPagination($pages, $page, $maxShortcuts, $query, $querySep='&') { global $view; $pageText = ''; if ( $pages > 1 ) { if ( $page ) { if ( $page < 0 ) $page = 1; if ( $page > $pages ) $page = $pages; if ( $page > 1 ) { if ( false && $page > 2 ) { $pageText .= '<<'; } $pageText .= '<'; $newPages = array(); $pagesUsed = array(); $lo_exp = max(2,log($page-1)/log($maxShortcuts)); for ( $i = 0; $i < $maxShortcuts; $i++ ) { $newPage = round($page-pow($lo_exp,$i)); if ( isset($pagesUsed[$newPage]) ) continue; if ( $newPage <= 1 ) break; $pagesUsed[$newPage] = true; array_unshift($newPages, $newPage); } if ( !isset($pagesUsed[1]) ) array_unshift( $newPages, 1 ); foreach ( $newPages as $newPage ) { $pageText .= ''.$newPage.' '; } } # end if page > 1 $pageText .= '- '.$page.' -'; if ( $page < $pages ) { $newPages = array(); $pagesUsed = array(); $hi_exp = max(2,log($pages-$page)/log($maxShortcuts)); for ( $i = 0; $i < $maxShortcuts; $i++ ) { $newPage = round($page+pow($hi_exp,$i)); if ( isset($pagesUsed[$newPage]) ) continue; if ( $newPage > $pages ) break; $pagesUsed[$newPage] = true; array_push($newPages, $newPage); } if ( !isset($pagesUsed[$pages]) ) array_push($newPages, $pages); foreach ( $newPages as $newPage ) { $pageText .= ' '.$newPage.''; } $pageText .= '>'; if ( false && $page < ($pages-1) ) { $pageText .= '>>'; } } # end if $page < $pages } } return $pageText; } function sortHeader($field, $querySep='&') { global $view; return implode($querySep, array( '?view='.$view, 'page=1'.(isset($_REQUEST['filter'])?$_REQUEST['filter']['query']:''), 'sort_field='.$field, 'sort_asc='.($_REQUEST['sort_field'] == $field ? !$_REQUEST['sort_asc'] : 0), 'limit='.validInt($_REQUEST['limit']), (isset($_REQUEST['eid']) ? 'eid='.$_REQUEST['eid'] : '' ), )); } function sortTag( $field ) { if ( $_REQUEST['sort_field'] == $field ) if ( $_REQUEST['sort_asc'] ) return '(^)'; else return '(v)'; return false; } function getLoad() { $load = sys_getloadavg(); return $load[0]; } function getDiskPercent($path = ZM_DIR_EVENTS) { $total = disk_total_space($path); if ( $total === false ) { ZM\Error('disk_total_space returned false. Verify the web account user has access to ' . $path); return 0; } elseif ( $total == 0 ) { ZM\Error('disk_total_space indicates the following path has a filesystem size of zero bytes ' . $path); return 100; } $free = disk_free_space($path); if ( $free === false ) { ZM\Error('disk_free_space returned false. Verify the web account user has access to ' . $path); } $space = round((($total - $free) / $total) * 100); return $space; } function getDiskBlocks() { if ( !$StorageArea ) $StorageArea = new ZM\Storage(); $df = shell_exec('df '.escapeshellarg($StorageArea->Path())); $space = -1; if ( preg_match('/\s(\d+)\s+\d+\s+\d+%/ms', $df, $matches) ) $space = $matches[1]; return $space; } function systemStats() { $load = getLoad(); $diskPercent = getDiskPercent(); $pathMapPercent = getDiskPercent(ZM_PATH_MAP); $cpus = getcpus(); $normalized_load = $load / $cpus; # Colorize the system load stat if ( $normalized_load <= 0.75 ) { $htmlLoad = $load; } else if ( $normalized_load <= 0.9 ) { $htmlLoad = "$load"; } else if ( $normalized_load <= 1.1 ) { $htmlLoad = "$load"; } else { $htmlLoad = "$load"; } # Colorize the disk space stat if ( $diskPercent < 98 ) { $htmlDiskPercent = $diskPercent.'%'; } else if ( $diskPercent <= 99 ) { $htmlDiskPercent = "$diskPercent%"; } else { $htmlDiskPercent = "$diskPercent%"; } # Colorize the PATH_MAP (usually /dev/shm) stat if ( $pathMapPercent < 90 ) { if ( disk_free_space(ZM_PATH_MAP) > 209715200 ) { # have to always have at least 200MiB free $htmlPathMapPercent = $pathMapPercent.'%'; } else { $htmlPathMapPercent = "$pathMapPercent%"; } } else if ( $pathMapPercent < 100 ) { $htmlPathMapPercent = "$pathMapPercent%"; } else { $htmlPathMapPercent = "$pathMapPercent%"; } $htmlString = translate('Load').": $htmlLoad - ".translate('Disk').": $htmlDiskPercent - ".ZM_PATH_MAP.": $htmlPathMapPercent"; return $htmlString; } function getcpus() { if ( is_readable('/proc/cpuinfo') ) { # Works on Linux preg_match_all('/^processor/m', file_get_contents('/proc/cpuinfo'), $matches); $num_cpus = count($matches[0]); } else { # Works on BSD $matches = explode(':', shell_exec('sysctl hw.ncpu')); $num_cpus = trim($matches[1]); } return $num_cpus; } // Function to fix a problem whereby the built in PHP session handling // features want to put the sid as a hidden field after the form or // fieldset tag, neither of which will work with strict XHTML Basic. function sidField() { if ( SID ) { list($sessname, $sessid) = explode('=', SID); ?> '; return false; } $dx1 = $line1[1]['x'] - $line1[0]['x']; $dy1 = $line1[1]['y'] - $line1[0]['y']; $dx2 = $line2[1]['x'] - $line2[0]['x']; $dy2 = $line2[1]['y'] - $line2[0]['y']; if ( $dx1 ) { $m1 = $dy1/$dx1; $b1 = $line1[0]['y'] - ($m1 * $line1[0]['x']); } else { $b1 = $line1[0]['y']; } if ( $dx2 ) { $m2 = $dy2/$dx2; $b2 = $line2[0]['y'] - ($m2 * $line2[0]['x']); } else { $b2 = $line2[0]['y']; } if ( $dx1 && $dx2 ) { // Both not vertical if ( $m1 != $m2 ) { // Not parallel or colinear $x = ( $b2 - $b1 ) / ( $m1 - $m2 ); if ( $x >= $min_x1 && $x <= $max_x1 && $x >= $min_x2 && $x <= $max_x2 ) { if ( $debug ) echo "Intersecting, at x $x