function PackageDownload() { global $txt, $scripturl, $boarddir, $context, $sourcedir, $db_prefix; // Use the downloaded sub template. $context['sub_template'] = 'downloaded'; // Security is good... checkSession('get'); if (isset($_GET['server'])) { $server = (int) $_GET['server']; // Query the server table to find the requested server. $request = db_query("\n\t\t\tSELECT name, url\n\t\t\tFROM {$db_prefix}package_servers\n\t\t\tWHERE ID_SERVER = {$server}\n\t\t\tLIMIT 1", __FILE__, __LINE__); list($name, $url) = mysql_fetch_row($request); mysql_free_result($request); // If server does not exist then dump out. if (empty($url)) { fatal_lang_error('smf191', false); } $url = $url . '/'; } else { // Initialize the requried variables. $server = ''; $url = ''; } $package_name = basename($_REQUEST['package']); if (isset($_REQUEST['conflict']) || isset($_REQUEST['auto']) && file_exists($boarddir . '/Packages/' . $package_name)) { // Find the extension, change abc.tar.gz to abc_1.tar.gz... if (strrpos(substr($package_name, 0, -3), '.') !== false) { $ext = substr($package_name, strrpos(substr($package_name, 0, -3), '.')); $package_name = substr($package_name, 0, strrpos(substr($package_name, 0, -3), '.')) . '_'; } else { $ext = ''; } // Find the first available. $i = 1; while (file_exists($boarddir . '/Packages/' . $package_name . $i . $ext)) { $i++; } $package_name = $package_name . $i . $ext; } // First make sure it's a package. if (getPackageInfo($url . $_REQUEST['package']) == false) { fatal_lang_error('package45', false); } // Use FTP if necessary. packageRequireFTP($scripturl . '?action=packageget;sa=download' . (isset($_GET['server']) ? ';server=' . $_GET['server'] : '') . (isset($_REQUEST['auto']) ? ';auto' : '') . ';package=' . $_REQUEST['package'] . (isset($_REQUEST['conflict']) ? ';conflict' : '') . ';sesc=' . $context['session_id'], array($boarddir . '/Packages/' . $package_name)); package_put_contents($boarddir . '/Packages/' . $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'])) { redirectexit('action=packages;sa=install;package=' . $package_name . ';sesc=' . $context['session_id']); } // You just downloaded a mod from SERVER_NAME_GOES_HERE. $context['package_server'] = $server; $context['package'] = getPackageInfo($package_name); if (empty($context['package'])) { fatal_lang_error('package_cant_download', false); } if ($context['package']['type'] == 'modification') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=packages;sa=install;package=' . $context['package']['filename'] . ';sesc=' . $context['session_id'] . '">[ ' . $txt['package11'] . ' ]</a>'; } elseif ($context['package']['type'] == 'avatar') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=packages;sa=install;package=' . $context['package']['filename'] . ';sesc=' . $context['session_id'] . '">[ ' . $txt['package12'] . ' ]</a>'; } elseif ($context['package']['type'] == 'language') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=packages;sa=install;package=' . $context['package']['filename'] . ';sesc=' . $context['session_id'] . '">[ ' . $txt['package13'] . ' ]</a>'; } else { $context['package']['install']['link'] = ''; } $context['package']['list_files']['link'] = '<a href="' . $scripturl . '?action=packages;sa=list;package=' . $context['package']['filename'] . '">[ ' . $txt['package14'] . ' ]</a>'; // Free a little bit of memory... unset($context['package']['xml']); $context['page_title'] = $txt['smf192']; }
function parseBoardMod($file, $testing = true, $undo = false, $theme_paths = array()) { global $boarddir, $sourcedir, $settings, $txt, $modSettings; @set_time_limit(600); $file = strtr($file, array("\r" => '')); $working_file = null; $working_search = null; $working_data = ''; $replace_with = null; $actions = array(); $everything_found = true; // This holds all the template changes in the standard mod file. $template_changes = array(); // This is just the temporary file. $temp_file = $file; // This holds the actual changes on a step counter basis. $temp_changes = array(); $counter = 0; $step_counter = 0; // Before we do *anything*, let's build a list of what we're editing, as it's going to be used for other theme edits. while (preg_match('~<(edit file|file|search|search for|add|add after|replace|add before|add above|above|before)>\\n(.*?)\\n</\\1>~is', $temp_file, $code_match) != 0) { $counter++; // Get rid of the old stuff. $temp_file = substr_replace($temp_file, '', strpos($temp_file, $code_match[0]), strlen($code_match[0])); // No interest to us? if ($code_match[1] != 'edit file' && $code_match[1] != 'file') { // It's a step, let's add that to the current steps. if (isset($temp_changes[$step_counter])) { $temp_changes[$step_counter]['changes'][] = $code_match[0]; } continue; } // We've found a new edit - let's make ourself heard, kind of. $step_counter = $counter; $temp_changes[$step_counter] = array('title' => $code_match[0], 'changes' => array()); $filename = parse_path($code_match[2]); // Now, is this a template file, and if so, which? foreach ($theme_paths as $id => $theme) { // If this filename is relative, if so take a guess at what it should be. if (strpos($filename, 'Themes') === 0) { $filename = $boarddir . '/' . $filename; } if (strpos($filename, $theme['theme_dir']) === 0) { $template_changes[$id][$counter] = substr($filename, strlen($theme['theme_dir']) + 1); } } } // Anything above $counter must be for custom themes. $custom_template_begin = $counter; // Reference for what theme ID this action belongs to. $theme_id_ref = array(); // Now we know what templates we need to touch, cycle through each theme and work out what we need to edit. if (!empty($template_changes[1])) { foreach ($theme_paths as $id => $theme) { // Don't do default, it means nothing to me. if ($id == 1) { continue; } // Now, for each file do we need to edit it? foreach ($template_changes[1] as $pos => $template_file) { // It does? Add it to the list darlin'. if (file_exists($theme['theme_dir'] . '/' . $template_file) && (!isset($template_changes[$id][$pos]) || !in_array($template_file, $template_changes[$id][$pos]))) { // Actually add it to the mod file too, so we can see that it will work ;) if (!empty($temp_changes[$pos]['changes'])) { $file .= "\n\n" . '<edit file>' . "\n" . $theme['theme_dir'] . '/' . $template_file . "\n" . '</edit file>' . "\n\n" . implode("\n\n", $temp_changes[$pos]['changes']); $theme_id_ref[$counter] = $id; $counter += 1 + count($temp_changes[$pos]['changes']); } } } } } $counter = 0; $is_custom = 0; while (preg_match('~<(edit file|file|search|search for|add|add after|replace|add before|add above|above|before)>\\n(.*?)\\n</\\1>~is', $file, $code_match) != 0) { // This is for working out what we should be editing. $counter++; // Edit a specific file. if ($code_match[1] == 'file' || $code_match[1] == 'edit file') { // Backup the old file. if ($working_file !== null) { package_chmod($working_file); // Don't even dare. if (basename($working_file) == 'Settings_bak.php') { continue; } if (!is_writable($working_file)) { $actions[] = array('type' => 'chmod', 'filename' => $working_file); } if (!$testing && !empty($modSettings['package_make_backups']) && file_exists($working_file)) { if (basename($working_file) == 'Settings.php') { @copy($working_file, dirname($working_file) . '/Settings_bak.php'); } else { @copy($working_file, $working_file . '~'); } } package_put_contents($working_file, $working_data, $testing); } if ($working_file !== null) { $actions[] = array('type' => 'saved', 'filename' => $working_file, 'is_custom' => $is_custom); } // Is this "now working on" file a theme specific one? $is_custom = isset($theme_id_ref[$counter - 1]) ? $theme_id_ref[$counter - 1] : 0; // Make sure the file exists! $working_file = parse_path($code_match[2]); if ($working_file[0] != '/' && $working_file[1] != ':') { trigger_error('parseBoardMod(): The filename \'' . $working_file . '\' is not a full path!', E_USER_WARNING); $working_file = $boarddir . '/' . $working_file; } if (!file_exists($working_file)) { $places_to_check = array($boarddir, $sourcedir, $settings['default_theme_dir'], $settings['default_theme_dir'] . '/languages'); foreach ($places_to_check as $place) { if (file_exists($place . '/' . $working_file)) { $working_file = $place . '/' . $working_file; break; } } } if (file_exists($working_file)) { // Load the new file. $working_data = str_replace("\r", '', package_get_contents($working_file)); $actions[] = array('type' => 'opened', 'filename' => $working_file); } else { $actions[] = array('type' => 'missing', 'filename' => $working_file); $working_file = null; $everything_found = false; } // Can't be searching for something... $working_search = null; } elseif (($code_match[1] == 'search' || $code_match[1] == 'search for') && $working_file !== null) { if ($working_search !== null) { $actions[] = array('type' => 'error', 'filename' => $working_file); $everything_found = false; } $working_search = $code_match[2]; } elseif ($working_search !== null) { // This is the base string.... $replace_with = $code_match[2]; // Add this afterward... if ($code_match[1] == 'add' || $code_match[1] == 'add after') { $replace_with = $working_search . "\n" . $replace_with; } elseif ($code_match[1] == 'before' || $code_match[1] == 'add before' || $code_match[1] == 'above' || $code_match[1] == 'add above') { $replace_with .= "\n" . $working_search; } // Otherwise.. replace with $replace_with ;). } // If we have a search string, replace string, and open file.. if ($working_search !== null && $replace_with !== null && $working_file !== null) { // Make sure it's somewhere in the string. if ($undo) { $temp = $replace_with; $replace_with = $working_search; $working_search = $temp; } if (strpos($working_data, $working_search) !== false) { $working_data = str_replace($working_search, $replace_with, $working_data); $actions[] = array('type' => 'replace', 'filename' => $working_file, 'search' => $working_search, 'replace' => $replace_with, 'search_original' => $working_search, 'replace_original' => $replace_with, 'position' => $code_match[1] == 'replace' ? 'replace' : ($code_match[1] == 'add' || $code_match[1] == 'add after' ? 'before' : 'after'), 'is_custom' => $is_custom, 'failed' => false); } else { $actions[] = array('type' => 'failure', 'filename' => $working_file, 'search' => $working_search, 'is_custom' => $is_custom, 'search_original' => $working_search, 'replace_original' => $replace_with, 'position' => $code_match[1] == 'replace' ? 'replace' : ($code_match[1] == 'add' || $code_match[1] == 'add after' ? 'before' : 'after'), 'is_custom' => $is_custom, 'failed' => true); $everything_found = false; } // These don't hold any meaning now. $working_search = null; $replace_with = null; } // Get rid of the old tag. $file = substr_replace($file, '', strpos($file, $code_match[0]), strlen($code_match[0])); } // Backup the old file. if ($working_file !== null) { package_chmod($working_file); if (!is_writable($working_file)) { $actions[] = array('type' => 'chmod', 'filename' => $working_file); } if (!$testing && !empty($modSettings['package_make_backups']) && file_exists($working_file)) { if (basename($working_file) == 'Settings.php') { @copy($working_file, dirname($working_file) . '/Settings_bak.php'); } else { @copy($working_file, $working_file . '~'); } } package_put_contents($working_file, $working_data, $testing); } if ($working_file !== null) { $actions[] = array('type' => 'saved', 'filename' => $working_file, 'is_custom' => $is_custom); } $actions[] = array('type' => 'result', 'status' => $everything_found); return $actions; }
function PackageDownload() { global $txt, $scripturl, $boarddir, $context, $sourcedir, $smcFunc; // Use the downloaded sub template. $context['sub_template'] = 'downloaded'; // Security is good... checkSession('get'); // To download something, we need a valid server or url. if (empty($_GET['server']) && (!empty($_GET['get']) && !empty($_REQUEST['package']))) { fatal_lang_error('package_get_error_is_zero', false); } if (isset($_GET['server'])) { $server = (int) $_GET['server']; // Query the server table to find the requested server. $request = $smcFunc['db_query']('', ' SELECT name, url FROM {db_prefix}package_servers WHERE id_server = {int:current_server} LIMIT 1', array('current_server' => $server)); list($name, $url) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // If server does not exist then dump out. if (empty($url)) { fatal_lang_error('couldnt_connect', false); } $url = $url . '/'; } else { // Initialize the requried variables. $server = ''; $url = ''; } if (isset($_REQUEST['byurl']) && !empty($_POST['filename'])) { $package_name = basename($_REQUEST['filename']); } else { $package_name = basename($_REQUEST['package']); } if (isset($_REQUEST['conflict']) || isset($_REQUEST['auto']) && file_exists($boarddir . '/Packages/' . $package_name)) { // Find the extension, change abc.tar.gz to abc_1.tar.gz... if (strrpos(substr($package_name, 0, -3), '.') !== false) { $ext = substr($package_name, strrpos(substr($package_name, 0, -3), '.')); $package_name = substr($package_name, 0, strrpos(substr($package_name, 0, -3), '.')) . '_'; } else { $ext = ''; } // Find the first available. $i = 1; while (file_exists($boarddir . '/Packages/' . $package_name . $i . $ext)) { $i++; } $package_name = $package_name . $i . $ext; } // First make sure it's a package. $packageInfo = getPackageInfo($url . $_REQUEST['package']); if (!is_array($packageInfo)) { 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'])); // 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'])) { redirectexit('action=admin;area=packages;sa=install;package=' . $package_name); } // You just downloaded a mod from SERVER_NAME_GOES_HERE. $context['package_server'] = $server; $context['package'] = getPackageInfo($package_name); if (!is_array($context['package'])) { fatal_lang_error('package_cant_download', false); } if ($context['package']['type'] == 'modification') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['install_mod'] . ' ]</a>'; } elseif ($context['package']['type'] == 'avatar') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['use_avatars'] . ' ]</a>'; } elseif ($context['package']['type'] == 'language') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['add_languages'] . ' ]</a>'; } else { $context['package']['install']['link'] = ''; } $context['package']['list_files']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=list;package=' . $context['package']['filename'] . '">[ ' . $txt['list_files'] . ' ]</a>'; // Free a little bit of memory... unset($context['package']['xml']); $context['page_title'] = $txt['download_success']; }
function FlushInstall() { global $boarddir, $sourcedir; // Always check the session. checkSession('get'); include_once $sourcedir . '/lib/Subs-Package.php'; // Record when we last did this. package_put_contents($boarddir . '/Packages/installed.list', time()); // Set everything as uninstalled. smf_db_query(' UPDATE {db_prefix}log_packages SET install_state = {int:not_installed}', array('not_installed' => 0)); redirectexit('action=admin;area=packages;sa=installed'); }
/** * Empty out the installed list. */ public function action_flush() { // Always check the session. checkSession('get'); include_once SUBSDIR . '/Package.subs.php'; // Record when we last did this. package_put_contents(BOARDDIR . '/packages/installed.list', time()); // Set everything as uninstalled. setPackagesAsUninstalled(); redirectexit('action=admin;area=packages;sa=installed'); }
function CleanupMods() { global $db_prefix, $modSettings, $upcontext, $boarddir, $sourcedir, $settings, $smcFunc, $command_line; // Sorry. Not supported for command line users. if ($command_line) { return true; } // Skipping first? if (!empty($_POST['skip'])) { unset($_POST['skip']); return true; } // If we get here withOUT SSI we need to redirect to ensure we get it! if (!isset($_GET['ssi']) || !function_exists('mktree')) { redirectLocation('&ssi=1'); } $upcontext['sub_template'] = 'clean_mods'; $upcontext['page_title'] = 'Cleanup Modifications'; // This can be skipped. $upcontext['skip'] = true; // If we're on the second redirect continue... if (isset($_POST['cleandone2'])) { return true; } // Do we already know about some writable files? if (isset($_POST['writable_files'])) { $writable_files = unserialize(base64_decode($_POST['writable_files'])); if (!makeFilesWritable($writable_files)) { // What have we left? $upcontext['writable_files'] = $writable_files; return false; } } // Load all theme paths.... $request = $smcFunc['db_query']('', ' SELECT id_theme, variable, value FROM {db_prefix}themes WHERE id_member = {int:id_member} AND variable IN ({string:theme_dir}, {string:images_url})', array('id_member' => 0, 'theme_dir' => 'theme_dir', 'images_url' => 'images_url', 'db_error_skip' => true)); $theme_paths = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { if ($row['id_theme'] == 1) { $settings['default_' . $row['variable']] = $row['value']; } elseif ($row['variable'] == 'theme_dir') { $theme_paths[$row['id_theme']][$row['variable']] = $row['value']; } } $smcFunc['db_free_result']($request); // Are there are mods installed that may need uninstalling? $request = $smcFunc['db_query']('', ' SELECT id_install, filename, name, themes_installed, version FROM {db_prefix}log_packages WHERE install_state = {int:installed} ORDER BY time_installed DESC', array('installed' => 1, 'db_error_skip' => true)); $upcontext['packages'] = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { // Work out the status. if (!file_exists($boarddir . '/Packages/' . $row['filename'])) { $status = 'Missing'; $status_color = 'red'; $result = 'Removed'; } else { $status = 'Installed'; $status_color = 'green'; $result = 'No Action Needed'; } $upcontext['packages'][$row['id_install']] = array('id' => $row['id_install'], 'themes' => explode(',', $row['themes_installed']), 'name' => $row['name'], 'filename' => $row['filename'], 'missing_file' => file_exists($boarddir . '/Packages/' . $row['filename']) ? 0 : 1, 'files' => array(), 'file_count' => 0, 'status' => $status, 'result' => $result, 'color' => $status_color, 'version' => $row['version'], 'needs_removing' => false); } $smcFunc['db_free_result']($request); // Don't carry on if there are none. if (empty($upcontext['packages'])) { return true; } // Setup some basics. if (!empty($upcontext['user']['version'])) { $_SESSION['version_emulate'] = $upcontext['user']['version']; } // Before we get started, don't report notice errors. $oldErrorReporting = error_reporting(E_ALL ^ E_NOTICE); if (!mktree($boarddir . '/Packages/temp', 0755)) { deltree($boarddir . '/Packages/temp', false); if (!mktree($boarddir . '/Packages/temp', 0777)) { deltree($boarddir . '/Packages/temp', false); //!!! Error here - plus chmod! } } // Anything which reinstalled should not have its entry removed. $reinstall_worked = array(); // We're gonna be doing some removin' $test = isset($_POST['cleandone']) ? false : true; foreach ($upcontext['packages'] as $id => $package) { // Can't do anything about this.... if ($package['missing_file']) { continue; } // Not testing *and* this wasn't checked? if (!$test && (!isset($_POST['remove']) || !isset($_POST['remove'][$id]))) { continue; } // What are the themes this was installed into? $cur_theme_paths = array(); foreach ($theme_paths as $tid => $data) { if ($tid != 1 && in_array($tid, $package['themes'])) { $cur_theme_paths[$tid] = $data; } } // Get the modifications data if applicable. $filename = $package['filename']; $packageInfo = getPackageInfo($filename); if (!is_array($packageInfo)) { continue; } $info = parsePackageInfo($packageInfo['xml'], $test, 'uninstall'); // Also get the reinstall details... if (isset($_POST['remove'])) { $infoInstall = parsePackageInfo($packageInfo['xml'], true); } if (is_file($boarddir . '/Packages/' . $filename)) { read_tgz_file($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp'); } else { copytree($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp'); } // Work out how we uninstall... $files = array(); foreach ($info as $change) { // Work out two things: // 1) Whether it's installed at the moment - and if so whether its fully installed, and: // 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']); if ($change['boardmod']) { $results = parseBoardMod($contents, $test, $change['reverse'], $cur_theme_paths); } else { $results = parseModification($contents, $test, $change['reverse'], $cur_theme_paths); } foreach ($results as $action) { // Something we can remove? Probably means it existed! if (($action['type'] == 'replace' || $action['type'] == 'append' || !empty($action['filename']) && $action['type'] == 'failure') && !in_array($action['filename'], $files)) { $files[] = $action['filename']; } if ($action['type'] == 'failure') { $upcontext['packages'][$id]['needs_removing'] = true; $upcontext['packages'][$id]['status'] = 'Reinstall Required'; $upcontext['packages'][$id]['color'] = '#FD6435'; } } } } // Store this info for the template as appropriate. $upcontext['packages'][$id]['files'] = $files; $upcontext['packages'][$id]['file_count'] = count($files); // If we've done something save the changes! if (!$test) { package_flush_cache(); } // Are we attempting to reinstall this thing? 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'); } else { copytree($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp'); } $errors = false; $upcontext['packages'][$id]['result'] = 'Removed'; foreach ($infoInstall as $change) { if ($change['type'] == 'modification') { $contents = @file_get_contents($boarddir . '/Packages/temp/' . $upcontext['base_path'] . $change['filename']); if ($change['boardmod']) { $results = parseBoardMod($contents, true, $change['reverse'], $cur_theme_paths); } else { $results = parseModification($contents, true, $change['reverse'], $cur_theme_paths); } // Are there any errors? foreach ($results as $action) { if ($action['type'] == 'failure') { $errors = true; } } } } if (!$errors) { $reinstall_worked[] = $id; $upcontext['packages'][$id]['result'] = 'Reinstalled'; $upcontext['packages'][$id]['color'] = 'green'; foreach ($infoInstall as $change) { if ($change['type'] == 'modification') { $contents = @file_get_contents($boarddir . '/Packages/temp/' . $upcontext['base_path'] . $change['filename']); if ($change['boardmod']) { $results = parseBoardMod($contents, false, $change['reverse'], $cur_theme_paths); } else { $results = parseModification($contents, false, $change['reverse'], $cur_theme_paths); } } } // Save the changes. package_flush_cache(); } } } // Put errors back on a sec. error_reporting($oldErrorReporting); // Check everything is writable. if ($test && !empty($upcontext['packages'])) { $writable_files = array(); foreach ($upcontext['packages'] as $package) { if (!empty($package['files'])) { foreach ($package['files'] as $file) { $writable_files[] = $file; } } } if (!empty($writable_files)) { $writable_files = array_unique($writable_files); $upcontext['writable_files'] = $writable_files; if (!makeFilesWritable($writable_files)) { return false; } } } if (file_exists($boarddir . '/Packages/temp')) { deltree($boarddir . '/Packages/temp'); } // Removing/Reinstalling any packages? if (isset($_POST['remove'])) { $deletes = array(); foreach ($_POST['remove'] as $id => $dummy) { if (!in_array((int) $id, $reinstall_worked)) { $deletes[] = (int) $id; } } if (!empty($deletes)) { upgrade_query(' UPDATE ' . $db_prefix . 'log_packages SET install_state = 0 WHERE id_install IN (' . implode(',', $deletes) . ')'); } // Ensure we don't lose our changes! package_put_contents($boarddir . '/Packages/installed.list', time()); $upcontext['sub_template'] = 'cleanup_done'; return false; } else { $allgood = true; // Is there actually anything that needs our attention? foreach ($upcontext['packages'] as $package) { if ($package['color'] != 'green') { $allgood = false; } } if ($allgood) { return true; } } $_GET['substep'] = 0; return isset($_POST['cleandone']) ? true : false; }
function FlushInstall() { global $boarddir, $sourcedir; checkSession('get'); include_once $sourcedir . '/Subs-Package.php'; // Open the file and write nothing to it. package_put_contents($boarddir . '/Packages/installed.list', ''); redirectexit('action=packages;sa=installed'); }
/** * Does the actual writing of the file * * - Writes the extracted file to disk or if we are extracting a single file * - it returns the extracted data */ private function _write_this_file() { $this->_skip = false; $this->_found = false; // A directory may need to be created if (strpos($this->_filename, '/') !== false && !$this->single_file || !$this->single_file && !is_dir($this->_file_info['dir'])) { mktree($this->_file_info['dir'], 0777); } // If we're looking for a **specific file**, and this is it... ka-bam, baby. if ($this->single_file && ($this->destination === $this->_filename || $this->destination === '*/' . basename($this->_filename))) { $this->_found = $this->_file_info['data']; } elseif ($this->single_file) { $this->_skip = true; } elseif ($this->files_to_extract !== null && !in_array($this->_filename, $this->files_to_extract)) { $this->_skip = true; } // Write it out then if ($this->_skip === true) { return; } elseif (!empty($this->_found)) { $this->_check_crc(); } elseif ($this->_skip === false && $this->_found === false && $this->_check_crc()) { package_put_contents($this->destination . '/' . $this->_filename, $this->_file_info['data']); } }
function parseBoardMod($file, $testing = true, $undo = false) { global $boarddir, $sourcedir, $settings, $txt, $modSettings; @set_time_limit(600); $file = strtr($file, array("\r" => '')); $working_file = null; $working_search = null; $working_data = ''; $replace_with = null; $actions = array(); $everything_found = true; while (preg_match('~<(edit file|file|search|search for|add|add after|replace|add before|add above|above|before)>\\n(.*?)\\n</\\1>~is', $file, $code_match) != 0) { // Edit a specific file. if ($code_match[1] == 'file' || $code_match[1] == 'edit file') { // Backup the old file. if ($working_file !== null) { package_chmod($working_file); // Don't even dare. if (basename($working_file) == 'Settings_bak.php') { continue; } if (!is_writable($working_file)) { $actions[] = array('type' => 'chmod', 'filename' => $working_file); } if (!$testing && !empty($modSettings['package_make_backups']) && file_exists($working_file)) { if (basename($working_file) == 'Settings.php') { @copy($working_file, dirname($working_file) . '/Settings_bak.php'); } else { @copy($working_file, $working_file . '~'); } } package_put_contents($working_file, $working_data, $testing); } if ($working_file !== null) { $actions[] = array('type' => 'saved', 'filename' => $working_file); } // Make sure the file exists! $working_file = parse_path($code_match[2]); if ($working_file[0] != '/' && $working_file[1] != ':') { trigger_error('parseBoardMod(): The filename \'' . $working_file . '\' is not a full path!', E_USER_WARNING); $working_file = $boarddir . '/' . $working_file; } if (!file_exists($working_file)) { $places_to_check = array($boarddir, $sourcedir, $settings['default_theme_dir'], $settings['default_theme_dir'] . '/languages'); foreach ($places_to_check as $place) { if (file_exists($place . '/' . $working_file)) { $working_file = $place . '/' . $working_file; break; } } } if (file_exists($working_file)) { // Load the new file. $working_data = str_replace("\r", '', package_get_contents($working_file)); $actions[] = array('type' => 'opened', 'filename' => $working_file); } else { $actions[] = array('type' => 'missing', 'filename' => $working_file); $working_file = null; $everything_found = false; } // Can't be searching for something... $working_search = null; } elseif (($code_match[1] == 'search' || $code_match[1] == 'search for') && $working_file !== null) { if ($working_search !== null) { $actions[] = array('type' => 'error', 'filename' => $working_file); $everything_found = false; } $working_search = $code_match[2]; } elseif ($working_search !== null) { // This is the base string.... $replace_with = $code_match[2]; // Add this afterward... if ($code_match[1] == 'add' || $code_match[1] == 'add after') { $replace_with = $working_search . "\n" . $replace_with; } elseif ($code_match[1] == 'before' || $code_match[1] == 'add before' || $code_match[1] == 'above' || $code_match[1] == 'add above') { $replace_with .= "\n" . $working_search; } // Otherwise.. replace with $replace_with ;). } // If we have a search string, replace string, and open file.. if ($working_search !== null && $replace_with !== null && $working_file !== null) { // Make sure it's somewhere in the string. if ($undo) { $temp = $replace_with; $replace_with = $working_search; $working_search = $temp; } if (strpos($working_data, $working_search) !== false) { $working_data = str_replace($working_search, $replace_with, $working_data); $actions[] = array('type' => 'replace', 'filename' => $working_file, 'search' => $working_search, 'replace' => $replace_with); } else { $actions[] = array('type' => 'failure', 'filename' => $working_file, 'search' => $working_search); $everything_found = false; } // These don't hold any meaning now. $working_search = null; $replace_with = null; } // Get rid of the old tag. $file = substr_replace($file, '', strpos($file, $code_match[0]), strlen($code_match[0])); } // Backup the old file. if ($working_file !== null) { package_chmod($working_file); if (!is_writable($working_file)) { $actions[] = array('type' => 'chmod', 'filename' => $working_file); } if (!$testing && !empty($modSettings['package_make_backups']) && file_exists($working_file)) { if (basename($working_file) == 'Settings.php') { @copy($working_file, dirname($working_file) . '/Settings_bak.php'); } else { @copy($working_file, $working_file . '~'); } } package_put_contents($working_file, $working_data, $testing); } if ($working_file !== null) { $actions[] = array('type' => 'saved', 'filename' => $working_file); } $actions[] = array('type' => 'result', 'status' => $everything_found); return $actions; }
/** * Install a smiley set. */ public function action_install() { global $modSettings, $scripturl, $context, $txt, $user_info; isAllowedTo('manage_smileys'); checkSession('request'); // One of these two may be necessary loadLanguage('Errors'); loadLanguage('Packages'); require_once SUBSDIR . '/Smileys.subs.php'; require_once SUBSDIR . '/Package.subs.php'; // Installing unless proven otherwise $testing = false; $destination = ''; $name = ''; if (isset($_REQUEST['set_gz'])) { $base_name = strtr(basename($_REQUEST['set_gz']), ':/', '-_'); $name = Util::htmlspecialchars(strtok(basename($_REQUEST['set_gz']), '.')); $name_pr = preg_replace(array('/\\s/', '/\\.[\\.]+/', '/[^\\w_\\.\\-]/'), array('_', '.', ''), $name); $context['filename'] = $base_name; // Check that the smiley is from simplemachines.org, for now... maybe add mirroring later. if (!isAuthorizedServer($_REQUEST['set_gz']) == 0) { fatal_lang_error('not_valid_server'); } $destination = BOARDDIR . '/packages/' . $base_name; if (file_exists($destination)) { fatal_lang_error('package_upload_error_exists'); } // Let's copy it to the packages directory file_put_contents($destination, fetch_web_data($_REQUEST['set_gz'])); $testing = true; } elseif (isset($_REQUEST['package'])) { $base_name = basename($_REQUEST['package']); $name = Util::htmlspecialchars(strtok(basename($_REQUEST['package']), '.')); $name_pr = preg_replace(array('/\\s/', '/\\.[\\.]+/', '/[^\\w_\\.\\-]/'), array('_', '.', ''), $name); $context['filename'] = $base_name; $destination = BOARDDIR . '/packages/' . 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 (!mktree(BOARDDIR . '/packages/temp', 0755)) { deltree(BOARDDIR . '/packages/temp', false); if (!mktree(BOARDDIR . '/packages/temp', 0777)) { deltree(BOARDDIR . '/packages/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)); deltree(BOARDDIR . '/packages/temp', false); if (!mktree(BOARDDIR . '/packages/temp', 0777)) { fatal_lang_error('package_cant_download', false); } } } $extracted = read_tgz_file($destination, BOARDDIR . '/packages/temp'); // @todo needs to change the URL in the next line ;) if (!$extracted) { fatal_lang_error('packageget_unable', false, array('http://custom.elkarte.net/index.php?action=search;type=12;basic_search=' . $name)); } if ($extracted && !file_exists(BOARDDIR . '/packages/temp/package-info.xml')) { foreach ($extracted as $file) { if (basename($file['filename']) == 'package-info.xml') { $base_path = dirname($file['filename']) . '/'; break; } } } if (!isset($base_path)) { $base_path = ''; } if (!file_exists(BOARDDIR . '/packages/temp/' . $base_path . 'package-info.xml')) { fatal_lang_error('package_get_error_missing_xml', false); } $smileyInfo = getPackageInfo($context['filename']); if (!is_array($smileyInfo)) { fatal_lang_error($smileyInfo); } // See if it is installed? if (isSmileySetInstalled($smileyInfo['id'])) { fata_lang_error('package_installed_warning1'); } // Everything is fine, now it's time to do something, first we test $actions = parsePackageInfo($smileyInfo['xml'], true, 'install'); $context['post_url'] = $scripturl . '?action=admin;area=smileys;sa=install;package=' . $base_name; $context['has_failure'] = false; $context['actions'] = array(); $context['ftp_needed'] = false; foreach ($actions as $action) { if ($action['type'] == 'readme' || $action['type'] == 'license') { $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"), ENT_COMPAT, 'UTF-8'); } elseif (file_exists($action['filename'])) { $context[$type] = htmlspecialchars(trim(file_get_contents($action['filename']), "\n\r"), ENT_COMPAT, 'UTF-8'); } if (!empty($action['parse_bbc'])) { require_once SUBSDIR . '/Post.subs.php'; preparsecode($context[$type]); $context[$type] = parse_bbc($context[$type]); } else { $context[$type] = nl2br($context[$type]); } continue; } elseif ($action['type'] == 'require-dir') { // Do this one... $thisAction = array('type' => $txt['package_extract'] . ' ' . ($action['type'] == 'require-dir' ? $txt['package_tree'] : $txt['package_file']), 'action' => Util::htmlspecialchars(strtr($action['destination'], array(BOARDDIR => '.')))); $file = BOARDDIR . '/packages/temp/' . $base_path . $action['filename']; if (isset($action['filename']) && (!file_exists($file) || !is_writable(dirname($action['destination'])))) { $context['has_failure'] = true; $thisAction += array('description' => $txt['package_action_error'], 'failed' => true); } // Show a description for the action if one is provided if (empty($thisAction['description'])) { $thisAction['description'] = isset($action['description']) ? $action['description'] : ''; } $context['actions'][] = $thisAction; } elseif ($action['type'] == 'credits') { // Time to build the billboard $credits_tag = array('url' => $action['url'], 'license' => $action['license'], 'copyright' => $action['copyright'], 'title' => $action['title']); } } if ($testing) { $context['sub_template'] = 'view_package'; $context['uninstalling'] = false; $context['is_installed'] = false; $context['package_name'] = $smileyInfo['name']; loadTemplate('Packages'); } else { $actions = parsePackageInfo($smileyInfo['xml'], false, 'install'); foreach ($context['actions'] as $action) { updateSettings(array('smiley_sets_known' => $modSettings['smiley_sets_known'] . ',' . basename($action['action']), 'smiley_sets_names' => $modSettings['smiley_sets_names'] . "\n" . $smileyInfo['name'] . (count($context['actions']) > 1 ? ' ' . (!empty($action['description']) ? Util::htmlspecialchars($action['description']) : basename($action['action'])) : ''))); } package_flush_cache(); // Time to tell pacman we have a new package installed! package_put_contents(BOARDDIR . '/packages/installed.list', time()); // Credits tag? $credits_tag = empty($credits_tag) ? '' : serialize($credits_tag); $installed = array('filename' => $smileyInfo['filename'], 'name' => $smileyInfo['name'], 'package_id' => $smileyInfo['id'], 'version' => $smileyInfo['filename'], 'id_member' => $user_info['id'], 'member_name' => $user_info['name'], 'credits_tag' => $credits_tag); logPackageInstall($installed); logAction('install_package', array('package' => Util::htmlspecialchars($smileyInfo['name']), 'version' => Util::htmlspecialchars($smileyInfo['version'])), 'admin'); cache_put_data('parsing_smileys', null, 480); cache_put_data('posting_smileys', null, 480); } if (file_exists(BOARDDIR . '/packages/temp')) { deltree(BOARDDIR . '/packages/temp'); } if (!$testing) { redirectexit('action=admin;area=smileys'); } }
/** * Does the actual writing of the file * * - Writes the extracted file to disk or if we are extracting a single file * - it returns the extracted data */ private function _write_this_file() { $this->_skip = false; $this->_found = false; // A directory may need to be created if (strpos($this->_current['filename'], '/') !== false && !$this->single_file) { mktree($this->destination . '/' . dirname($this->_current['filename']), 0777); } // Is this the file we're looking for? if ($this->single_file && ($this->destination === $this->_current['filename'] || $this->destination === '*/' . basename($this->_current['filename']))) { $this->_found = $this->_current['data']; } elseif ($this->single_file) { $this->_skip = true; } elseif ($this->files_to_extract !== null && !in_array($this->_current['filename'], $this->files_to_extract)) { $this->_skip = true; } // Write it out then if ($this->_check_header_crc() && $this->_skip === false && $this->_found === false) { package_put_contents($this->destination . '/' . $this->_current['filename'], $this->_current['data']); } }
function fixp_main() { global $txt, $sourcedir, $boarddir, $boardurl, $context, $user_info, $smcFunc; loadLanguage('Admin'); loadLanguage('Packages'); loadTemplate('Admin'); fixp_loadLanguage(); // Sorry, only logged in admins...unless you want so. if (empty($context['override_security'])) { isAllowedTo('admin_forum'); } $context['install'] = isset($_GET['uninstall']) ? 0 : 1; if (!empty($_POST['remove']) && is_array($_POST['remove'])) { checkSession(); foreach ($_POST['remove'] as $id) { if (isset($id) && is_numeric($id)) { if (!empty($context['install'])) { $smcFunc['db_query']('', ' UPDATE {db_prefix}log_packages SET id_member_removed = {int:id_member}, member_removed = {string:member_name}, time_removed = {int:time_removed}, install_state = 0 WHERE id_install = {int:inst_package_id}', array('id_member' => $user_info['id'], 'member_name' => $user_info['name'], 'time_removed' => time(), 'inst_package_id' => $id)); } else { $smcFunc['db_query']('', ' UPDATE {db_prefix}log_packages SET id_member_removed = 0, member_removed = 0, time_removed = 0, install_state = 1 WHERE id_install = {int:inst_package_id}', array('inst_package_id' => $id)); } } } require_once $sourcedir . '/Subs-Package.php'; package_put_contents($boarddir . '/Packages/installed.list', time()); } if (isset($_POST['remove_hooks'])) { remove_hooks(); } $context['sub_template'] = 'admin'; $context['page_title'] = $txt['log_packages_title_' . (!empty($context['install']) ? 'installed' : 'removed')]; // Making a list is not hard with this beauty. require_once $sourcedir . '/Subs-List.php'; // Use the standard templates for showing this. $listOptions = array('id' => 'log_packages', 'title' => $context['page_title'], 'get_items' => array('function' => 'list_getPacks'), 'get_count' => array('function' => 'list_getNumPacks'), 'columns' => array('name' => array('header' => array('value' => $txt['mod_name']), 'data' => array('db' => 'name')), 'version' => array('header' => array('value' => $txt['mod_version']), 'data' => array('db' => 'version')), 'install_date' => array('header' => array('value' => $txt['mod_' . (!empty($context['install']) ? 'installed' : 'removed')]), 'data' => array('function' => create_function('&$data', ' return timeformat($data[\'time_' . (!empty($context['install']) ? 'installed' : 'removed') . '\']); '))), 'check' => array('header' => array('value' => '<input type="checkbox" onclick="invertAll(this, this.form);" class="input_check" />'), 'data' => array('function' => create_function('$data', ' return \'<input type="checkbox" name="remove[]" value="\' . $data[\'id_install\'] . \'" class="input_check" />\'; '), 'class' => 'centertext'))), 'form' => array('href' => $boardurl . '/fix_packages.php?' . $context['session_var'] . '=' . $context['session_id'] . (!empty($context['install']) ? '' : ';uninstall')), 'additional_rows' => array(array('position' => 'below_table_data', 'value' => ' <a href="' . $boardurl . '/fix_packages.php' . (!empty($context['install']) ? '?uninstall' : '') . '">[ ' . (!empty($context['install']) ? $txt['uninstall'] : $txt['install']) . ' ]</a> <input type="submit" name="remove_packages" value="' . $txt['pack_button_' . (!empty($context['install']) ? 'remove' : 'install')] . '" class="button_submit" /> <input type="submit" name="remove_hooks" value="' . $txt['remove_hooks'] . '" class="button_submit" />', 'class' => 'righttext'))); $context['sub_template'] = 'show_list'; $context['default_list'] = 'log_packages'; // Create the request list. createList($listOptions); }
/** * Download a package. * * - Accessed by action=admin;area=packageservers;sa=download */ public function action_download() { global $txt, $scripturl, $context; require_once SUBSDIR . '/PackageServers.subs.php'; // Use the downloaded sub template. $context['sub_template'] = 'downloaded'; // Security is good... checkSession('get'); // To download something, we need a valid server or url. if (empty($_GET['server']) && (!empty($_GET['get']) && !empty($_REQUEST['package']))) { fatal_lang_error('package_get_error_is_zero', false); } if (isset($_GET['server'])) { $server = (int) $_GET['server']; // Query the server table to find the requested server. $packageserver = fetchPackageServers($server); $url = $packageserver[0]['url']; // If server does not exist then dump out. if (empty($url)) { fatal_lang_error('couldnt_connect', false); } $url = $url . '/'; } else { // Initialize the required variables. $server = ''; $url = ''; } // Entered a url and name to download? if (isset($_REQUEST['byurl']) && !empty($_POST['filename'])) { $package_name = basename($_REQUEST['filename']); } else { $package_name = basename($_REQUEST['package']); } // Is this a "master" package from github or bitbucket? if (preg_match('~^http(s)?://(www.)?(bitbucket\\.org|github\\.com)/(.+?(master(\\.zip|\\.tar\\.gz)))$~', $_REQUEST['package'], $matches) == 1) { // @todo maybe use the name/version in the package instead, although the link will be cleaner // Name this master.zip based on repo name in the link $path_parts = pathinfo($matches[4]); list(, $newname, ) = explode('/', $path_parts['dirname']); // Just to be safe, no invalid file characters $invalid = array_merge(array_map('chr', range(0, 31)), array('<', '>', ':', '"', '/', '\\', '|', '?', '*')); $package_name = str_replace($invalid, '_', $newname) . $matches[6]; // We could read the package info and see if we have a duplicate id & version, however that is // not always accurate, especially when dealing with repos. So for now just put in in no conflict mode // and do the save. $_REQUEST['auto'] = true; } if (isset($_REQUEST['conflict']) || isset($_REQUEST['auto']) && file_exists(BOARDDIR . '/packages/' . $package_name)) { // Find the extension, change abc.tar.gz to abc_1.tar.gz... if (strrpos(substr($package_name, 0, -3), '.') !== false) { $ext = substr($package_name, strrpos(substr($package_name, 0, -3), '.')); $package_name = substr($package_name, 0, strrpos(substr($package_name, 0, -3), '.')) . '_'; } else { $ext = ''; } // Find the first available. $i = 1; while (file_exists(BOARDDIR . '/packages/' . $package_name . $i . $ext)) { $i++; } $package_name = $package_name . $i . $ext; } // First make sure it's a package. $packageInfo = getPackageInfo($url . $_REQUEST['package']); if (!is_array($packageInfo)) { fatal_lang_error($packageInfo); } // Save the package to disk, use FTP if necessary create_chmod_control(array(BOARDDIR . '/packages/' . $package_name), array('destination_url' => $scripturl . '?action=admin;area=packageservers;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'])); // Done! Did we get this package automatically? if (preg_match('~^http://[\\w_\\-]+\\.elkarte\\.net/~', $_REQUEST['package']) == 1 && strpos($_REQUEST['package'], 'dlattach') === false && isset($_REQUEST['auto'])) { redirectexit('action=admin;area=packages;sa=install;package=' . $package_name); } // You just downloaded a addon from SERVER_NAME_GOES_HERE. $context['package_server'] = $server; // Read in the newly saved package information $context['package'] = getPackageInfo($package_name); if (!is_array($context['package'])) { fatal_lang_error('package_cant_download', false); } if ($context['package']['type'] == 'modification') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['install_mod'] . ' ]</a>'; } elseif ($context['package']['type'] == 'avatar') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['use_avatars'] . ' ]</a>'; } elseif ($context['package']['type'] == 'language') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['add_languages'] . ' ]</a>'; } else { $context['package']['install']['link'] = ''; } $context['package']['list_files']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=list;package=' . $context['package']['filename'] . '">[ ' . $txt['list_files'] . ' ]</a>'; // Free a little bit of memory... unset($context['package']['xml']); $context['page_title'] = $txt['download_success']; }
/** * Download a package. * * What it does: * - Accessed by action=admin;area=packageservers;sa=download * - If server is set, loads json file from package server * - requires both section and num values to validate the file to download from the json file * - If $_POST['byurl']) $_POST['filename'])) are set, will download a file from the url and save it as filename * - If just $_POST['byurl']) is set will fetch that file and save it * - github and bitbucket master files are renamed to repo name to avoid collisions * - Files are saved to the package directory and validate to be ElkArte packages */ public function action_download() { global $txt, $scripturl, $context; require_once SUBSDIR . '/PackageServers.subs.php'; // Use the downloaded sub template. $context['sub_template'] = 'downloaded'; // Security is good... if (isset($_GET['server'])) { checkSession('get'); } else { checkSession(); } // To download something, we need either a valid server or url. if (empty($_GET['server']) && (!empty($_GET['get']) && !empty($_POST['package']))) { fatal_lang_error('package_get_error_is_zero', false); } // Start off with nothing $package_name = ''; $server = ''; $url = ''; // Download from a package server? if (!empty($_GET['server'])) { list(, $url, $server) = $this->_package_server(); // Fetch the package listing from the package server $listing = json_decode(fetch_web_data($url)); // Find the requested package by section and number, make sure it matches $section = $listing->{$_GET}['section']; // This is what they requested, yes? if (basename($section[$_GET['num']]->server[0]->download) === $_GET['package']) { // Where to download it from $package_name = $this->_rename_master($section[$_GET['num']]->server[0]->download); $path_url = pathinfo($section[$_GET['num']]->server[0]->download); $url = isset($path_url['dirname']) ? $path_url['dirname'] . '/' : ''; } else { fatal_lang_error('package_cant_download', false); } } elseif (isset($_POST['byurl']) && !empty($_POST['filename'])) { $package_name = basename($_POST['filename']); } else { $package_name = $this->_rename_master($_POST['package']); } // Avoid over writing any existing package files of the same name if (isset($_REQUEST['conflict']) || isset($_REQUEST['auto']) && file_exists(BOARDDIR . '/packages/' . $package_name)) { // Find the extension, change abc.tar.gz to abc_1.tar.gz... if (strrpos(substr($package_name, 0, -3), '.') !== false) { $ext = substr($package_name, strrpos(substr($package_name, 0, -3), '.')); $package_name = substr($package_name, 0, strrpos(substr($package_name, 0, -3), '.')) . '_'; } else { $ext = ''; } // Find the first available free name $i = 1; while (file_exists(BOARDDIR . '/packages/' . $package_name . $i . $ext)) { $i++; } $package_name = $package_name . $i . $ext; } // First make sure it's a package. $packageInfo = getPackageInfo($url . $_REQUEST['package']); if (!is_array($packageInfo)) { fatal_lang_error($packageInfo); } // Save the package to disk as $package_name, use FTP if necessary create_chmod_control(array(BOARDDIR . '/packages/' . $package_name), array('destination_url' => $scripturl . '?action=admin;area=packageservers;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'])); // Done! Did we get this package automatically? if (preg_match('~^http://[\\w_\\-]+\\.elkarte\\.net/~', $_REQUEST['package']) == 1 && strpos($_REQUEST['package'], 'dlattach') === false && isset($_REQUEST['auto'])) { redirectexit('action=admin;area=packages;sa=install;package=' . $package_name); } // You just downloaded a addon from SERVER_NAME_GOES_HERE. $context['package_server'] = $server; // Read in the newly saved package information $context['package'] = getPackageInfo($package_name); if (!is_array($context['package'])) { fatal_lang_error('package_cant_download', false); } if ($context['package']['type'] == 'modification') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['install_mod'] . ' ]</a>'; } elseif ($context['package']['type'] == 'avatar') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['use_avatars'] . ' ]</a>'; } elseif ($context['package']['type'] == 'language') { $context['package']['install']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=install;package=' . $context['package']['filename'] . '">[ ' . $txt['add_languages'] . ' ]</a>'; } else { $context['package']['install']['link'] = ''; } $context['package']['list_files']['link'] = '<a href="' . $scripturl . '?action=admin;area=packages;sa=list;package=' . $context['package']['filename'] . '">[ ' . $txt['list_files'] . ' ]</a>'; // Free a little bit of memory... unset($context['package']['xml']); $context['page_title'] = $txt['download_success']; }