<?php
//
//	file: includes/class_attach_download.php
//	author: ptirhiik
//	begin: 05/03/2006
//	version: 1.6.0 - 10/06/2006
//	license: http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
//
//	based on : attachment_mod copyright (c) 2002 Meik Sievertsen (acydburn)
//

//
// well, not really a class, but this allows to sort the script filenames :)
//

if ( !defined('IN_PHPBB') )
{
	die('Hacking attempt');
	exit;
}

//
// Delete the / * to uncomment the block, and edit the values (read the comments) to
// enable additional security to your board (preventing third site linkage)
//
/*
define('ALLOWED_DENIED', 0);
define('DENIED_ALLOWED', 1);

//
// From this line on you are able to edit the stuff
//

// Possible Values:
// ALLOWED_DENIED <- First allow the listed sites, and then deny all others
// DENIED_ALLOWED <- First deny the listed sites, and then allow all others
$allow_deny_order = ALLOWED_DENIED;

//
// Allowed Syntax:
// Full Domain Name -> www.opentools.de
// Partial Domain Names -> opentools.de
//
$sites = array(
	$config->data['server_name'], // This is your domain
	'opentools.de',
	'phpbb.com',
	'phpbbhacks.com',
	'phpbb.de',
);

// This is the message displayed, if someone links to this site...
$lang['Denied_Message'] = 'You are not authorized to view, download or link to this Site.';

// End of editable area

//
// Parse the order and evaluate the array
//
$site = trim(getenv('HTTP_REFERER')); 
$site = empty($site) ? trim($_SERVER['HTTP_REFERER']) : trim($HTTP_SERVER_VARS['HTTP_REFERER']);
$site = explode('?', $site);
$url = trim($site[0]);
if ( !$allowed = empty($url) )
{
	$allowed = ($allow_deny_order != ALLOWED_DENIED);
	for ($i = 0; $i < count($sites); $i++)
	{
		if (strstr($url, $sites[$i]))
		{
			$allowed = ($allow_deny_order == ALLOWED_DENIED);
			break;
		}
	}
}
if ( !$allowed )
{
	message_die(GENERAL_MESSAGE, 'Denied_Message');
}

// Delete the following line, to uncomment this block
*/

//
// Start Session Management
//
$userdata = session_pagestart($user_ip, PAGE_INDEX);
$user->set('viewtopic', array('download'));
//
// End Session Management
//

// get parms
$download_id = _read('id', TYPE_INT);
$thumbnail = _read('thumb', TYPE_INT);
if ( !$download_id )
{
	message_die(GENERAL_ERROR, 'No_attachment_selected');
}
if ( intval($attach_config->data['disable_mod']) && ($user->data['user_level'] != ADMIN) )
{
	message_die(GENERAL_MESSAGE, 'Attachment_feature_disabled');
}

//
// get the attachment desc
//
$sql = 'SELECT *
			FROM ' . ATT_DESC_TABLE . '
			WHERE attach_id = ' . intval($download_id);
$result = $db->sql_query($sql, false, __LINE__, __FILE__);
$attachment = ($row = $db->sql_fetchrow($result)) ? $row : array();
$db->sql_freeresult($result);
if ( !$attachment )
{
	message_die(GENERAL_MESSAGE, 'Error_no_attachment');
}

//
// verify the auth to download
//
if ( !$authorised = ($user->data['user_level'] == ADMIN) )
{
	// we need only one row (other are copies) : the first will be fine
	$sql = 'SELECT *
				FROM ' . ATT_LINKS_TABLE . '
				WHERE attach_id = ' . intval($download_id) . '
				LIMIT 1';
	$result = $db->sql_query($sql, false, __LINE__, __FILE__);
	$row = $db->sql_fetchrow($result);
	$db->sql_freeresult($result);
	if ( !$row )
	{
		// here knowing the poster id (so the owner of the file) would be necessary to do a proper check
		$authorised = true;
	}
	else if ( intval($row['post_id']) )
	{
		// get the forum
		$sql = 'SELECT forum_id
					FROM ' . POSTS_TABLE . '
					WHERE post_id = ' . intval($row['post_id']);
		$result = $db->sql_query($sql, false, __LINE__, __FILE__);
		$forum_id = ($row = $db->sql_fetchrow($result)) ? intval($row['forum_id']) : 0;
		$db->sql_freeresult($result);
		if ( $authorised = !empty($forum_id) )
		{
			if ( empty($user->cache[POST_FORUM_URL]) )
			{
				$user->get_cache(POST_FORUM_URL);
			}
			$authorised = $user->auth(POST_FORUM_URL, 'auth_download', $forum_id);
		}
	}
	else if ( intval($row['privmsgs_id']) )
	{
		$authorised = false;
		if ( intval($attach_config->data['allow_pm_attach']) )
		{
			$sql = 'SELECT privmsgs_from_userid, privmsgs_to_userid
						FROM ' . PRIVMSGS_TABLE . '
						WHERE privmsgs_id = ' . intval($row['privmsgs_id']);
			$result = $db->sql_query($sql, false, __LINE__, __FILE__);
			$user_ids = ($row = $db->sql_fetchrow($result)) ? array(intval($row['privmsgs_from_userid']), intval($row['privmsgs_to_userid'])) : array();
			$authorised = in_array($user->data['user_id'], $user_ids);
		}
	}
}
if ( !$authorised )
{
	message_die(GENERAL_MESSAGE, 'Sorry_auth_view_attach');
}

