Beispiel #1
0
	public function __construct()
	{
		$this->object	= 'dir';
		$this->subtype	= 'children';
		$this->method	= 'direct';
		$this->filter_name = 'PlatformSkipdirs';

		// We take advantage of the filter class magic to inject our custom filters
		$configuration =& AEFactory::getConfiguration();
		if(defined('AKEEBACLI'))
		{
			$tmpdir = AEUtilJconfig::getValue('tmp_path');
		}
		else
		{
			$jreg =& JFactory::getConfig();
			$tmpdir = $jreg->getValue('config.tmp_path');
		}

		$this->filter_data['[SITEROOT]'] = array (
			// Output & temp directory of the component
			self::treatDirectory($configuration->get('akeeba.basic.output_directory')),
			self::treatDirectory($configuration->get('akeeba.basic.temporary_directory')),
			// Joomla! temporary directory
			self::treatDirectory($tmpdir),
			// Joomla! front- and back-end cache, as reported by Joomla!
			self::treatDirectory(JPATH_CACHE),
			self::treatDirectory(JPATH_ADMINISTRATOR.DS.'cache'),
			self::treatDirectory(JPATH_ROOT.DS.'cache'),
			// This is not needed except on sites running SVN or beta releases
			self::treatDirectory(JPATH_ROOT.DS.'installation'),
			// Joomla! front- and back-end cache, as calculated by us (redundancy, for funky server setups)
			self::treatDirectory( AEPlatform::get_site_root().DS.'cache' ),
			self::treatDirectory( AEPlatform::get_site_root().DS.'administrator'.DS.'cache'),
			'administrator/components/com_akeeba/backup',
			// MyBlog's cache
			self::treatDirectory( AEPlatform::get_site_root().DS.'components'.DS.'libraries'.DS.'cmslib'.DS.'cache' ),
			// The logs directory
			'logs'
		);

		parent::__construct();
	}
