Final step Problem

Having problems installing EM? Let's fix that
Forum rules
DO NOT give out any FTP passwords to anyone! There is no reason to do so! If you need help badly enough, create a temporary FTP account that is restricted to only the files that you need help with and give the information for that. Giving out FTP information can be very dangerous!
Locked
User avatar
Lumpy Burgertushie
Registered User
Posts: 1006
Joined: Tue Feb 28, 2006 5:26 pm

Re: Final step Problem

Post by Lumpy Burgertushie »

this error:

Code: Select all

Warning: require_once(../../../admin/em_includes/em_cipher.php) [function.require-once]: failed to open stream: No such file or directory in /usr/home/web/wse75376/PHPbb/phpbb2019/phpBB2/admin/mods/easymod/em_includes/em_functions.php on line 59
says that the file em_cipher.php is not in the em_includes folder that is supposed to be in the admin folder.


robert

magnusgus
Registered User
Posts: 10
Joined: Mon Nov 26, 2007 9:12 pm

Re: Final step Problem

Post by magnusgus »

Yes I see, but when I look with my ftp-program, ../language/lang_english/lang_easymod.php
, is there!
It's right inside the Easymod/mods/ -directory sinc I put it here manually.
It was another directory there already, languages with the same lang_easymod.php in the first place (made in by the previous stage) and my new copy in langage/ didn't make any diff.
Almost all steps are confirmed.

I have already the three headings in the adminpanel of PHPbb,
Modifications
MOD ainstall
MOD history
MOD settings


only that I can't use EM, or watch the history etc.


But these three messages on top of the admin panel, leftside:

Warning: include() [function.include]: Unable to access ./../language/lang_english/lang_easymod.php in /usr/home/web/wse75376/PHPbb/phpbb2019/phpBB2/admin/admin_easymod.php on line 32

Warning: include(./../language/lang_english/lang_easymod.php) [function.include]: failed to open stream: Invalid argument in /usr/home/web/wse75376/PHPbb/phpbb2019/phpBB2/admin/admin_easymod.php on line 32

Warning: include() [function.include]: Failed opening './../language/lang_english/lang_easymod.php' for inclusion (include_path='.:/usr/local/share/pear') in /usr/home/web/wse75376/PHPbb/phpbb2019/phpBB2/admin/admin_easymod.php on line 32

User avatar
Lumpy Burgertushie
Registered User
Posts: 1006
Joined: Tue Feb 28, 2006 5:26 pm

Re: Final step Problem

Post by Lumpy Burgertushie »

that is a completely different set of errors from what you posted above.

anyway, its not saying that the language file is missing, it is saying that the admin_easymod.php
file is calling it wrong or something.

copy your admin_easymod.php file and paste it here in some code tags for me to see.

robert

User avatar
WhiteWolfSix
Registered User
Posts: 210
Joined: Fri Jan 21, 2005 9:05 am
Location: 48°43′N, 19°08′E

Re: Final step Problem

Post by WhiteWolfSix »

Read this: http://easymod.sourceforge.net/readme/#faq_stp5_lang

I think you have a problem with permision. Please, check the chmod of the all folders if it is correctly set up.
Image
WhiteWolfSix (WW6)

User avatar
Lumpy Burgertushie
Registered User
Posts: 1006
Joined: Tue Feb 28, 2006 5:26 pm

Re: Final step Problem

Post by Lumpy Burgertushie »

that is a possibility as well.

the permissions for all of the php files should be set to 644 and all of the folders should be set to 755

magnusgus
Registered User
Posts: 10
Joined: Mon Nov 26, 2007 9:12 pm

Re: Final step Problem

Post by magnusgus »

the permissions for all of the php files should be set to 644 and all of the folders should be set to 755
that is a possibility as well.
The new dir language was not 755 so I fixed it, all other dirs and files seems to correct now.
But still the same probem as above.
copy your admin_easymod.php file and paste it here in some code tags for me to see.
OK part1:

Code: Select all

<?php
/***************************************************************************
 *                             admin_easymod.php
 *                            -------------------
 *   begin                : Sunday Mar 31, 2002
 *   copyright            : (C) 2002-2004 by Nuttzy - Craig Nuttall, 2005 The phpBB Group
 *   email                : support@phpbb.com
 *
 *   $Id: admin_easymod.php.txt,v 1.44 2005/11/08 16:52:41 markus_petrux Exp $
 *
 *
 ***************************************************************************/

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