//
// Get Information on currently allowed Extensions
//
$attach_extensions->read();
if ( !isset($attach_extensions->data[ $attachment['extension'] ]) && ($user->data['user_level'] != ADMIN) )
{
	message_die(GENERAL_MESSAGE, sprintf($user->lang('Extension_disabled_after_posting'), $attachment['extension']));
}

// Update download count
if ( !intval($thumbnail) )
{
	$sql = 'UPDATE ' . ATT_DESC_TABLE . '
				SET download_count = download_count + 1
				WHERE attach_id = ' . intval($download_id);
	$db->sql_query($sql, false, __LINE__, __FILE__);
}

//
// We have verified auths, now send the file
//

// prepare handler
$file_handler = new file_handler($attach_config->data);

// get filename
$filename = $thumbnail ? THUMB_DIR . '/t_' . basename($attachment['physical_filename']) : basename($attachment['physical_filename']);

// get the appropriate download mode
// $download_mode = ($dst_file = $file_handler->get_download_url($filename, false)) ? PHYSICAL_LINK : (isset($attach_extensions->data[ $attachment['extension'] ]) ? intval($attach_extensions->data[ $attachment['extension'] ]['download_mode']) : INLINE_LINK);
$download_mode = isset($attach_extensions->data[ $attachment['extension'] ]) ? intval($attach_extensions->data[ $attachment['extension'] ]['download_mode']) : INLINE_LINK;
if ( ($download_mode == PHYSICAL_LINK) && !($dst_file = $file_handler->get_download_url($filename, false)) )
{
	$download_mode = INLINE_LINK;
}

// Physical link asked : redirect to the image url
if ( $download_mode == PHYSICAL_LINK )
{
	redirect($dst_file);
}

// inline mode : get an internal link to the physical file, if necessary get a temporary file
$real_filename = html_entity_decode(basename($attachment['real_filename']));

$tmp_filename = $file_handler->get_temporary($file_handler->path($filename), $attachment['mimetype']);
if ( !$tmp_filename )
{
	message_die(GENERAL_ERROR, $file_handler->error());
}

//
// Determine the Browser the User is using, because of some nasty incompatibilities.
// Most of the methods used in this function are from phpMyAdmin. :)
//
$user_agent = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : (!empty($HTTP_SERVER_VARS['HTTP_USER_AGENT']) ? $HTTP_SERVER_VARS['HTTP_USER_AGENT'] : '');

if ( ereg('Opera(/| )([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version) )
{
	$browser_version = $log_version[2];
	$browser_agent = 'opera';
}
else if ( ereg('MSIE ([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version) )
{
	$browser_version = $log_version[1];
	$browser_agent = 'ie';
}
else if ( ereg('OmniWeb/([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version) )
{
	$browser_version = $log_version[1];
	$browser_agent = 'omniweb';
}
else if ( ereg('Netscape([0-9]{1})', $HTTP_USER_AGENT, $log_version) )
{
	$browser_version = $log_version[1];
	$browser_agent = 'netscape';
}
else if ( ereg('Mozilla/([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version) )
{
	$browser_version = $log_version[1];
	$browser_agent = 'mozilla';
}
else if ( ereg('Konqueror/([0-9].[0-9]{1,2})', $HTTP_USER_AGENT, $log_version) )
{
	$browser_version = $log_version[1];
	$browser_agent = 'konqueror';
}
else
{
	$browser_version = 0;
	$browser_agent = 'other';
}

// Correct the mime type - we force application/octetstream for all files, except images
// Please do not change this, it is a security precaution
if ( !strstr($attachment['mimetype'], 'image') )
{
	$attachment['mimetype'] = (($browser_agent == 'ie') || ($browser_agent == 'opera')) ? 'application/octetstream' : 'application/octet-stream';
}

// Now the tricky part... let's dance
// @ob_end_clean();
// @ini_set('zlib.output_compression', 'Off');
// header('Pragma: public');
// header('Content-Transfer-Encoding: none');

// Send the file
header('Pragma: public');
header('Content-Type: ' . $attachment['mimetype'] . '; name="' . $real_filename . '"');
header('Content-Disposition: inline; filename="' . $real_filename . '"');
if ( $size = @filesize($tmp_filename) )
{
	header('Content-length: ' . intval($size));
}
readfile($tmp_filename);

// delete the temporary file if necessary
$file_handler->unlink_temporary($tmp_filename);
unset($file_handler);
exit;

?>