Browse Source

Merge pull request #556 from jdarwood007/moveable-packages-dir

Moveable packages dir
Michael Eshom 10 years ago
parent
commit
20c2292bff

+ 3 - 0
.gitignore

@@ -5,6 +5,9 @@ cache/data*.php
 Packages/backups/*
 Packages/temp
 *.*~
+Packages/*.tgz
+Packages/*.tar.gz
+Packages/*.zip
 
 # Compiled source #
 ###################

+ 1 - 1
Sources/Class-Package.php

@@ -612,7 +612,7 @@ class xmlArray
 		$trans_tbl = array_flip(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES));
 
 		// Translate all the entities out.
-		$data = strtr(preg_replace_callback('~&#(\d{1,4});~e', create_function('$m', 'return chr("\$m[1]");'), $data), $trans_tbl);
+		$data = strtr(preg_replace_callback('~&#(\d{1,4});~', create_function('$m', 'return chr("\$m[1]");'), $data), $trans_tbl);
 
 		return $this->trim ? trim($data) : $data;
 	}

+ 2 - 2
Sources/DbPackages-sqlite.php

@@ -614,7 +614,7 @@ function smf_db_list_indexes($table_name, $detail = false, $parameters = array()
  */
 function smf_db_alter_table($table_name, $columns)
 {
-	global $smcFunc, $db_prefix, $db_name, $boarddir;
+	global $smcFunc, $db_prefix, $db_name, $boarddir, $packagesdir;
 
 	$db_file = substr($db_name, -3) === '.db' ? $db_name : $db_name . '.db';
 
@@ -666,7 +666,7 @@ function smf_db_alter_table($table_name, $columns)
 
 	// Let's make a backup of the current database.
 	// We only want the first backup of a table modification.  So if there is a backup file and older than an hour just delete and back up again
-	$db_backup_file = $boarddir . '/Packages/backups/backup_' . $table_name . '_' . basename($db_file) . md5($table_name . $db_file);
+	$db_backup_file = $packagesdir . '/backups/backup_' . $table_name . '_' . basename($db_file) . md5($table_name . $db_file);
 	if (file_exists($db_backup_file) && time() - filemtime($db_backup_file) > 3600)
 	{
 		@unlink($db_backup_file);

+ 21 - 21
Sources/ManageSmileys.php

@@ -1403,7 +1403,7 @@ function EditSmileyOrder()
  */
 function InstallSmileySet()
 {
-	global $sourcedir, $boarddir, $modSettings, $smcFunc, $scripturl, $context, $txt, $user_info;
+	global $sourcedir, $boarddir, $packagesdir, $modSettings, $smcFunc, $scripturl, $context, $txt, $user_info;
 
 	isAllowedTo('manage_smileys');
 	checkSession('request');
@@ -1427,7 +1427,7 @@ function InstallSmileySet()
 		if (preg_match('~^http://[\w_\-]+\.simplemachines\.org/~', $_REQUEST['set_gz']) == 0 || strpos($_REQUEST['set_gz'], 'dlattach') !== false)
 			fatal_lang_error('not_on_simplemachines');
 
-		$destination = $boarddir . '/Packages/' . $base_name;
+		$destination = $packagesdir . '/' . $base_name;
 
 		if (file_exists($destination))
 			fatal_lang_error('package_upload_error_exists');
@@ -1443,35 +1443,35 @@ function InstallSmileySet()
 		$name_pr = preg_replace(array('/\s/', '/\.[\.]+/', '/[^\w_\.\-]/'), array('_', '.', ''), $name);
 		$context['filename'] = $base_name;
 
-		$destination = $boarddir . '/Packages/' . basename($_REQUEST['package']);
+		$destination = $packagesdir . '/' . basename($_REQUEST['package']);
 	}
 
 	if (!file_exists($destination))
 		fatal_lang_error('package_no_file', false);
 
 	// Make sure temp directory exists and is empty.
-	if (file_exists($boarddir . '/Packages/temp'))
-		deltree($boarddir . '/Packages/temp', false);
+	if (file_exists($packagesdir . '/temp'))
+		deltree($packagesdir . '/temp', false);
 
-	if (!mktree($boarddir . '/Packages/temp', 0755))
+	if (!mktree($packagesdir . '/temp', 0755))
 	{
-		deltree($boarddir . '/Packages/temp', false);
-		if (!mktree($boarddir . '/Packages/temp', 0777))
+		deltree($packagesdir . '/temp', false);
+		if (!mktree($packagesdir . '/temp', 0777))
 		{
-			deltree($boarddir . '/Packages/temp', false);
+			deltree($packagesdir . '/temp', false);
 			// @todo not sure about url in destination_url
-			create_chmod_control(array($boarddir . '/Packages/temp/delme.tmp'), array('destination_url' => $scripturl . '?action=admin;area=smileys;sa=install;set_gz=' . $_REQUEST['set_gz'], 'crash_on_error' => true));
+			create_chmod_control(array($packagesdir . '/temp/delme.tmp'), array('destination_url' => $scripturl . '?action=admin;area=smileys;sa=install;set_gz=' . $_REQUEST['set_gz'], 'crash_on_error' => true));
 
-			deltree($boarddir . '/Packages/temp', false);
-			if (!mktree($boarddir . '/Packages/temp', 0777))
+			deltree($packagesdir . '/temp', false);
+			if (!mktree($packagesdir . '/temp', 0777))
 				fatal_lang_error('package_cant_download', false);
 		}
 	}
 
-	$extracted = read_tgz_file($destination, $boarddir . '/Packages/temp');
+	$extracted = read_tgz_file($destination, $packagesdir . '/temp');
 	if (!$extracted)
 		fatal_lang_error('packageget_unable', false, array('http://custom.simplemachines.org/mods/index.php?action=search;type=12;basic_search=' . $name));
-	if ($extracted && !file_exists($boarddir . '/Packages/temp/package-info.xml'))
+	if ($extracted && !file_exists($packagesdir . '/temp/package-info.xml'))
 		foreach ($extracted as $file)
 			if (basename($file['filename']) == 'package-info.xml')
 			{
@@ -1482,7 +1482,7 @@ function InstallSmileySet()
 	if (!isset($base_path))
 		$base_path = '';
 
-	if (!file_exists($boarddir . '/Packages/temp/' . $base_path . 'package-info.xml'))
+	if (!file_exists($packagesdir . '/temp/' . $base_path . 'package-info.xml'))
 		fatal_lang_error('package_get_error_missing_xml', false);
 
 	$smileyInfo = getPackageInfo($context['filename']);
@@ -1521,8 +1521,8 @@ function InstallSmileySet()
 		{
 			$has_readme = true;
 			$type = 'package_' . $action['type'];
-			if (file_exists($boarddir . '/Packages/temp/' . $base_path . $action['filename']))
-				$context[$type] = htmlspecialchars(trim(file_get_contents($boarddir . '/Packages/temp/' . $base_path . $action['filename']), "\n\r"));
+			if (file_exists($packagesdir . '/temp/' . $base_path . $action['filename']))
+				$context[$type] = htmlspecialchars(trim(file_get_contents($packagesdir . '/temp/' . $base_path . $action['filename']), "\n\r"));
 			elseif (file_exists($action['filename']))
 				$context[$type] = htmlspecialchars(trim(file_get_contents($action['filename']), "\n\r"));
 
@@ -1545,7 +1545,7 @@ function InstallSmileySet()
 				'action' => $smcFunc['htmlspecialchars'](strtr($action['destination'], array($boarddir => '.')))
 			);
 
-			$file =  $boarddir . '/Packages/temp/' . $base_path . $action['filename'];
+			$file =  $packagesdir . '/temp/' . $base_path . $action['filename'];
 			if (isset($action['filename']) && (!file_exists($file) || !is_writable(dirname($action['destination']))))
 			{
 				$context['has_failure'] = true;
@@ -1596,7 +1596,7 @@ function InstallSmileySet()
 		package_flush_cache();
 
 		// Time to tell pacman we have a new package installed!
-		package_put_contents($boarddir . '/Packages/installed.list', time());
+		package_put_contents($packagesdir . '/installed.list', time());
 		// Credits tag?
 		$credits_tag = (empty($credits_tag)) ? '' : serialize($credits_tag);
 		$smcFunc['db_insert']('',
@@ -1622,8 +1622,8 @@ function InstallSmileySet()
 		cache_put_data('posting_smileys', null, 480);
 	}
 
-	if (file_exists($boarddir . '/Packages/temp'))
-		deltree($boarddir . '/Packages/temp');
+	if (file_exists($packagesdir . '/temp'))
+		deltree($packagesdir . '/temp');
 
 	if (!$testing)
 		redirectexit('action=admin;area=smileys');

+ 17 - 17
Sources/PackageGet.php

@@ -85,7 +85,7 @@ function PackageGet()
  */
 function PackageServers()
 {
-	global $txt, $scripturl, $context, $boarddir, $sourcedir, $modSettings, $smcFunc;
+	global $txt, $scripturl, $context, $boarddir, $sourcedir, $packagesdir, $modSettings, $smcFunc;
 
 	// Ensure we use the correct template, and page title.
 	$context['sub_template'] = 'servers';
@@ -109,15 +109,15 @@ function PackageServers()
 	}
 	$smcFunc['db_free_result']($request);
 
-	$context['package_download_broken'] = !is_writable($boarddir . '/Packages') || !is_writable($boarddir . '/Packages/installed.list');
+	$context['package_download_broken'] = !is_writable($packagesdir) || !is_writable($packagesdir . '/installed.list');
 
 	if ($context['package_download_broken'])
 	{
-		@chmod($boarddir . '/Packages', 0777);
-		@chmod($boarddir . '/Packages/installed.list', 0777);
+		@chmod($packagesdir, 0777);
+		@chmod($packagesdir . '/installed.list', 0777);
 	}
 
-	$context['package_download_broken'] = !is_writable($boarddir . '/Packages') || !is_writable($boarddir . '/Packages/installed.list');
+	$context['package_download_broken'] = !is_writable($packagesdir) || !is_writable($packagesdir . '/installed.list');
 
 	if ($context['package_download_broken'])
 	{
@@ -147,7 +147,7 @@ function PackageServers()
 			elseif ($ftp->error !== false && !isset($ftp_error))
 				$ftp_error = $ftp->last_message === null ? '' : $ftp->last_message;
 
-			list ($username, $detect_path, $found_path) = $ftp->detect_path($boarddir);
+			list ($username, $detect_path, $found_path) = $ftp->detect_path($packagesdir);
 
 			if ($found_path || !isset($_POST['ftp_path']))
 				$_POST['ftp_path'] = $detect_path;
@@ -167,8 +167,8 @@ function PackageServers()
 		{
 			$context['package_download_broken'] = false;
 
-			$ftp->chmod('Packages', 0777);
-			$ftp->chmod('Packages/installed.list', 0777);
+			$ftp->chmod('.', 0777);
+			$ftp->chmod('installed.list', 0666);
 
 			$ftp->close();
 		}
@@ -512,7 +512,7 @@ function PackageGBrowse()
  */
 function PackageDownload()
 {
-	global $txt, $scripturl, $boarddir, $context, $sourcedir, $smcFunc;
+	global $txt, $scripturl, $boarddir, $context, $sourcedir, $packagesdir, $smcFunc;
 
 	// Use the downloaded sub template.
 	$context['sub_template'] = 'downloaded';
@@ -559,7 +559,7 @@ function PackageDownload()
 	else
 		$package_name = basename($_REQUEST['package']);
 
-	if (isset($_REQUEST['conflict']) || (isset($_REQUEST['auto']) && file_exists($boarddir . '/Packages/' . $package_name)))
+	if (isset($_REQUEST['conflict']) || (isset($_REQUEST['auto']) && file_exists($packagesdir . '/' . $package_name)))
 	{
 		// Find the extension, change abc.tar.gz to abc_1.tar.gz...
 		if (strrpos(substr($package_name, 0, -3), '.') !== false)
@@ -572,7 +572,7 @@ function PackageDownload()
 
 		// Find the first available.
 		$i = 1;
-		while (file_exists($boarddir . '/Packages/' . $package_name . $i . $ext))
+		while (file_exists($packagesdir . '/' . $package_name . $i . $ext))
 			$i++;
 
 		$package_name = $package_name . $i . $ext;
@@ -584,8 +584,8 @@ function PackageDownload()
 		fatal_lang_error($packageInfo);
 
 	// Use FTP if necessary.
-	create_chmod_control(array($boarddir . '/Packages/' . $package_name), array('destination_url' => $scripturl . '?action=admin;area=packages;get;sa=download' . (isset($_GET['server']) ? ';server=' . $_GET['server'] : '') . (isset($_REQUEST['auto']) ? ';auto' : '') . ';package=' . $_REQUEST['package'] . (isset($_REQUEST['conflict']) ? ';conflict' : '') . ';' . $context['session_var'] . '=' . $context['session_id'], 'crash_on_error' => true));
-	package_put_contents($boarddir . '/Packages/' . $package_name, fetch_web_data($url . $_REQUEST['package']));
+	create_chmod_control(array($packagesdir . '/' . $package_name), array('destination_url' => $scripturl . '?action=admin;area=packages;get;sa=download' . (isset($_GET['server']) ? ';server=' . $_GET['server'] : '') . (isset($_REQUEST['auto']) ? ';auto' : '') . ';package=' . $_REQUEST['package'] . (isset($_REQUEST['conflict']) ? ';conflict' : '') . ';' . $context['session_var'] . '=' . $context['session_id'], 'crash_on_error' => true));
+	package_put_contents($packagesdir . '/' . $package_name, fetch_web_data($url . $_REQUEST['package']));
 
 	// Done!  Did we get this package automatically?
 	if (preg_match('~^http://[\w_\-]+\.simplemachines\.org/~', $_REQUEST['package']) == 1 && strpos($_REQUEST['package'], 'dlattach') === false && isset($_REQUEST['auto']))
@@ -621,7 +621,7 @@ function PackageDownload()
  */
 function PackageUpload()
 {
-	global $txt, $scripturl, $boarddir, $context, $sourcedir;
+	global $txt, $scripturl, $boarddir, $context, $sourcedir, $packagesdir;
 
 	// Setup the correct template, even though I'll admit we ain't downloading ;)
 	$context['sub_template'] = 'downloaded';
@@ -644,7 +644,7 @@ function PackageUpload()
 	$packageName = basename($_FILES['package']['name']);
 
 	// Setup the destination and throw an error if the file is already there!
-	$destination = $boarddir . '/Packages/' . $packageName;
+	$destination = $packagesdir . '/' . $packageName;
 	// @todo Maybe just roll it like we do for downloads?
 	if (file_exists($destination))
 		fatal_lang_error('package_upload_error_exists');
@@ -666,11 +666,11 @@ function PackageUpload()
 		fatal_lang_error('package_upload_error_broken', false, $txt[$context['package']]);
 	}
 	// Is it already uploaded, maybe?
-	elseif ($dir = @opendir($boarddir . '/Packages'))
+	elseif ($dir = @opendir($packagesdir))
 	{
 		while ($package = readdir($dir))
 		{
-			if ($package == '.' || $package == '..' || $package == 'temp' || $package == $packageName || (!(is_dir($boarddir . '/Packages/' . $package) && file_exists($boarddir . '/Packages/' . $package . '/package-info.xml')) && substr(strtolower($package), -7) != '.tar.gz' && substr(strtolower($package), -4) != '.tgz' && substr(strtolower($package), -4) != '.zip'))
+			if ($package == '.' || $package == '..' || $package == 'temp' || $package == $packageName || (!(is_dir($packagesdir . '/' . $package) && file_exists($packagesdir . '/' . $package . '/package-info.xml')) && substr(strtolower($package), -7) != '.tar.gz' && substr(strtolower($package), -4) != '.tgz' && substr(strtolower($package), -4) != '.zip'))
 				continue;
 
 			$packageInfo = getPackageInfo($package);

+ 89 - 89
Sources/Packages.php

@@ -95,7 +95,7 @@ function Packages()
  */
 function PackageInstallTest()
 {
-	global $boarddir, $txt, $context, $scripturl, $sourcedir, $modSettings, $smcFunc, $settings;
+	global $boarddir, $txt, $context, $scripturl, $sourcedir, $packagesdir, $modSettings, $smcFunc, $settings;
 
 	// You have to specify a file!!
 	if (!isset($_REQUEST['package']) || $_REQUEST['package'] == '')
@@ -111,19 +111,19 @@ function PackageInstallTest()
 	create_chmod_control();
 
 	// Make sure temp directory exists and is empty.
-	if (file_exists($boarddir . '/Packages/temp'))
-		deltree($boarddir . '/Packages/temp', false);
+	if (file_exists($packagesdir . '/temp'))
+		deltree($packagesdir . '/temp', false);
 
-	if (!mktree($boarddir . '/Packages/temp', 0755))
+	if (!mktree($packagesdir . '/temp', 0755))
 	{
-		deltree($boarddir . '/Packages/temp', false);
-		if (!mktree($boarddir . '/Packages/temp', 0777))
+		deltree($packagesdir . '/temp', false);
+		if (!mktree($packagesdir . '/temp', 0777))
 		{
-			deltree($boarddir . '/Packages/temp', false);
-			create_chmod_control(array($boarddir . '/Packages/temp/delme.tmp'), array('destination_url' => $scripturl . '?action=admin;area=packages;sa=' . $_REQUEST['sa'] . ';package=' . $_REQUEST['package'], 'crash_on_error' => true));
+			deltree($packagesdir . '/temp', false);
+			create_chmod_control(array($packagesdir . '/temp/delme.tmp'), array('destination_url' => $scripturl . '?action=admin;area=packages;sa=' . $_REQUEST['sa'] . ';package=' . $_REQUEST['package'], 'crash_on_error' => true));
 
-			deltree($boarddir . '/Packages/temp', false);
-			if (!mktree($boarddir . '/Packages/temp', 0777))
+			deltree($packagesdir . '/temp', false);
+			if (!mktree($packagesdir . '/temp', 0777))
 				fatal_lang_error('package_cant_download', false);
 		}
 	}
@@ -139,18 +139,18 @@ function PackageInstallTest()
 
 	$context['sub_template'] = 'view_package';
 
-	if (!file_exists($boarddir . '/Packages/' . $context['filename']))
+	if (!file_exists($packagesdir . '/' . $context['filename']))
 	{
-		deltree($boarddir . '/Packages/temp');
+		deltree($packagesdir . '/temp');
 		fatal_lang_error('package_no_file', false);
 	}
 
 	// Extract the files so we can get things like the readme, etc.
-	if (is_file($boarddir . '/Packages/' . $context['filename']))
+	if (is_file($packagesdir . '/' . $context['filename']))
 	{
-		$context['extracted_files'] = read_tgz_file($boarddir . '/Packages/' . $context['filename'], $boarddir . '/Packages/temp');
+		$context['extracted_files'] = read_tgz_file($packagesdir . '/' . $context['filename'], $packagesdir . '/temp');
 
-		if ($context['extracted_files'] && !file_exists($boarddir . '/Packages/temp/package-info.xml'))
+		if ($context['extracted_files'] && !file_exists($packagesdir . '/temp/package-info.xml'))
 			foreach ($context['extracted_files'] as $file)
 				if (basename($file['filename']) == 'package-info.xml')
 				{
@@ -161,10 +161,10 @@ function PackageInstallTest()
 		if (!isset($context['base_path']))
 			$context['base_path'] = '';
 	}
-	elseif (is_dir($boarddir . '/Packages/' . $context['filename']))
+	elseif (is_dir($packagesdir . '/' . $context['filename']))
 	{
-		copytree($boarddir . '/Packages/' . $context['filename'], $boarddir . '/Packages/temp');
-		$context['extracted_files'] = listtree($boarddir . '/Packages/temp');
+		copytree($packagesdir . '/' . $context['filename'], $packagesdir . '/temp');
+		$context['extracted_files'] = listtree($packagesdir . '/temp');
 		$context['base_path'] = '';
 	}
 	else
@@ -247,7 +247,7 @@ function PackageInstallTest()
 		// Wait, it's not installed yet!
 		if (!isset($old_version) && $context['uninstalling'])
 		{
-			deltree($boarddir . '/Packages/temp');
+			deltree($packagesdir . '/temp');
 			fatal_lang_error('package_cant_uninstall', false);
 		}
 
@@ -256,7 +256,7 @@ function PackageInstallTest()
 		// Gadzooks!  There's no uninstaller at all!?
 		if (empty($actions))
 		{
-			deltree($boarddir . '/Packages/temp');
+			deltree($packagesdir . '/temp');
 			fatal_lang_error('package_uninstall_cannot', false);
 		}
 
@@ -320,8 +320,8 @@ function PackageInstallTest()
 		elseif ($action['type'] == 'readme' || $action['type'] == 'license')
 		{
 			$type = 'package_' . $action['type'];
-			if (file_exists($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']))
-				$context[$type] = htmlspecialchars(trim(file_get_contents($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']), "\n\r"));
+			if (file_exists($packagesdir . '/temp/' . $context['base_path'] . $action['filename']))
+				$context[$type] = htmlspecialchars(trim(file_get_contents($packagesdir . '/temp/' . $context['base_path'] . $action['filename']), "\n\r"));
 			elseif (file_exists($action['filename']))
 				$context[$type] = htmlspecialchars(trim(file_get_contents($action['filename']), "\n\r"));
 
@@ -349,7 +349,7 @@ function PackageInstallTest()
 		}
 		elseif ($action['type'] == 'modification')
 		{
-			if (!file_exists($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']))
+			if (!file_exists($packagesdir . '/temp/' . $context['base_path'] . $action['filename']))
 			{
 				$context['has_failure'] = true;
 
@@ -364,9 +364,9 @@ function PackageInstallTest()
 			{
 
 				if ($action['boardmod'])
-					$mod_actions = parseBoardMod(@file_get_contents($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']), true, $action['reverse'], $theme_paths);
+					$mod_actions = parseBoardMod(@file_get_contents($packagesdir . '/temp/' . $context['base_path'] . $action['filename']), true, $action['reverse'], $theme_paths);
 				else
-					$mod_actions = parseModification(@file_get_contents($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']), true, $action['reverse'], $theme_paths);
+					$mod_actions = parseModification(@file_get_contents($packagesdir . '/temp/' . $context['base_path'] . $action['filename']), true, $action['reverse'], $theme_paths);
 
 				if (count($mod_actions) == 1 && isset($mod_actions[0]) && $mod_actions[0]['type'] == 'error' && $mod_actions[0]['filename'] == '-')
 					$mod_actions[0]['filename'] = $action['filename'];
@@ -648,9 +648,9 @@ function PackageInstallTest()
 			continue;
 
 		if ($context['uninstalling'])
-			$file = in_array($action['type'], array('remove-dir', 'remove-file')) ? $action['filename'] : $boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename'];
+			$file = in_array($action['type'], array('remove-dir', 'remove-file')) ? $action['filename'] : $packagesdir . '/temp/' . $context['base_path'] . $action['filename'];
 		else
-			$file =  $boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename'];
+			$file =  $packagesdir . '/temp/' . $context['base_path'] . $action['filename'];
 
 		if (isset($action['filename']) && !file_exists($file))
 		{
@@ -743,8 +743,8 @@ function PackageInstallTest()
 	// Trash the cache... which will also check permissions for us!
 	package_flush_cache(true);
 
-	if (file_exists($boarddir . '/Packages/temp'))
-		deltree($boarddir . '/Packages/temp');
+	if (file_exists($packagesdir . '/temp'))
+		deltree($packagesdir . '/temp');
 
 	if (!empty($chmod_files))
 	{
@@ -761,7 +761,7 @@ function PackageInstallTest()
  */
 function PackageInstall()
 {
-	global $boarddir, $txt, $context, $boardurl, $scripturl, $sourcedir, $modSettings;
+	global $boarddir, $txt, $context, $boardurl, $scripturl, $sourcedir, $packagesdir, $modSettings;
 	global $user_info, $smcFunc;
 
 	// Make sure we don't install this mod twice.
@@ -791,24 +791,24 @@ function PackageInstall()
 
 	$context['sub_template'] = 'extract_package';
 
-	if (!file_exists($boarddir . '/Packages/' . $context['filename']))
+	if (!file_exists($packagesdir . '/' . $context['filename']))
 		fatal_lang_error('package_no_file', false);
 
 	// Load up the package FTP information?
 	create_chmod_control(array(), array('destination_url' => $scripturl . '?action=admin;area=packages;sa=' . $_REQUEST['sa'] . ';package=' . $_REQUEST['package']));
 
 	// Make sure temp directory exists and is empty!
-	if (file_exists($boarddir . '/Packages/temp'))
-		deltree($boarddir . '/Packages/temp', false);
+	if (file_exists($packagesdir . '/temp'))
+		deltree($packagesdir . '/temp', false);
 	else
-		mktree($boarddir . '/Packages/temp', 0777);
+		mktree($packagesdir . '/temp', 0777);
 
 	// Let the unpacker do the work.
-	if (is_file($boarddir . '/Packages/' . $context['filename']))
+	if (is_file($packagesdir . '/' . $context['filename']))
 	{
-		$context['extracted_files'] = read_tgz_file($boarddir . '/Packages/' . $context['filename'], $boarddir . '/Packages/temp');
+		$context['extracted_files'] = read_tgz_file($packagesdir . '/' . $context['filename'], $packagesdir . '/temp');
 
-		if (!file_exists($boarddir . '/Packages/temp/package-info.xml'))
+		if (!file_exists($packagesdir . '/temp/package-info.xml'))
 			foreach ($context['extracted_files'] as $file)
 				if (basename($file['filename']) == 'package-info.xml')
 				{
@@ -819,10 +819,10 @@ function PackageInstall()
 		if (!isset($context['base_path']))
 			$context['base_path'] = '';
 	}
-	elseif (is_dir($boarddir . '/Packages/' . $context['filename']))
+	elseif (is_dir($packagesdir . '/' . $context['filename']))
 	{
-		copytree($boarddir . '/Packages/' . $context['filename'], $boarddir . '/Packages/temp');
-		$context['extracted_files'] = listtree($boarddir . '/Packages/temp');
+		copytree($packagesdir . '/' . $context['filename'], $packagesdir . '/temp');
+		$context['extracted_files'] = listtree($packagesdir . '/temp');
 		$context['base_path'] = '';
 	}
 	else
@@ -922,7 +922,7 @@ function PackageInstall()
 	// @todo Replace with a better error message!
 	if (!isset($old_version) && $context['uninstalling'])
 	{
-		deltree($boarddir . '/Packages/temp');
+		deltree($packagesdir . '/temp');
 		fatal_error('Hacker?', false);
 	}
 	// Uninstalling?
@@ -977,9 +977,9 @@ function PackageInstall()
 			if ($action['type'] == 'modification' && !empty($action['filename']))
 			{
 				if ($action['boardmod'])
-					$mod_actions = parseBoardMod(file_get_contents($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']), false, $action['reverse'], $theme_paths);
+					$mod_actions = parseBoardMod(file_get_contents($packagesdir . '/temp/' . $context['base_path'] . $action['filename']), false, $action['reverse'], $theme_paths);
 				else
-					$mod_actions = parseModification(file_get_contents($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']), false, $action['reverse'], $theme_paths);
+					$mod_actions = parseModification(file_get_contents($packagesdir . '/temp/' . $context['base_path'] . $action['filename']), false, $action['reverse'], $theme_paths);
 
 				// Any errors worth noting?
 				foreach ($mod_actions as $key => $action)
@@ -1003,8 +1003,8 @@ function PackageInstall()
 				global $txt, $boarddir, $sourcedir, $modSettings, $context, $settings, $forum_version, $smcFunc;
 
 				// Now include the file and be done with it ;).
-				if (file_exists($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']))
-					require($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']);
+				if (file_exists($packagesdir . '/temp/' . $context['base_path'] . $action['filename']))
+					require($packagesdir . '/temp/' . $context['base_path'] . $action['filename']);
 			}
 			elseif ($action['type'] == 'credits')
 			{
@@ -1034,14 +1034,14 @@ function PackageInstall()
 				db_extend('packages');
 
 				// Let the file work its magic ;)
-				if (file_exists($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']))
-					require($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']);
+				if (file_exists($packagesdir . '/temp/' . $context['base_path'] . $action['filename']))
+					require($packagesdir . '/temp/' . $context['base_path'] . $action['filename']);
 			}
 			// Handle a redirect...
 			elseif ($action['type'] == 'redirect' && !empty($action['redirect_url']))
 			{
 				$context['redirect_url'] = $action['redirect_url'];
-				$context['redirect_text'] = !empty($action['filename']) && file_exists($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']) ? file_get_contents($boarddir . '/Packages/temp/' . $context['base_path'] . $action['filename']) : ($context['uninstalling'] ? $txt['package_uninstall_done'] : $txt['package_installed_done']);
+				$context['redirect_text'] = !empty($action['filename']) && file_exists($packagesdir . '/temp/' . $context['base_path'] . $action['filename']) ? file_get_contents($packagesdir . '/temp/' . $context['base_path'] . $action['filename']) : ($context['uninstalling'] ? $txt['package_uninstall_done'] : $txt['package_installed_done']);
 				$context['redirect_timeout'] = $action['redirect_timeout'];
 
 				// Parse out a couple of common urls.
@@ -1059,7 +1059,7 @@ function PackageInstall()
 		package_flush_cache();
 
 		// First, ensure this change doesn't get removed by putting a stake in the ground (So to speak).
-		package_put_contents($boarddir . '/Packages/installed.list', time());
+		package_put_contents($packagesdir . '/installed.list', time());
 
 		// See if this is already installed, and change it's state as required.
 		$request = $smcFunc['db_query']('', '
@@ -1193,8 +1193,8 @@ function PackageInstall()
 	}
 
 	// Clean house... get rid of the evidence ;).
-	if (file_exists($boarddir . '/Packages/temp'))
-		deltree($boarddir . '/Packages/temp');
+	if (file_exists($packagesdir . '/temp'))
+		deltree($packagesdir . '/temp');
 
 	// Log what we just did.
 	logAction($context['uninstalling'] ? 'uninstall_package' : (!empty($is_upgrade) ? 'upgrade_package' : 'install_package'), array('package' => $smcFunc['htmlspecialchars']($packageInfo['name']), 'version' => $smcFunc['htmlspecialchars']($packageInfo['version'])), 'admin');
@@ -1211,7 +1211,7 @@ function PackageInstall()
  */
 function PackageList()
 {
-	global $txt, $scripturl, $boarddir, $context, $sourcedir;
+	global $txt, $scripturl, $boarddir, $context, $sourcedir, $packagesdir;
 
 	require_once($sourcedir . '/Subs-Package.php');
 
@@ -1230,10 +1230,10 @@ function PackageList()
 	$context['filename'] = $_REQUEST['package'];
 
 	// Let the unpacker do the work.
-	if (is_file($boarddir . '/Packages/' . $context['filename']))
-		$context['files'] = read_tgz_file($boarddir . '/Packages/' . $context['filename'], null);
-	elseif (is_dir($boarddir . '/Packages/' . $context['filename']))
-		$context['files'] = listtree($boarddir . '/Packages/' . $context['filename']);
+	if (is_file($packagesdir . '/' . $context['filename']))
+		$context['files'] = read_tgz_file($packagesdir . '/' . $context['filename'], null);
+	elseif (is_dir($packagesdir . '/' . $context['filename']))
+		$context['files'] = listtree($packagesdir . '/' . $context['filename']);
 }
 
 /**
@@ -1241,7 +1241,7 @@ function PackageList()
  */
 function ExamineFile()
 {
-	global $txt, $scripturl, $boarddir, $context, $sourcedir;
+	global $txt, $scripturl, $boarddir, $context, $sourcedir, $packagesdir;
 
 	require_once($sourcedir . '/Subs-Package.php');
 
@@ -1258,10 +1258,10 @@ function ExamineFile()
 
 	if (isset($_REQUEST['raw']))
 	{
-		if (is_file($boarddir . '/Packages/' . $_REQUEST['package']))
-			echo read_tgz_file($boarddir . '/Packages/' . $_REQUEST['package'], $_REQUEST['file'], true);
-		elseif (is_dir($boarddir . '/Packages/' . $_REQUEST['package']))
-			echo file_get_contents($boarddir . '/Packages/' . $_REQUEST['package'] . '/' . $_REQUEST['file']);
+		if (is_file($packagesdir . '/' . $_REQUEST['package']))
+			echo read_tgz_file($packagesdir . '/' . $_REQUEST['package'], $_REQUEST['file'], true);
+		elseif (is_dir($packagesdir . '/' . $_REQUEST['package']))
+			echo file_get_contents($packagesdir . '/' . $_REQUEST['package'] . '/' . $_REQUEST['file']);
 
 		obExit(false);
 	}
@@ -1282,10 +1282,10 @@ function ExamineFile()
 		$context['filedata'] = '<img src="' . $scripturl . '?action=admin;area=packages;sa=examine;package=' . $_REQUEST['package'] . ';file=' . $_REQUEST['file'] . ';raw" alt="' . $_REQUEST['file'] . '" />';
 	else
 	{
-		if (is_file($boarddir . '/Packages/' . $_REQUEST['package']))
-			$context['filedata'] = htmlspecialchars(read_tgz_file($boarddir . '/Packages/' . $_REQUEST['package'], $_REQUEST['file'], true));
-		elseif (is_dir($boarddir . '/Packages/' . $_REQUEST['package']))
-			$context['filedata'] = htmlspecialchars(file_get_contents($boarddir . '/Packages/' . $_REQUEST['package'] . '/' . $_REQUEST['file']));
+		if (is_file($packagesdir . '/' . $_REQUEST['package']))
+			$context['filedata'] = htmlspecialchars(read_tgz_file($packagesdir . '/' . $_REQUEST['package'], $_REQUEST['file'], true));
+		elseif (is_dir($packagesdir . '/' . $_REQUEST['package']))
+			$context['filedata'] = htmlspecialchars(file_get_contents($packagesdir . '/' . $_REQUEST['package'] . '/' . $_REQUEST['file']));
 
 		if (strtolower(strrchr($_REQUEST['file'], '.')) == '.php')
 			$context['filedata'] = highlight_php_code($context['filedata']);
@@ -1311,7 +1311,7 @@ function InstalledList()
  */
 function FlushInstall()
 {
-	global $boarddir, $sourcedir, $smcFunc;
+	global $boarddir, $sourcedir, $packagesdir, $smcFunc;
 
 	// Always check the session.
 	checkSession('get');
@@ -1319,7 +1319,7 @@ function FlushInstall()
 	include_once($sourcedir . '/Subs-Package.php');
 
 	// Record when we last did this.
-	package_put_contents($boarddir . '/Packages/installed.list', time());
+	package_put_contents($packagesdir . '/installed.list', time());
 
 	// Set everything as uninstalled.
 	$smcFunc['db_query']('', '
@@ -1338,7 +1338,7 @@ function FlushInstall()
  */
 function PackageRemove()
 {
-	global $scripturl, $boarddir;
+	global $scripturl, $boarddir, $packagesdir;
 
 	// Check it.
 	checkSession('get');
@@ -1349,16 +1349,16 @@ function PackageRemove()
 	$_GET['package'] = preg_replace('~[\.]+~', '.', strtr($_GET['package'], array('/' => '_', '\\' => '_')));
 
 	// Can't delete what's not there.
-	if (file_exists($boarddir . '/Packages/' . $_GET['package']) && (substr($_GET['package'], -4) == '.zip' || substr($_GET['package'], -4) == '.tgz' || substr($_GET['package'], -7) == '.tar.gz' || is_dir($boarddir . '/Packages/' . $_GET['package'])) && $_GET['package'] != 'backups' && substr($_GET['package'], 0, 1) != '.')
+	if (file_exists($packagesdir . '/' . $_GET['package']) && (substr($_GET['package'], -4) == '.zip' || substr($_GET['package'], -4) == '.tgz' || substr($_GET['package'], -7) == '.tar.gz' || is_dir($packagesdir . '/' . $_GET['package'])) && $_GET['package'] != 'backups' && substr($_GET['package'], 0, 1) != '.')
 	{
-		create_chmod_control(array($boarddir . '/Packages/' . $_GET['package']), array('destination_url' => $scripturl . '?action=admin;area=packages;sa=remove;package=' . $_GET['package'], 'crash_on_error' => true));
+		create_chmod_control(array($packagesdir . '/' . $_GET['package']), array('destination_url' => $scripturl . '?action=admin;area=packages;sa=remove;package=' . $_GET['package'], 'crash_on_error' => true));
 
-		if (is_dir($boarddir . '/Packages/' . $_GET['package']))
-			deltree($boarddir . '/Packages/' . $_GET['package']);
+		if (is_dir($packagesdir . '/' . $_GET['package']))
+			deltree($packagesdir . '/' . $_GET['package']);
 		else
 		{
-			@chmod($boarddir . '/Packages/' . $_GET['package'], 0777);
-			unlink($boarddir . '/Packages/' . $_GET['package']);
+			@chmod($packagesdir . '/' . $_GET['package'], 0777);
+			unlink($packagesdir . '/' . $_GET['package']);
 		}
 	}
 
@@ -1525,7 +1525,7 @@ function PackageBrowse()
  */
 function list_getPackages($start, $items_per_page, $sort, $params, $installed)
 {
-	global $boarddir, $scripturl, $context, $forum_version;
+	global $boarddir, $scripturl, $packagesdir, $context, $forum_version;
 	static $instmods, $packages;
 
 	// Start things up
@@ -1533,8 +1533,8 @@ function list_getPackages($start, $items_per_page, $sort, $params, $installed)
 		$packages[$params] = array();
 
 	// We need the packages directory to be writable for this.
-	if (!@is_writable($boarddir . '/Packages'))
-		create_chmod_control(array($boarddir . '/Packages'), array('destination_url' => $scripturl . '?action=admin;area=packages', 'crash_on_error' => true));
+	if (!@is_writable($packagesdir))
+		create_chmod_control(array($packagesdir), array('destination_url' => $scripturl . '?action=admin;area=packages', 'crash_on_error' => true));
 
 	$the_version = strtr($forum_version, array('SMF ' => ''));
 
@@ -1595,7 +1595,7 @@ function list_getPackages($start, $items_per_page, $sort, $params, $installed)
 		foreach ($context['modification_types'] as $type)
 			$packages[$type] = array();
 
-	if ($dir = @opendir($boarddir . '/Packages'))
+	if ($dir = @opendir($packagesdir))
 	{
 		$dirs = array();
 		$sort_id = array(
@@ -1607,7 +1607,7 @@ function list_getPackages($start, $items_per_page, $sort, $params, $installed)
 		);
 		while ($package = readdir($dir))
 		{
-			if ($package == '.' || $package == '..' || $package == 'temp' || (!(is_dir($boarddir . '/Packages/' . $package) && file_exists($boarddir . '/Packages/' . $package . '/package-info.xml')) && substr(strtolower($package), -7) != '.tar.gz' && substr(strtolower($package), -4) != '.tgz' && substr(strtolower($package), -4) != '.zip'))
+			if ($package == '.' || $package == '..' || $package == 'temp' || (!(is_dir($packagesdir . '/' . $package) && file_exists($packagesdir . '/' . $package . '/package-info.xml')) && substr(strtolower($package), -7) != '.tar.gz' && substr(strtolower($package), -4) != '.tgz' && substr(strtolower($package), -4) != '.zip'))
 				continue;
 
 			$skip = false;
@@ -1619,7 +1619,7 @@ function list_getPackages($start, $items_per_page, $sort, $params, $installed)
 				continue;
 
 			// Skip directories or files that are named the same.
-			if (is_dir($boarddir . '/Packages/' . $package))
+			if (is_dir($packagesdir . '/' . $package))
 			{
 				if (in_array($package, $dirs))
 					continue;
@@ -1829,7 +1829,7 @@ function PackageOptions()
  */
 function ViewOperations()
 {
-	global $context, $txt, $boarddir, $sourcedir, $smcFunc, $modSettings;
+	global $context, $txt, $boarddir, $sourcedir, $packagesdir, $smcFunc, $modSettings;
 
 	// Can't be in here buddy.
 	isAllowedTo('admin_forum');
@@ -1848,11 +1848,11 @@ function ViewOperations()
 	$context['filename'] = preg_replace('~[\.]+~', '.', $_REQUEST['package']);
 
 	// We need to extract this again.
-	if (is_file($boarddir . '/Packages/' . $context['filename']))
+	if (is_file($packagesdir . '/' . $context['filename']))
 	{
-		$context['extracted_files'] = read_tgz_file($boarddir . '/Packages/' . $context['filename'], $boarddir . '/Packages/temp');
+		$context['extracted_files'] = read_tgz_file($packagesdir . '/' . $context['filename'], $packagesdir . '/temp');
 
-		if ($context['extracted_files'] && !file_exists($boarddir . '/Packages/temp/package-info.xml'))
+		if ($context['extracted_files'] && !file_exists($packagesdir . '/temp/package-info.xml'))
 			foreach ($context['extracted_files'] as $file)
 				if (basename($file['filename']) == 'package-info.xml')
 				{
@@ -1863,10 +1863,10 @@ function ViewOperations()
 		if (!isset($context['base_path']))
 			$context['base_path'] = '';
 	}
-	elseif (is_dir($boarddir . '/Packages/' . $context['filename']))
+	elseif (is_dir($packagesdir . '/' . $context['filename']))
 	{
-		copytree($boarddir . '/Packages/' . $context['filename'], $boarddir . '/Packages/temp');
-		$context['extracted_files'] = listtree($boarddir . '/Packages/temp');
+		copytree($packagesdir . '/' . $context['filename'], $packagesdir . '/temp');
+		$context['extracted_files'] = listtree($packagesdir . '/temp');
 		$context['base_path'] = '';
 	}
 
@@ -1890,9 +1890,9 @@ function ViewOperations()
 
 	// Boardmod?
 	if (isset($_REQUEST['boardmod']))
-		$mod_actions = parseBoardMod(@file_get_contents($boarddir . '/Packages/temp/' . $context['base_path'] . $_REQUEST['filename']), true, $reverse, $theme_paths);
+		$mod_actions = parseBoardMod(@file_get_contents($packagesdir . '/temp/' . $context['base_path'] . $_REQUEST['filename']), true, $reverse, $theme_paths);
 	else
-		$mod_actions = parseModification(@file_get_contents($boarddir . '/Packages/temp/' . $context['base_path'] . $_REQUEST['filename']), true, $reverse, $theme_paths);
+		$mod_actions = parseModification(@file_get_contents($packagesdir . '/temp/' . $context['base_path'] . $_REQUEST['filename']), true, $reverse, $theme_paths);
 
 	// Ok lets get the content of the file.
 	$context['operations'] = array(

+ 17 - 17
Sources/Subs-Package.php

@@ -384,10 +384,10 @@ function url_exists($url)
  */
 function loadInstalledPackages()
 {
-	global $boarddir, $smcFunc;
+	global $boarddir, $packagesdir, $smcFunc;
 
 	// First, check that the database is valid, installed.list is still king.
-	$install_file = implode('', file($boarddir . '/Packages/installed.list'));
+	$install_file = implode('', file($packagesdir . '/installed.list'));
 	if (trim($install_file) == '')
 	{
 		$smcFunc['db_query']('', '
@@ -447,20 +447,20 @@ function loadInstalledPackages()
  */
 function getPackageInfo($gzfilename)
 {
-	global $boarddir, $sourcedir, $smcFunc;
+	global $boarddir, $sourcedir, $packagesdir, $smcFunc;
 
 	// Extract package-info.xml from downloaded file. (*/ is used because it could be in any directory.)
 	if (strpos($gzfilename, 'http://') !== false)
 		$packageInfo = read_tgz_data(fetch_web_data($gzfilename, '', true), '*/package-info.xml', true);
 	else
 	{
-		if (!file_exists($boarddir . '/Packages/' . $gzfilename))
+		if (!file_exists($packagesdir . '/' . $gzfilename))
 			return 'package_get_error_not_found';
 
-		if (is_file($boarddir . '/Packages/' . $gzfilename))
-			$packageInfo = read_tgz_file($boarddir . '/Packages/' . $gzfilename, '*/package-info.xml', true);
-		elseif (file_exists($boarddir . '/Packages/' . $gzfilename . '/package-info.xml'))
-			$packageInfo = file_get_contents($boarddir . '/Packages/' . $gzfilename . '/package-info.xml');
+		if (is_file($packagesdir . '/' . $gzfilename))
+			$packageInfo = read_tgz_file($packagesdir . '/' . $gzfilename, '*/package-info.xml', true);
+		elseif (file_exists($packagesdir . '/' . $gzfilename . '/package-info.xml'))
+			$packageInfo = file_get_contents($packagesdir . '/' . $gzfilename . '/package-info.xml');
 		else
 			return 'package_get_error_missing_xml';
 	}
@@ -469,7 +469,7 @@ function getPackageInfo($gzfilename)
 	if (empty($packageInfo))
 	{
 		// Perhaps they are trying to install a theme, lets tell them nicely this is the wrong function
-		$packageInfo = read_tgz_file($boarddir . '/Packages/' . $gzfilename, '*/theme_info.xml', true);
+		$packageInfo = read_tgz_file($packagesdir . '/' . $gzfilename, '*/theme_info.xml', true);
 		if (!empty($packageInfo))
 			return 'package_get_error_is_theme';
 		else
@@ -1031,7 +1031,7 @@ function packageRequireFTP($destination_url, $files = null, $return = false)
  */
 function parsePackageInfo(&$packageXML, $testing_only = true, $method = 'install', $previous_version = '')
 {
-	global $boarddir, $forum_version, $context, $temp_path, $language;
+	global $boarddir, $packagesdir, $forum_version, $context, $temp_path, $language;
 
 	// Mayday!  That action doesn't exist!!
 	if (empty($packageXML) || !$packageXML->exists($method))
@@ -1088,7 +1088,7 @@ function parsePackageInfo(&$packageXML, $testing_only = true, $method = 'install
 	$return = array();
 
 	$temp_auto = 0;
-	$temp_path = $boarddir . '/Packages/temp/' . (isset($context['base_path']) ? $context['base_path'] : '');
+	$temp_path = $packagesdir . '/temp/' . (isset($context['base_path']) ? $context['base_path'] : '');
 
 	$context['readmes'] = array();
 	$context['licences'] = array();
@@ -2882,7 +2882,7 @@ function package_crypt($pass)
  */
 function package_create_backup($id = 'backup')
 {
-	global $sourcedir, $boarddir, $smcFunc;
+	global $sourcedir, $boarddir, $packagesdir, $smcFunc;
 
 	$files = array();
 
@@ -2943,11 +2943,11 @@ function package_create_backup($id = 'backup')
 		$listing->close();
 	}
 
-	if (!file_exists($boarddir . '/Packages/backups'))
-		mktree($boarddir . '/Packages/backups', 0777);
-	if (!is_writable($boarddir . '/Packages/backups'))
-		package_chmod($boarddir . '/Packages/backups');
-	$output_file = $boarddir . '/Packages/backups/' . strftime('%Y-%m-%d_') . preg_replace('~[$\\\\/:<>|?*"\']~', '', $id);
+	if (!file_exists($packagesdir . '/backups'))
+		mktree($packagesdir . '/backups', 0777);
+	if (!is_writable($packagesdir . '/backups'))
+		package_chmod($packagesdir . '/backups');
+	$output_file = $packagesdir . '/backups/' . strftime('%Y-%m-%d_') . preg_replace('~[$\\\\/:<>|?*"\']~', '', $id);
 	$output_ext = '.tar' . (function_exists('gzopen') ? '.gz' : '');
 
 	if (file_exists($output_file . $output_ext))

+ 5 - 0
other/Settings.php

@@ -153,6 +153,11 @@ $boarddir = dirname(__FILE__);
  * @var string
  */
 $sourcedir = dirname(__FILE__) . '/Sources';
+/**
+ * Path to the Packages directory.
+ * @var string
+ */
+$packagesdir = dirname(__FILE__) . '/Packages';
 
 ########## Error-Catching ##########
 # Note: You shouldn't touch these settings.

+ 29 - 20
other/upgrade.php

@@ -1239,7 +1239,7 @@ function checkLogin()
 // Step 1: Do the maintenance and backup.
 function UpgradeOptions()
 {
-	global $db_prefix, $command_line, $modSettings, $is_debug, $smcFunc;
+	global $db_prefix, $command_line, $modSettings, $is_debug, $smcFunc, $packagesdir;
 	global $boarddir, $boardurl, $sourcedir, $maintenance, $mmessage, $cachedir, $upcontext, $db_type;
 
 	$upcontext['sub_template'] = 'upgrade_options';
@@ -1341,6 +1341,11 @@ function UpgradeOptions()
 	if (empty($db_type))
 		$changes['db_type'] = 'mysql';
 
+	// Maybe we haven't had this option yet?
+	if (empty($packagesdir))
+		$changes['packagesdir'] = '\'' . fixRelativePath($boarddir) . '/Packages\'';
+
+
 	// @todo Maybe change the cookie name if going to 1.1, too?
 
 	// Update Settings.php with the new settings.
@@ -1561,7 +1566,7 @@ function DatabaseChanges()
 // Clean up any mods installed...
 function CleanupMods()
 {
-	global $db_prefix, $modSettings, $upcontext, $boarddir, $sourcedir, $settings, $smcFunc, $command_line;
+	global $db_prefix, $modSettings, $upcontext, $boarddir, $sourcedir, $packagesdir, $settings, $smcFunc, $command_line;
 
 	// Sorry. Not supported for command line users.
 	if ($command_line)
@@ -1600,6 +1605,10 @@ function CleanupMods()
 		}
 	}
 
+	// Make sure we have some sort of packages directory.
+	if (!isset($packagesdir))
+		$packagesdir = $boarddir . '/Packages';
+
 	// Load all theme paths....
 	$request = $smcFunc['db_query']('', '
 		SELECT id_theme, variable, value
@@ -1638,7 +1647,7 @@ function CleanupMods()
 	while ($row = $smcFunc['db_fetch_assoc']($request))
 	{
 		// Work out the status.
-		if (!file_exists($boarddir . '/Packages/' . $row['filename']))
+		if (!file_exists($packagesdir . '/' . $row['filename']))
 		{
 			$status = 'Missing';
 			$status_color = 'red';
@@ -1656,7 +1665,7 @@ function CleanupMods()
 			'themes' => explode(',', $row['themes_installed']),
 			'name' => $row['name'],
 			'filename' => $row['filename'],
-			'missing_file' => file_exists($boarddir . '/Packages/' . $row['filename']) ? 0 : 1,
+			'missing_file' => file_exists($packagesdir . '/' . $row['filename']) ? 0 : 1,
 			'files' => array(),
 			'file_count' => 0,
 			'status' => $status,
@@ -1679,12 +1688,12 @@ function CleanupMods()
 	// Before we get started, don't report notice errors.
 	$oldErrorReporting = error_reporting(E_ALL ^ E_NOTICE);
 
-	if (!mktree($boarddir . '/Packages/temp', 0755))
+	if (!mktree($packagesdir . '/temp', 0755))
 	{
-		deltree($boarddir . '/Packages/temp', false);
-		if (!mktree($boarddir . '/Packages/temp', 0777))
+		deltree($packagesdir . '/temp', false);
+		if (!mktree($packagesdir . '/temp', 0777))
 		{
-			deltree($boarddir . '/Packages/temp', false);
+			deltree($packagesdir . '/temp', false);
 			// @todo Error here - plus chmod!
 		}
 	}
@@ -1721,10 +1730,10 @@ function CleanupMods()
 		if (isset($_POST['remove']))
 			$infoInstall = parsePackageInfo($packageInfo['xml'], true);
 
-		if (is_file($boarddir . '/Packages/' . $filename))
-			read_tgz_file($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp');
+		if (is_file($packagesdir . '/' . $filename))
+			read_tgz_file($packagesdir . '/' . $filename, $packagesdir . '/temp');
 		else
-			copytree($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp');
+			copytree($packagesdir . '/' . $filename, $packagesdir . '/temp');
 
 		// Work out how we uninstall...
 		$files = array();
@@ -1735,7 +1744,7 @@ function CleanupMods()
 			// 2) Whether it could be installed on the new version.
 			if ($change['type'] == 'modification')
 			{
-				$contents = @file_get_contents($boarddir . '/Packages/temp/' . $upcontext['base_path'] . $change['filename']);
+				$contents = @file_get_contents($packagesdir . '/temp/' . $upcontext['base_path'] . $change['filename']);
 				if ($change['boardmod'])
 					$results = parseBoardMod($contents, $test, $change['reverse'], $cur_theme_paths);
 				else
@@ -1768,10 +1777,10 @@ function CleanupMods()
 		if (isset($_POST['remove']) && !$test && isset($infoInstall))
 		{
 			// Need to extract again I'm afraid.
-			if (is_file($boarddir . '/Packages/' . $filename))
-				read_tgz_file($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp');
+			if (is_file($packagesdir . '/' . $filename))
+				read_tgz_file($packagesdir . '/' . $filename, $packagesdir . '/temp');
 			else
-				copytree($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp');
+				copytree($packagesdir . '/' . $filename, $packagesdir . '/temp');
 
 			$errors = false;
 			$upcontext['packages'][$id]['result'] = 'Removed';
@@ -1779,7 +1788,7 @@ function CleanupMods()
 			{
 				if ($change['type'] == 'modification')
 				{
-					$contents = @file_get_contents($boarddir . '/Packages/temp/' . $upcontext['base_path'] . $change['filename']);
+					$contents = @file_get_contents($packagesdir . '/temp/' . $upcontext['base_path'] . $change['filename']);
 					if ($change['boardmod'])
 						$results = parseBoardMod($contents, true, $change['reverse'], $cur_theme_paths);
 					else
@@ -1800,7 +1809,7 @@ function CleanupMods()
 				{
 					if ($change['type'] == 'modification')
 					{
-						$contents = @file_get_contents($boarddir . '/Packages/temp/' . $upcontext['base_path'] . $change['filename']);
+						$contents = @file_get_contents($packagesdir . '/temp/' . $upcontext['base_path'] . $change['filename']);
 						if ($change['boardmod'])
 							$results = parseBoardMod($contents, false, $change['reverse'], $cur_theme_paths);
 						else
@@ -1838,8 +1847,8 @@ function CleanupMods()
 		}
 	}
 
-	if (file_exists($boarddir . '/Packages/temp'))
-		deltree($boarddir . '/Packages/temp');
+	if (file_exists($packagesdir . '/temp'))
+		deltree($packagesdir . '/temp');
 
 	// Removing/Reinstalling any packages?
 	if (isset($_POST['remove']))
@@ -1858,7 +1867,7 @@ function CleanupMods()
 				WHERE id_install IN (' . implode(',', $deletes) . ')');
 
 		// Ensure we don't lose our changes!
-		package_put_contents($boarddir . '/Packages/installed.list', time());
+		package_put_contents($packagesdir . '/installed.list', time());
 
 		$upcontext['sub_template'] = 'cleanup_done';
 		return false;