// entries to be displayed in the ACP index
if (!empty($setmodules))
{
	if ( @file_exists($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/lang_easymod.' . $phpEx) )
	{
		include($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/lang_easymod.' . $phpEx);
	}
	else
	{
		include($phpbb_root_path . 'language/lang_english/lang_easymod.' . $phpEx);
	}

	$file = basename(__FILE__);
	$module['Modifications']['MOD_ainstall'] = "$file?mode=install";
	$module['Modifications']['MOD_settings'] = "$file?mode=settings";
	$module['Modifications']['MOD_history'] = "$file?mode=history";
	return;
}


// if we are downloading the file (or backup), then we don't want to send a page header from pagestart.php
$mode = (isset($HTTP_POST_VARS['mode'])) ? stripslashes($HTTP_POST_VARS['mode']) : ((isset($HTTP_GET_VARS['mode'])) ? stripslashes($HTTP_GET_VARS['mode']) : '');
if (($mode == 'download_file') || ($mode == 'download_backup') ||
	($mode == 'display_file') || ($mode == 'display_backup'))
{
	$no_page_header = true;
}
unset($mode);

//
// Load phpBB code, do session and security stuff
//
define('IN_PHPBB', 1);
$phpbb_root_path = '../';
require($phpbb_root_path . 'extension.inc');
require('./pagestart.' . $phpEx);

//
$script_path = 'admin/';
//

// Load the EM language file
if ( @file_exists($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/lang_easymod.' . $phpEx) )
{
	include($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/lang_easymod.' . $phpEx);
}
else
{
	include($phpbb_root_path . 'language/lang_english/lang_easymod.' . $phpEx);
}

// make sure em_functions is where it needs to be or else the user will get a blank screen :roll:
if (!file_exists($phpbb_root_path . 'admin/em_includes/em_functions.' . $phpEx))
{
	$message = sprintf($lang['EM_err_no_file'], $phpbb_root_path . 'admin/em_includes/em_functions.' . $phpEx);
	if( !defined('IN_ADMIN') )
	{
		// We can reach this point if pagestart has not been called, therefore we better close the DB and do a plain PHP die.
		$db->sql_close();
		die($message);
	}
	message_die(GENERAL_ERROR, $message);
}

// Enable debug helpers?
define('EM_DEBUG_AID', 1);

include($phpbb_root_path . 'admin/em_includes/em_ftp.' . $phpEx);
include($phpbb_root_path . 'admin/em_includes/em_modio.' . $phpEx);
include($phpbb_root_path . 'admin/em_includes/em_functions.' . $phpEx);


///
///
define('EASYMOD_VER', 'beta (0.3.0)');
define('FAQ_LINK', '<a href="http://easymod.sourceforge.net/readme/" target="_blank">');
define('REPORT_LINK', '<a href="http://area51.phpbb.com/phpBB/viewtopic.php?t=12143" target="_blank">');
define('HOW_TO_INSTALL_MODS_URL', 'http://easymod.sourceforge.net/readme/#faq_mod_inst_main');
///
///


// prevent from attempts to read files out of expected scope
function check_file_scope($filename, $expected_scope, $simply_die = false)
{
	global $db, $lang;

	// make sure a file is located somewhere inside the specified directory
	if( !@file_exists(phpbb_realpath($filename)) || !strstr(phpbb_realpath($filename), phpbb_realpath($expected_scope)) )
	{
		$message = sprintf($lang['EM_modio_open_read'], $filename);
		if( $simply_die )
		{
			$db->sql_close();
			die($message);
		}
		message_die(GENERAL_ERROR, $message);
	}
}

// write command info to the screen (add to template)
function display_line($command, $body)
{
	global $template, $theme;

	// print the command
	$template->assign_block_vars('processed', array(
		'ROW_CLASS' => $theme['td_class2'],
		'LINE' => '<b>' . htmlspecialchars($command['command']) . '</b> &nbsp;&nbsp;&nbsp;' . $lang['EM_line'] . ' #' . $command['line'] . "\n")
	);

	// print the command body
	$line = '';
	for ($i=0; $i<count($body); $i++)
	{
//		$line .= htmlspecialchars($body[$i]) . "<br />\n";
		$line .= htmlspecialchars($body[$i]);
	}

	// make sure there is a body to print!
	if (count($body) > 0)
	{
		$template->assign_block_vars('processed', array(
			'ROW_CLASS' => $theme['td_class1'],
//			'LINE' => $line)
			'LINE' => "\n<pre>$line</pre>\n")
		);
	}
}


// write command info to the screen (add to template)
function display_unprocessed_line($command, $body)
{
	global $template, $theme;

	// print the command
	$template->assign_block_vars('unprocessed', array(
		'ROW_CLASS' => $theme['td_class2'],
		'LINE' => '<b>' . htmlspecialchars($command['command']) . '</b> &nbsp;&nbsp;&nbsp;' . $lang['EM_line'] . ' #' . $command['line'] . "\n")
	);

	// print the command body
	$line = '';
	for ($i=0; $i<count($body); $i++)
	{
//		$line .= htmlspecialchars($body[$i]) . "<br />\n";
		$line .= htmlspecialchars($body[$i]);
	}
	$template->assign_block_vars('unprocessed', array(
		'ROW_CLASS' => $theme['td_class1'],
//		'LINE' => $line)
		'LINE' => "\n<pre>$line</pre>\n")
	);
}


// display error message info; it will look like a message_die box
function display_error($message)
{
	global $template, $mode, $lang;

	// template is not defined if we are displaying/downloading the file so echo the error
	if (($mode == 'display_file') || ($mode == 'download_file'))
	{
		echo ( $mode == 'display_file' ) ? '</pre>' . $message . ' :: ' . FAQ_LINK . $lang['EM_FAQ'] . '</a> :: ' . REPORT_LINK . $lang['EM_report'] . '</a><br /><br />' : '';
		return;
	}

	$template->assign_block_vars('error', array(
		'L_TITLE' => $lang['EM_error_detail'],
		'ERROR_MESSAGE' => $message . ' :: ' . FAQ_LINK . $lang['EM_FAQ'] . '</a> :: ' . REPORT_LINK . $lang['EM_report'] . '</a>')
	);
}


// look in the DB to see if we already processed this MOD
function is_unprocessed($db, $mod_title, $mod_version, $phpbb_version)
{
	$sql = "SELECT *
		FROM " . EASYMOD_TABLE . "
		WHERE mod_title = '" . substr($mod_title, 0, 255) . "'
			AND mod_version = '" . substr($mod_version, 0, 15) . "'
		ORDER BY mod_id DESC";
	if ( !($result = $db->sql_query($sql)) || !$db->sql_fetchrow($result) )
	{
		return true;
	}
	return false;
}


// parse the MOD file and get properties about it (make sure it really is a MOD too)
function get_mod_properties($file, &$mod_title, &$mod_author_handle, &$mod_author_email, &$mod_author_name, &$mod_author_url, &$mod_description, &$mod_version, &$compliant)
{
	global $phpbb_root_path, $script_path;

	// used to add a little tolerance on the Author line
	$faux_author = false;
	$legit_author = false;

	// open the file and grab the first line
	check_file_scope($file, $phpbb_root_path . $script_path);
	$f_mod_script = fopen($file, 'r');
	if (!$f_mod_script)
	{
		return false;
	}
	$buffer = fgets($f_mod_script, 1024);

	// see if it is EMC right away; first line starts with ## on it and contains "easymod"
	$compliant = false;
	if ((stristr($buffer, 'easymod')) && (substr($buffer,0,2) == '##'))
	{
		$compliant = true;
	}

	// loop through file and try to get MOD info; only look at lines starting with ##
	$getting_desc = 0;
	$first_line = true;
	while ( (!feof($f_mod_script)) && ( substr($buffer,0,2) == '##'))
	{
		// we've already gotten the first line but still need to process it
		$buffer = ($first_line) ? $buffer : fgets($f_mod_script, 1024);
		$first_line = false;

		// check for mod title; allow just "title" if we don't have a title yet
		if ((stristr($buffer, 'MOD Title:')) || (($mod_title == '') && (stristr( $buffer, 'Title:'))))
		{
			$mod_title = htmlspecialchars(trim(substr($buffer, strpos($buffer, ":")+1)));
			$getting_desc = 0;
		}

		// check for author info
		else if ( (stristr($buffer, 'MOD Author:')) || (stristr($buffer, 'Author:') ))
		{
			// if we've already gotten a legit MOD Author, then don't go looking for another
			if ($legit_author)
			{
				continue;
			}

			// they are using just Author instead of MOD author and we've already gotten a "faux" one; get outta here
			else if ((!stristr( $buffer, 'MOD Author:')) && ($faux_author))
			{
				continue;
			}

			// again using some variant of "Author" but allow it; we'll only accept the first non-MOD Author entry
			else if ((!stristr($buffer, 'MOD Author:')) && (!$faux_author))
			{
				$faux_author = true;
			}

			// they are using the proper "MOD Author" label
			else
			{
				$legit_author = true;
			}

			// init our vars
			$mod_author_handle = '';
			$mod_author_email = '';
			$mod_author_name = '';
			$mod_author_url = '';

			// trim off the label
			$orig = trim(substr($buffer, strpos($buffer, ":")+1));

			// get real name + email address
			if (strstr($orig, '<'))
			{
				$left = strpos( $orig, "<")+1;
				$len = strpos( $orig, ">") - $left;
				$mod_author_email = htmlspecialchars(trim(substr($orig, $left, $len)));
				$mod_author_handle = htmlspecialchars(trim(substr($orig, 0, $left-1)));
				$mod_author_url = htmlspecialchars(trim(substr($orig, $left + $len +1)));
			}

			// get handle + web site
			if (strstr($orig, '('))
			{
				$left = strpos( $orig, "(")+1;
				$len = strpos( $orig, ")") - $left;
				$mod_author_name = htmlspecialchars(trim(substr($orig, $left, $len)));
				$mod_author_url = htmlspecialchars(trim(substr($orig, $left + $len +1)));
				if ( $mod_author_handle == '')
				{
					$mod_author_handle = htmlspecialchars(trim(substr($orig, 0, $left-1)));
				}
			}

			// could't get proper format so make it all the handle field
			else if ($mod_author_handle == '')
			{
				$mod_author_handle = htmlspecialchars($orig);
			}

			// see if we can debork a borked url; if there is "http:" but also spaces, take the chunck without spaces
			if ((strstr($mod_author_url, ' ')) && (strstr($mod_author_url, 'http:')))
			{
				$url_array = explode(' ', $mod_author_url);
				$pos_name = '';

				// looking for the element that has no http without any spaces; that will be our URL
				for ($url=0; $url<count($url_array); $url++)
				{
					// found our proper url
					if (strstr($url_array[$url], 'http:'))
					{
						$mod_author_url = htmlspecialchars($url_array[$url]);

						// if we didn't get a proper real name, then use whatever was in front of the url
						if ($mod_author_name == '')
						{
							$mod_author_name = htmlspecialchars($pos_name);
						}
						break;
					}

					// didn't find a url so build a potentially new value for real name
					else
					{
						$pos_name .= ($pos_name != '') ? ' ' . $url_array[$url] : $url_array[$url];
					}
				}
			}

			// if we don't have an author handle, then see what we can do
			if (($mod_author_handle == '') && ($mod_author_name != ''))
			{
				$mod_author_handle = htmlspecialchars($mod_author_name);
			}
			else if (($mod_author_handle == '') && ($mod_author_email != ''))
			{
				$mod_author_handle = htmlspecialchars($mod_author_email);
			}

			$getting_desc = 0;
		}

		// get the description (up to 3 lines); allow just "description" if we don't have a description yet
		else if ((stristr($buffer, 'MOD Description:')) || (($mod_description == '') && (stristr( $buffer, 'Description:'))))
		{
			$mod_description = htmlspecialchars(trim(substr($buffer, strpos($buffer, ":")+1)));
			$getting_desc = 1;
		}

		// get the version; allow just "version" if we don't have a version yet
		else if ((stristr( $buffer, 'MOD Version:')) || (($mod_description == '') && (stristr( $buffer, 'Version:'))))
		{
			$mod_version = htmlspecialchars(trim(substr($buffer, strpos($buffer, ":")+1)));
			$getting_desc = 0;
		}

		// if we are getting the description, chop carriage returns and make one long line; only allow 3 lines
		else if ($getting_desc > 0)
		{
			$new_line = ' ' . trim(substr($buffer, 2));
			$mod_description .= htmlspecialchars($new_line);
			$getting_desc = ($getting_desc >= 3) ? 0 : $getting_desc + 1;
		}
	}
	fclose($f_mod_script);

	// if we have a title and a handle, then that is good enough to call this a MOD (fixed in 0.0.10; used to be name)
	if (($mod_title != '') && ($mod_author_handle != ''))
	{
		return true;
	}
	else
	{
		return false;
	}
}


// strip the body array of a command down to the minimum
function strip_whitespace($body, $single_line=true)
{
	$new_array = array();
	$have_line = false;

	// rebuild the array and drop the whitespace lines
	for ($i=0; $i<count($body); $i++)
	{
		// if we already have line and are only looking for one, then skip this line
		if (($have_line) && ($single_line))
		{
			// do nothing
		}

		// if the line has something on it, then we'll want to store it
		else if (strlen(trim($body[$i])) > 0)
		{
			$new_array[] = $body[$i];
			$have_line = true;
		}

		// empty line so get this out of our body array
		else
		{
			// do nothing
		}
	}

	// the white space is now gone, return the result
	return $new_array;
}


// if we encounter an error will modifiying a file then print errors, clean up, and terminate processing if need be
function handle_error( $result, &$file_list, $line, $close_files=false, $find_array=array())
{
	global $lang;

	// if we are halting the processing then finish writing all files, just to be neat i guess
	if (($close_files) && ($result == FIND_FAIL_CRITICAL))
	{
		// if we failed on an IN-LINE command be sure to write the find_array
		if (count($find_array) > 0)
		{
			write_find_array( $find_array, $file_list);
		}

		// don't worry if file repro fails since we are halting anyway
		complete_file_reproduction( $file_list);
	}


	// handle warnings and critical errors
	$failed_close = false;
	if ( $result != OPEN_OK)
	{
		// loop through all files; print errors; and remove file from our file array
		$new_list = array();
		for ($err=0; $err<count($file_list); $err++)
		{
			// if there was an error associated with this file, then get down to biz
			if ($file_list[$err]->err_msg != '')
			{
				// if this file through a warning and we aren't halting then close just this file
				if (($close_files) && ($result != FIND_FAIL_CRITICAL))
				{
					$temp_array = array();
					$temp_array[] = $file_list[$err];

					// if we failed on an IN-LINE command be sure to write the find_array
					if (count($find_array) > 0)
					{
						write_find_array( $find_array, $temp_array);
					}

					// clean up this file
					if (!complete_file_reproduction( $temp_array))
					{
						// repro failed meaning close failed meaning we now have a show stopping error!
						$failed_close = true;
					}
				}

				// show the error(s); do this last in case file repro throw another error
				display_error( $file_list[$err]->err_msg . "<br />\n" . $lang['EM_line_num'] . $line);
			}

			// no error so this file can stay in our file list; ones with errors are removed
			else
			{
				$new_list[] = $file_list[$err];
			}
		}
		$file_list = $new_list;

		// if we have a critical error, then we have to halt the processing NOW!
		if ( ($result == OPEN_FAIL_CRITICAL) || ($failed_close))
		{
			return true;
		}
	}

	// no show stopping errors
	return false;
}


// look in the config table to get the EM settings
function get_em_settings($filename, $path, $em_pass, $preview = false)
{
	global $db, $phpbb_root_path;

	//
	// grab the EM settings
	//
	$sql = "SELECT *
		FROM " . CONFIG_TABLE . "
		WHERE config_name LIKE 'EM_%'";
	if( !$result = $db->sql_query($sql) )
	{
		message_die(GENERAL_ERROR, $lang['EM_err_config_info'], '', __LINE__, __FILE__, $sql);
	}

	// loop through all the settings and assign the EM ones as appropriate
	while ($row = $db->sql_fetchrow($result))
	{
		if ($row['config_name'] == 'EM_read')
		{
			$read = $row['config_value'];
		}
		else if ($row['config_name'] == 'EM_write')
		{
			$write = $row['config_value'];
		}
		else if ($row['config_name'] == 'EM_move')
		{
			$move = $row['config_value'];
		}
		else if ($row['config_name'] == 'EM_ftp_dir')
		{
			$ftp_dir = $row['config_value'];
		}
		else if ($row['config_name'] == 'EM_ftp_user')
		{
			$ftp_user = $row['config_value'];
		}
		else if ($row['config_name'] == 'EM_ftp_pass')
		{
			$ftp_pass = crypt_ftp_pass(EM_DECRYPT, $row['config_value'], $em_pass);
		}
		else if ($row['config_name'] == 'EM_ftp_host')
		{
			$ftp_host = $row['config_value'];
		}
		else if ($row['config_name'] == 'EM_ftp_port')
		{
			$ftp_port = $row['config_value'];
		}
		else if ($row['config_name'] == 'EM_ftp_type')
		{
			$ftp_type = $row['config_value'];
		}
		else if ($row['config_name'] == 'EM_ftp_cache')
		{
			$ftp_cache = $row['config_value'];
		}
	}

	// if we are in preview mode, then no matter what we will set to display to screen
	if ($preview)
	{
		$write = 'screen';
		$move = 'ftpm';
	}

	// easiest thing to do is return a mod_io object
	return new mod_io($filename, $path, $read, $write, $move, $ftp_user, $ftp_pass, $ftp_dir, $ftp_host, $ftp_port, $ftp_type, $ftp_cache);
}

// look in the config table to get the EM Version
function get_em_version()
{
	global $db;

	// look in db
	$sql = "SELECT *
		FROM " . CONFIG_TABLE . " 
		WHERE config_name = 'EM_version'";
	if( !$result = $db->sql_query($sql) )
	{
		message_die(GENERAL_ERROR, $lang['EM_err_config_info'], '', __LINE__, __FILE__, $sql);
	}

	// loop through all the settings and assign the EM ones as appropriate
	if ( $row = $db->sql_fetchrow($result))
	{
		return $row['config_value'];
	}

	return '';
}








// handle the mode; this is the key to securing EM
$mode = '';
$preview = false;
$get_password = false;

// if mode is passed in a GET, be very suspicious!  we don't like it when the user sends us GET vars so make sure they
//   are supposed to be
if (isset($HTTP_GET_VARS['mode']))
{
	// be very selective about what we allow from GET;  the allowed types will also require password auth
	$mode = (isset($HTTP_GET_VARS['mode'])) ? stripslashes($HTTP_GET_VARS['mode']) : '';

	if ($mode == 'help')
	{
		$template->set_filenames(array(
			'body' => 'admin/mod_help.tpl')
		);
		$template->assign_vars(array(
			'L_TITLE' => $lang['EM_installer_help'])
		);
		$first_item = true;
		foreach( $lang['help'] as $name => $paragraphs )
		{
			if( $first_item )
			{
				$first_item = false;
			}
			else
			{
				$template->assign_block_vars('helpitem.separator', array());
			}
			$template->assign_block_vars('helpitem', array(
				'TITLE' => $paragraphs[0],
				'NAME' => $name
			));
			for( $i = 1; $i < count($paragraphs); $i++ )
			{
				$template->assign_block_vars('helpitem.paragraph', array(
					'TEXT' => $paragraphs[$i]
				));
			}
		}
		$template->pparse('body');
		include('page_footer_admin.'.$phpEx);
	}

	if (($mode == 'install') || ($mode == 'settings') || ($mode == 'history'))
	{
		$get_password = true;
	}

	// if we are displaying the file to screen, then get the pw to confirm against
	else if (($mode == 'display_file') || ($mode == 'display_backup'))
	{
		$password = (isset($HTTP_GET_VARS['password'])) ? stripslashes($HTTP_GET_VARS['password']) : '';
		$install_file = ( !empty($HTTP_GET_VARS['install_file']) ) ? stripslashes(trim($HTTP_GET_VARS['install_file'])) : '';
		$install_path = ( !empty($HTTP_GET_VARS['install_path']) ) ? stripslashes(trim($HTTP_GET_VARS['install_path'])) : '';

		// important! we are writing the file output to screen so the PRE tag will format it nicely for us
		echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">' . "\n"
			. '<html>' . "\n"
			. '<head>' . "\n"
			. '<title>' . $lang['EM_Title'] . '</title>' . "\n"
			. '<style type="text/css"><!--' . "\n"
			. 'pre.normal {color:black; margin:0px; padding:0px;}' . "\n"
			. 'pre.preview {color:red; margin:0px; padding:0px; font-weight:bold;}' . "\n"
			. '--></style>' . "\n"
			. '</head>' . "\n"
			. '<body>' . "\n"
			. '<pre class="normal">';
	}

	// unexpected mode, someone is trying to circumvent the password!  we'll fix 'em ;-)
	else
	{
		// they'll now end up at the password screen instead of whatever they were trying
		$mode = 'install';
		$get_password = true;
	}
}

// get post variables; we trust post variables ;-)
else
{
	$mode = ( !empty($HTTP_POST_VARS['mode']) ) ? stripslashes(trim($HTTP_POST_VARS['mode'])) : '';

	$password = ( !empty($HTTP_POST_VARS['password']) ) ? stripslashes($HTTP_POST_VARS['password']) : '';
	$install_file = ( !empty($HTTP_POST_VARS['install_file']) ) ? stripslashes(trim($HTTP_POST_VARS['install_file'])) : '';
	$install_path = ( !empty($HTTP_POST_VARS['install_path']) ) ? stripslashes(trim($HTTP_POST_VARS['install_path'])) : '';

	// 0.0.11 preview mode
	$preview = (isset($HTTP_POST_VARS['preview'])) ? true : false;
}


// make sure mode is valid; if not then set to default mode and get pw
if (($mode != 'history') && ($mode != 'settings') && ($mode != 'install') &&
	($mode != 'display_file') && ($mode != 'download_file') &&
	($mode != 'display_backup') && ($mode != 'download_backup') &&
	($mode != 'SQL_view') && ($mode != 'SQL_execute') &&
	($mode != 'update') && ($mode != 'process') && ($mode != 'post_process') && ($mode != 'diy_process') &&
	($mode != 'history_details') && ($mode != 'del_files') && ($mode != 'del_record') && ($mode != 'restore_backups') && ($mode != 'install_lang') && ($mode != 'install_themes') && ($mode != 'uninstall'))
{
	$mode = 'install';
	$get_password = true;
}



//
// if they are trying to get to the first page, check the pw; after that assume they are validated
//
$pass_message = '';
if ((($mode == 'install') || ($mode == 'settings') || ($mode == 'history') ||
	($mode == 'display_file') || ($mode == 'display_backup')) && (!$get_password))
{
	// compare passwords and send them back to the password screen if they fail
	if (md5($password) !== get_em_pw())
	{
		$get_password = true;
		$pass_message = '<b>' . $lang['EM_err_pw_fail'] . '</b><br />';
	}
}


//
// if they are downloading or displaying a file or backup then we need to get setup
//

// downloading a file or a backup from the completed processing screen
if (($mode == 'download_file') || ($mode == 'download_backup'))
{
	// they clicked a form button; we need to figure out which one so we know what file they are looking for
	$num_files = ( isset($HTTP_POST_VARS['mod_count'])) ? intval($HTTP_POST_VARS['mod_count']) : 0;

	// loop through all the submit buttons to see which one was pressed
///////////////////////////////////
///////////////////////////////////
/////////////////////////////////// possible error.... should start at 0? was a 1 before
///////////////////////////////////
///////////////////////////////////
	for( $i=0; $i<=$num_files; $i++ )
	{
		$var_name = 'submitfile' . $i;

		// if this is the button that was pressed then we are all set!  get the file name
		if (isset($HTTP_POST_VARS[$var_name]))
		{
			$file = (isset($HTTP_POST_VARS['file'.$i])) ? stripslashes($HTTP_POST_VARS['file'.$i]) : '';
			break;
		}
	}

	// we'll need to look at the path and filename so split things up
	$split = explode('/', $file);

	// if a file, then make sure we have the filename correct
	if ($mode == 'download_file')
	{
		// by default the filename sent will match the one in the MOD script
		$process_file = (substr($file, 0, 9) == '../../../') ? substr($file, 9) : '';
		$orig_file = $process_file;

		// handle the special cases of a template file to download; only subSilver will appear in the MOD script
		if (($split[3] == 'templates') && ($split[4] != 'subSilver'))
		{
			$process_file = str_replace( $split[4], 'subSilver', $process_file);
		}

		// handle the special cases of a language file to download; only english will appear in the MOD script
		else if (($split[3] == 'language') && ($split[4] != 'lang_english'))
		{
			$process_file = str_replace( $split[4], 'lang_english', $process_file);
		}
	}

	// if a backup then we can assume the filename is valid
	else
	{
		$orig_file = $file;
		$process_file = (substr($file, 0, 9) == '../../../') ? substr($file, 9) : '';
		$process_file = $phpbb_root_path . $process_file;
	}


	// if there is no file to process then we are in trouble!
	if ($process_file == '')
	{
		message_die(GENERAL_ERROR, $lang['EM_err_no_process_file']);
	}

	// set up the redirects so we will download a file, the contents of which we will echo out
	header('Content-Type: text/x-delimtext; name="' . $split[count($split)-1] . '"');
	header('Content-disposition: attachment; filename="' . $split[count($split)-1] . '"');
}

// writing to screen, get set up
else if (($mode == 'display_file') || ($mode == 'display_backup'))
{
	// get the file name
	$file = (isset($HTTP_GET_VARS['file'])) ? stripslashes($HTTP_GET_VARS['file']) : '';
	$split = explode('/', $file);

	// if a file, then make sure we have the filename correct
	if ($mode == 'display_file')
	{
		// by default the filename sent will match the one in the MOD script
		$process_file = (substr($file, 0, 9) == '../../../') ? substr($file, 9) : '';
		$orig_file = $process_file;

		// handle the special cases of a template file to display; only subSilver will appear in the MOD script
		if (($split[3] == 'templates') && ($split[4] != 'subSilver'))
		{
			$process_file = str_replace( $split[4], 'subSilver', $process_file);
		}

		// handle the special cases of a language file to display; only english will appear in the MOD script
		else if (($split[3] == 'language') && ($split[4] != 'lang_english'))
		{
			$process_file = str_replace( $split[4], 'lang_english', $process_file);
		}
	}

	// if a backup then we can assume the filename is valid
	else
	{
		$orig_file = $file;
		$process_file = (substr($file, 0, 9) == '../../../') ? substr($file, 9) : '';
		$process_file = $phpbb_root_path . $process_file;
	}

	// if there is no file to process then we are in trouble!
	if ( $process_file == '')
	{
		message_die(GENERAL_ERROR, $lang['EM_err_no_process_file']);
	}
}



//
// Show the page header (if we aren't doing the display modes)
//
if (($mode != 'display_file') && ($mode != 'download_file') && ($mode != 'display_backup') && ($mode != 'download_backup'))
{
	$template->set_filenames(array(
		'mod_header' => 'admin/mod_header.tpl')
	);

	$template->assign_vars(array(
		'L_TITLE' => $lang['EM_Title'],
		'L_EM_VERSION' => EASYMOD_VER)
	);

	$template->pparse('mod_header');
}





//
// password authentication page
//
if ($get_password)
{
	// load the password page template
	$template->set_filenames(array(
		"body" => "admin/mod_login.tpl")
	);


	$template->assign_vars(array(
		'S_ACTION' => append_sid('admin_easymod.' . $phpEx),
		'L_ACCESS_WARNING' => $lang['EM_access_warning'],
		'L_MESSAGE' => $pass_message,
		'L_PASSWORD_TITLE' => $lang['EM_password_title'],
		'L_PASSWORD' => $lang['EM_password'],
		'L_ACCESS_EM' => $lang['EM_access_EM'],

		'MODE' => $mode)
	);
}


//
// display the settings page
//
else if ($mode == 'settings')
{
	// load the settings page template
	$template->set_filenames(array(
		"body" => "admin/mod_settings.tpl")
	);

	$command_file = get_em_settings('6E7574747A79.72756C657321', '', $password);

	$select_read =  '<option value="server"' . (($command_file->read_method == 'server') ? ' selected=selected' : ''). '>' . $lang['EM_read_server'] . '</option>';

	$select_write =  '<option value="server"' . (($command_file->write_method == 'server') ? ' selected=selected' : ''). '>' . $lang['EM_write_server'] . '</option>' . "\n";
	$select_write .= '<option value="ftpb"' . (($command_file->write_method == 'ftpb') ? ' selected=selected' : ''). '>' . $lang['EM_write_ftp'] . '</option>' . "\n";
	$select_write .= '<option value="local"' . (($command_file->write_method == 'local') ? ' selected=selected' : ''). '>' . $lang['EM_write_download'] . '</option>' . "\n";
	$select_write .= '<option value="screen">' . (($command_file->write_method == 'screen') ? ' selected=selected' : ''). '' . $lang['EM_write_screen'] . '</option>' . "\n";

	$select_move =  '<option value="copy"' . (($command_file->move_method == 'copy') ? ' selected=selected' : ''). '>' . $lang['EM_move_copy'] . '</option>' . "\n";
	$select_move .= '<option value="ftpa"' . (($command_file->move_method == 'ftpa') ? ' selected=selected' : ''). '>' . $lang['EM_move_ftp'] . '</option>' . "\n";
	$select_move .= '<option value="exec"' . (($command_file->move_method == 'exec') ? ' selected=selected' : ''). '>' . $lang['EM_move_exec'] . '</option>' . "\n";
	$select_move .= '<option value="ftpm"' . (($command_file->move_method == 'ftpm') ? ' selected=selected' : ''). '>' . $lang['EM_move_manual'] . '</option>' . "\n";

	$template->assign_vars(array(
		'S_ACTION' => append_sid('admin_easymod.' . $phpEx),
		'L_SETTINGS' => $lang['EM_settings'],
		'L_DESC' => $lang['EM_settings_desc'],

		'L_PW_TITLE' => $lang['EM_password_title'],
		'L_PW_DESC' => $lang['EM_settings_pw'],
		'L_PW_SET' => $lang['EM_password_set'],
		'L_PW_CONFIRM' => $lang['EM_password_confirm'],
		'L_EM_VERSION' => $lang['EM_easymod_version'],
		'L_EMV_DESC' => $lang['EM_emv_description'],

		'L_FILE_TITLE' => $lang['EM_file_title'],
		'L_FILE_DESC' => $lang['EM_file_desc'],
		'L_FILE_READ' => $lang['EM_file_reading'],
		'L_FILE_WRITE' => $lang['EM_file_writing'],
		'L_FILE_MOVE' => $lang['EM_file_moving'],

		'L_FTP_TITLE' => $lang['EM_ftp_title'],
		'L_FTP_DESC' => $lang['EM_ftp_desc'],
		'L_FTP_DIR' => $lang['EM_ftp_dir'],
		'L_FTP_USER' => $lang['EM_ftp_user'],
		'L_FTP_PASS' => $lang['EM_ftp_pass'],
		'L_FTP_HOST' => $lang['EM_ftp_host'],
		'L_FTP_PORT' => $lang['EM_ftp_port'],
		'L_FTP_DEBUG' => $lang['EM_ftp_debug'],
		'L_FTP_DEBUG_WARN' => $lang['EM_ftp_debug_not'],
		'L_FTP_EXT' => $lang['EM_ftp_use_ext'],
		'L_FTP_EXT_WARN' => $lang['EM_ftp_ext_not'],
		'L_FTP_CACHE' => $lang['EM_ftp_cache'],
		'L_SUPPLY_CHANGE' => $lang['EM_supply_on_change'],
		'L_YES' => $lang['EM_yes'],
		'L_NO' => $lang['EM_no'],
		'L_SUBMIT' => $lang['EM_settings_update'],

		'EM_PASS' => htmlspecialchars($password),
		'EM_VERSION' => get_em_version(),

		'SELECT_READ' => $select_read,
		'SELECT_WRITE' => $select_write,
		'SELECT_MOVE' => $select_move,

		'FTP_USER' => $command_file->ftp_user,
		'FTP_PASS' => '', // don't send FTP password to page, is unsecure $command_file->ftp_pass,
		'FTP_PATH' => $command_file->ftp_path,
		'FTP_HOST' => $command_file->ftp_host,
		'FTP_PORT' => $command_file->ftp_port,
		'FTP_EXT' => ($command_file->ftp_type == 'ext') ? 'checked="checked"' : '',
		'FTP_FSOCK' => ($command_file->ftp_type == 'fsock') ? 'checked="checked"' : '',
		'FTP_CACHE_YES' => ($command_file->ftp_cache) ? 'checked="checked"' : '',
		'FTP_CACHE_NO' => (!$command_file->ftp_cache) ? 'checked="checked"' : '',

		'U_HELP' => append_sid('admin_easymod.' . $phpEx . '?mode=help'),
		'L_HELP' => $lang['EM_more_info'],

		'MODE' => 'update')
	);
}


//
// update the EM settings; they already filled out the settings page and hit submit
//
else if ($mode == 'update')
{
	// password settings
	$em_pass = (isset($HTTP_POST_VARS['em_pass'])) ? stripslashes($HTTP_POST_VARS['em_pass']) : '';
	$em_pass_confirm = (isset($HTTP_POST_VARS['em_pass_confirm'])) ? stripslashes($HTTP_POST_VARS['em_pass_confirm']) : '';
	$em_version = (isset($HTTP_POST_VARS['em_version'])) ? stripslashes($HTTP_POST_VARS['em_version']) : '';

	// file access settings
	$read = (isset($HTTP_POST_VARS['sel_read'])) ? stripslashes($HTTP_POST_VARS['sel_read']) : '';
	$write = (isset($HTTP_POST_VARS['sel_write'])) ? stripslashes($HTTP_POST_VARS['sel_write']) : '';
	$move = (isset($HTTP_POST_VARS['sel_move'])) ? stripslashes($HTTP_POST_VARS['sel_move']) : '';

	// ftp settings
	$ftp_user = (isset($HTTP_POST_VARS['ftp_user'])) ? stripslashes($HTTP_POST_VARS['ftp_user']) : '';
	$ftp_pass = (isset($HTTP_POST_VARS['ftp_pass'])) ? stripslashes($HTTP_POST_VARS['ftp_pass']) : '';
	$ftp_host = (isset($HTTP_POST_VARS['ftp_host'])) ? stripslashes($HTTP_POST_VARS['ftp_host']) : '';
	$ftp_port = (isset($HTTP_POST_VARS['ftp_port'])) ? intval($HTTP_POST_VARS['ftp_port']) : 0;
	$ftp_debug = (isset($HTTP_POST_VARS['ftp_debug'])) ? intval($HTTP_POST_VARS['ftp_debug']) : false;
	$ftp_type = (isset($HTTP_POST_VARS['ftp_type'])) ? stripslashes($HTTP_POST_VARS['ftp_type']) : 'fsock';
	$ftp_cache = (isset($HTTP_POST_VARS['ftp_cache'])) ? intval($HTTP_POST_VARS['ftp_cache']) : 0;
	$ftp_dir = (isset($HTTP_POST_VARS['ftp_dir'])) ? stripslashes($HTTP_POST_VARS['ftp_dir']) : '/';
	$ftp_dir == ( $ftp_dir == '') ? '/' : $ftp_dir;

	// confirm passwords match and update pw if needed
	if ($em_pass === $em_pass_confirm)
	{
		// update the password; starting with 0.0.11 store as MD5 hash
		em_db_update('EM_password', md5($em_pass));
		$pass_msg = (empty($em_pass)) ? $lang['EM_pass_disabled'] : $lang['EM_pass_updated'];
		$force_ftp_pass = true;
	}
	// the confirm is empty so they are not trying to update the pw, so don't
	else if (empty($em_pass_confirm))
	{
		$pass_msg = $lang['EM_pass_not_updated'];
		$force_ftp_pass = false;
	}
	// passwords do not match so throw an error
	else if ($em_pass !== $em_pass_confirm)
	{
		message_die(GENERAL_ERROR, $lang['EM_err_set_pw']);
	}

	// update the settings
	em_db_update('EM_read', str_replace("'", "''", $read));
	em_db_update('EM_write', str_replace("'", "''", $write));
	em_db_update('EM_move', str_replace("'", "''", $move));
	em_db_update('EM_ftp_dir', str_replace("'", "''", $ftp_dir));
	em_db_update('EM_ftp_user', str_replace("'", "''", $ftp_user));

	if ( $force_ftp_pass || !empty($ftp_pass) )
	{
		// If they are updating the EM password, but they haven't supplied the FTP password, then
		// we need the old EM password to decrypt the FTP password so it can be encrypted again
		if( empty($ftp_pass) )
		{
			$ftp_pass = crypt_ftp_pass(EM_DECRYPT, $board_config['EM_ftp_pass'], $password);
		}
		em_db_update('EM_ftp_pass', str_replace("'", "''", crypt_ftp_pass(EM_ENCRYPT, $ftp_pass, $em_pass)));
	}

	em_db_update('EM_ftp_host', str_replace("'", "''", $ftp_host));
	em_db_update('EM_ftp_port', $ftp_port);
	em_db_update('EM_ftp_type', str_replace("'", "''", $ftp_type));
	em_db_update('EM_ftp_cache', $ftp_cache);
	em_db_update('EM_version', str_replace("'", "''", $em_version));

	// Test the FTP connection?
	if( $write == 'ftpb' || $move == 'ftpa' )
	{
		$command_file = get_em_settings('6E7574747A79.72756C657321', '', $password);
		$test_report = '';
		$test_result = capture_test_ftp($ftp_user, $ftp_pass, $ftp_dir, $ftp_host, $ftp_port, $ftp_debug, $ftp_type, $ftp_cache, $test_report);
		$test_report = '<table align="center"><tr><td align="left">' . $test_report . '</td></tr></table>';
	}
	else
	{
		$test_report = '';
	}

	message_die(GENERAL_MESSAGE, '<br />' . $lang['EM_settings_success'] . " $pass_msg<br /><br />$test_report");
}

//
// history
//
else if ($mode == 'history')
{
	$filter_option = isset($HTTP_POST_VARS['filter_option']) ? stripslashes(trim($HTTP_POST_VARS['filter_option'])) : '';

	// load the history page template
	$template->set_filenames(array(
		"body" => "admin/mod_history.tpl")
	);

	// Build the select options for the 'Filter By File' field.
	// First get distinct file names from DB, they include path relative to phpBB directory.
	// ...we will later build the $distinct_files array based on the basename of files.
	$sql = 'SELECT DISTINCT mod_processed_file FROM ' . EASYMOD_PROCESSED_FILES_TABLE;
	if( !($result = $db->sql_query($sql)) )
	{
	   message_die(GENERAL_ERROR, $lang['EM_err_em_info'], '', __LINE__, __FILE__, $sql);
	}
	$distinct_rows = $db->sql_fetchrowset($result);
	$distinct_count = count($distinct_rows);

	$distinct_files = array();
	for( $i = 0; $i < $distinct_count; $i++ )
	{
		$basename = basename($distinct_rows[$i]['mod_processed_file']);
		if( !in_array($basename, $distinct_files) )
		{
			$distinct_files[] = $basename;
		}
	}
	sort($distinct_files);
	$filter_select_options = '<option value="">' . htmlspecialchars($lang['EM_All_mods']) . '</option>';
	for( $i = 0; $i < count($distinct_files); $i++ )
	{
		$selected = $distinct_files[$i] == $filter_option ? ' selected="selected"' : '';
		$filter_select_options .= '<option value="' . htmlspecialchars($distinct_files[$i]) . '"' . $selected . '>' . htmlspecialchars($distinct_files[$i]) . '</option>';
	}

	// Build the list of mod_ids matching the selected processed file
	if( !empty($filter_option) )
	{
		$sql = "SELECT mod_id FROM " . EASYMOD_PROCESSED_FILES_TABLE . "
			WHERE mod_processed_file LIKE '%" . str_replace("'", "''", $filter_option) . "%'
			ORDER BY mod_id";

		if( !($result = $db->sql_query($sql)) )
		{
		   message_die(GENERAL_ERROR, $lang['EM_err_em_info'], '', __LINE__, __FILE__, $sql);
		}

		$mod_id_list = array();
		while( $row = $db->sql_fetchrow($result) )
		{
			$mod_id_list[] = $row['mod_id'];
		}
		if( count($mod_id_list) <= 0 )
		{
			$mod_id_list[] = -1;
		}
		$filter_by_mod_id_list = 'WHERE mod_id IN (' . implode(',', $mod_id_list) . ')';
		$history_status = $lang['EM_Filtered'];
	}
	else
	{
		$filter_by_mod_id_list = '';
		$history_status = $lang['EM_Unfiltered'];
	}

	// finally, get the list of matching MODs
	$sql = "SELECT *
		FROM " . EASYMOD_TABLE . "
		$filter_by_mod_id_list
		ORDER BY mod_id DESC";
	if( !$result = $db->sql_query($sql) )
	{
	   message_die(GENERAL_ERROR, $lang['EM_err_em_info'], '', __LINE__, __FILE__, $sql);
	}

	$total_mods = 0;
	while( $row = $db->sql_fetchrow($result) )
	{
		$row_class = ( !($total_mods % 2) ) ? $theme['td_class1'] : $theme['td_class2'];
		$template->assign_block_vars('install', array(
			'ROW_CLASS' => $row_class,
			'INSTALL_DATE' => create_date($board_config['default_dateformat'], $row['mod_process_date'], $board_config['board_timezone']),
			'TITLE' => $row['mod_title'],
			'VERSION' => $row['mod_version'],
			'AUTHOR' => $row['mod_author_handle'],
			'URL' => $row['mod_author_url'],
			'PHPBB_VER' => $row['mod_phpBB_version'],

			'S_ACTION' => append_sid('admin_easymod.' . $phpEx),
			'S_HIDDEN_FIELDS' => '<input type="hidden" name="mod_id" value="' . $row['mod_id'] . '" /><input type="hidden" name="mode" value="history_details" /><input type="hidden" name="password" value="' . htmlspecialchars($password) . '" /><input type="hidden" name="filter_option" value="' . htmlspecialchars($filter_option) . '" />',

/////////////////
///////////////// blah, what about schema name?
/////////////////
			'THEMES' => $row['mod_processed_themes'],
			'LANGS' => $row['mod_processed_langs'])
		);
		$total_mods++;
	}
	if ( $total_mods == 0 )
	{
		$template->assign_block_vars('no_install', array());
	}

	$template->assign_vars(array(
		'L_INSTALLED' => $lang['EM_Installed'],
		'L_INSTALLED_DESC' => $lang['EM_installed_desc'],
		'L_INSTALL_DATE' => $lang['EM_install_date'],
		'L_MOD_NAME' => $lang['EM_Mod'],
		'L_FILE' => $lang['EM_File'],
		'L_VERSION' => $lang['EM_Version'],
		'L_AUTHOR' => $lang['EM_Author'],
		'L_DESCRIPTION' => $lang['EM_Description'],
		'L_DATE' => $lang['EM_Process_Date'],
		'L_PHPBB_VER' => $lang['EM_phpBB_version'],
		'L_THEMES' => $lang['EM_Themes'],
		'L_LANGUAGES' => $lang['EM_Languages'],
		'L_NONE_INSTALLED' => ( empty($filter_by_mod_id_list) ? $lang['EM_none_installed'] : $lang['EM_none_found'] ),
		'S_DETAILS' => $lang['EM_details'],
		'L_FILTER' => $lang['EM_Filter'],
		'L_FILTER_BY_FILE' => $lang['EM_Filter_by_file'],
		'S_FILTER_OPTIONS' => $filter_select_options,
		'L_HISTORY_STATUS' => $history_status,
		'L_TOTAL_MODS' => $lang['EM_Total_mods'],
		'S_TOTAL_MODS' => $total_mods,
		'S_HIDDEN_FIELDS' => '<input type="hidden" name="mode" value="history" /><input type="hidden" name="password" value="' . htmlspecialchars($password) . '" />',
		'S_ACTION' => append_sid('admin_easymod.' . $phpEx))
	);
}

//
// history details
//
else if ( $mode == 'history_details' || (isset($HTTP_POST_VARS['cancel']) && in_array($mode, array('post_process', 'del_files', 'del_record', 'restore_backups', 'install_lang', 'install_themes', 'uninstall'))) )
{
	// get the mod id
	if ( isset($HTTP_POST_VARS['mod_id']) )
	{
		$mod_id = intval($HTTP_POST_VARS['mod_id']);
	}
	else
	{
		message_die(GENERAL_ERROR, $lang['EM_No_mod_selected']);
	}

	// load the template
	$template->set_filenames(array(
		"body" => "admin/mod_history_details.tpl")
	);

	$template->assign_vars(array(
		'L_MOD_DATA' => $lang['EM_Mod_Data'],
		'L_MOD_TITLE' => $lang['EM_Mod_Title'],
		'L_MOD_DESCRIPTION' => $lang['EM_Description'],
		'L_AUTHOR' => $lang['EM_Author'],
		'L_INSTALL_DATE' => $lang['EM_install_date'],
		'L_PHPBB_VER' => $lang['EM_phpBB_version'],
		'L_THEMES' => $lang['EM_Proc_Themes'],
		'L_LANGUAGES' => $lang['EM_Proc_Languages'],
		'L_FILES' => $lang['EM_Files'],
		'L_DB_ALTS' => $lang['EM_db_alt'],
		'L_ADDED' => $lang['EM_tables_added'],
		'L_ALTERED' => $lang['EM_tables_altered'],
		'L_INSERTED' => $lang['EM_rows_added'],
		
		'L_BACK_TO_HISTORY' => $lang['EM_back_to_history'],
		'L_DELETE_FILES' => $lang['EM_del_files'],
		'L_DELETE_RECORD' => $lang['EN_del_record'],
		'L_INSTALL_LANG' => $lang['EM_install_new_lang'],
		'L_INSTALL_THEMES' => $lang['EM_install_new_themes'],
		'L_RESTORE_BACKUPS' => $lang['EM_restore_backups'],
		'L_UNISTALL' => $lang['EM_uninstall'],
		'L_GO' => $lang['Go'],
			
		'S_ACTION' => append_sid('admin_easymod.' . $phpEx),
		'S_HIDDEN_FIELDS' => '<input type="hidden" name="mod_id" value="' . $mod_id . '" /><input type="hidden" name="password" value="' . htmlspecialchars($password) . '" /><input type="hidden" name="filter_option" value="' . htmlspecialchars(stripslashes($HTTP_POST_VARS['filter_option'])) . '" />')
	);

	$sql = "SELECT * FROM " . EASYMOD_TABLE . "
		WHERE mod_id = $mod_id
		LIMIT 0, 1";

	if( !$result = $db->sql_query($sql) )
	{
	   message_die(GENERAL_ERROR, $lang['EM_err_em_info'], '', __LINE__, __FILE__, $sql);
	}

	$row = $db->sql_fetchrow($result);

	// file
	$file = explode('/', $row['mod_file']);

	if ( file_exists('./mods/' . $row['mod_file']) )
	{
		$temp_url = $phpbb_root_path . 'admin/mods/' . $row['mod_file'];
		$mod_file = '<a href="' . htmlspecialchars($temp_url) . '" class="gen" target="_blank">' . htmlspecialchars($file[1]) . '</a>';

		// Let's hide coming soon features until fully implemented
		//$template->assign_block_vars('switch_install_file', array());
	}
	else
	{
		$mod_file = $file[1];
	}

	// see what files are there so we can work with them
	if ( file_exists('./mods/' . $file[0] . '/processed/') || file_exists('./mods/' . $file[0]. '/backups/') )
	{
		// Let's hide coming soon features until fully implemented
		//$template->assign_block_vars('switch_files', array());
	}
	// see if backups are there so we can give them the option to restore them
	if ( file_exists('./mods/' . $file[0]. '/backups/') )
	{
		$template->assign_block_vars('switch_backups', array());
	}

	// build the list of processed files for the current MOD
	$sql = "SELECT mod_processed_file FROM " . EASYMOD_PROCESSED_FILES_TABLE . "
		WHERE mod_id = $mod_id
		ORDER BY mod_processed_file";
	if( !($result = $db->sql_query($sql)) )
	{
	   message_die(GENERAL_ERROR, $lang['EM_err_em_info'], '', __LINE__, __FILE__, $sql);
	}
	$epf_rows = $db->sql_fetchrowset($result);
	$epf_count = count($epf_rows);
	$epf_list = '';
	for( $i = 0; $i < $epf_count; $i++ )
	{
		$epf_list .= '<br />' . htmlspecialchars($epf_rows[$i]['mod_processed_file']);
	}

	$template->assign_vars(array(
		'TITLE' => $row['mod_title'],
		'VERSION' => $row['mod_version'],
		'MOD_FILE' => $mod_file,
		'DESCRIPTION' => $row['mod_description'],
		'AUTHOR' => $row['mod_author_handle'],
		'EMAIL' => $row['mod_author_email'],
		'REAL_NAME' => $row['mod_author_name'],
		'URL' => $row['mod_author_url'],
		'DATE' => create_date($board_config['default_dateformat'], $row['mod_process_date'], $board_config['board_timezone']),
		'PHPBB_VERSION' => $row['mod_phpBB_version'],
		'THEMES' => $row['mod_processed_themes'],
		'LANGUAGES' => $row['mod_processed_langs'],
		'FILES' => $row['mod_files_edited'],
		'FILE_LIST' => $epf_list,
		'ADDED' => $row['mod_tables_added'],
		'ALTERED' => $row['mod_tables_altered'],
		'INSERTED' => $row['mod_rows_inserted'])
	);

}

//
// delete MOD files
//
else if ( $mode == 'del_files' )
{
	// display which folders to delete, either
	// processed, backups, or the complete folder
	message_die(GENERAL_MESSAGE, $lang['Coming_soon']);

}

//
// delete MOD record
//
else if ( $mode == 'del_record' )
{
	// display confirm and delete sql entry

	// get the mod id
	if ( isset($HTTP_POST_VARS['mod_id']) )
	{
		$mod_id = intval($HTTP_POST_VARS['mod_id']);
	}
	else
	{
		message_die(GENERAL_ERROR, $lang['EM_No_mod_selected']);
	}

	// Should we display the confirm box?
	if( !isset($HTTP_POST_VARS['confirm']) )
	{
		$s_hidden_fields = '<input type="hidden" name="mod_id" value="' . $mod_id . '" />'.
							'<input type="hidden" name="password" value="' . htmlspecialchars($password) . '" />'.
							'<input type="hidden" name="mode" value="' . $mode . '" />';
		$template->set_filenames(array(
			'body' => 'confirm_body.tpl')
		);
		$template->assign_vars(array(
			'L_INDEX'			=> '',	// Not really necessary here
			'MESSAGE_TITLE'		=> $lang['EN_del_record'],
			'MESSAGE_TEXT'		=> $lang['EM_are_you_sure'],
			'L_YES'				=> $lang['Yes'],
			'L_NO'				=> $lang['No'],
			'S_CONFIRM_ACTION'	=> append_sid('admin_easymod.' . $phpEx),
			'S_HIDDEN_FIELDS'	=> $s_hidden_fields)
		);
	}
	else
	{
		// ok, let's do it!
		$sql = "SELECT * FROM " . EASYMOD_TABLE . "
			WHERE mod_id = $mod_id";
		if( !($result = $db->sql_query($sql)) || !($row = $db->sql_fetchrow($result)) )
		{
			message_die(GENERAL_ERROR, $lang['EM_err_em_info'], '', __LINE__, __FILE__, $sql);
		}
		$mod_file = $phpbb_root_path . 'admin/mods/' . $row['mod_file'];
		$mod_folder = dirname($mod_file).'/';

		$sql = "DELETE FROM " . EASYMOD_TABLE . "
			WHERE mod_id = $mod_id";
		if( !$db->sql_query($sql) )
		{
			message_die(GENERAL_ERROR, $lang['EM_err_delete_em_info'], '', __LINE__, __FILE__, $sql);
		}

		$message = '<form method="post" action="' . append_sid('admin_easymod.' . $phpEx . '?mode=history') . '">';
		$message .= '<br />' . $lang['EM_record_deleted'] . '<br /><br />';
		if( @file_exists($mod_file) )
		{
			$message .= '<br />' . $lang['EM_warning_deldir'] . '<br /><br /><b>' . htmlspecialchars($mod_folder) . '</b><br /><br /><br />';
		}
		$message .= '<input type="submit" name="submit" class="liteoption" value="' . htmlspecialchars($lang['MOD_history']) . '" />';
		$message .= '<input type="hidden" name="password" value="' . htmlspecialchars($password) . '" />';
		$message .= '</form>';
		message_die(GENERAL_MESSAGE, $message);
	}

}

//
// Restore Backups
//
else if ( $mode == 'restore_backups' && !isset($HTTP_POST_VARS['confirm']) )
{
	// display confirm and move the backups into place

	// get the mod id
	if ( isset($HTTP_POST_VARS['mod_id']) )
	{
		$mod_id = intval($HTTP_POST_VARS['mod_id']);
	}
	else
	{
		message_die(GENERAL_ERROR, $lang['EM_No_mod_selected']);
	}

	// Read MOD information from DB...
	$sql = "SELECT * FROM " . EASYMOD_TABLE . "
		WHERE mod_id = $mod_id";
	if( !($result = $db->sql_query($sql)) || !($mod_row = $db->sql_fetchrow($result)) )
	{
		message_die(GENERAL_ERROR, $lang['EM_err_em_info'], '', __LINE__, __FILE__, $sql);
	}
	$sql = "SELECT mod_processed_file FROM " . EASYMOD_PROCESSED_FILES_TABLE . "
		WHERE mod_id = $mod_id
		ORDER BY mod_processed_file";
	if( !($result = $db->sql_query($sql)) )
	{
		message_die(GENERAL_ERROR, $lang['EM_err_em_info'], '', __LINE__, __FILE__, $sql);
	}
	$epf_rows = $db->sql_fetchrowset($result);
	$epf_count = count($epf_rows);

	// build the command array for the restore backups job
	$mod_file = './mods/' . $mod_row['mod_file'];
	$mod_folder = dirname($mod_file).'/';
	$command_ary = array();
	for( $i = 0; $i < $epf_count; $i++ )
	{
		$mod_processed_file = $epf_rows[$i]['mod_processed_file'];
		$command_ary[] = array('backups/' . $mod_processed_file . '.txt', '../../../' . $mod_processed_file);
	}

	if( ($num_command_steps = count($command_ary)) <= 0 )
	{
		message_die(GENERAL_ERROR, $lang['EM_err_no_step']);
	}

	// ok, let's build the NEW post_process stuff, then display the confirm dialog box!
	$mode = 'post_process';

	$hidden_vars_ary = array(
		'mod_id'			=> $mod_id,
		'password'			=> htmlspecialchars($password),
		'mode'				=> $mode,
		'install_path'		=> dirname($mod_file).'/',
		'install_file'		=> basename($mod_file),
		'themes'			=> $mod_row['mod_processed_themes'],
		'languages'			=> $mod_row['mod_processed_langs'],
		'files'				=> $mod_row['mod_files_edited'],
		'num_proc'			=> $mod_row['mod_files_edited'],
		'num_unproc'		=> 0
	);

	$s_hidden_fields = '';
	for( $i=0; $i < $num_command_steps; $i++ )
	{
		$command_line = 'copy ' . $command_ary[$i][0] . ' ' . $command_ary[$i][1];
		$s_hidden_fields .= '<input type="hidden" name="command_step'.$i.'" value="' . htmlspecialchars($command_line) . "\" />\n";
	}
	$s_hidden_fields .= '<input type="hidden" name="num_command_steps" value="' . $i . "\" />\n";

	foreach( $hidden_vars_ary as $key => $val )
	{
		$s_hidden_fields .= '<input type="hidden" name="' . $key . '" value="' . htmlspecialchars($val) . "\" />\n";
	}

	$template->set_filenames(array(
		'body' => 'confirm_body.tpl')
	);

	$message = '<b>' . $lang['EM_restore_backups'] . "</b>:<br /><br />\n";
	for( $i=0; $i < $num_command_steps; $i++ )
	{
		$from = $mod_folder.$command_ary[$i][0];
		$to = ((substr($command_ary[$i][1], 0, 9) == '../../../') ? substr($command_ary[$i][1], 9) : $command_ary[$i][1]);
		$message .= '<b>COPY</b> ' . htmlspecialchars($from) . ' <b>TO</b> ' . htmlspecialchars($to) . "<br />\n";
	}
	$message .= '<br /><br />' . $lang['EM_are_you_sure'];

	$template->assign_vars(array(
		'L_INDEX'			=> '',	// Not really necessary here
		'MESSAGE_TITLE'		=> $lang['EM_restore_backups'],
		'MESSAGE_TEXT'		=> $message,
		'L_YES'				=> $lang['Yes'],
		'L_NO'				=> $lang['No'],
		'S_CONFIRM_ACTION'	=> append_sid('admin_easymod.' . $phpEx),
		'S_HIDDEN_FIELDS'	=> $s_hidden_fields)
	);

}

//
// Install MOD on new Languages
//
else if ( $mode == 'install_lang' )
{
	// list which languages so user can choose and go through install process
	message_die(GENERAL_ERROR, $lang['Coming_soon']);

}

>
Last edited by magnusgus on Sat Dec 15, 2007 6:27 pm, edited 1 time in total.

magnusgus
Registered User
Posts: 10
Joined: Mon Nov 26, 2007 9:12 pm

Re: Final step Problem

Post by magnusgus »

Part2:

Code: Select all

//
// Install MOD on new themes
//
else if ( $mode == 'install_themes' )
{
	// list which themes so user can choose and go through install process
	message_die(GENERAL_ERROR, $lang['Coming_soon']);

}

//
// uninstall the mod
//
else if ( $mode == 'uninstall' )
{
	message_die(GENERAL_MESSAGE, $lang['Coming_soon']);
}

//
// display install MOD page
//
else if ( $mode == 'install')
{
	// load the install page template
	$template->set_filenames(array(
		'body' => 'admin/mod_install.tpl')
	);

	$template->assign_vars(array(
		'L_EM_INTRO' => $lang['EM_Intro'],

		'L_UNPROCESSED' => $lang['EM_Unprocessed'],
		'L_UNPROCESSED_DESC' => sprintf($lang['EM_unprocessed_mods'], HOW_TO_INSTALL_MODS_URL),

		'L_MOD' => $lang['EM_Mod'],
		'L_AUTHOR' => $lang['EM_Author'],
		'L_SUPPORT' => $lang['EM_support_thread'],
		'L_DESCRIPTION' => $lang['EM_Description'],
		'L_EMC' => $lang['EM_EMC'],
		'L_PROCESS' => $lang['EM_process'],
		'L_PREVIEW' => $lang['EM_preview'],
		'L_ALL_PROCESSED' => $lang['EM_All_Processed'],

		'S_ACTION' => append_sid('admin_easymod.' . $phpEx),
		'EM_PASS' => htmlspecialchars($password))
	);



	$phpbb_version = get_phpbb_version();
	if ($phpbb_version == '')
	{
		message_die(GENERAL_ERROR, $lang['EM_err_phpbb_ver']);
	}

	// parse the "mods" directory, looking for newly extracted mods, or mod updates
	$top_handle = opendir('./mods');
	$i = 0;
	while (false !== ($dir = readdir($top_handle)))
	{
		// only want the subdirectories (but not . and ..)
		if ( (is_dir('./mods/' . $dir) ) && ($dir != '.') && ($dir != '..'))
		{
			$path = './mods/' . $dir;
			$dir_handle = opendir($path);
			// loop through the subdirs, looking for mod files
			while (false !== ($file = readdir($dir_handle)))
			{
				$file_path =  $path . '/' . $file;
				// make sure it is not a dir, and that it ends with .txt or .mod
				if ( !is_dir( $file_path) && ( (eregi(".txt$", $file_path)) || (eregi(".mod$", $file_path))))
				{
					$mod_title = '';
					$mod_author_handle = '';
					$mod_author_email = '';
					$mod_author_name = '';
					$mod_author_url = '';
					$mod_description = '';
					$mod_version = '';
					$compliant = false;

					$is_mod = get_mod_properties($file_path, $mod_title, $mod_author_handle, $mod_author_email, $mod_author_name, $mod_author_url, $mod_description, $mod_version, $compliant);

					// if it is a MOD and has not been processed yet then add it to the list
					if (($is_mod) && ( is_unprocessed( $db, $mod_title, $mod_version, $phpbb_version)))
					{
						$row_class = ( !($i % 2) ) ? $theme['td_class1'] : $theme['td_class2'];
						$template->assign_block_vars('unprocessed', array(
							'ROW_CLASS' => $row_class,
							'MOD_TITLE' => $mod_title,
							'MOD_AUTHOR' => $mod_author_handle,
							'MOD_URL' => $mod_author_url,
							'MOD_VERSION' => $mod_version,
							'MOD_DESC' => $mod_description,
							'MOD_EMC' => ($compliant) ? '<img src="../templates/subSilver/images/emc.gif">' : $lang['No'],
							'MOD_PATH' => $path . '/',
							'MOD_FILE' => $file,
							'MOD_FILE_URL' => $path . '/' . $file)
						);
						$i++;
					}
				}
			}
		}
	}

	// didn't find any MODs we can process
	if ( $i == 0 )
	{
		$template->assign_block_vars('no_unprocessed', array());
	}
}


//
// preview the changes EM will be making to files
//
else if ($preview)
{
	$files = array();
	check_file_scope($install_path . $install_file, $phpbb_root_path . $script_path);
	$f_mod_script = fopen($install_path . $install_file, 'r');
	while (!feof($f_mod_script))
	{
		$buffer = fgets($f_mod_script, 4096);

		// if the line starts with #, this is either a comment or an action command

		// after obtaining the command, skip any comments until we reach the command body
		if (($buffer[0] == '#') && ($in_header))
		{
			// do nothing until we are out of the command header!!
		}

		// not in a header so this comment is either a random comment or start of a command header
		else if ($buffer[0] == '#')
		{
			// if we find [ and ] and OPEN on this line, then we can be reasonably sure we've got an OPEN command
			if ((strstr($buffer, '[')) && (strstr($buffer, ']')) && (strstr($buffer, 'OPEN')))
			{
				// get us past any remaining # lines
				$buffer = fgets($f_mod_script, 4096);
				while ($buffer[0] == '#')
				{
					if ( feof($f_mod_script))
					{
						break;
					}
					$buffer = fgets($f_mod_script, 4096);
				}

				// loop until we get a filename (a non-whitespace line) or the next # line
				while (!feof($f_mod_script))
				{
					// got a line with some text not starting with #, so we're calling this a filename ;)
					if ((strlen(trim($buffer)) > 0) && ($buffer[0] != '#'))
					{
						$files[] = trim($buffer);
						break;
					}

					// we found a # so get us out of here
					else if ($buffer[0] == '#')
					{
						break;
					}

					$buffer = fgets($f_mod_script, 4096);
				}

				// if we hit eof, then get us out of here
				if (feof($f_mod_script))
				{
					break;
				}
			}
		}

		// not a comment or command so this is the body of the command
		else
		{
			$in_header = false;
		}
	}
	fclose($f_mod_script);


	// Show the preview page
	$template->set_filenames(array(
		'body' => 'admin/mod_preview.tpl')
	);

	$template->assign_vars(array(
		'L_HEADER' => $lang['EM_preview_mode'],
		'L_PREVIEW_DESC' => $lang['EM_preview_desc'],
		'L_FILENAME' => $lang['EM_preview_filename'],
		'L_VIEW' => $lang['EM_preview_view'])
	);


	// load in the filename and link info
	for ($i=0; $i<count($files); $i++)
	{
		$link = append_sid('admin_easymod.' . $phpEx . '?mode=display_file&file=../../../' . $files[$i] . "&password=$password&install_file=$install_file&install_path=$install_path");

		$template->assign_block_vars('files', array(
			'NAME' => $files[$i],
			'URL' => $link)
		);
	}

	// if there are no files to be modified, then display the message
	if ( count($files) == 0)
	{
		$template->assign_block_vars('nofiles', array(
			'L_NO_FILES' => $lang['EM_preview_nofile'])
		);
	}
}


//
// download or display a backup of the core phpBB file
//
else if (($mode == 'display_backup') || ($mode == 'download_backup'))
{
	// open the core file
	check_file_scope($process_file, $phpbb_root_path . $script_path, true);
	if (!$read_file = fopen($process_file, 'r'))
	{
		// gotta echo out the message since message_die is not an option
		echo sprintf( $lang['EM_err_backup_open'], $process_file) . "\n";
		exit;
	}

	// write out the lines
	while (!feof($read_file))
	{
		$newline = fgets($read_file, 4096);
		if ($mode == 'download_backup')
		{
			echo $newline;
		}
		else
		{
			echo htmlspecialchars($newline);
		}
	}
	fclose($read_file);

	// finish the PRE formatting tag
	if ($mode == 'display_backup')
	{
		echo "</pre>\n</body>\n</html>\n";
	}

	// done! done! done!
	exit;
}


//
// process the MOD script and modify the files
//
else if (($mode == 'process' ) || ($mode == 'display_file') || ($mode == 'download_file'))
{
	// 0.0.11 preview mode
	$preview = (isset($HTTP_POST_VARS['preview'])) ? 1 : ($mode == 'display_file') ? 1 : 0;

	$current_command = '';
	$commands = array();
	$body = array();

	$in_header = false;			// in the header of the command (the ## section)
	$line_num = 0;				// line number in the MOD script we are parsing

	$found_file = false;		// only for the special cases


	//
	// open the mod script and load an array with commands to execute
	//

	check_file_scope($install_path . $install_file, $phpbb_root_path . $script_path);
	$f_mod_script = fopen($install_path . $install_file, 'r');
	while (!feof($f_mod_script))
	{
		$buffer = fgets($f_mod_script, 4096);
		$line_num++;

		// if the line starts with #, this is either a comment or an action command; will also tell us when
		//    we've hit the last search line of the target content for this command (meaning we've reached the
		//    next command)

		// after obtaining the command, skip any comments until we reach the command body
		if (($buffer[0] == '#') && ($in_header))
		{
			// do nothing until we are out of the command header!!
		}

		// not in a header so this comment is either a random comment or start of a command header
		else if ($buffer[0] == '#')
		{
			// done with last command now that we've hit a comment (regardless if a new command or just a comment)
			if ( $current_command != '')
			{
				$current_command = '';
			}

			// if we find [ and ] on this line, then we can be reasonably sure it is an action command
			if ((strstr($buffer, '[')) && (strstr($buffer, ']')))
			{

				//
				// we know it's an action, take appropriate steps for the action; see if the current command
				//   is found on our list;  NOTE: since we are using strstr, it is important to keep the
				//   IN-LINE commands listed before thier similarly named cousins
				//

				if (strstr($buffer, 'OPEN'))
				{
					$current_command = 'OPEN';
				}
				else if (strstr($buffer, 'IN-LINE FIND'))
				{
					$current_command = 'IN-LINE FIND';
				}
				else if (strstr($buffer, 'FIND'))
				{
					$current_command = 'FIND';
				}
				else if (strstr($buffer, 'IN-LINE AFTER, ADD'))
				{
					$current_command = 'IN-LINE AFTERADD';
				}
				else if (strstr($buffer, 'AFTER, ADD'))
				{
					$current_command = 'AFTERADD';
				}
				else if (strstr($buffer, 'IN-LINE BEFORE, ADD'))
				{
					$current_command = 'IN-LINE BEFOREADD';
				}
				else if (strstr($buffer, 'BEFORE, ADD'))
				{
					$current_command = 'BEFOREADD';
				}
				else if (strstr($buffer, 'IN-LINE REPLACE'))
				{
					$current_command = 'IN-LINE REPLACE';
				}
				else if (strstr($buffer, 'REPLACE'))
				{
					$current_command = 'REPLACE';
				}
				else if (strstr($buffer, 'COPY'))
				{
					$current_command = 'COPY';
				}
				else if (strstr($buffer, 'SQL'))
				{
					$current_command = 'SQL';
				}
				else if ( strstr($buffer, 'DIY INSTRUCTIONS') )
				{
					$current_command = 'DIY INSTRUCTIONS';
				}
				else if ( strstr($buffer, 'INCREMENT') )
				{
					$current_command = 'INCREMENT';
				}
				else if (strstr($buffer, 'SAVE/CLOSE'))
				{
					$current_command = 'CLOSE';
				}

				// not a known command, let see if it is unrecognized command or just a comment
				else
				{
					$left_bracket = strpos($buffer, '[');
					$right_bracket = strpos($buffer, ']');
					$left_of_bracket = substr($buffer, 0, $left_bracket);
					$right_of_bracket = substr($buffer, $right_bracket);

					// if there is no "--" both before and after the brackets, this must be a comment
					if (($left_bracket < $right_bracket) && (strstr($left_of_bracket, '--')) && (strstr($right_of_bracket, '--')))
					{
						$current_command = trim(substr($buffer, $left_bracket+1, (($right_bracket-1)-($left_bracket+1))));
					}
				}

				// handle special cases when we display or download the file; we are looking for the commands
				//   for one file ONLY, so skip commands until we find the corresponding OPEN
				if (($mode == 'display_file') || ($mode == 'download_file'))
				{
					if ( $current_command != '')
					{
						// not found found file yet so this is a possible canidate
						if ((!$found_file) && ($current_command == 'OPEN'))
						{
							$in_header = true;
						}

						// ignore all other commands until we have our file
						else if ((!$found_file) && ($current_command != 'OPEN'))
						{
							$current_command = '';
						}

						// after found, once we hit another OPEN or the CLOSE, then we are done
						else if ((($found_file) && ($current_command == 'OPEN') && (!$in_header)) || ($current_command == 'CLOSE'))
						{
							$current_command = '';
							break;
						}

						// allow processing of this command
						else
						{
							$in_header = true;
							$commands[] = array( 'command' => $current_command, 'line' => $line_num);
							$body[] = array();
						}
					}
				}

				// normal command processing
				else if ( $current_command != '')
				{
					$in_header = true;
					$commands[] = array( 'command' => $current_command, 'line' => $line_num);
					$body[] = array();
				}
			}
		}

		// not a comment or command so this is the body of the command
		else if ( $current_command != '')
		{
			// handle special cases; make sure this is for the specific file we are looking for
			if (($mode == 'display_file') || ($mode == 'download_file'))
			{
				// not found found file yet so see if this is it
				if ((!$found_file) && ($current_command == 'OPEN'))
				{
					// found the file, excellent!
					if (trim($buffer) == $process_file)
					{
						$commands[] = array( 'command' => $current_command, 'line' => $line_num);
						$body[] = array();
						$body[ count($body)-1 ][] = $buffer;
						$found_file = true;
					}
				}

				// haven't found the file yet, so don't process this command (should never get in here)
				else if (!$found_file)
				{
					$current_command = '';
				}

				// this command relates to the file we are looking for, so go ahead
				else
				{
					$body[ count($body)-1 ][] = $buffer;
				}
				$in_header = false;
			}

			// store this as this body of our command
			else
			{
				$in_header = false;
				$body[ count($body)-1 ][] = $buffer;
			}
		}
	}
	fclose($f_mod_script);

	// load the process mod template unless we are in special case mode
	if (($mode != 'display_file') && ($mode != 'download_file'))
	{
		// set the template
		$template->set_filenames(array(
			'body' => 'admin/mod_process.tpl')
		);
	}


	$file_list = array();

	$search_array = array();		// what we are searching for
	$search_fragment = '';			// the IN-LINE FIND fragment we are looking for
	$find_array = array();			// contains lines from a FIND which potentially contain our search target

	$files_edited = 0;
	$num_processed = 0;
	$num_unprocessed = 0;

	$failed = true;
	$exec_close = false;			// did we hit the close command?

	// grab the EM settings and open the command file
	$command_file = get_em_settings('post_process.sh', '', $password, $preview);

	// this is really more about moving the other files than is about the command file; establish the FTP connection
	//  for moving files if necessary
	if (!$command_file->modio_prep('move'))
	{
		$command_file->err_msg = $lang['EM_trace'] . ': main[1]->' . $command_file->err_msg;
		message_die(GENERAL_ERROR, '<b>' . $lang['EM_err_critical_error'] . ':</b><br />' . $command_file->err_msg . '<br />');
	}


////////////////////
//////////////////// emcopy - to be fixed and removed in 0.0.11
////////////////////
	$display_copy_warning = false;
	$display_sql_warning = false;
	$sql = array();


	//
	// now that we have the commands all set let's start to process them
	//

	// loop through the command and knock 'em out ;-)
	for ($i=0; $i<count($commands); $i++)
	{
		// a catch all at the end will switch to false if we fail to process
		$processed = true;
		$bad_command = false;

		// protect against malformed script that didn't perform a FIND first; this acts as a gatekeeper to ensure
		//   that the find_array is being managed correctly; OPEN and FIND write out any remenants of find_array; AFTER
		//   and REPLACE destroy the array while BEFORE and the IN-LINE's preserve it to be used again
		if ((count($find_array) == 0 ) && (($commands[$i]['command'] == 'BEFOREADD') || (strstr($commands[$i]['command'], 'IN-LINE'))))
		{
			display_error( '<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $commands[$i]['command'] . $lang['EM_err_no_find'] . "<br />\n" . $lang['EM_line_num'] . $commands[$i]['line']);
			break;
		}


		//
		// open phpBB core file
		//
		if ($commands[$i]['command'] == 'OPEN')
		{
			// if we were doing an BEFORE or an IN-LINE command we need to write out the find_array
			//   also, see if we need to write the lines in preview format
			if ($i>0)
			{
				$do_preview = ((strstr($commands[$i-1]['command'], 'IN-LINE') || $commands[$i-1]['command'] == 'INCREMENT') && ($preview)) ? true : false;
			}
			else
			{
				$do_preview = false;
			}

			write_find_array( $find_array, $file_list, $do_preview);
			$find_array = array();

			// if we already had a file open, close it now
			if (!complete_file_reproduction($file_list))
			{
				// close failed; throw errors and halt
				for ($errs=0; $errs<count($file_list); $errs++)
				{
					display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $file_list[$errs]->err_msg . "<br />\n" . $lang['EM_line_num'] . $commands[$i]['line']);
				}

				// halt processing
				break;
			}

			// strip the body of whitespace down and down to a single line
			$body[$i] = strip_whitespace($body[$i], true);

			// if there is not exactly 1 line then throw a critical error
			if ( count($body[$i]) != 1)
			{
				display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $lang['EM_err_comm_open'] . "<br />\n" . $lang['EM_line_num'] . $commands[$i]['line']);
				break;
			}

			// strip off the path and get the file name
			$splitarray = explode('/', trim($body[$i][0]));
			$filename = $splitarray[count($splitarray)-1];

			// now get the path
			$path = '';
			for ($k=0; $k<count($splitarray)-1; $k++)
			{
				$path .= $splitarray[$k] . '/';
			}


			// open the file(s)
			$file_list = array();
			$result = open_files($filename, $path, $file_list, $command_file);

			// display any errors; if it was critical, terminate processing; if warn, remove file from list
			if (handle_error($result, $file_list, $commands[$i]['line']))
			{
				break;
			}

			// increment our count
			$files_edited += count($file_list);
		}

		//
		// find a string or sequential group of strings in the file
		//
		else if ($commands[$i]['command'] == 'FIND')
		{
			// if we were doing an BEFORE or an IN-LINE command we need to write out the find_array
			//   also, see if we need to write the lines in preview format
			$do_preview = ((strstr($commands[$i-1]['command'], 'IN-LINE') || $commands[$i-1]['command'] == 'INCREMENT') && ($preview)) ? true : false;
			write_find_array($find_array, $file_list, $do_preview);

			// reinit key vars
			$find_array = array();
			$search_fragment = '';

			// strip the body of whitespace lines; allow multiple lines
			$body[$i] = strip_whitespace($body[$i], false);


			// make sure we have something to search for; throw a warning if not
			$search_array = $body[$i];
			if ( count($search_array) == 0 )
			{
				display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $lang['EM_err_comm_find'] . "<br />\n" . $lang['EM_line_num'] . $commands[$i]['line']);
				break;
			}

			// do the find and see what happens
			$result = perform_find($file_list, $find_array, $search_array);

			// display any errors; if it was critical, terminate processing; if warn, remove file from list
			//   the command will also close the files that we were writing
			if (handle_error($result, $file_list, $commands[$i]['line'], true))
			{
				break;
			}
		}

		//
		// write out the find array then write the body
		//
		else if ($commands[$i]['command'] == 'AFTERADD')
		{
			$insert_string = '';
			for ($j=0; $j<count($body[$i]); $j++)
			{
				$insert_string .= $body[$i][$j];
			}

			// if we are preview mode, then mark these effect lines as special
			if ($mode == 'display_file')
			{
				$insert_string = 'EM>>' . $insert_string;
			}

			// see if we need to write the lines in preview format
			$do_preview = ((strstr($commands[$i-1]['command'], 'IN-LINE') || $commands[$i-1]['command'] == 'INCREMENT') && ($preview)) ? true : false;

			write_find_array($find_array, $file_list, $do_preview);
			write_files($file_list, $insert_string);

			// we've written the find array already so we can no longer operate on it
			$find_array = array();
		}

		//
		// write the body then write out the find array
		//
		else if ($commands[$i]['command'] == 'BEFOREADD')
		{
			$insert_string = '';
			for ($j=0; $j<count($body[$i]); $j++)
			{
				$insert_string .= $body[$i][$j];
			}

			// if we are preview mode, then mark these effect lines as special
			if ($mode == 'display_file')
			{
				$insert_string = 'EM>>' . $insert_string;
			}

			write_files($file_list, $insert_string);

			// NOTE: since we have not modified the find_array in any way we can still perform operations on it
			//   so do not write it out
		}

		//
		// write the body then throw out the find array!
		//
		else if ($commands[$i]['command'] == 'REPLACE')
		{
			// is this a totally easy command or what!?!?!  That's why it is soooo dangerous to use.  Another
			//   mod will never be able to work again if it needs to FIND what we just replaced	

			// write the replace lines and notice how we never will write the find_array lines
			for ($j=0; $j<count($body[$i]); $j++)
			{
				// if we are preview mode, then mark these effect lines as special
				if ($mode == 'display_file')
				{
					write_files($file_list, 'EM>>' . $body[$i][$j]);
				}
				else
				{
					write_files($file_list, $body[$i][$j]);
				}
			}

			// we've obliterated the find array already so we can no longer operate on it
			$find_array = array();
		}

		else if ($commands[$i]['command'] == 'INCREMENT')
		{
			// strip the body of whitespace down and down to a single line
			$body[$i] = strip_whitespace($body[$i], true);

			// if there is not exactly 1 line then throw a critical error
			if (count($body[$i]) != 1)
			{
				display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $commands[$i]['command'] . $lang['EM_err_increment_body'] . "<br />\n" . $lang['EM_line_num'] . $commands[$i]['line']);
				break;
			}

			// parse the increment command
			$inc_data = array();
			if (!preg_match('#(%\:\d+)\s*([\+\-]\d+)?#',trim($body[$i][0]),$inc_data))
			{
				display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $commands[$i]['command'] . $lang['EM_err_increment_body'] . "<br />\n" . $lang['EM_line_num'] . $commands[$i]['line']);
				break;
			}
			$inc_data[1] = '{'.$inc_data[1].'}';
			$inc_data[2] = isset($inc_data[2]) ? $inc_data[2] : 1;

			// perform the increment / throw an error as appropriate
			$err_level = FIND_OK;
			for ( $file_count = 0; $file_count < count($file_list); $file_count++ )
			{
				for ( $j = 0; $j < count($find_array); $j++ )
				{
					$increment_search = ($search_fragment != '') ? $search_fragment : $search_array[$j];
					$result = increment_wildcard($inc_data[1], $inc_data[2], $increment_search, $find_array[$file_count][$j]);
					if ($result !== false)
					{
						$find_array[$file_count][$j] = $result;
						break;
					}
				}
				if ($j == count($find_array))
				{
					// halt if this is an english lang file
					if (strstr($file_list[$file_count]->path, 'language/lang_english'))
					{
						$file_list[$file_count]->err_msg = '<b>' . $lang['EM_err_critical_error'] . '</b><br /><br />';
						$err_level = FIND_FAIL_CRITICAL;
					}

					// halt if this is a subsilver style file
					else if (strstr($file_list[$file_count]->path, 'templates/subSilver'))
					{
						$file_list[$file_count]->err_msg = '<b>' . $lang['EM_err_critical_error'] . '</b><br /><br />';
						$err_level = FIND_FAIL_CRITICAL;
					}

					// if a different lang, then allow to continue processing
					else if (strstr($file_list[$file_count]->path, 'language/lang_'))
					{
						$file_list[$file_count]->err_msg = '<b>' . $lang['EM_err_warning'] . '</b><br /><br />';
						$err_level = FIND_FAIL_OK;
					}

					// if a different style file, then allow to continue processing
					else if (strstr($file_list[$file_count]->path, 'templates/'))
					{
						$file_list[$file_count]->err_msg = '<b>' . $lang['EM_err_warning'] . '</b><br /><br />';
						$err_level = FIND_FAIL_OK;
					}

					// any other file then halt processing
					else
					{
						$file_list[$file_count]->err_msg = '<b>' . $lang['EM_err_critical_error'] . '</b><br /><br />';
						$err_level = FIND_FAIL_CRITICAL;
					}
					$file_list[$file_count]->err_msg .= sprintf($lang['EM_err_ifind_fail'], $file_list[$file_count]->path . trim($file_list[$file_count]->filename)) . ':<br /><br />' . htmlspecialchars($search_fragment) . "<br />\n";
				}
			}
			// display any errors; if it was critical, terminate processing; if warn, remove file from list
			//   the command will also close the files that we were writing
			if (handle_error($err_level, $file_list, $commands[$i]['line'], true, $find_array))
			{
				break;
			}
		}

		//
		// IN-LINE commands; perform precision operations on a single line
		//
		else if (strstr($commands[$i]['command'], 'IN-LINE'))
		{
/////////////////////
///////////////////// wasn't there something about not trimming the left side?
/////////////////////
			// strip the body of whitespace down and down to a single line
			$body[$i] = strip_whitespace($body[$i], true);

			// if there is not exactly 1 line then throw a critical error
			if (count($body[$i]) != 1)
			{
				display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $commands[$i]['command'] . $lang['EM_err_inline_body'] . "<br />\n" . $lang['EM_line_num'] . $commands[$i]['line']);
				break;
			}

			// if there is no search fragment for an AFTER, BEFORE, or REPLACE then throw a crit error
			if (($search_fragment == '') && ($commands[$i]['command'] != 'IN-LINE FIND'))
			{
				display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $commands[$i]['command'] . $lang['EM_err_no_ifind'] . "<br />\n" . $lang['EM_line_num'] .$commands[$i]['line']);
				break;
			}


			// make the actual alteration for after, before, and replace
			if ($commands[$i]['command'] == 'IN-LINE AFTERADD')
			{
				$result = perform_inline_add($find_array, $file_list, $search_fragment, $body[$i][0], 'after');
			}
			else if ($commands[$i]['command'] == 'IN-LINE BEFOREADD')
			{
				$result = perform_inline_add($find_array, $file_list, $search_fragment, $body[$i][0], 'before');
			}
			else if ($commands[$i]['command'] == 'IN-LINE REPLACE')
			{
				$result = perform_inline_add($find_array, $file_list, $search_fragment, $body[$i][0], 'replace');
			}
			// strip off white space and get our search fragment (we already know it is not an empty string)
			else if ($commands[$i]['command'] == 'IN-LINE FIND')
			{
				$search_fragment = trim($body[$i][0]);
			}
			else
			{
				$bad_command = true;
			}

			// display any errors; if it was critical, terminate processing; if warn, remove file from list
			//   the command will also close the files that we were writing
			if (handle_error($result, $file_list, $commands[$i]['line'], true, $find_array))
			{
				break;
			}
		}

		else if ($commands[$i]['command'] == 'SQL')
		{
			$sql[] = $body[$i];
		}

		else if ( $commands[$i]['command'] == 'DIY INSTRUCTIONS')
		{
			$diy[] = $body[$i];
		}

		//
		// setup the copying of files from the mod directory to core directories
		//
		else if ($commands[$i]['command'] == 'COPY')
		{
			// strip the body of whitespace lines; allow multiple lines
			$body[$i] = strip_whitespace($body[$i], false);

/*
//////////////////////////////////////////////////////////////////////////////
// this COPY command was mostly written by Ptirhiik and integrated by me.  It's not perfect yet, and I can't remember why
//   since it's been soooooo long since I worked on the dang thing!  Will fine tune it later.  
//////////////////////////////////////////////////////////////////////////////


////////// yeah.... can't remember what most of these notes mean ;-)

copy to *.*
copy *.*
copy templates/*.*				to foo
copy includes/functions?.* to foo
copy templates/subSilver/images/icon*.gif to foo
copy templates/sub* to templates/sav
copy ind*.php to sav*.?u?

copy foo_body.tpl to templates/subSilver/foo_body.tpl 
copy foo_body.tpl to templates/subSilver/ 
copy *.* to templates/subSilver/ 

want to work:
copy admin_flags.php to admin/admin_flags.php				// basic
copy admin_flags.php 		to 	admin/admin_flags.php		// basic with tabs
copy admin_flags.php		to	admin/				// to a dir with trailing slash
copy admin_flags.php		to	admin					// to a dir without trailing slash
copy admin_flags.php		to	admin/*.*				// to a dir as *.*
copy admin_flags.?h?		to	admin					// from with ? wildcards
copy admin_flags.*		to	admin					// from with * wildcard
copy a*.*				to	admin					// from with * wildcards
copy *.*				to	admin					// from as *.*

on the bubble:
copy admin_flags.php		to	admin/*				// to a dir as *
copy a*s.*				to	admin					// from with * wildcards
copy templates/sub* to templates/sav			// wow!!!
copy ind*.php to sav*.?u?					// the heck??



#copy admin_flags.php		to	admin/
#copy admin_flags.php		to	admin/*.*
#copy admin_flags.?h?		to	admin
#copy admin_flags.*		to	admin
#copy admin_flags.*		to	admin/
#copy a*.*			to	admin/
#copy a*.*			to	admin/xxx		// sends files to admin/xxx/ directory
#copy admin_flags.php		to	admin			// careful! Will create a FILE named admin!!
#copy *.*			to	admin
#copy flags/a*.*		to	admin
#copy admin_flags.php		to	admin/*			// careful! file named 'admin_flags' w/o .php!
#copy admin_flags.php		to	admin/*.sfdg
#copy a*s.*				to	admin
#copy processed/templates/sub* to templates/sav
#copy a*.php to sav*.?u?


*/

			// multiple copies : from
			$tmp_mult['from_path'] = array();
			$tmp_mult['from_file'] = array();
			$tmp_mult['to_path'] = array();
			$tmp_mult['to_file'] = array();


			//
			// first pass : split qualified copies from masked copies
			//
			$bad_copy = false;
			for ( $j = 0; $j < count($body[$i]); $j++ )
			{
				$split_line = array();
				// make sure the command is in proper format "copy x to y"
				if (!$split_line = copy_check_basic_form($body[$i][$j]))
				{
//echo "1<br />\n";
					display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $lang['EM_err_copy_format'] . '<br />' . trim($body[$i][$j]) . "<br />\n" . $lang['EM_line_num'] .$commands[$i]['line']);
					$bad_copy = true;
					break;
				}

				// makes sure the filename+path are ok and do a little formatting
				if ((!$targ = copy_check_file(trim( $split_line[1]))) || 
					(!$dest = copy_check_file(trim( $split_line[3]))))
				{
//echo "2<br />\n";
					display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $lang['EM_err_copy_format'] . '<br />' . trim($body[$i][$j]) . "<br />\n" . $lang['EM_line_num'] .$commands[$i]['line']);
					$bad_copy = true;
					break;
				}

				// final format check, make sure we have a muli dest if we have a multi targ
				if ( strstr($targ['file'], '*') || strstr($targ['file'], '?') )
				{
					// force this to be a multi dest listing if not so already
					if ((!strstr( $dest['file'], '*')) && (!strstr( $dest['file'], '?')) )
					{
						$dest['path'] .= $dest['file'] . '/';
						$dest['file'] = '*.*';
					}
				}				
				else
				{
					// check to see if the file exists
					if (!file_exists($install_path . $targ['path'] . $targ['file']) )
					{
						display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . sprintf($lang['EM_err_comm_copy'], $install_path . $targ['path'], $targ['file']) . '<br />' . trim($body[$i][$j]) . "<br />\n" . $lang['EM_line_num'] .$commands[$i]['line']);
						$bad_copy = true;					
					}

				}

				// store
				$tmp_mult['from_path'][] = $targ['path'];
				$tmp_mult['from_file'][] = $targ['file'];
				$tmp_mult['to_path'][] = $dest['path'];
				$tmp_mult['to_file'][] = $dest['file'];
			}

			// if we failed then halt processing
			if ($bad_copy)
			{
				break;
			}

			//
			// second pass : get the relevant files with the mask
			//
			for ( $j = 0; $j < count($tmp_mult['from_path']); $j++ )
			{
				if ($bad_copy)
				{
					break;
				}
				$tmp_from_path = $tmp_mult['from_path'][$j];
				$tmp_from_file = $tmp_mult['from_file'][$j];
				$tmp_to_path = $tmp_mult['to_path'][$j];
				$tmp_to_file = $tmp_mult['to_file'][$j];

				// from mask
				$tmp_all = ($tmp_from_file == '*.*');
				$tmp_from_mask = '^' . str_replace(array('*', '?'), array('(.+)', '(.)'), $tmp_from_file . '$');

				// to maks
				$tmp_to_mask = $tmp_to_file;
				$tmp_pos = strrpos($tmp_to_mask, '.');
				if ( $tmp_pos === false )
				{
					$tmp_to_ext = '';
					$tmp_to_base = $tmp_to_file;
				}
				else
				{
					$tmp_to_ext = substr($tmp_to_file, $tmp_pos+1);
					$tmp_to_base = substr($tmp_to_file, 0, $tmp_pos);
				}

				// stack of subdirs
				$tmp_dirs_from = array();
				$tmp_dirs_to = array();

				// init with the asked dir
				array_push($tmp_dirs_from, $tmp_from_path);
				array_push($tmp_dirs_to, $tmp_to_path);

				// let's go
				$first_pass = true;
				while ( !empty($tmp_dirs_from) )
				{
					// get the dir
					$tmp_from_dir = array_pop($tmp_dirs_from);
					$tmp_to_dir = array_pop($tmp_dirs_to);

					// we are no more on the main dir, so accept all files and sub dirs
					if ( !$first_pass )
					{
						$tmp_all = true;
					}
					$first_pass = false;

					// another one bites the dust
					if (!$tmp_handle = @opendir($install_path . $tmp_from_dir) )
					{
//echo "3 [$install_path][$tmp_from_dir]<br />\n";
						display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $lang['EM_err_copy_format'] . '<br />' . trim($body[$i][$j]) . "<br />\n" . $lang['EM_line_num'] .$commands[$i]['line']);
						$bad_copy = true;
						break;
					}

					while ( $tmp_file = readdir($tmp_handle) )
					{
						// don't take care of . & ..
						if ( in_array($tmp_file, array('.', '..')) )
						{
							continue;
						}
						// check if relevant name
						else if ( !$tmp_all && !ereg($tmp_from_mask, $tmp_file) )
						{
							continue;
						}

						// if we keep the full name or are in sub-dirs, don't bother to filter the dest mask
						$tmp_to_file = $tmp_file;
						if ( !$tmp_all )
						{
							// split in basename + ext
							$tmp_pos = strrpos($tmp_file, '.');
							$tmp_from_ext = '';
							$tmp_from_base = $tmp_file;
							if ( $tmp_pos)
							{
								$tmp_from_ext = substr($tmp_file, $tmp_pos+1);
								$tmp_from_base = substr($tmp_file, 0, $tmp_pos);
							}

							$w_base = process_file_split($tmp_to_base, $tmp_from_base);
							$w_ext = process_file_split($tmp_to_ext, $tmp_from_ext);

							// get the final result
							$tmp_to_file = $w_base . ( empty($w_ext) ? '' : '.' . $w_ext );
						}


						// if we are on a dir, push it
						if ( is_dir($install_path . $tmp_from_dir . $tmp_file) )
						{
							array_push($tmp_dirs_from, $tmp_from_dir . $tmp_file . '/');
							array_push($tmp_dirs_to, $tmp_to_dir . $tmp_to_file . '/');
						}
						// we are on a file
						else
						{
							$final = array();
							$final = final_formatting($tmp_to_dir, $tmp_to_file, $tmp_from_dir, $tmp_file);
							for ($x=0; $x<count($final); $x++)
							{
								//$command_file->modio_mkdirs_copy( $final[$x]['to_path']);
								$command_file->afile[] = 'copy ' . $final[$x]['from_path'] . $final[$x]['from_file'] . ' ../../../' . $final[$x]['to_path'] . $final[$x]['to_file'];

//echo 'copy ' . $final[$x]['from_path'] . $final[$x]['from_file'] . ' ../../../' . $final[$x]['to_path'] . $final[$x]['to_file'] . "<br />\n";
							}
						}
					}
				}
			}


			// if we failed then halt processing
			if ($bad_copy)
			{
				break;
			}
		}


		//
		// we are done!  close up shop and stop processing
		//
		else if ($commands[$i]['command'] == 'CLOSE')
		{
			// if we haven't dumped the find_array, then do it now
			if (count($find_array) != 0)
			{
				//   also, see if we need to write the lines in preview format
				$do_preview = ((strstr($commands[$i-1]['command'], 'IN-LINE') || $commands[$i-1]['command'] == 'INCREMENT') && ($preview)) ? true : false;
				write_find_array($find_array, $file_list, $do_preview);
				$find_array = array();
			}

			// if we have a file open, close it now
			if (!complete_file_reproduction( $file_list))
			{
				// close failed; throw errors and halt
				for ($errs=0; $errs<count($file_list); $errs++)
				{
					display_error('<b>' . $lang['EM_err_critical_error'] . "</b><br /><br />\n" . $file_list[$errs]->err_msg . "<br />\n" . $lang['EM_line_num'] . $commands[$i]['line']);
				}

				// halt processing
				break;
			}

			$body[$i] = array();
			$failed = false;
			$exec_close = true;
		}
		else
		{
			$bad_command = true;
		}

		//
		// where unloved commands go ;-)
		//
		if ($bad_command)
		{
			$processed = false;
			$num_unprocessed++;
			if ($mode == 'process')
			{
				display_unprocessed_line($commands[$i], $body[$i]);
			}
		}


		// we processed the command, increase our count and display command info on screen
		if (($processed) && ($mode == 'process'))
		{
			$num_processed++;
			display_line( $commands[$i], $body[$i]);
		}
	}

	// close the ftp connection
	$command_file->modio_cleanup('move');

	//
	// we will now finish up the download or display file if that's what we're doing
	//
	if (($mode == 'display_file') || ($mode == 'download_file'))
	{
		// if we have a file open, close it now
		if (!$exec_close)
		{
			// if we haven't dumped the find_array, then do it now
			if (count($find_array) != 0)
			{
				//   also, see if we need to write the lines in preview format
				$do_preview = ((strstr($commands[$i-1]['command'], 'IN-LINE') || $commands[$i-1]['command'] == 'INCREMENT') && ($preview)) ? true : false;
				write_find_array($find_array, $file_list, $do_preview);
			}

			// not likely a close error will be thrown
			complete_file_reproduction($file_list);
		}

		// make sure we have the right file
		for ($file=0; $file<count($file_list); $file++)
		{
			// make sure this is what we are looking for, otherwise keep looking
			if ($orig_file != ($file_list[$file]->path . $file_list[$file]->filename))
			{
				continue;
			}

			// write out the lines
			$preview_display = false;
			$preview_count = count($file_list[$file]->afile);
			for ($i=0; $i<$preview_count; $i++)
			{
				// writing to file, so do NOT use htmlspecial chars
				if ($mode == 'download_file')
				{
					echo $file_list[$file]->afile[$i];
				}

				// writing to screen so you damn well better use htmlspecial chars!
				else
				{
					// if we encountered a line with the designated EM preview symbol then make it stand out
					if (substr($file_list[$file]->afile[$i], 0, 4) == 'EM>>')
					{
						// the first line of a preview display, being bolding
						if (!$preview_display)
						{
							echo '</pre><pre class="preview">' . htmlspecialchars(substr($file_list[$file]->afile[$i], 4));
						}

						// special case: the very last line of the file, end the bolding
						else if ($i == ($preview_count-1))
						{
							echo htmlspecialchars(substr($file_list[$file]->afile[$i], 4));
						}

						// a middle line of the preview display, just print the line
						else
						{
							echo htmlspecialchars(substr($file_list[$file]->afile[$i], 4));
						}

						$preview_display = true;
					}

					// first line following a preview display line, end the bolding and then carry on
					else if ($preview_display)
					{
						echo '</pre><pre class="normal">' . htmlspecialchars($file_list[$file]->afile[$i]);
						$preview_display = false;
					}

					// normal line
					else
					{
						echo htmlspecialchars($file_list[$file]->afile[$i]);
					}
				}
			}

			// finish the html tag
			if ($mode == 'display_file')
			{
				echo "</pre>\n</body>\n</html>\n";
			}

			// done! done! done!
			exit;
		}

		// didn't find the file!  OH CRAP!
		echo sprintf($lang['EM_err_modify'], $orig_file)  . "\n";
		exit;
	}


	//
	// fill in the template info
	//
	$mod_title = '';
	$mod_author_handle = '';
	$mod_author_email = '';
	$mod_author_name = '';
	$mod_author_url = '';
	$mod_description = '';
	$mod_version = '';
	$compliant = false;

	// get the properties of the MOD so we can display them nicely
	get_mod_properties($install_path . '/' . $install_file, $mod_title, $mod_author_handle, $mod_author_email, $mod_author_name, $mod_author_url, $mod_description, $mod_version, $compliant);

	$mod_themes = get_themes();
	if ($mod_themes == '')
	{
		message_die(CRITICAL_ERROR, $lang['EM_err_theme_info']);
	}
	$mod_langs = get_languages('../language');

	$phpbb_version = get_phpbb_version();
	if ($phpbb_version == '')
	{
		message_die(GENERAL_ERROR, $lang['EM_err_phpbb_ver']);
	}
	$print_path = 'admin' . substr($install_path, 1);

	// fill in the template with all our info
	$template->assign_vars(array(
		'S_ACTION' => append_sid('admin_easymod.' . $phpEx),
		'L_MOD_DATA' => $lang['EM_Mod_Data'],
		'L_MOD_TITLE' => $lang['EM_Mod_Title'],
		'L_AUTHOR' => $lang['EM_Author'],
		'L_THEMES' => $lang['EM_Proc_Themes'],
		'L_LANGUAGES' => $lang['EM_Proc_Languages'],
		'L_FILES' => $lang['EM_Files'],
		'L_UNPROCESSED' => $lang['EM_unprocessed_commands'],
		'L_UNPROCESSED_DESC' => $lang['EM_unprocessed_desc'],
		'L_PROCESSED' => $lang['EM_processed_commands'],
		'L_PROCESSED_DESC' => $lang['EM_processed_desc'],

		'INSTALL_PATH' => $print_path,
		'TITLE' => $mod_title,
		'VERSION' => $mod_version,
		'MOD_FILE' => $install_file,
		'AUTHOR' => $mod_author_handle,
		'EMAIL' => $mod_author_email,
		'REAL_NAME' => $mod_author_name,
		'URL' => $mod_author_url,

		'THEMES' => $mod_themes,
		'LANGUAGES' => $mod_langs,
		'FILES' => $files_edited,
		'PROCESSED' => $num_processed,
		'UNPROCESSED' => $num_unprocessed,
		'PREVIEW' => $preview,
		'EM_PASS' => htmlspecialchars($password))
	);


	// if we succeed, tell them where to go from here (1 step down, 2 more to go)
	if ( !$failed)
	{
		// we'll want to remember the command file steps, so pass them along
		$hidden = '';
		for ($i=0; $i<count( $command_file->afile); $i++)
		{
			$hidden .= '<input type="hidden" name="command_step'.$i.'" value="' . $command_file->afile[$i] . "\" />\n";
		}
		$hidden .= '<input type="hidden" name="num_command_steps" value="' . $i . "\" />\n";

		// load up any SQL commands into hidden fields as well
		for ($i=0; $i<count($sql); $i++)
		{
			$line = '';
			for ($j=0; $j<count($sql[$i]); $j++)
			{
				$line .= $sql[$i][$j];
			}
			$hidden .= '<input type="hidden" name="SQL'.$i.'" value="' . htmlspecialchars($line) . "\" />\n";
		}
		$hidden .= '<input type="hidden" name="num_sql_steps" value="' . $i . "\" />\n";

		// put DIY INSTRUCTIONS in hidden fields
		for($i = 0; $i < count($diy); $i++ )
		{
			$line = '';
			for ($j=0; $j<count($diy[$i]); $j++)
			{
				$line .= $diy[$i][$j];
			}
			$hidden .= '<input type="hidden" name="diy_array[]" value="' . htmlspecialchars($line) . "\" />\n";
		}

		$template->assign_block_vars('success', array(
			'L_STEP' => $lang['EM_proc_step1'],
			'L_COMPLETE' => $lang['EM_proc_complete'],
			'L_DESC' => $lang['EM_proc_desc'],
			'L_NEXT_STEP' => $lang['EM_next_step'],

			'TITLE' => $mod_title,
			'INSTALL_PATH' => $print_path,

			'HIDDEN' => $hidden,
			'MOD_FILE' => $install_file,
			'MOD_PATH' => $install_path)
		);
	}

	// if we failed, then we'll report the bad news and what to do
	else
	{
		$template->assign_block_vars('fail', array(
			'L_TITLE' => $lang['EM_error_detail'],
			'L_FAILED' => $lang['EM_proc_failed'],
			'L_FAILED_DESC' => $lang['EM_proc_failed_desc'],
			'ERROR_MESSAGE' => $fail_message)
		);
	}
}

