* 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 ('' != 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; }