* Copyright 2001-2012 Strangecode, LLC
*
* This file is part of The Strangecode Codebase.
*
* The Strangecode Codebase is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* The Strangecode Codebase is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* The Strangecode Codebase. If not, see .
*/
/**
* logs.php
*/
// Redefine include_path including the codebase/services but allow local templates override global ones.
ini_set('include_path', join(PATH_SEPARATOR, array(
get_include_path(),
dirname(__FILE__) . '/templates'
)));
$auth->requireLogin();
require_once 'codebase/lib/PageNumbers.inc.php';
require_once 'codebase/lib/SortOrder.inc.php';
require_once 'codebase/lib/TemplateGlue.inc.php';
require_once 'codebase/lib/Prefs.inc.php';
require_once 'codebase/lib/Upload.inc.php';
/******************************************************************************
* CODE CONFIG
*****************************************************************************/
// Files with these extensions will be displayed at the top of the log list.
$valid_file_extensions = array('', 'txt', 'log');
// Files that shouldn't be deleted (preg search expressions).
$no_delete_files = '/^php_error_log$|^access_log$|^error_log$|^ssl_request_log$/';
// Files that shouldn't be cleared (preg search expressions).
$no_clear_files = '/__|^access_log$|^error_log$|^ssl_request_log$/';
// Files that shouldn't be archived (preg search expressions).
$no_archive_files = '/__|^access_log$|^error_log$|^ssl_request_log$/';
// Files that shouldn't be downloaded (preg search expressions).
$no_download_files = '/^$/';
// Configure the prefs object.
$tmp_prefs = new Prefs('admin_logs');
$tmp_prefs->setParam(array('persistent' => false));
$tmp_prefs->setDefaults(array(
'log_file' => $app->getParam('log_filename')
));
if (getFormData('log', false)) {
$tmp_prefs->set('log_file', getFormData('log'));
}
// Titles and navigation header.
$nav->add(sprintf(_("Viewing %s"), oTxt($tmp_prefs->get('log_file'))), '/admin/logs.php');
$nav->set('id', 'logs');
/********************************************************************
* MAIN
********************************************************************/
// Allow realtime file stats.
clearstatcache();
// What action to take.
switch (getFormData('op')) {
case 'delete' :
deleteLog($tmp_prefs->get('log_file'));
$tmp_prefs->set('log_file', $app->getParam('log_filename'));
if ($app->validBoomerangURL('app_log')) {
// Display boomerang page.
$app->dieBoomerangURL('app_log');
}
// Display default page.
$app->dieURL($_SERVER['PHP_SELF']);
break;
case 'clear' :
clearLog($tmp_prefs->get('log_file'));
if ($app->validBoomerangURL('app_log')) {
// Display boomerang page.
$app->dieBoomerangURL('app_log');
}
// Display default page.
$app->dieURL($_SERVER['PHP_SELF']);
break;
case 'archive' :
if (archiveLog($tmp_prefs->get('log_file'))) {
// Now flush current log.
$app->dieURL($_SERVER['PHP_SELF'] . '?op=clear');
}
if ($app->validBoomerangURL('app_log')) {
// Display boomerang page.
$app->dieBoomerangURL('app_log');
}
// Display default page.
$app->dieURL($_SERVER['PHP_SELF']);
break;
// case 'output' :
// $main_template = 'output';
// break;
case 'download' :
header('Content-Type: application/octet-stream');
header(sprintf('Content-Disposition: attachment; filename=%s.txt', $tmp_prefs->get('log_file')));
printLog($tmp_prefs->get('log_file'));
die;
break;
default :
$list =& getLog($tmp_prefs->get('log_file'), getFormData('search_query'));
$main_template = 'log_list.ihtml';
break;
}
/******************************************************************************
* TEMPLATE INITIALIZATION
*****************************************************************************/
$logs = &getLogList();
// Instantiate page numbers. Total items are set and calculation is done in the getRecordList function.
$page = new PageNumbers();
$page->setPerPage(getFormData('per_page'), 500);
$page->setPageNumber(getFormData('page_number'));
$page->setTotalItems(sizeof($list));
$page->per_page_options = array(100, 250, 500, 600, 800, 1000, 2000, 5000, 10000);
$page->calculate();
include 'header.' . $app->getParam('template_ext');
if ('output' == $main_template) {
printLog($tmp_prefs->get('log_file'));
} else {
include $main_template;
}
include 'footer.' . $app->getParam('template_ext');
/********************************************************************
* FUNCTIONS
********************************************************************/
function deleteLog($log_file)
{
$app =& App::getInstance();
if (!file_exists($app->getParam('log_directory') . '/' . $log_file)) {
$app->raiseMsg(sprintf(_("Log file %s does not exist."), $log_file), MSG_NOTICE, __FILE__, __LINE__);
$app->logMsg(sprintf('Cannot delete nonexistent log file %s', $app->getParam('log_directory') . '/' . $log_file), LOG_INFO, __FILE__, __LINE__);
return false;
}
if (!is_writable($app->getParam('log_directory') . '/' . $log_file) && !is_writable($app->getParam('log_directory'))) {
$app->raiseMsg(sprintf(_("Log file %s could not be deleted."), $log_file), MSG_NOTICE, __FILE__, __LINE__);
$app->logMsg(sprintf('Cannot delete log file %s, not writable.', $app->getParam('log_directory') . '/' . $log_file), LOG_INFO, __FILE__, __LINE__);
return false;
}
if (unlink($app->getParam('log_directory') . '/' . $log_file)) {
$app->raiseMsg(sprintf(_("Log file %s has been deleted."), $log_file), MSG_NOTICE, __FILE__, __LINE__);
$app->logMsg(sprintf('Log file %s has been deleted', $log_file), LOG_INFO, __FILE__, __LINE__);
return true;
} else {
$app->raiseMsg(sprintf(_("Log file %s could not be deleted."), $log_file), MSG_WARNING, __FILE__, __LINE__);
$app->logMsg(sprintf('unlink failed on log file %s', $app->getParam('log_directory') . '/' . $log_file), LOG_WARNING, __FILE__, __LINE__);
return false;
}
}
function clearLog($log_file)
{
$app =& App::getInstance();
if (!$fp = fopen($app->getParam('log_directory') . '/' . $log_file, 'r+')) {
$app->raiseMsg(sprintf(_("Log file %s could not be opened."), $log_file), MSG_NOTICE, __FILE__, __LINE__);
$app->logMsg(sprintf('fopen failed on log file %s', $app->getParam('log_directory') . '/' . $log_file), LOG_INFO, __FILE__, __LINE__);
return false;
}
flock($fp, LOCK_EX);
$ftruncate_return = ftruncate($fp, 0);
flock($fp, LOCK_UN);
fclose($fp);
if (!$ftruncate_return) {
$app->raiseMsg(sprintf(_("Log file %s could not be cleared."), $log_file), MSG_WARNING, __FILE__, __LINE__);
$app->logMsg(sprintf('ftruncate failed on log file %s', $app->getParam('log_directory') . '/' . $log_file), LOG_WARNING, __FILE__, __LINE__);
return false;
} else {
$app->raiseMsg(sprintf(_("Log file %s has been cleared."), $log_file), MSG_NOTICE, __FILE__, __LINE__);
$app->logMsg(sprintf('Log file %s has been cleared', $log_file), LOG_INFO, __FILE__, __LINE__);
return true;
}
}
function archiveLog($log_file)
{
$app =& App::getInstance();
$old_file_name = $log_file;
$new_file_name = $log_file . '__' . date('Y-m-d');
If (!is_writable($app->getParam('log_directory') . '')) {
$app->raiseMsg(sprintf('Cannot archive log, log directory not writable: %s', $app->getParam('log_directory')), MSG_WARNING, __FILE__, __LINE__);
$app->logMsg(sprintf('Cannot archive log, log directory not writable: %s', $app->getParam('log_directory')), LOG_WARNING, __FILE__, __LINE__);
return false;
}
If (!copy($app->getParam('log_directory') . '/' . $old_file_name, $app->getParam('log_directory') . '/' . $new_file_name)) {
$app->raiseMsg(sprintf(_("Cannot archive log, copying old log file failed."), null), MSG_WARNING, __FILE__, __LINE__);
$app->logMsg(sprintf('Cannot archive log, copying old log file failed.', null), LOG_WARNING, __FILE__, __LINE__);
return false;
}
$app->raiseMsg(sprintf(_("Log file %s has been archived to %s."), $old_file_name, $new_file_name), MSG_NOTICE, __FILE__, __LINE__);
$app->logMsg(sprintf('Log file %s has been archived to %s.', $old_file_name, $new_file_name), LOG_NOTICE, __FILE__, __LINE__);
return true;
}
function printLog($log_file)
{
$app =& App::getInstance();
if (!is_file($app->getParam('log_directory') . '/' . $log_file)) {
$app->raiseMsg(sprintf(_("Log file %s not found."), $log_file), MSG_WARNING, __FILE__, __LINE__);
$app->logMsg(sprintf('Log file %s not found.', $app->getParam('log_directory') . '/' . $log_file), LOG_WARNING, __FILE__, __LINE__);
return false;
}
readfile($app->getParam('log_directory') . '/' . $log_file);
}
function &getLog($log_file, $search_query='')
{
$app =& App::getInstance();
$log = array();
if (!is_file($app->getParam('log_directory') . '/' . $log_file)) {
$app->raiseMsg(sprintf(_("Log file %s not found."), $log_file), MSG_WARNING, __FILE__, __LINE__);
$app->logMsg(sprintf('Log file %s not found.', $app->getParam('log_directory') . '/' . $log_file), LOG_WARNING, __FILE__, __LINE__);
return $log;
}
$log = file($app->getParam('log_directory') . '/' . $log_file);
if (isset($search_query) && '' != trim($search_query)) {
if (getFormData('search_grep')) {
$log = preg_grep('/' . str_replace('/', '\/', $search_query) . '/', $log);
} else {
$log = preg_grep('/' . preg_quote($search_query, '/') . '/i', $log);
}
}
$log = array_values($log);
return $log;
}
function &getLogList()
{
global $valid_file_extensions;
$app =& App::getInstance();
// Get a list of all files in the log directory.
$dir_handle = opendir($app->getParam('log_directory'));
$list = array();
while ($dir_handle && ($file = readdir($dir_handle)) !== false) {
if (!preg_match('/^\./', $file) && is_file($app->getParam('log_directory') . '/' . $file) && in_array(mb_strtolower(Upload::getFilenameExtension($file)), $valid_file_extensions)) {
$list[] = array(
'filename' => $file,
'filesize' => filesize($app->getParam('log_directory') . '/' . $file),
'modified' => filemtime($app->getParam('log_directory') . '/' . $file),
);
}
}
if (is_array($list) && !empty($list)) {
sort($list);
}
return $list;
}