//
// setup the SQL processing - skip this step in preview mode!
//
else if (($mode == 'SQL_view') && (!$preview))
{
	// get the vars we are passing along
	$themes = (isset($HTTP_POST_VARS['themes'])) ? stripslashes($HTTP_POST_VARS['themes']) : '';
	$languages = (isset($HTTP_POST_VARS['languages'])) ? stripslashes($HTTP_POST_VARS['languages']) : '';
	$files = (isset($HTTP_POST_VARS['files'])) ? intval($HTTP_POST_VARS['files']) : 0;
	$num_proc = (isset($HTTP_POST_VARS['num_proc'])) ? intval($HTTP_POST_VARS['num_proc']) : 0;
	$num_unproc = (isset($HTTP_POST_VARS['num_unproc'])) ? intval($HTTP_POST_VARS['num_unproc']) : 0;
	$diy = (isset($HTTP_POST_VARS['diy_array'])) ? $HTTP_POST_VARS['diy_array'] : array();

	// get the post process operations and prepare to send them to the next step
	$num_command_steps = (isset($HTTP_POST_VARS['num_command_steps'])) ? intval($HTTP_POST_VARS['num_command_steps']) :0;
	$hidden = '';
	for( $i = 0; $i < $num_command_steps; $i++ )
	{
		$var_name = 'command_step' . $i;
		if (isset($HTTP_POST_VARS[$var_name]))
		{
			$hidden .= '<input type="hidden" name="command_step'.$i.'" value="' . $HTTP_POST_VARS[$var_name] . "\" />\n";
		}
	}
	$hidden .= '<input type="hidden" name="num_command_steps" value="' . $i . "\" />\n";

	// put DIY instructions in hidden vars
	for( $i = 0; $i < count($diy); $i++ )
	{
		$hidden .= '<input type="hidden" name="diy_array[]" value="' . stripslashes(htmlspecialchars($diy[$i])) . "\" />\n";
	}

	// get the SQL commands we are going to translate
	$sql = array();
	$num_sql_steps = (isset($HTTP_POST_VARS['num_sql_steps'])) ? intval($HTTP_POST_VARS['num_sql_steps']) : 0;
	for( $i = 0; $i < $num_sql_steps; $i++ )
	{
		$var_name = 'SQL' . $i;
		if (isset($HTTP_POST_VARS[$var_name]))
		{
			if (isset($HTTP_POST_VARS[$var_name]))
			{
				$sql[] = trim(stripslashes($HTTP_POST_VARS[$var_name]));
			}
		}
	}

	// Show the SQL template
	$template->set_filenames(array(
		'body' => 'admin/mod_sql_body.tpl')
	);

	// Parser SQL statements, if any
	$formatted_sql = array();
	$sql_warnings = array();
	$error = '';
	if( count($sql) > 0 )
	{
		// Use the old SQL Parser for MS-Access, support for which has been dropped
		if( SQL_LAYER == 'msaccess' )
		{
			// turn the psuedo mysql into SQL for this user's DB type
			require($phpbb_root_path . 'admin/em_includes/em_schema.' . $phpEx);
			for( $i = 0; $i < count($sql); $i++ )
			{
				$return_sql = handle_db_alteration($sql[$i], $error);
				if (!empty($error))
				{
					$template->assign_block_vars('error', array('ERROR_MSG' => $error));
					break;
				}

				for( $j = 0; $j < count($return_sql); $j++ )
				{
					$formatted_sql[] = $return_sql[$j];
				}
			}
		}

		// Use the new SQL Parser to deal with any other SQL server
		else
		{
			// Load the new SQL Parser
			if( @file_exists($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/lang_sql_parser.' . $phpEx) )
			{
				require($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/lang_sql_parser.' . $phpEx);
			}
			else
			{
				require($phpbb_root_path . 'language/lang_english/lang_sql_parser.' . $phpEx);
			}
			require($phpbb_root_path . 'includes/sql/sql_parser.' . $phpEx);

			// Instatiate the SQL Parser object.
			$sql_parser = new sql_parser();

			// Parse and convert the SQL statements for this user's DB type.
			$result = $sql_parser->parse_stream(implode("\n", $sql), $table_prefix);

			if( $result & SQL_PARSER_ERROR )
			{
				$error = '<b>Error:</b><br />' . $sql_parser->error_message['message'] . '<br /><br /><b>SQL:</b><br />' . $sql_parser->sql_input[$sql_parser->sql_count];
				$template->assign_block_vars('error', array('ERROR_MSG' => $error));
			}
			if( $result & SQL_PARSER_WARNINGS )
			{
				$sql_warnings = $sql_parser->warnings;
			}
			for( $j = 0; $j < count($sql_parser->sql_output); $j++ )
			{
				$formatted_sql[] = $sql_parser->sql_output[$j];
			}
		}
	}

	// print message if there is no SQL to worry about
	else
	{
		$template->assign_block_vars('no_sql', array());
		$template->assign_vars(array('L_NO_SQL' => $lang['EM_no_sql']));
		$error = 'none';
	}

	// display the list of SQL to generate and give user the option to not run them; display warnings if needed
	$drop_warning = false;
	$steps = 0;
	// if there was an error, then simply skip this
	if (empty($error))
	{
		// Display warnings generated by the SQL Parser, if any
		for( $i = 0; $i < count($sql_warnings); $i++ )
		{
			$sql_warnings_count = count($sql_warnings);
			$template->assign_block_vars('warnings_block', array(
				'TITLE'		=> sprintf($lang['EM_sql_warnings_reported'], $sql_warnings_count)
			));
			for( $j = 0; $j < $sql_warnings_count; $j++ )
			{
				$template->assign_block_vars('warnings_block.line', array(
					'TEXT'	=> $sql_warnings[$j]['message']
				));
			}
		}

		// Show the mark/unmark commands
		$template->assign_block_vars('sql_rows', array());

		for( $i = 0; $i < count($formatted_sql); $i++ )
		{
			$row_class = ( !($i % 2) ) ? $theme['td_class1'] : $theme['td_class2'];

			// see if this is the warning about dropping columns in postgresql
			$split = explode(' ', $formatted_sql[$i]);
			$hidden_sql = '';
			if ($split[0] == 'ABORTED:')
			{
				$formatted_sql[$i] = '<b>' . htmlspecialchars($formatted_sql[$i]) . ';</b>';
				$hidden_sql = '';
				$check = '';
			}
			else
			{
				$formatted_sql[$i] = htmlspecialchars($formatted_sql[$i]) . ';';
				$hidden_sql = '<input type="hidden" name="SQL' . $steps . '" value="' . htmlspecialchars($formatted_sql[$i]) . '" />';
				$check = '<input type="checkbox" name="check_SQL' . $steps . '" checked="checked" />';
				$steps++;
			}

			// see if there are any DROP's we should warn the user about; we only want to display the warning once
			if ((!$drop_warning) && ((strtoupper($split[0]) == 'DROP') || (strtoupper($split[3]) == 'DROP')))
			{
				$template->assign_block_vars('drop_warning', array());
				$template->assign_vars(array(
					'L_SQL_DROP_WARN' => $lang['EM_sql_drop_warning'],
					'L_URGENT_WARNING' => $lang['EM_urgent_warning'])
				);
				$drop_warning = true;
			}

			$template->assign_block_vars('sql_row', array(
				'ROW_CLASS' => $row_class,
				'STMT_COUNT' => $i+1,
				'HIDDEN_SQL' => $hidden_sql,
				'CHECK' => $check,
				'DISPLAY_SQL' => $formatted_sql[$i])
			);
		}
	}
	$hidden .= '<input type="hidden" name="num_sql_steps" value="' . $steps . "\" />\n";

	// if it's postgre or mssql, let them know I don't have things quite right yet!
// Commented out since the new SQL Parser should process them nicely
//	if (($error == '') && ((SQL_LAYER == 'mssql') || (SQL_LAYER == 'postgresql')))
//	{
//		$link = 'http://area51.phpbb.com/phpBB/viewtopic.php?t=';
//		$link .= (SQL_LAYER == 'postgresql') ? '15388' : '15389';
//
//		$template->assign_block_vars('experimental', array());
//		$template->assign_vars(array(
//			'L_EXPERIMENTAL_EXPLAIN' => sprintf($lang['EM_experimental_explain'], SQL_LAYER, $link))
//		);
//	}

	// if it's msaccess, let them know that we can't add defaults :(
	if (($error == '') && (SQL_LAYER == 'msaccess'))
	{
		$template->assign_block_vars('msaccess', array());
		$template->assign_vars(array('L_SQL_MSACCESS_WARN' => $lang['EM_sql_msaccess_warning']));
	}

	// fill the template
	$template->assign_vars(array(
		'S_ACTION' => append_sid('admin_easymod.' . $phpEx),

		'L_STEP' => $lang['EM_sql_step2'],
		'L_SQL_INTRO' => $lang['EM_sql_intro_explain'],
		'L_ALTERATIONS' => $lang['EM_Alterations'],
		'L_PSEUDO' => sprintf($lang['EM_proposed_alterations'], SQL_LAYER),
		'L_ALLOW' => $lang['EM_Allow'],
		'L_PERFORM' => $lang['EM_Perform'],
		'L_COMPLETE' => $lang['EM_complete_install'],
		'L_NOTICE' => $lang['EM_notice'],
		'L_MARK_ALL' => $lang['Mark_all'],
		'L_UNMARK_ALL' => $lang['Unmark_all'],

		'L_SQL_PROCESS_ERROR' => $lang['EM_sql_process_error'],
		'L_NO_SQL_PREFORMED' => $lang['EM_no_sql_preformed'],
		'L_FOLLOWING_ERROR' => $lang['EM_following_error'],

		'THEMES' => $themes,
		'LANGUAGES' => $languages,
		'FILES' => $files,
		'PROCESSED' => $num_proc,
		'UNPROCESSED' => $num_unproc,
		'MOD_FILE' => $install_file,
		'MOD_PATH' => $install_path,
		'MODE' => ($error == '') ? 'SQL_execute' : 'post_process',
		'HIDDEN' => $hidden,
		'EM_PASS' => htmlspecialchars($password))
	);
}

else if ( $mode == 'SQL_execute' )
{
	// get the vars we are passing along
	$themes = (isset($HTTP_POST_VARS['themes'])) ? stripslashes($HTTP_POST_VARS['themes']) : '';
	$languages = (isset($HTTP_POST_VARS['languages'])) ? stripslashes($HTTP_POST_VARS['languages']) : '';
	$files = (isset($HTTP_POST_VARS['files'])) ? intval($HTTP_POST_VARS['files']) : 0;
	$num_proc = (isset($HTTP_POST_VARS['num_proc'])) ? intval($HTTP_POST_VARS['num_proc']) : 0;
	$num_unproc = (isset($HTTP_POST_VARS['num_unproc'])) ? intval($HTTP_POST_VARS['num_unproc']) : 0;
	$diy = (isset($HTTP_POST_VARS['diy_array'])) ? $HTTP_POST_VARS['diy_array'] : array();

	// get the post process operations and prepare to send them to the next step
	$num_command_steps = (isset($HTTP_POST_VARS['num_command_steps'])) ? intval($HTTP_POST_VARS['num_command_steps']) :0;
	$hidden = '';
	for( $i = 0; $i < $num_command_steps; $i++ )
	{
		$var_name = 'command_step' . $i;
		if (isset($HTTP_POST_VARS[$var_name]))
		{
			$hidden .= '<input type="hidden" name="command_step'.$i.'" value="' . $HTTP_POST_VARS[$var_name] . "\" />\n";
		}
	}
	$hidden .= '<input type="hidden" name="num_command_steps" value="' . $i . "\" />\n";

	// put DIY instructions in hidden vars
	for( $i = 0; $i < count($diy); $i++ )
	{
		$hidden .= '<input type="hidden" name="diy_array[]" value="' . stripslashes(htmlspecialchars($diy[$i])) . "\" />\n";
	}

	// get the SQL commands we are going to execute
	$num_sql_steps = (isset($HTTP_POST_VARS['num_sql_steps'])) ? intval($HTTP_POST_VARS['num_sql_steps']) : 0;
	$sql = array();
	$failure = false;
	for( $i = 0; $i < $num_sql_steps; $i++ )
	{
		$sql_name = 'SQL' . $i;
		$sql_check = 'check_' . $sql_name;
		$sql_line = ( !empty($HTTP_POST_VARS[$sql_name]) ) ? stripslashes(trim($HTTP_POST_VARS[$sql_name])) : '';
		$sql_allow = ( isset($HTTP_POST_VARS[$sql_check])) ? ( ($HTTP_POST_VARS[$sql_check]) ? TRUE : 0 ) : 0;

		if ($failure)
		{
			$sql[] = array('command' => $sql_line, 'status' => '<b>' . $lang['EM_not_attempted'] . '</b>');
		}
		else if ($sql_allow)
		{

			if( !($result = $db->sql_query($sql_line)) )
			{
				// set the status
				$sql[] = array('command' => $sql_line, 'status' => '<b>' . $lang['EM_failed'] . '</b>');
				$failure = true;

				$error = $db->sql_error();
//echo "[" . $error['message'] . "][" . $error['code'] . "]<br />\n";
//exit;
				// load up an error message
				$template->assign_block_vars( 'sql_error', array(
					'LINE' => htmlspecialchars($sql_line) . ';',
					'ERROR_CODE' => $error['code'],
					'ERROR_MSG' => $error['message'])
				);
				$template->assign_vars(array(
					'L_SQL_ERROR' => $lang['EM_sql_error'],
					'L_SQL_ERROR_EXPLAIN' => $lang['EM_sql_error_explain'],
					'L_FAILED_LINE' => $lang['EM_failed_line'],
					'L_SQL_HALTED' => $lang['EM_sql_halted'])
				);
			}
			else
			{
				$sql[] = array('command' => $sql_line, 'status' => $lang['EM_success']);
			}
		}
		else
		{
			$sql[] = array('command' => $sql_line, 'status' => '<b>' . $lang['EM_skipped'] . '</b>');
		}
	}


	// Show the SQL template
	$template->set_filenames(array(
		'body' => 'admin/mod_sql_body.tpl')
	);

	// display the list of SQL to generate and give use the option to not run them; display warnings if needed
	$steps = 0;
	for( $i = 0; $i < count($sql); $i++ )
	{
		$row_class = ( !($i % 2) ) ? $theme['td_class1'] : $theme['td_class2'];
		$template->assign_block_vars( 'sql_row', array(
			'ROW_CLASS' => $row_class,
			'HIDDEN' => '',
			'CHECK' => $sql[$i]['status'],
			'DISPLAY_SQL' => htmlspecialchars($sql[$i]['command']) . ';')
		);
	}
	$sql_intro = $lang['EM_line_results'];
	$sql_intro .= (!$failure) ? ' - <b>' . $lang['EM_all_lines_successfull'] . '</b>' : ' - <b>' . $lang['EM_errors_detected'] . '</b>';

	// fill the template
	$template->assign_vars(array(
		'S_ACTION' => append_sid('admin_easymod.' . $phpEx),

		'L_STEP' => $lang['EM_sql_step2'],
		'L_SQL_INTRO' => $sql_intro,
		'L_ALTERATIONS' => $lang['EM_processing_results'],
		'L_PSEUDO' => $lang['EM_sql_attempted'],
		'L_ALLOW' => $lang['EM_Allow'],
		'L_PERFORM' => $lang['EM_Perform'],
		'L_COMPLETE' => $lang['EM_complete_install'],

		'THEMES' => $themes,
		'LANGUAGES' => $languages,
		'FILES' => $files,
		'PROCESSED' => $num_proc,
		'UNPROCESSED' => $num_unproc,
		'MOD_FILE' => $install_file,
		'MOD_PATH' => $install_path,
		'MODE' => 'post_process',
		'HIDDEN' => $hidden,
		'EM_PASS' => htmlspecialchars($password))
	);
}

//
// last step!  move the files into place - force this step if in preview mode
//
else if (($mode == 'post_process') || ($preview))
{
	// get the info we are passing along
	$themes = (isset($HTTP_POST_VARS['themes'])) ? stripslashes($HTTP_POST_VARS['themes']) : '';
	$languages = (isset($HTTP_POST_VARS['languages'])) ? stripslashes($HTTP_POST_VARS['languages']) : '';
	$files = (isset($HTTP_POST_VARS['files'])) ? intval($HTTP_POST_VARS['files']) : 0;
	$num_proc = (isset($HTTP_POST_VARS['num_proc'])) ? intval($HTTP_POST_VARS['num_proc']) : 0;
	$num_unproc = (isset($HTTP_POST_VARS['num_unproc'])) ? intval($HTTP_POST_VARS['num_unproc']) : 0;
	$diy = (isset($HTTP_POST_VARS['diy_array'])) ? $HTTP_POST_VARS['diy_array'] : array();

	$hidden = '';

	// explode each new line so they can have their own bullet
	if ( count($diy) )
	{
		$template->assign_block_vars('diy_switch', array(
			'MODE'		=> 'diy_process',
			'S_ACTION'	=> append_sid('admin_easymod.' . $phpEx),
			'EM_PASS' => htmlspecialchars($password))
		);

		$diy_process = array();
		for( $i = 0; $i < count($diy); $i++ )
		{
			$diy_process = array_merge($diy_process, explode("\n", $diy[$i]));
		}

		for( $i = 0; $i < count($diy_process); $i++ )
		{
			$diy_process[$i] = trim($diy_process[$i]);
			if ( !empty($diy_process[$i]) )
			{
				$hidden .= '<input type="hidden" name="diy_array[]" value="' . stripslashes(htmlspecialchars($diy_process[$i])) . "\" />\n";

				$template->assign_block_vars('diy_switch.diyrow', array(
					'INSTRUCTIONS'	=> stripslashes(htmlspecialchars($diy_process[$i])))
				);
			}
		}
	}

	// get the post process operations
	$num_command_steps = (isset($HTTP_POST_VARS['num_command_steps'])) ? intval($HTTP_POST_VARS['num_command_steps']) : 0;
	$command = array();
	for( $i = 0; $i < $num_command_steps; $i++ )
	{
		$var_name = 'command_step' . $i;
		if (isset($HTTP_POST_VARS[$var_name]))
		{
			$command[] = htmlspecialchars($HTTP_POST_VARS[$var_name]);
		}
	}


	// Show the post process page
	$template->set_filenames(array(
		'body' => 'admin/mod_complete.tpl')
	);


	// write the command files
	$command_file = get_em_settings('post_process.sh', '', $password, $preview);
	$command_bat = new mod_io('post_process.bat', '', $command_file->read_method, $command_file->write_method, $command_file->move_method, $command_file->ftp_user, $command_file->ftp_pass, $command_file->ftp_path, $command_file->ftp_host, $command_file->ftp_port, $command_file->ftp_type, $command_file->ftp_cache);

	// open the command file: config=true,command=true
	if ((!$command_file->modio_open(true)) || ( !$command_bat->modio_open(true)))
	{
		$command_file->err_msg = $lang['EM_trace'] . ':<br /> main[2]->' . $command_file->err_msg;
		message_die(GENERAL_ERROR, '<br />' . $lang['EM_err_open_pp'] . '<br />' . $lang['EM_err_cwd'] . ': ' . getcwd() . '<br />');
	}

	// this is really more about moving the other files than is about the command file; establish the FTP connection
	//  for moving files if necessary
	if (!$command_file->modio_prep('move'))
	{
		$command_file->err_msg = $lang['EM_trace'] . ': main[3]->' . $command_file->err_msg;
		message_die(GENERAL_ERROR, '<b>' . $lang['EM_err_critical_error'] . ':</b><br /> ' . $command_file->err_msg . '<br />');
	}
	// share FTP attributes with the bat file
	$command_bat->emftp = $command_file->emftp;


////////////////////
////////////////////
////////////////////-md5
////////////////////
////////////////////
//	$em_pass = get_em_pw();
	$em_pass = $password;

	$processed_files = array();

	// execute the move!
	$mod_count = 0;
	for( $i = 0; $i < $num_command_steps; $i++ )
	{
/////////BUG: if there is a dir with spaces in the name that is going to cause problems
		$parms = explode(' ', $command[$i]);
		if ($parms[0] == 'copy')
		{
			// write to the post-process script
			$command_file->modio_write('cp ' . $parms[1] . ' ' . $parms[2] . "\n");
			$command_bat->modio_write(str_replace('/', "\\", $command[$i]) . "\r\n");

			$split_from = explode('/', $parms[1]);
			$split_to = explode('/', $parms[2]);

			// set vars depending if this is a backup or a download file
			if ($split_to[0] == 'backups')
			{
				$from = $parms[1];
				$to = $parms[2];
				$type = $lang['EM_pp_backup'];
				$is_backup = true;
				$link = append_sid('admin_easymod.' . $phpEx . '?mode=display_backup&file=' . $parms[1] . "&password=$em_pass");
			}
			else
			{
				$from = $parms[1];
				$to = $parms[2];
				$type = $lang['EM_pp_download'];
				$is_backup = false;
				$link = append_sid('admin_easymod.' . $phpEx . '?mode=display_file&file=' . $parms[2] . "&password=$em_pass&install_file=$install_file&install_path=$install_path");
			}

			// create the directory before moving files into it
			// could be optimized such that modio_mkdirs_copy is only called once per
			// new directory, as opposed to once per original COPY action, but oh well...
			if ((substr($parms[1],0,9) != "processed") && (substr($parms[1],0,9) != "../../../"))
			{
				$command_file->modio_mkdirs_copy(substr(dirname($parms[2]),9).'/' );
			}

			// now the magic happens ;-)
			$ret_value = $command_file->modio_move($parms[2], $parms[1], $mod_count, $link, $type);
			$mod_count++;

			// if there is no return value then that means it didn't work; print the err_msg and bail
			if ($ret_value == '')
			{
				message_die(GENERAL_ERROR, '<b>' . $lang['EM_err_critical_error'] . ':</b> ' . $command_file->err_msg . '<br />' . $lang['EM_err_attempt_remainder'] . '<br />');
			}

			// move was a success, display the output
			else
			{
				// if the destination is a backup, then put in the backup listing
				if ($is_backup)
				{
					// this is relative to the phpBB directory
					$from_file = (substr($from, 0, 9) == '../../../') ? substr($from, 9) : $from;
					$processed_files[] = $from_file;

					$template->assign_block_vars('backups', array(
						'FROM' => $from_file,
						'TO' => $ret_value)
					);
				}

				// put in the move list
				else
				{
					if (!(strstr($parms[1], 'processed/')) && ($ret_value != '<b>' . $lang['EM_pp_complete'] . '</b>') && ($ret_value != '<b>' . $lang['EM_pp_ready'] . '</b>'))
					{
						$ret_value = '<b>' . $lang['EM_pp_manual'] . '</b>';
					}

					$template->assign_block_vars('files', array(
						'FROM' => $from,
						'TO' => ((substr($to, 0, 9) == '../../../') ? substr($to, 9) : $to),
						'COMPLETED' => $ret_value)
					);
				}
			}
		}
	}

	$mod_title = '';
	$mod_author_handle = '';
	$mod_author_email = '';
	$mod_author_name = '';
	$mod_author_url = '';
	$mod_description = '';
	$mod_version = '';
	$compliant = false;
	get_mod_properties($install_path . '/' . $install_file, $mod_title, $mod_author_handle, $mod_author_email, $mod_author_name, $mod_author_url, $mod_description, $mod_version, $compliant);

	$template->assign_vars(array(
		'S_ACTION' => append_sid('admin_easymod.' . $phpEx),

		'L_STEP' => $lang['EM_pp_step3'],
		'L_COMPLETE' => $lang['EM_pp_install_comp'],
		'L_COMP_DESC' => $lang['EM_pp_comp_desc'],
		'L_COPY_TO' => $lang['EM_pp_to'],
		'L_COPY_STATUS' => $lang['EM_pp_status'],
		'L_COPY_FROM' => sprintf($lang['EM_pp_from'], $install_path . 'processed/'),
		'L_MAKING_BACKUPS' => sprintf( $lang['EM_pp_backups'], $install_path . 'backups/'),

		'L_MOD_DATA' => $lang['EM_Mod_Data'],
		'L_MOD_TITLE' => $lang['EM_Mod_Title'],
		'L_AUTHOR' => $lang['EM_Author'],
		'L_THEMES' => $lang['EM_Proc_Themes'],
		'L_LANGUAGES' => $lang['EM_Proc_Languages'],
		'L_FILES' => $lang['EM_Files'],
		'L_PROCESSED' => $lang['EM_processed_commands'],
		'L_UNPROCESSED' => $lang['EM_unprocessed_commands'],
		'L_DB_ALTERATIONS' => $lang['EM_database_alterations'],
		'L_TABLES_ADDED' => $lang['EM_tables_added'],
		'L_TABLES_ALTERED' => $lang['EM_tables_altered'],
		'L_ROWS_ADDED' => $lang['EM_rows_added'],
		'L_DEPENDS_ON_MOVE' => $lang['EM_text_depend_move'],

		'L_DIY_INSTRUCTIONS' => $lang['DIY_Instructions'],
		'L_DIY_INTRO' => $lang['DIY_intro'],
		'L_FINAL_INSTALL_STEP' => $lang['Final_install_step'],

		'INSTALL_PATH' => $print_path,
		'TITLE' => $mod_title,
		'VERSION' => $mod_version,
		'MOD_FILE' => $install_file,
		'AUTHOR' => $mod_author_handle,
		'EMAIL' => $mod_author_email,
		'REAL_NAME' => $mod_author_name,
		'URL' => $mod_author_url,

		'MOD_FILE' => $install_file,
		'MOD_PATH' => $install_path,
		'MOD_COUNT' => $mod_count,
		'THEMES' => $themes,
		'LANGUAGES' => $languages,
		'FILES' => $files,
		'PROCESSED' => $num_proc,
		'UNPROCESSED' => $num_unproc,
		
		'HIDDEN'	=> $hidden)
	);


	// finish the script generation
	if ((!$command_file->modio_close(true)) || (!$command_bat->modio_close(true)))
	{
		message_die(GENERAL_ERROR, '<br />' . $lang['EM_err_write_pp'] . '<br />' . $lang['EM_err_cwd'] . ': ' . getcwd() . '<br />');
	}

	// closs the FTP session
	$command_file->modio_cleanup('move');	


	$phpbb_version = get_phpbb_version();
	$mod_title = str_replace("'", "''", substr($mod_title, 0, 255));
	$mod_author_handle = str_replace("'", "''", substr($mod_author_handle, 0, 25));
	$mod_author_email = str_replace("'", "''", substr($mod_author_email, 0, 100));
	$mod_author_name = str_replace("'", "''", substr($mod_author_name, 0, 100));
	$mod_author_url = str_replace("'", "''", substr($mod_author_url, 0, 100));
	$mod_description = str_replace("'", "''", $mod_description);
	$mod_version = str_replace("'", "''", substr($mod_version, 0, 15));
	$themes = str_replace("'", "''", $themes);
	$languages = str_replace("'", "''", $languages);

	if ($preview)
	{
		// do not update the DB while in preview mode
	}
	else
	{
		// We might come here from the 'Restore Backups' option, in this case we'll find the mod_id in the POST array.
		if ( isset($HTTP_POST_VARS['mod_id']) && ($mod_id = intval($HTTP_POST_VARS['mod_id'])) > 0 )
		{
			// If we have restored backups, what we really need now is delete the MOD record.
			$sql = 'DELETE FROM ' . EASYMOD_TABLE . " WHERE mod_id = $mod_id";
		}
		else
		{
			// Otherwise, we have just installed a new MOD.
			$sql = 'INSERT INTO ' . EASYMOD_TABLE . " ( mod_file, mod_title, mod_version, mod_author_handle, mod_author_email, mod_author_url, mod_author_name, mod_description, mod_process_date, mod_phpBB_version, mod_processed_themes, mod_processed_langs, mod_files_edited)
				VALUES ( '" . substr($install_path, 7) . $install_file . "', '$mod_title', '$mod_version', '$mod_author_handle', '$mod_author_email', '$mod_author_url', '$mod_author_name', '$mod_description', " . time() . ", '" . $phpbb_version . "', '" . $themes . "', '" . $languages . "', $files)";
		}

		if ( !($result = $db->sql_query($sql)) )
		{
			message_die(GENERAL_ERROR, $lang['EM_err_em_info'], '', __LINE__, __FILE__, $sql);
		}

		if( isset($mod_id) )
		{
			$sql = 'DELETE FROM ' . EASYMOD_PROCESSED_FILES_TABLE . " WHERE mod_id = $mod_id";
			if ( !($result = $db->sql_query($sql)) )
			{
				message_die(GENERAL_ERROR, $lang['EM_err_em_info'], '', __LINE__, __FILE__, $sql);
			}
		}
		else
		{
			// get the ID of the just installed MOD.
			$mod_id = $db->sql_nextid();

			for( $i = 0; $i < count($processed_files); $i++ )
			{
				$sql = 'INSERT INTO ' . EASYMOD_PROCESSED_FILES_TABLE . " (mod_processed_file, mod_id)
					VALUES ('" . $processed_files[$i] . "', $mod_id)";
				if ( !($result = $db->sql_query($sql)) )
				{
					message_die(GENERAL_ERROR, $lang['EM_err_em_info'], '', __LINE__, __FILE__, $sql);
				}
			}
		}
	}
}

//
// show the DIY instructions
// move below post_process?
//
else if ( $mode == 'diy_process' )
{
	$diy = (isset($HTTP_POST_VARS['diy_array'])) ? $HTTP_POST_VARS['diy_array'] : array();

	// explode each new line so they can have their own bullet
	$diy_process = array();
	for( $i = 0; $i < count($diy); $i++ )
	{
		$diy_process = array_merge($diy_process, explode("\n", $diy[$i]));
	}

	for( $i = 0; $i < count($diy_process); $i++ )
	{
		$diy_process[$i] = trim($diy_process[$i]);
		if ( !empty($diy_process[$i]) )
		{
			$template->assign_block_vars('diyrow', array(
				'INSTRUCTIONS'	=> stripslashes(htmlspecialchars($diy_process[$i])))
			);
		}
	}

	// Show the SQL template
	$template->set_filenames(array(
		'body' => 'admin/mod_diy_body.tpl')
	);

	// fill the template
	$template->assign_vars(array(
		'L_STEP' => $lang['DIY_final'],
		'L_COMPLETE' => $lang['DIY_Instructions'],
		'L_DIY_INTRO' => $lang['DIY_intro'],
		'L_INSTALL_COMPLETE' => $lang['Install_complete'])
	);

}
	

// actually outputs the template date we've built
$template->pparse('body');

// output the footer
include('page_footer_admin.'.$phpEx);

?

magnusgus
Registered User
Posts: 10
Joined: Mon Nov 26, 2007 9:12 pm

Re: Final step Problem

Post by magnusgus »

Hello...
Anyone here...?

magnusgus
Registered User
Posts: 10
Joined: Mon Nov 26, 2007 9:12 pm

Re: Final step Problem

Post by magnusgus »

Hello,
Can someone please help out here, I was aiming for a mod of a spamfiltration since my forum is flooded currently by viagra-*beep*!
Or is it maybe better to upgrade to PHPbb 3 (is there better spamcontrol built in..?)

User avatar
WhiteWolfSix
Registered User
Posts: 210
Joined: Fri Jan 21, 2005 9:05 am
Location: 48°43′N, 19°08′E

Re: Final step Problem

Post by WhiteWolfSix »

I would sugest you to convert your forum to phpBB3 that is now in stable version (Gold release) and has much more features than phpBB2. You may find these articles useful:
The features and Compare phpBB
Image
WhiteWolfSix (WW6)

Locked