Beispiel #2
0
	/**
	 * Scans a directory for files and directories, updating the directory_list and file_list
	 * private fields
	 *
	 * @return bool True if more work has to be done, false if the dirextory stack is empty
	 */
	private function scan_directory( )
	{
		// Are we supposed to scan for more files?
		if( $this->done_scanning ) return true;

		// Get the next directory to scan, if the folders and files of the last directory
		// have been scanned.
		if($this->done_subdir_scanning && $this->done_file_scanning)
		{
			if( count($this->directory_list) == 0 )
			{
				// No directories left to scan
				return false;
			}
			else
			{
				// Get and remove the last entry from the $directory_list array
				$this->current_directory = array_pop($this->directory_list);
				$this->setStep($this->current_directory);
				$this->done_subdir_scanning = false;
				$this->done_file_scanning = false;
				$this->processed_files_counter = 0;
			}
		}

		$engine =& AEFactory::getScanEngine();

		// Break directory components
		$root = $this->root;
		$translated_root = AEUtilFilesystem::TranslateWinPath($this->root);
		if($this->root == '[SITEROOT]') {
			$translated_root = AEUtilFilesystem::TranslateWinPath(AEPlatform::get_site_root());
		} else {
			$translated_root = $this->remove_path_prefix;
		}
		$dir = AEUtilFilesystem::TrimTrailingSlash($this->current_directory);
		if(substr($dir,0,strlen($translated_root)) == $translated_root)
			$dir = substr($dir,strlen($translated_root));
		if(substr($dir,0,1) == '/') $dir = substr($dir,1);

		// get a filters instance
		$filters =& AEFactory::getFilters();

		// Scan subdirectories, if they have not yet been scanned.
		if(!$this->done_subdir_scanning)
		{
			// Apply DEF (directory exclusion filters)
			//if (in_array( $this->current_directory, $this->_ExcludeDirs )) {
			if($filters->isFiltered($dir, $root, 'dir', 'all') ) {
				AEUtilLogger::WriteLog(_AE_LOG_INFO, "Skipping directory ".$this->current_directory);
				$this->done_subdir_scanning = true;
				$this->done_file_scanning = true;
				return true;
			}

			// Apply Skip Contained Directories Filters
			//if (in_array( $this->current_directory, $this->_skipContainedDirectories )) {
			if($filters->isFiltered($dir, $root, 'dir', 'children') ) {
				AEUtilLogger::WriteLog(_AE_LOG_INFO, "Skipping subdirectories of directory ".$this->current_directory);
				$this->done_subdir_scanning = true;
			}
			else
			{
				AEUtilLogger::WriteLog(_AE_LOG_INFO, "Scanning directories of ".$this->current_directory);
				
				// Get subdirectories
				$subdirs = $engine->getFolders($this->current_directory);
				// Error propagation
				$this->propagateFromObject($engine);

				// If the list contains "too many" items, please break this step!
				$registry =& AEFactory::getConfiguration();
				if($registry->get('volatile.breakflag', false))
				{
					// Log the step break decision, for debugging reasons
					AEUtilLogger::WriteLog(_AE_LOG_INFO, "Large directory ".$this->current_directory." while scanning for subdirectories; I will resume scanning in next step.");
					// Return immediately, marking that we are not done yet!
					return true;
				}

				// Error control
				if($this->getError())
				{
					return false;
				}

				if(!empty($subdirs) && is_array($subdirs))
				{
					$registry =& AEFactory::getConfiguration();
					$dereferencesymlinks = $registry->get('engine.archiver.common.dereference_symlinks');
					if($dereferencesymlinks)
					{
						// Treat symlinks to directories as actual directories
						foreach($subdirs as $subdir)
						{
							$this->directory_list[] = $subdir;
							$this->progressAddFolder();
						}
					}
					else
					{
						// Treat symlinks to directories as simple symlink files (ONLY WORKS WITH CERTAIN ARCHIVERS!)
						foreach($subdirs as $subdir)
						{
							if(is_link($subdir))
							{
								// Symlink detected; apply file filters to it
								if(empty($dir)) {
									$dirSlash = $dir;
								} else {
									$dirSlash = $dir.'/';
								}
								$check = $dir.basename($subdir);
								if(_AKEEBA_IS_WINDOWS) $check = AEUtilFilesystem::TranslateWinPath ($check);
								// Do I need this? $dir contains a path relative to the root anyway...
								$check = ltrim(str_replace($translated_root, '', $check),'/');
								if($filters->isFiltered($check, $root, 'file', 'all') ) {
									AEUtilLogger::WriteLog(_AE_LOG_INFO, "Skipping directory symlink ".$check);
								} else {
									AEUtilLogger::WriteLog(_AE_LOG_DEBUG, 'Adding symlink to folder as file: '.$check);
									$this->file_list[] = $subdir;
									$this->progressAddFile();
								}
							}
							else
							{
								$this->directory_list[] = $subdir;
								$this->progressAddFolder();
							}
						}
					}
				}
			}

			$this->done_subdir_scanning = true;
			return true; // Break operation
		}

		// If we are here, we have not yet scanned the directory for files, so there
		// is no need to test for done_file_scanning (saves a tiny amount of CPU time)

		// Apply Skipfiles
		if($filters->isFiltered($dir, $root, 'dir', 'content') ) {
			AEUtilLogger::WriteLog(_AE_LOG_INFO, "Skipping files of directory ".$this->current_directory);
			// Try to find and include .htaccess and index.htm(l) files
			// # Fix 2.4: Do not add DS if we are on the site's root and it's an empty string
			$ds = ($this->current_directory == '') || ($this->current_directory == '/') ? '' : DS;
			$checkForTheseFiles = array(
				$this->current_directory.$ds.'.htaccess',
				$this->current_directory.$ds.'index.html',
				$this->current_directory.$ds.'index.htm',
				$this->current_directory.$ds.'robots.txt'
			);
			$this->processed_files_counter = 0;
			foreach($checkForTheseFiles as $fileName)
			{
				if(@file_exists($fileName))
				{
					// Fix 3.3 - We have to also put them through other filters, ahem!
					if(!$filters->isFiltered($fileName, $root, 'file', 'all')) {
						$this->file_list[] = $fileName;
						$this->processed_files_counter++;
					}
				}
			}
			$this->done_file_scanning = true;
		}
		else
		{
			AEUtilLogger::WriteLog(_AE_LOG_INFO, "Scanning files of ".$this->current_directory);
			// Get file listing
			$fileList =& $engine->getFiles( $this->current_directory );
			// Error propagation
			$this->propagateFromObject($engine);

			// If the list contains "too many" items, please break this step!
			$registry =& AEFactory::getConfiguration();
			if($registry->get('volatile.breakflag', false))
			{
				// Log the step break decision, for debugging reasons
				AEUtilLogger::WriteLog(_AE_LOG_INFO, "Large directory ".$this->current_directory." while scanning for files; I will resume scanning in next step.");
				// Return immediately, marking that we are not done yet!
				return true;
			}

			// Error control
			if($this->getError())
			{
				return false;
			}

			$this->processed_files_counter = 0;

			if (($fileList === false)) {
				// A non-browsable directory; however, it seems that I never get FALSE reported here?!
				$this->setWarning('Unreadable directory '.$this->current_directory);
			}
			else
			{
				if(is_array($fileList) && !empty($fileList))
				{
					// Add required trailing slash to $dir
					if(!empty($dir)) $dir.='/';
					// Scan all directory entries
					foreach($fileList as $fileName) {
						$check = $dir.basename($fileName);
						if(_AKEEBA_IS_WINDOWS) $check = AEUtilFilesystem::TranslateWinPath ($check);
						// Do I need this? $dir contains a path relative to the root anyway...
						$check = ltrim(str_replace($translated_root, '', $check),'/');
						$skipThisFile = $filters->isFiltered($check, $root, 'file', 'all');
						if ($skipThisFile) {
							AEUtilLogger::WriteLog(_AE_LOG_INFO, "Skipping file $fileName");
						} else {
							$this->file_list[] = $fileName;
							$this->processed_files_counter++;
							$this->progressAddFile();
						}
					} // end foreach
				} // end if
			} // end filelist not false

			$this->done_file_scanning = true;
		}

		// Check to see if there were no contents of this directory added to our search list
		if ( $this->processed_files_counter == 0 ) {
			$archiver =& AEFactory::getArchiverEngine();
			if($this->current_directory != $this->remove_path_prefix) {
				$archiver->addFile($this->current_directory, $this->remove_path_prefix, $this->path_prefix);
			}

			// Error propagation
			$this->propagateFromObject($archiver);
			if($this->getError())
			{
				return false;
			}

			AEUtilLogger::WriteLog(_AE_LOG_INFO, "Empty directory ".$this->current_directory);
			unset($archiver);

			$this->done_scanning = false; // Because it was an empty dir $file_list is empty and we have to scan for more files
		}
		else
		{
			// Next up, add the files to the archive!
			$this->done_scanning = true;
		}

		// We're done listing the contents of this directory
		unset($engine);

		return true;
	}
