diff --git a/.gitignore b/.gitignore
index 8f4e287..0db8385 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,3 +28,4 @@ web.config
#libraries
library/jpgraph
library/FirePHPCore
+patches
diff --git a/admin/schema.php b/admin/schema.php
index c87f0a6..b10b315 100644
--- a/admin/schema.php
+++ b/admin/schema.php
@@ -606,3 +606,12 @@ $upgrade[] = Array( 'CreateIndexSQL', Array( 'idx_project_hierarchy_parent_id',
/* 180 */
$upgrade[] = Array( 'CreateIndexSQL', Array( 'idx_tag_name', db_get_table( 'tag' ), 'name' ) );
$upgrade[] = Array( 'CreateIndexSQL', Array( 'idx_bug_tag_tag_id', db_get_table( 'bug_tag' ), 'tag_id' ) );
+
+/* 190 */
+$upgrade[] = Array( 'AddColumnSQL', Array( db_get_table( 'user' ), "
+ password_128 C(128) NOTNULL DEFAULT \" '' \" " ) );
+$upgrade[] = Array( 'AddColumnSQL', Array( db_get_table( 'user' ), "
+ password_hash C(10) NOTNULL DEFAULT \" 'MD5' \" " ) );
+$upgrade[] = Array( 'UpdateFunction', "password_hash_migrate", Array( 'password_128', 'password_hash' ) );
+$upgrade[] = Array( 'DropColumnSQL', Array( db_get_table( 'user' ), "password" ) );
+$upgrade[] = Array( 'RenameColumnSQL', Array( db_get_table( 'user' ), "password_128", "password", "password C(128) NOTNULL DEFAULT \" '' \" " ) );
diff --git a/config_defaults_inc.php b/config_defaults_inc.php
index 702b5dc..eee3566 100644
--- a/config_defaults_inc.php
+++ b/config_defaults_inc.php
@@ -2571,8 +2571,9 @@ $g_allow_no_category = OFF;
/**
* login method
- * CRYPT or PLAIN or MD5 or LDAP or BASIC_AUTH. You can simply change this at
- * will. MantisBT will try to figure out how the passwords were encrypted.
+ * CRYPT or PLAIN or MD5 or SHA1 or LDAP or BASIC_AUTH.
+ * You can simply change this at will. MantisBT will try to figure out how the
+ * passwords were encrypted.
* @global int $g_login_method
*/
$g_login_method = MD5;
diff --git a/core/authentication_api.php b/core/authentication_api.php
index 8e0b422..e7e6afa 100644
--- a/core/authentication_api.php
+++ b/core/authentication_api.php
@@ -345,10 +345,22 @@ function auth_does_password_match( $p_user_id, $p_test_password ) {
$t_password = user_get_field( $p_user_id, 'password' );
$t_login_methods = Array(
+ SHA1,
MD5,
CRYPT,
PLAIN,
);
+ if( substr($t_password, 0, 1) == '{' && strpos($t_password, '}') > 1 ) {
+ $t_method = substr( $t_password, 1, strpos($t_password, '}')-1 );
+ $t_methods_arr = Array('SHA'=>SHA1, 'MD5'=>MD5, 'CRYPT'=>CRYPT,
+ 'PLAIN'=>PLAIN);
+ if( in_array($t_method, $t_methods_arr)
+ && in_array($t_methods_arr[$t_method], $t_login_methods) ) {
+ $t_login_methods = Array($t_methods_arr[$t_method]);
+ $t_password = substr( $t_password, strlen($t_method)+2 );
+ }
+ }
+
foreach( $t_login_methods as $t_login_method ) {
# pass the stored password in as the salt
@@ -405,6 +417,9 @@ function auth_does_password_match( $p_user_id, $p_test_password ) {
case MD5:
$t_processed_password = md5( $p_password );
break;
+ case SHA1:
+ $t_processed_password = sha1( $p_password );
+ break;
case BASIC_AUTH:
case PLAIN:
default:
diff --git a/core/bug_api.php b/core/bug_api.php
index fb32839..4326199 100644
--- a/core/bug_api.php
+++ b/core/bug_api.php
@@ -1324,6 +1324,28 @@ function bug_get_newest_bugnote_timestamp( $p_bug_id ) {
}
/**
+ * return the reporter (user_id) for the most recent time at which a bugnote
+ * associated with the bug was modified
+ * @param int p_bug_id integer representing bug id
+ * @return bool|int false or user id in integer format representing last bugnote reporter
+ * @access public
+ * @uses database_api.php
+ */
+function bug_get_last_bugnote_reporter( $p_bug_id ) {
+ $c_bug_id = db_prepare_int( $p_bug_id );
+ $t_bugnote_table = db_get_table( 'bugnote' );
+
+ $query = "SELECT MIN(reporter_id)
+ FROM $t_bugnote_table A
+ WHERE A.date_submitted = (SELECT MAX(X.date_submitted)
+ FROM $t_bugnote_table X
+ WHERE X.bug_id = A.bug_id) AND
+ A.bug_id=" . db_param();
+ $result = db_query_bound( $query, Array( $c_bug_id ), 1 );
+ return db_result( $result );
+}
+
+/**
* return the timestamp for the most recent time at which a bugnote
* associated with the bug was modified and the total bugnote
* count in one db query
diff --git a/core/constant_inc.php b/core/constant_inc.php
index 7e3e274..42bde13 100644
--- a/core/constant_inc.php
+++ b/core/constant_inc.php
@@ -134,6 +134,7 @@ define( 'MD5', 3 );
define( 'LDAP', 4 );
define( 'BASIC_AUTH', 5 );
define( 'HTTP_AUTH', 6 );
+define( 'SHA1', 7 );
# file upload methods
define( 'DISK', 1 );
@@ -552,6 +553,6 @@ define( 'PHPMAILER_METHOD_SMTP', 2 );
# Lengths - NOTE: these may represent hard-coded values in db schema and should not be changed.
define( 'USERLEN', 32);
define( 'REALLEN', 64);
-define( 'PASSLEN', 32);
+define( 'PASSLEN', 128);
define( 'SECONDS_PER_DAY', 86400 );
diff --git a/core/filter_api.php b/core/filter_api.php
index 7e61912..01b2292 100644
--- a/core/filter_api.php
+++ b/core/filter_api.php
@@ -1865,19 +1865,19 @@ function filter_get_bug_rows( &$p_page_number, &$p_per_page, &$p_page_count, &$p
break;
case CUSTOM_FIELD_DATE_NONE:
array_push( $t_join_clauses, $t_cf_join_clause );
- $t_custom_where_clause = '(( ' . $t_table_name . '.bug_id is null) OR ( ' . $t_table_name . '.value = 0)';
+ $t_custom_where_clause = '(( ' . $t_table_name . '.bug_id is null) OR ( CAST(' . $t_table_name . '.value AS FLOAT) = 0)';
break;
case CUSTOM_FIELD_DATE_BEFORE:
array_push( $t_join_clauses, $t_cf_join_clause );
- $t_custom_where_clause = '(( ' . $t_table_name . '.value != 0 AND (' . $t_table_name . '.value+0) < ' . ( $t_filter['custom_fields'][$t_cfid][2] ) . ')';
+ $t_custom_where_clause = '(( CAST(' . $t_table_name . '.value AS FLOAT) != 0 AND ( CAST(' . $t_table_name . '.value AS FLOAT) + 0) < ' . ( $t_filter['custom_fields'][$t_cfid][2] ) . ')';
break;
case CUSTOM_FIELD_DATE_AFTER:
array_push( $t_join_clauses, $t_cf_join_clause );
- $t_custom_where_clause = '( (' . $t_table_name . '.value+0) > ' . ( $t_filter['custom_fields'][$t_cfid][1] + 1 );
+ $t_custom_where_clause = '( (CAST(' . $t_table_name . '.value AS FLOAT) + 0) > ' . ( $t_filter['custom_fields'][$t_cfid][1] + 1 );
break;
default:
array_push( $t_join_clauses, $t_cf_join_clause );
- $t_custom_where_clause = '( (' . $t_table_name . '.value+0) BETWEEN ' . $t_filter['custom_fields'][$t_cfid][1] . ' AND ' . $t_filter['custom_fields'][$t_cfid][2];
+ $t_custom_where_clause = '( ( CAST(' . $t_table_name . '.value AS FLOAT) + 0) BETWEEN ' . $t_filter['custom_fields'][$t_cfid][1] . ' AND ' . $t_filter['custom_fields'][$t_cfid][2];
break;
}
} else {
diff --git a/core/html_api.php b/core/html_api.php
index 4bdf300..1f37ca1 100644
--- a/core/html_api.php
+++ b/core/html_api.php
@@ -1201,11 +1201,19 @@ function html_status_legend() {
# draw the status bar
$width = (int)( 100 / count( $t_status_array ) );
- foreach( $t_status_array as $t_status => $t_name ) {
- $t_val = $t_status_names[$t_status];
- $t_color = get_status_color( $t_status );
+ for($i=0; $i<10; $i++) {
+ if ( $i != 0 ) {
+ echo '
';
+ }
+ foreach( $t_status_array as $t_status => $t_name ) {
+ if($t_status % 10 == $i) {
+ $t_val = $t_status_names[$t_status];
+ $t_color = get_status_color( $t_status );
- echo "$t_val | ";
+ echo "$t_val | ";
+ }
+ }
+ echo '
';
}
echo '';
diff --git a/core/install_helper_functions_api.php b/core/install_helper_functions_api.php
index f33e4c5..9a36745 100644
--- a/core/install_helper_functions_api.php
+++ b/core/install_helper_functions_api.php
@@ -221,4 +221,63 @@ function install_date_migrate( $p_data) {
function install_do_nothing() {
# return 2 because that's what ADOdb/DataDict does when things happen properly
return 2;
-}
\ No newline at end of file
+}
+
+function install_password_hash_migrate( $p_data) {
+ // $p_data = [0] temp_password column, [1] password_hash column
+ global $g_db_log_queries;
+ global $g_login_method;
+
+ if( $g_login_method === LDAP ) {
+ return 2;
+ }
+
+ $t_login_method = array(PLAIN => 'PLAIN', CRYPT => 'CRYPT',
+ CRYPT_FULL_SALT => 'CRYPT_FULL_SALT', MD5 => 'MD5', SHA1 => 'SHA1'
+ )[$g_login_method];
+
+
+ // disable query logging (even if it's enabled in config for this)
+ if ( $g_db_log_queries !== 0 ) {
+ $t_log_queries = $g_db_log_queries;
+ $g_db_log_queries = 0;
+ } else {
+ $t_log_queries = null;
+ }
+
+ $t_table = db_get_table( 'user' );
+ $t_temp_col = $p_data[0];
+ $t_password_hash_col = $p_data[1];
+
+ // fill password_hash and temp_col
+ $query = "SELECT id, password FROM $t_table";
+ $t_result = db_query_bound( $query );
+
+ while( $row = db_fetch_array( $t_result ) ) {
+
+ $t_id = (int)$row['id'];
+ $t_hash_mode = $t_login_method;
+ $t_password = $row['password'];
+
+ if( substr($t_password, 0, 1) == '{'
+ && strpos($t_password, '}') > 1 ) {
+
+ $t_hash_mode = substr($t_password, 1, strpos($t_password, '}') - 1);
+ $t_password = substr($t_password, strlen($t_hash_mode) + 2);
+ }
+
+ $query = "UPDATE $t_table SET $t_temp_col=" . db_param() . ", "
+ "$t_password_hash_col=" . db_param() . "
+ WHERE id=" . db_param();
+ db_query_bound( $query, array( $t_password, $t_hash_mode, $t_id ) );
+ }
+
+ // re-enabled query logging if we disabled it
+ if ( $t_log_queries !== null ) {
+ $g_db_log_queries = $t_log_queries;
+ }
+
+ # return 2 because that's what ADOdb/DataDict does when things happen properly
+ return 2;
+
+}
diff --git a/docbook/adminguide/en/authentication.sgml b/docbook/adminguide/en/authentication.sgml
index a960c1e..ffbe0f6 100644
--- a/docbook/adminguide/en/authentication.sgml
+++ b/docbook/adminguide/en/authentication.sgml
@@ -14,6 +14,7 @@
CRYPT_FULL_SALT - deprecated.
PLAIN - deprecated.
MD5 - This is default and recommended approach. See MD5 topic on Wikipedia for more details.
+ SHA1 - Even stronger than MD5. See SHA1 topic on Wikipedia for more details.
diff --git a/docbook/adminguide/en/configuration.sgml b/docbook/adminguide/en/configuration.sgml
index bce4bdd..99df312 100644
--- a/docbook/adminguide/en/configuration.sgml
+++ b/docbook/adminguide/en/configuration.sgml
@@ -1583,6 +1583,9 @@
+ SHA1
+
+
MD5
diff --git a/my_view_inc.php b/my_view_inc.php
index 97c131c..ff2e62d 100644
--- a/my_view_inc.php
+++ b/my_view_inc.php
@@ -434,6 +434,9 @@ echo "($v_start - $v_end / $t_bug_count)";
$t_summary = string_display_line_links( $t_bug->summary );
$t_last_updated = date( config_get( 'normal_date_format' ), $t_bug->last_updated );
+ $t_last_reporter_id = bug_get_last_bugnote_reporter( $t_bug->id );
+ $t_last_reporter = $t_last_reporter_id ? user_get_name( $t_last_reporter_id ) : '';
+
# choose color based on status
$status_color = get_status_color( $t_bug->status );
@@ -498,9 +501,9 @@ echo "($v_start - $v_end / $t_bug_count)";
echo string_display_line( category_full_name( $t_bug->category_id, true, $t_bug->project_id ) );
if( $t_bug->last_updated > strtotime( '-' . $t_filter[FILTER_PROPERTY_HIGHLIGHT_CHANGED] . ' hours' ) ) {
- echo ' - ' . $t_last_updated . '';
+ echo ' - ' . $t_last_updated . ' - ' . $t_last_reporter . '';
} else {
- echo ' - ' . $t_last_updated;
+ echo ' - ' . $t_last_updated . ' - ' . $t_last_reporter;
}
?>
diff --git a/plugins/AutoMonitor/AutoMonitor.API.php b/plugins/AutoMonitor/AutoMonitor.API.php
new file mode 100644
index 0000000..ab86729
--- /dev/null
+++ b/plugins/AutoMonitor/AutoMonitor.API.php
@@ -0,0 +1,89 @@
+ $val ) {
+ $t_ret[] = $val;
+ }
+ return $t_ret;
+}
diff --git a/plugins/AutoMonitor/AutoMonitor.ViewAPI.php b/plugins/AutoMonitor/AutoMonitor.ViewAPI.php
new file mode 100644
index 0000000..d2fcddf
--- /dev/null
+++ b/plugins/AutoMonitor/AutoMonitor.ViewAPI.php
@@ -0,0 +1,105 @@
+
+>
+
+
+ |
+
+ '/>
+ '/>
+ |
+
+
+ |
+
+ '/>
+ '/>
+ |
+
+
+ |
+
+ '/>
+ '/>
+ |
+
+$t_display_a[$i]\n";
+ }
+}
+?>
diff --git a/plugins/AutoMonitor/AutoMonitor.php b/plugins/AutoMonitor/AutoMonitor.php
new file mode 100644
index 0000000..90e8d3b
--- /dev/null
+++ b/plugins/AutoMonitor/AutoMonitor.php
@@ -0,0 +1,146 @@
+name = plugin_lang_get('title');
+ $this->description = plugin_lang_get('description');
+ $this->author = 'Adam Sutton';
+ $this->contact = 'adam@adamsutton.co.uk';
+ $this->url = 'http://www.adamsutton.co.uk';
+ $this->version = '0.0.0';
+ $this->requires = array(
+ 'MantisCore' => '1.2.0',
+ );
+ $this->page = 'config';
+ }
+
+ /**
+ * Initialise
+ */
+ function init ()
+ {
+ require_once('AutoMonitor.API.php');
+ require_once('AutoMonitor.ViewAPI.php');
+ }
+
+ /**
+ * Configuration
+ */
+ function config ()
+ {
+ return array(
+ );
+ }
+
+ /**
+ * Schema
+ */
+ function schema ()
+ {
+ return array(
+ array('CreateTableSQL', array(plugin_table('list'), "
+ user_id I UNSIGNED NOTNULL PRIMARY,
+ project_id I UNSIGNED NOTNULL PRIMARY,
+ category_id I UNSIGNED NOTNULL PRIMARY,
+ state L NOTNULL")),
+ );
+ }
+
+ /**
+ * Event hooks
+ */
+ function hooks ()
+ {
+ return array(
+ 'EVENT_MANAGE_PROJECT_PAGE' => 'manage_project_list',
+ 'EVENT_REPORT_BUG' => 'add_monitors',
+ );
+ }
+
+ /* ************************************************************************
+ * Hook handlers
+ * ***********************************************************************/
+
+ function manage_project_list ()
+ {
+ /* Check access */
+ $f_project_id = gpc_get_int('project_id');
+ if ( !access_has_project_level(config_get('project_user_threshold'), $f_project_id) ) {
+ return;
+ }
+
+ /* Get user list */
+ $t_users = AutoMonitor_get_users($f_project_id, 0);
+?>
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+project_id, 0);
+ print_r($t_users);
+ foreach($t_users as $t_user) {
+ if($t_user['automonitor_state'] > 0)
+ bug_monitor($p_bug_id, $t_user['id']);
+ }
+ }
+ }
+}
+?>
diff --git a/plugins/AutoMonitor/lang/strings_english.txt b/plugins/AutoMonitor/lang/strings_english.txt
new file mode 100644
index 0000000..7df3ee8
--- /dev/null
+++ b/plugins/AutoMonitor/lang/strings_english.txt
@@ -0,0 +1,17 @@
+
diff --git a/plugins/AutoMonitor/lang/strings_hungarian.txt b/plugins/AutoMonitor/lang/strings_hungarian.txt
new file mode 100644
index 0000000..3f597b9
--- /dev/null
+++ b/plugins/AutoMonitor/lang/strings_hungarian.txt
@@ -0,0 +1,17 @@
+
diff --git a/plugins/AutoMonitor/pages/category_edit_page.php b/plugins/AutoMonitor/pages/category_edit_page.php
new file mode 100644
index 0000000..c52ffda
--- /dev/null
+++ b/plugins/AutoMonitor/pages/category_edit_page.php
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/AutoMonitor/pages/project_update.php b/plugins/AutoMonitor/pages/project_update.php
new file mode 100644
index 0000000..afcaca6
--- /dev/null
+++ b/plugins/AutoMonitor/pages/project_update.php
@@ -0,0 +1,78 @@
+name = 'FileDistribution'; # Proper name of plugin
+ $this->description = 'Static file distrubution'; # Short description of the plugin
+ $this->page = ''; # Default plugin page
+
+ $this->version = '1.0'; # Plugin version string
+ $this->requires = array( # Plugin dependencies, array of basename => version pairs
+ 'MantisCore' => '1.2.0', # Should always depend on an appropriate version of MantisBT
+ );
+
+ $this->author = 'Tamás Gulácsi'; # Author/team name
+ $this->contact = 'T.Gulacsi@unosoft.hu'; # Author/team e-mail address
+ $this->url = 'http://www.unosoft.hu'; # Support webpage
+ }
+
+ function config() {
+ return array(
+ 'url' => NULL,
+ 'path' => NULL,
+ 'users' => array(),
+ 'secret_word' => '1234567890',
+ );
+ }
+
+ function hooks() {
+ return array(
+ 'EVENT_MENU_MAIN' => 'menu',
+ 'EVENT_MENU_MANAGE' => 'manage',
+ );
+ }
+
+ function menu( ) {
+ //require_once( 'core.php' );
+ require_once( dirname(__FILE__).'/core/filedistrib_api.php' );
+
+ if ( user_allowed() ) {
+ return array( '' .
+ plugin_lang_get('static_files') . '', );
+ }
+ }
+
+ function manage( ) {
+ require_once( 'core.php' );
+
+ if ( access_get_project_level() >= MANAGER) {
+ return array( ''
+ . plugin_lang_get('config') . '', );
+ }
+ }
+}
diff --git a/plugins/FileDistribution/core/filedistrib_api.php b/plugins/FileDistribution/core/filedistrib_api.php
new file mode 100644
index 0000000..ac978cd
--- /dev/null
+++ b/plugins/FileDistribution/core/filedistrib_api.php
@@ -0,0 +1,49 @@
+
diff --git a/plugins/FileDistribution/lang/strings_english.txt b/plugins/FileDistribution/lang/strings_english.txt
new file mode 100755
index 0000000..3fbaf47
--- /dev/null
+++ b/plugins/FileDistribution/lang/strings_english.txt
@@ -0,0 +1,8 @@
+.
+
+auth_reauthenticate( );
+access_ensure_global_level( config_get( 'manage_plugin_threshold' ) );
+
+html_page_top( plugin_lang_get( 'name' ) );
+
+print_manage_menu( );
+
+?>
+
+
+
+
+
diff --git a/plugins/FileDistribution/pages/config_edit.php b/plugins/FileDistribution/pages/config_edit.php
new file mode 100644
index 0000000..2fc7aee
--- /dev/null
+++ b/plugins/FileDistribution/pages/config_edit.php
@@ -0,0 +1,51 @@
+.
+
+form_security_validate( 'plugin_filedistrib_config_edit' );
+
+auth_reauthenticate( );
+access_ensure_global_level( config_get( 'manage_plugin_threshold' ) );
+
+$f_url = gpc_get_string( 'url', NULL );
+$f_path = gpc_get_string( 'path', NULL );
+$f_secret_word = gpc_get_string( 'secret_word', NULL );
+/*
+echo 'old_url='.plugin_config_get( 'url' ).', new_url='.$f_url.'
';
+*/
+
+if( plugin_config_get( 'url' ) != $f_url ) {
+ plugin_config_set( 'url', $f_url );
+}
+if( plugin_config_get( 'path' ) != $f_path && is_dir($f_path) && file_exists($f_path) ) {
+ plugin_config_set( 'path', $f_path );
+}
+if( plugin_config_get( 'secret_word' ) != $f_secret_word && $f_secret_word != NULL) {
+ plugin_config_set( 'secret_word', $f_secret_word );
+}
+
+//require_once( 'core.php' );
+require_once( dirname(__FILE__).'/../core/filedistrib_api.php' );
+
+$t_users_old = list2str(str2list(plugin_config_get( 'users', '' )));
+$f_users = list2str(str2list(gpc_get_string( 'users', '' )));
+if( $t_users_old != $f_users ) {
+ plugin_config_set( 'users', list2str(str2list($f_users)) );
+}
+
+form_security_purge( 'plugin_filedistrib_config_edit' );
+
+print_successful_redirect( plugin_page( 'config', true ) );
+?>
diff --git a/plugins/FileDistribution/pages/send_file.php b/plugins/FileDistribution/pages/send_file.php
new file mode 100755
index 0000000..cde6946
--- /dev/null
+++ b/plugins/FileDistribution/pages/send_file.php
@@ -0,0 +1,84 @@
+= $v[0]) {
+ if (empty($v[2]) || $v[2] == '*') {
+ return true;
+ } elseif ($phpV[2] >= $v[2]) {
+ if (empty($v[4]) || $v[4] == '*' || $phpV[4] >= $v[4]) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+//header('HTTP/1.1 200 OK');
+//header('Content-Type: text/plain');
+
+$f_url = $_REQUEST['url'];
+if($f_url == false) {
+ $p = strpos($_SERVER['QUERY_STRING'], '%3Furl%3D');
+ if($p >= 0) {
+ //echo '!' . substr($_SERVER['QUERY_STRING'], $p+9) . "!\n";
+ $f_url = urldecode(substr($_SERVER['QUERY_STRING'], $p+9));
+ } else {
+ //echo '!QS='.$_SERVER['QUERY_STRING']."! p=$p\n";
+ }
+}
+//if($f_url == false) phpinfo();
+//echo "URL=$f_url\n";
+
+$arr = explode('/', $f_url);
+//print_r($arr);
+$f_time = array_pop(&$arr);
+$t_time = hexdec($f_time);
+$t_now = time();
+if ($t_now >= $t_time) {
+ header('HTTP/1.1 403 Timeout');
+ header('Content-Type: text/plain');
+ echo "Your link has expired (actual=$t_now, link=$t_time).\n";
+ exit();
+}
+$f_hash = array_pop(&$arr);
+$f_fn = implode('/', $arr);
+//echo "fn=$f_fn, hash=$f_hash, time=$f_time";
+
+$t_secret = plugin_config_get('secret_word');
+$t_hash = md5($f_fn . '/' . $t_secret . '/' . $f_time);
+if($t_hash != $f_hash) {
+ header('HTTP/1.1 403 Bad Request');
+ header('Content-Type: text/plain');
+ echo "Your link has bad hash (actual=$t_hash, link=$f_hash).\n";
+ exit();
+}
+
+$t_path_base = plugin_config_get('path');
+$t_url_base = plugin_config_get('url');
+
+$f_path = $t_path_base . '/' . $f_fn;
+if ($f_fn != false && file_exists($f_path)) {
+ $mime = mime_content_type($f_fn);
+ header('Content-Description: File Transfer');
+ header('Content-Type: ' . $mime);
+ header('Content-Disposition: attachment; filename=' . basename($f_fn));
+ header('Content-Transfer-Encoding: binary');
+ header('Expires: 0');
+ header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+ header('Pragma: public');
+ header('Content-Length: ' . filesize($f_path));
+
+ header('X-Accel-Redirect: /protected' . $t_url_base . '/' . $f_fn);
+} else {
+ header('Content-Type: text/plain');
+ echo "NOT EXISTS (fn=$f_fn, path=$f_path, url_base=$t_url_base, path_base=$t_path_base)";
+}
diff --git a/plugins/FileDistribution/pages/static_files.php b/plugins/FileDistribution/pages/static_files.php
new file mode 100755
index 0000000..288a107
--- /dev/null
+++ b/plugins/FileDistribution/pages/static_files.php
@@ -0,0 +1,115 @@
+handle . "\n";
+echo "Path: " . $d->path . "\n";
+*/
+$t_post_url = plugin_page( 'send_file.php' );
+/*
+$t_post_url = str_replace('FileDistribution/', 'FileDistribution/pages/',
+ str_replace('plugin.php?page=', 'plugins/', $t_post_url ));
+*/
+/*
+$d = scandir($t_url);
+echo '';
+foreach($d as $entry) {
+ if(preg_match('/\.(tar\.|t)(gz|bz2)$/', $entry)) {
+ ?>
+ -
+
+
+';
+*/
+function get_dirs($path) {
+ $arr = array();
+ foreach(scandir($path, TRUE) as $elt) {
+ $p = $path . '/' . $elt;
+ if( is_dir($p) && $elt != '.' && $elt != '..' ) {
+ $arr[] = $p;
+ }
+ }
+ return $arr;
+}
+
+function get_files($path, $regex) {
+ $arr = array();
+ foreach(scandir($path, FALSE) as $elt) {
+ $p = $path . '/' . $elt;
+ if( is_file($p) && is_readable($p) && preg_match($regex, $elt) ) {
+ $arr[] = $p;
+ }
+ }
+ return $arr;
+}
+
+function print_struct($path, $regex, $level=0) {
+ if($level > 10) return;
+ $t_path = plugin_config_get('path');
+ $t_secret = plugin_config_get('secret_word');
+ $t_timeout = plugin_config_get('timeout', 300);
+
+ $t_plugin_page = plugin_page('send_file.php');
+ $t_url = $t_plugin_page;
+ $t_url = substr($t_url, 0, strpos($t_url, '/plugin.php'))
+ . plugin_config_get('url');
+ print '';
+ print ''.basename($path).'';
+ $i = 0;
+ foreach(get_dirs($path) as $d) {
+ # DFS
+ //print 'd: '.$d.' lev='.$level;
+ print_struct($d, $regex, $level+1);
+ if($i++ > 100) break;
+ }
+ print '
';
+ $i = 0;
+ foreach(get_files($path, $regex) as $f) {
+ # md5 (reference, secret_word);
+ $t_resource = substr($f, strlen($t_path)+1);
+ $t_pre = $t_resource; #$t_url . '/' . $t_resource;
+ $t_time = sprintf("%X", time() + $t_timeout);
+ $t_hash = md5($t_pre . '/' . $t_secret . '/' . $t_time);
+ $t_link = $t_pre . '/' . $t_hash . '/' . $t_time;
+ //print "
pre=$t_pre, time=$t_time, hash=$t_hash, secr=$t_secret, $t_pre/$t_secret/$t_time
";
+ //print '' . basename($f).'';
+ print ''.basename($f).'';
+ if($i++ > 100) break;
+ }
+ print '';
+ print '';
+} #mantIs3456
+
+print_struct($t_path, '/.*/');
+
+
+html_page_bottom();