Beispiel #3
0
	/**
	 * Q003 - HIGH - Backup output or temporary set to site's root
	 *
	 * @return bool
	 */
	private static function q003()
	{
		$stock_dirs = AEPlatform::get_stock_directories();

		$registry =& AEFactory::getConfiguration();
		$outdir = $registry->get('akeeba.basic.output_directory');
		foreach( $stock_dirs as $macro => $replacement )
		{
			$outdir = str_replace($macro, $replacement, $outdir);
		}
		$tempdir = $registry->get('akeeba.basic.temporary_directory');
		foreach( $stock_dirs as $macro => $replacement )
		{
			$tempdir = str_replace($macro, $replacement, $tempdir);
		}

		$outdir_real = @realpath($outdir);
		if(!empty($outdir_real)) $outdir = $outdir_real;
		$tempdir_real = @realpath($tempdir);
		if(!empty($tempdir_real)) $tempdir = $tempdir_real;

		$siteroot = AEPlatform::get_site_root();
		$siteroot_real = @realpath($siteroot);
		if(!empty($siteroot_real)) $siteroot = $siteroot_real;

		return ($siteroot == $outdir) || ($siteroot == $tempdir);
	}
Beispiel #4
0
	/**
	 * Writes a line to the log, if the log level is high enough
	 *
	 * @param int|bool $level The log level (_AE_LOG_XX constants). Use FALSE to pause logging, TRUE to resume logging
	 * @param string $message The message to write to the log
	 */
	static function WriteLog( $level, $message = '' )
	{
		static $oldLog = null;
		static $configuredLoglevel;
		static $site_root_untranslated;
		static $site_root;
		static $fp = null;

		// Make sure we have a log name
		if(empty(self::$logName))
		{
			self::$logName = self::logName();
		}

		// Check for log name changes
		if(is_null($oldLog)) {
			$oldLog = self::$logName;
		} elseif($oldLog != self::$logName) {
			// The log file changed. Close the old log.
			if(is_resource($fp)) @fclose($fp);
			$fp = null;
		}

		// Close the log file if the level is set to NULL
		if( is_null($level) && !is_null($fp) )
		{
			@fclose($fp);
			$fp = null;
			return;
		}

		if(empty($site_root) || empty($site_root_untranslated))
		{
			$site_root_untranslated = AEPlatform::get_site_root();
			$site_root = AEUtilFilesystem::TranslateWinPath( $site_root_untranslated );
		}

		if(empty($configuredLoglevel) or ($level === true))
		{
			// Load the registry and fetch log level
			$registry =& AEFactory::getConfiguration();
			$configuredLoglevel = $registry->get('akeeba.basic.log_level');
			$configuredLoglevel = $configuredLoglevel * 1;
			return;
		}

		if($level === false)
		{
			// Pause logging
			$configuredLogLevel = false;
			return;
		}

		// Catch paused logging
		if($configuredLoglevel === false) return;

		if( ($configuredLoglevel >= $level) && ($configuredLoglevel != 0))
		{
			$message = str_replace( $site_root_untranslated, "<root>", $message );
			$message = str_replace( $site_root, "<root>", $message );
			$message = str_replace( "\n", ' \n ', $message );
			switch( $level )
			{
				case _AE_LOG_ERROR:
					$string = "ERROR   |";
					break;
				case _AE_LOG_WARNING:
					$string = "WARNING |";
					break;
				case _AE_LOG_INFO:
					$string = "INFO    |";
					break;
				default:
					$string = "DEBUG   |";
					break;
			}
			$string .= @strftime( "%y%m%d %H:%M:%S" ) . "|$message\r\n";

			if(is_null($fp))
			{
				$fp = @fopen( AEUtilLogger::$logName, "a" );
			}

			if (!($fp === FALSE))
			{
				$result = @fwrite( $fp, $string );
				if($result === false) {
					// Try harder with the file pointer, will ya?
					$fp = @fopen( AEUtilLogger::$logName, "a" );
					$result = @fwrite( $fp, $string );
				}
			}
		}
	}