Initial checkin of resolver.php
- use \\ instead of just \ in FileName - Use file_put_contents instead of open/write - Use file_exist instead of stat - Added /lib directory - Moved /tftpboot/index.cfg -> /config.ini - Moved /tftpboot/resolver.php -> /lib/resolver.php - Added /lib/config.php - include /lib/config.php in resolver.php and index.php - Changed $config array - Remove print_r($config['main']['base_path']) from config.php - Add isValidRequest() function - Use Boolean in tree_base data - Simplify config['subdirs'] substitution - Add lib/utils.php file - Added simple shell/utf/html escape checking - Added a collection of test cases (we need some more escape checking ones) - Added lib/logger.php (copied from tftpserver.php, so that it can be reused for that). - Clarify config.ini logformat - Update logger implementation - Replaced index.php with version that uses lib/resolver.php - Replaced ../etc/nginx/sites-available/tftpboot Example file
This commit is contained in:
17
config.ini
Normal file
17
config.ini
Normal file
@@ -0,0 +1,17 @@
|
||||
[main]
|
||||
debug = on ; The output in the browser window for more information
|
||||
cache_filename = "/tmp/provision_sccp_resolver.cache"
|
||||
default_language = English_United_States
|
||||
log_type = SYSLOG ; SYSLOG|STDERR|STDOUT|NULL|FILE
|
||||
log_level = LOG_INFO ; LOG_EMERG|LOG_ALERT|LOG_CRIT|LOG_ERR|LOG_WARNING|LOG_NOTICE|LOG_INFO|LOG_DEBUG
|
||||
;log_filename = provision.log ; only in case of log_type = FILE
|
||||
|
||||
[subdirs]
|
||||
tftproot = tftpboot
|
||||
firmware = firmware
|
||||
settings = settings
|
||||
wallpapers = wallpapers
|
||||
ringtones = ringtones
|
||||
locales = locales
|
||||
countries = countries
|
||||
languages = languages
|
@@ -1,260 +1,29 @@
|
||||
server {
|
||||
listen 6970;
|
||||
server_name tftp.servername.org;
|
||||
#root /tftpboot;
|
||||
root /data/development/sccp/sources/tftp/tftpboot;
|
||||
index XMLDefault.cnf.xml;
|
||||
listen 6970;
|
||||
server_name tftp.servername.org;
|
||||
root /data/development/sccp/sources/tftp/tftpboot;
|
||||
|
||||
# Normal Logging
|
||||
#access_log /var/log/nginx/tftp.access.log;
|
||||
#error_log /var/log/nginx/tftp.error.log;
|
||||
# Normal Logging
|
||||
access_log /var/log/nginx/tftp1.access.log;
|
||||
error_log /var/log/nginx/tftp1.error.log;
|
||||
|
||||
# Debug Rewrite Rules
|
||||
rewrite_log on;
|
||||
access_log /var/log/nginx/tftp.access.log;
|
||||
error_log /var/log/nginx/tftp.error.log notice;
|
||||
index index.php;
|
||||
location ~ \.php$ {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
|
||||
location / {
|
||||
# settings
|
||||
rewrite ^/((.*)(\.cnf\.xml|\.tlv|authorized_keys)(\.enc)?(\.sgn)?)$ /settings/$1 last;
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php$is_args$args;
|
||||
rewrite ^/(.*)$ /index.php?filename=$1 last;
|
||||
}
|
||||
|
||||
# firmware
|
||||
rewrite ^/((.*).(bin|bin.|loads|LOADS|sbn|SBN|sb2|sbin|zz|zup)(\.sgn)?)$ /firmware/$1 last;
|
||||
|
||||
# locales
|
||||
rewrite ^/(.*)/((.*)-tones\.xml(\.sgn)?)$ /locales/countries/$1/$2 last;
|
||||
rewrite ^/(.*)/((.*)(-dictionary(.*)\.xml)(\.sgn)?)$ /locales/languages/$1/$2 last;
|
||||
rewrite ^/(.*)/((.*)(-kate(.*)\.xml)(\.sgn)?)$ /locales/languages/$1/$2 last;
|
||||
rewrite ^/(.*)/((.*)(-sccp\.jar)(\.sgn)?)$ /locales/languages/$1/$2 last;
|
||||
rewrite ^/(.*)/((.*)(-font\.xml)(\.sgn)?)$ /locales/languages/$1/$2 last;
|
||||
rewrite ^/(.*)/(CIPC_Locale\.(.*))(\.sgn)?)$ /locales/languages/$1/$2 last;
|
||||
|
||||
rewrite ^/(.*)/((.*)(-tones.xml)(\.sgn)?)$ /locales/countries/$1/$2 last;
|
||||
|
||||
# ringtones
|
||||
rewrite ^/([D|d]istinctive)?([R|r]ing[L|l]ist)\.(xml|XML)(\.sgn)?$ /ringtones/ringlist.xml last;
|
||||
#rewrite ^/((.*)(\.raw|\.pcm)(\.sgn))?$ /ringtones/$1 last;
|
||||
|
||||
# wallpapers
|
||||
rewrite ^/Desktops/(.*)/((.*)(\.sgn)?)$ /wallpapers/$1/$2 last;
|
||||
try_files $uri $uri/ =404;
|
||||
autoindex off;
|
||||
}
|
||||
|
||||
# settings
|
||||
location /settings {
|
||||
try_files $uri $uri/ =404;
|
||||
autoindex off;
|
||||
}
|
||||
|
||||
# firmware
|
||||
location /firmware {
|
||||
# 6901 firmware (java-based)
|
||||
rewrite ^/firmware/(APP6901SCCP.+\.sgn)$ /firmware/6901/$1 last;
|
||||
rewrite ^/firmware/(KNL6901SCCP.+\.sgn)$ /firmware/6901/$1 last;
|
||||
rewrite ^/firmware/(SCCP6901.+\.loads)$ /firmware/6901/$1 last;
|
||||
|
||||
# 6911 firmware (java-based)
|
||||
rewrite ^/firmware/(APP6911SCCP.+\.sgn)$ /firmware/6911/$1 last;
|
||||
rewrite ^/firmware/(BFS6911SCCP.+\.sgn)$ /firmware/6911/$1 last;
|
||||
rewrite ^/firmware/(KNL6911SCCP.+\.sgn)$ /firmware/6911/$1 last;
|
||||
rewrite ^/firmware/(SCCP6911.+\.loads)$ /firmware/6911/$1 last;
|
||||
|
||||
# 6921 firmware (java-based)
|
||||
rewrite ^/firmware/(BOOT69xx.+\.sgn)$ /firmware/6921/$1 last;
|
||||
rewrite ^/firmware/(DSP69xx.+\.sgn)$ /firmware/6921/$1 last;
|
||||
rewrite ^/firmware/(SCCP69xx.+\.loads)$ /firmware/6921/$1 last;
|
||||
rewrite ^/firmware/(SCCP69xx.+\.sgn)$ /firmware/6921/$1 last;
|
||||
|
||||
# 6945 firmware (java-based)
|
||||
rewrite ^/firmware/(SCCP6945.+\.sgn)$ /firmware/6945/$1 last;
|
||||
rewrite ^/firmware/(SCCP6945.+\.loads)$ /firmware/6945/$1 last;
|
||||
|
||||
# 69xx firmware (java-based)
|
||||
rewrite ^/firmware/(BOOT69xx.+\.sgn)$ /firmware/69xx/$1 last;
|
||||
rewrite ^/firmware/(DSP69xx.+\.sgn)$ /firmware/69xx/$1 last;
|
||||
rewrite ^/firmware/(SCCP69xx.+\.loads)$ /firmware/69xx/$1 last;
|
||||
rewrite ^/firmware/(SCCP69xx.+\.sgn)$ /firmware/69xx/$1 last;
|
||||
|
||||
# 7902 firmware (ancient)
|
||||
rewrite ^/firmware/(CP7902080002SCCP060817A.sbin)$ /firmware/7902/$1 last;
|
||||
|
||||
# 7905 firmware (ancient)
|
||||
rewrite ^/firmware/(CP7905080003SCCP070409A.sbin)$ /firmware/7905/$1 last;
|
||||
rewrite ^/firmware/(CP7905080003SCCP070409A.zup)$ /firmware/7905/$1 last;
|
||||
|
||||
# 7906_7911 firmware (java-based)
|
||||
rewrite ^/firmware/(apps11.+\.sbn)$ /firmware/7906_7911/$1 last;
|
||||
rewrite ^/firmware/(cnu11.+\.sbn)$ /firmware/7906_7911/$1 last;
|
||||
rewrite ^/firmware/(cvm11sccp.+\.sbn)$ /firmware/7906_7911/$1 last;
|
||||
rewrite ^/firmware/(dsp11.+\.sbn)$ /firmware/7906_7911/$1 last;
|
||||
rewrite ^/firmware/(jar11sccp.+\.sbn)$ /firmware/7906_7911/$1 last;
|
||||
rewrite ^/firmware/(SCCP11.+\.loads)$ /firmware/7906_7911/$1 last;
|
||||
rewrite ^/firmware/(term06.+\.loads)$ /firmware/7906_7911/$1 last;
|
||||
rewrite ^/firmware/(term11.+\.loads)$ /firmware/7906_7911/$1 last;
|
||||
|
||||
# 7910 firmware (ancient)
|
||||
rewrite ^/firmware/(P00405000700.bin)$ /firmware/7910/$1 last;
|
||||
rewrite ^/firmware/(P00405000700.sbn)$ /firmware/7910/$1 last;
|
||||
|
||||
# 7912 firmware (ancient)
|
||||
rewrite ^/firmware/(CP7912080004SCCP080108A.sbin)$ /firmware/7912/$1 last;
|
||||
|
||||
# 7915 firmware (ancient)
|
||||
rewrite ^/firmware/(B015-1-0-4.SBN)$ /firmware/7915/$1 last;
|
||||
|
||||
# 7916 firmware (ancient)
|
||||
rewrite ^/firmware/(B016-1-0-4.SBN)$ /firmware/7916/$1 last;
|
||||
|
||||
# 7920 firmware (ancient)
|
||||
rewrite ^/firmware/(cmterm_7920.4.0-03-02.bin)$ /firmware/7920/$1 last;
|
||||
|
||||
# 7921_7925 firmware (ancient)
|
||||
rewrite ^/firmware/(APPS-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
|
||||
rewrite ^/firmware/(CP7921G-1.4.3.4.LOADS)$ /firmware/7921_7925/$1 last;
|
||||
rewrite ^/firmware/(GUI-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
|
||||
rewrite ^/firmware/(SYS-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
|
||||
rewrite ^/firmware/(TNUX-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
|
||||
rewrite ^/firmware/(TNUXR-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
|
||||
rewrite ^/firmware/(WLAN-1.4.3.4.SBN)$ /firmware/7921_7925/$1 last;
|
||||
|
||||
# 7926 firmware (ancient)
|
||||
rewrite ^/firmware/(APPSS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
|
||||
rewrite ^/firmware/(CP7926G-1.4.1SR1.LOADS)$ /firmware/7926/$1 last;
|
||||
rewrite ^/firmware/(EA15FW-BF3-220.SBN)$ /firmware/7926/$1 last;
|
||||
rewrite ^/firmware/(GUIS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
|
||||
rewrite ^/firmware/(JSYSS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
|
||||
rewrite ^/firmware/(JUIS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
|
||||
rewrite ^/firmware/(SYSS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
|
||||
rewrite ^/firmware/(TNUXRS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
|
||||
rewrite ^/firmware/(TNUXS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
|
||||
rewrite ^/firmware/(WLANS-1.4.1SR1.SBN)$ /firmware/7926/$1 last;
|
||||
|
||||
# 7931 firmware (java-based)
|
||||
rewrite ^/firmware/(apps31.+\.sbn)$ /firmware/7931/$1 last;
|
||||
rewrite ^/firmware/(cnu31.+\.sbn)$ /firmware/7931/$1 last;
|
||||
rewrite ^/firmware/(cvm31sccp.+\.sbn)$ /firmware/7931/$1 last;
|
||||
rewrite ^/firmware/(dsp31.+\.sbn)$ /firmware/7931/$1 last;
|
||||
rewrite ^/firmware/(jar31sccp.+\.sbn)$ /firmware/7931/$1 last;
|
||||
rewrite ^/firmware/(SCCP31.+\.loads)$ /firmware/7931/$1 last;
|
||||
rewrite ^/firmware/(term31.+\.loads)$ /firmware/7931/$1 last;
|
||||
|
||||
# 7935 firmware (ancient)
|
||||
rewrite ^/firmware/(P00503021900.bin)$ /firmware/7935/$1 last;
|
||||
|
||||
# 7936 firmware (ancient)
|
||||
rewrite ^/firmware/(cmterm_7936.3-3-21-0.bin)$ /firmware/7936/$1 last;
|
||||
|
||||
# 7937 firmware (ancient)
|
||||
rewrite ^/firmware/(apps37sccp.1-4-5-7.bin)$ /firmware/7937/$1 last;
|
||||
|
||||
# 7940_7960 firmware (ancient)
|
||||
rewrite ^/firmware/(P0030801SR.+\.bin)$ /firmware/7940_7960/$1 last;
|
||||
rewrite ^/firmware/(P0030801SR.+\.loads)$ /firmware/7940_7960/$1 last;
|
||||
rewrite ^/firmware/(P0030801SR.+\.sb2)$ /firmware/7940_7960/$1 last;
|
||||
rewrite ^/firmware/(P0030801SR.+\.sbn)$ /firmware/7940_7960/$1 last;
|
||||
|
||||
# 7941_7961 firmware (java-based)
|
||||
rewrite ^/firmware/(apps41.+\.sbn)$ /firmware/7941_7961/$1 last;
|
||||
rewrite ^/firmware/(cnu41.+\.sbn)$ /firmware/7941_7961/$1 last;
|
||||
rewrite ^/firmware/(cvm41sccp.+\.sbn)$ /firmware/7941_7961/$1 last;
|
||||
rewrite ^/firmware/(dsp41.+\.sbn)$ /firmware/7941_7961/$1 last;
|
||||
rewrite ^/firmware/(jar41sccp.+\.sbn)$ /firmware/7941_7961/$1 last;
|
||||
rewrite ^/firmware/(SCCP41.+\.loads)$ /firmware/7941_7961/$1 last;
|
||||
rewrite ^/firmware/(term41.+\.loads)$ /firmware/7941_7961/$1 last;
|
||||
rewrite ^/firmware/(term61.+\.loads)$ /firmware/7941_7961/$1 last;
|
||||
|
||||
# 7942_7962 firmware (java-based)
|
||||
rewrite ^/firmware/(apps42.+\.sbn)$ /firmware/7942_7962/$1 last;
|
||||
rewrite ^/firmware/(cnu42.+\.sbn)$ /firmware/7942_7962/$1 last;
|
||||
rewrite ^/firmware/(cvm42sccp.+\.sbn)$ /firmware/7942_7962/$1 last;
|
||||
rewrite ^/firmware/(dsp42.+\.sbn)$ /firmware/7942_7962/$1 last;
|
||||
rewrite ^/firmware/(jar42sccp.+\.sbn)$ /firmware/7942_7962/$1 last;
|
||||
rewrite ^/firmware/(SCCP42.+\.loads)$ /firmware/7942_7962/$1 last;
|
||||
rewrite ^/firmware/(term42.+\.loads)$ /firmware/7942_7962/$1 last;
|
||||
rewrite ^/firmware/(term62.+\.loads)$ /firmware/7942_7962/$1 last;
|
||||
|
||||
# 7945_7965 firmware (java-based)
|
||||
rewrite ^/firmware/(apps45.+\.sbn)$ /firmware/7945_7965/$1 last;
|
||||
rewrite ^/firmware/(cnu45.+\.sbn)$ /firmware/7945_7965/$1 last;
|
||||
rewrite ^/firmware/(cvm45sccp.+\.sbn)$ /firmware/7945_7965/$1 last;
|
||||
rewrite ^/firmware/(dsp45.+\.sbn)$ /firmware/7945_7965/$1 last;
|
||||
rewrite ^/firmware/(jar45sccp.+\.sbn)$ /firmware/7945_7965/$1 last;
|
||||
rewrite ^/firmware/(SCCP45.+\.loads)$ /firmware/7945_7965/$1 last;
|
||||
rewrite ^/firmware/(term45.+\.loads)$ /firmware/7945_7965/$1 last;
|
||||
rewrite ^/firmware/(term65.+\.loads)$ /firmware/7945_7965/$1 last;
|
||||
|
||||
# 7970_7971 firmware (java-based)
|
||||
rewrite ^/firmware/(apps70.+\.sbn)$ /firmware/7970_7971/$1 last;
|
||||
rewrite ^/firmware/(cnu70.+\.sbn)$ /firmware/7970_7971/$1 last;
|
||||
rewrite ^/firmware/(cvm70sccp.+\.sbn)$ /firmware/7970_7971/$1 last;
|
||||
rewrite ^/firmware/(dsp70.+\.sbn)$ /firmware/7970_7971/$1 last;
|
||||
rewrite ^/firmware/(jar70sccp.+\.sbn)$ /firmware/7970_7971/$1 last;
|
||||
rewrite ^/firmware/(SCCP70.+\.loads)$ /firmware/7970_7971/$1 last;
|
||||
rewrite ^/firmware/(term70.+\.loads)$ /firmware/7970_7971/$1 last;
|
||||
rewrite ^/firmware/(term71.+\.loads)$ /firmware/7970_7971/$1 last;
|
||||
|
||||
# 7975 firmware (java-based)
|
||||
rewrite ^/firmware/(apps75.+\.sbn)$ /firmware/7975/$1 last;
|
||||
rewrite ^/firmware/(cnu75.+\.sbn)$ /firmware/7975/$1 last;
|
||||
rewrite ^/firmware/(cvm75sccp.+\.sbn)$ /firmware/7975/$1 last;
|
||||
rewrite ^/firmware/(dsp75.+\.sbn)$ /firmware/7975/$1 last;
|
||||
rewrite ^/firmware/(jar75sccp.+\.sbn)$ /firmware/7975/$1 last;
|
||||
rewrite ^/firmware/(SCCP75.+\.loads)$ /firmware/7975/$1 last;
|
||||
rewrite ^/firmware/(term75.+\.loads)$ /firmware/7975/$1 last;
|
||||
|
||||
# 7985 firmware (ancient)
|
||||
rewrite ^/firmware/(cmterm_7985.4-1-7-0.bin)$ /firmware/7985/$1 last;
|
||||
|
||||
# 894x firmware (java-based)
|
||||
rewrite ^/firmware/(BOOT894x.+\.sgn)$ /firmware/894x/$1 last;
|
||||
rewrite ^/firmware/(SCCP894x.+\.sgn)$ /firmware/894x/$1 last;
|
||||
rewrite ^/firmware/(SCCP894x.+\.loads)$ /firmware/894x/$1 last;
|
||||
|
||||
# ata186 firmware (ancient)
|
||||
rewrite ^/firmware/(ATA030204SCCP090202A.zup)$ /firmware/ata186/$1 last;
|
||||
|
||||
# ata188 firmware (ancient)
|
||||
rewrite ^/firmware/(ATA030204SCCP090202A.zup)$ /firmware/ata188/$1 last;
|
||||
|
||||
# SPA50x
|
||||
rewrite ^/firmware/(spa50x.+\.bin)$ /firmware/spa50x/$1 last;
|
||||
rewrite ^/firmware/(spa51x.+\.bin)$ /firmware/spa51x/$1 last;
|
||||
rewrite ^/firmware/(spa515.+\.bin)$ /firmware/spa525/$1 last;
|
||||
rewrite ^/firmware/(spa941.+\.bin)$ /firmware/spa941/$1 last;
|
||||
|
||||
try_files $uri $uri/ =404;
|
||||
autoindex off;
|
||||
}
|
||||
|
||||
# locales
|
||||
|
||||
location /locales {
|
||||
try_files $uri $uri/ =404;
|
||||
autoindex off;
|
||||
}
|
||||
|
||||
# ringtones
|
||||
location /ringtones {
|
||||
try_files $uri $uri/ =404;
|
||||
autoindex off;
|
||||
}
|
||||
|
||||
# wallpapers
|
||||
location /wallpapers {
|
||||
try_files $uri $uri/ =404;
|
||||
autoindex off;
|
||||
}
|
||||
|
||||
# Deny access to .htaccess
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
error_page 404 /;
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
error_page 404 /;
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
|
80
lib/config.php
Normal file
80
lib/config.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
include_once("logger.php");
|
||||
|
||||
$base_path = !empty($_SERVER['DOCUMENT_ROOT']) ? realpath($_SERVER['DOCUMENT_ROOT'] . "/../"): realpath(getcwd()."/../");
|
||||
$base_config = Array(
|
||||
'main' => Array(
|
||||
'debug' => 1,
|
||||
'default_language' => 'English_United_States',
|
||||
'log_type' => "NULL",
|
||||
'log_level' => LOG_EMERG
|
||||
),
|
||||
'subdirs' => Array(
|
||||
'tftproot' => 'tftpboot',
|
||||
'firmware' => 'firmware',
|
||||
'settings' => 'settings',
|
||||
'wallpapers' => 'wallpapers',
|
||||
'ringtones' => 'ringtones',
|
||||
'locales' => 'locales',
|
||||
'countries' => 'countries',
|
||||
'languages' => 'languages',
|
||||
)
|
||||
);
|
||||
$tree_base = Array(
|
||||
'settings' => array('path' => 'tftproot', "strip" => TRUE),
|
||||
'wallpapers' => array('path' => 'tftproot', "strip" => FALSE),
|
||||
'ringtones' => array('path' => 'tftproot', "strip" => TRUE),
|
||||
'locales' => array('path' => 'tftproot', "strip" => TRUE),
|
||||
'firmware' => array('path' => 'tftproot', "strip" => TRUE),
|
||||
'languages' => array('path' => 'locales', "strip" => FALSE),
|
||||
'countries' => array('path' => 'locales', "strip" => FALSE),
|
||||
'default_language' => array('path' => 'locales', "strip" => TRUE),
|
||||
);
|
||||
|
||||
# Merge config
|
||||
$ini_array = parse_ini_file('../config.ini', TRUE, INI_SCANNER_TYPED);
|
||||
if (!empty($ini_array)) {
|
||||
$config = array_merge($base_config, $ini_array);
|
||||
}
|
||||
|
||||
# build new config['subdirs'] paths substituting bases from tree_base
|
||||
foreach ($tree_base as $key => $value) {
|
||||
$tmp = $config;
|
||||
if (!empty($tmp['subdirs'][$key])) {
|
||||
if (substr($tmp['subdirs'][$key], 0, 1) !== "/") {
|
||||
if (is_array($tmp['subdirs'][$value['path']])) {
|
||||
$path = $tmp['subdirs'][$value['path']]['path'].'/'.$tmp['subdirs'][$key];
|
||||
} else {
|
||||
$path = $tmp['subdirs'][$value['path']].'/'.$tmp['subdirs'][$key];
|
||||
}
|
||||
}
|
||||
$config['subdirs'][$key] = array('path' => $path, 'strip' => $value['strip']);
|
||||
}
|
||||
}
|
||||
|
||||
$config['main']['base_path'] = $base_path;
|
||||
$config['main']['tftproot'] = (!empty($config['main']['tftproot'])) ? $base_path . "tftpboot" : '/tftpboot';
|
||||
|
||||
switch($config['main']['log_type']) {
|
||||
case 'SYSLOG':
|
||||
$logger = new Logger_Syslog($config['main']['log_level']);
|
||||
break;
|
||||
case 'FILE':
|
||||
if (!isempty($config['main']['log_file'])) {
|
||||
$logger = new Logger_Filename($config['main']['log_level'], $config['main']['log_file']);
|
||||
}
|
||||
break;
|
||||
case 'STDOUT':
|
||||
$logger = new Logger_Stdout($config['main']['log_level']);
|
||||
break;
|
||||
case 'STDERR':
|
||||
$logger = new Logger_Stderr($config['main']['log_level']);
|
||||
break;
|
||||
default:
|
||||
$logger = new Logger_Null($config['main']['log_level']);
|
||||
}
|
||||
|
||||
# Fixup debug
|
||||
$print_debug = (!empty($config['main']['debug'])) ? $config['main']['debug'] : 'off';
|
||||
$print_debug = ($print_debug == 1) ? 'on' : $print_debug;
|
||||
?>
|
94
lib/logger.php
Normal file
94
lib/logger.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/* Note about the Logger class:
|
||||
* The "priority" and "minimum should be one of the constants used for syslog.
|
||||
* See: http://php.net/manual/en/function.syslog.php
|
||||
* They are: LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE,
|
||||
* LOG_INFO, LOG_DEBUG
|
||||
* Note that LOG_EMERG, LOG_ALERT, and LOG_CRIT are not really relevant to a
|
||||
* tftp server - these represent instability in the entire operating system.
|
||||
* Note that the number they are represented by are in reverse order -
|
||||
* LOG_EMERG is the lowest, LOG_DEBUG the highest.
|
||||
*/
|
||||
abstract class Logger
|
||||
{
|
||||
function __construct($minimum)
|
||||
{
|
||||
$this->minimum = $minimum;
|
||||
}
|
||||
|
||||
function shouldlog($priority)
|
||||
{
|
||||
// Note: this looks reversed, but is correct
|
||||
// the priority must be AT LEAST the minimum,
|
||||
// because higher priorities represent lower numbers.
|
||||
return $priority <= $this->minimum;
|
||||
}
|
||||
|
||||
abstract function log($priority, $message);
|
||||
}
|
||||
|
||||
class Logger_Null extends Logger
|
||||
{
|
||||
function log($priority, $message)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class Logger_Syslog extends Logger
|
||||
{
|
||||
function log($priority, $message)
|
||||
{
|
||||
if($this->shouldlog($priority))
|
||||
syslog($priority,$message);
|
||||
}
|
||||
}
|
||||
|
||||
class Logger_Filehandle extends Logger
|
||||
{
|
||||
private $priority_map = array(
|
||||
LOG_DEBUG => "D",
|
||||
LOG_INFO => "I",
|
||||
LOG_NOTICE => "N",
|
||||
LOG_WARNING => "W",
|
||||
LOG_ERR => "E",
|
||||
LOG_CRIT => "C",
|
||||
LOG_ALERT => "A",
|
||||
LOG_EMERG => "!"
|
||||
);
|
||||
function __construct($minimum, $filehandle, $dateformat = "r")
|
||||
{
|
||||
$this->filehandle = $filehandle;
|
||||
$this->dateformat = $dateformat;
|
||||
return parent::__construct($minimum);
|
||||
}
|
||||
|
||||
function log($priority, $message)
|
||||
{
|
||||
if($this->shouldlog($priority))
|
||||
fwrite($this->filehandle, date($this->dateformat) . ": " . $this->priority_map[$priority] . " $message\n");
|
||||
}
|
||||
}
|
||||
|
||||
class Logger_Filename extends Logger_Filehandle
|
||||
{
|
||||
function __construct($minimum, $filename, $dateformat = "r")
|
||||
{
|
||||
return parent::__construct($minimum, fopen($filename, "a"), $dateformat);
|
||||
}
|
||||
}
|
||||
|
||||
class Logger_Stderr extends Logger_Filehandle
|
||||
{
|
||||
function __construct($minimum, $dateformat = "r")
|
||||
{
|
||||
return parent::__construct($minimum, STDERR, $dateformat);
|
||||
}
|
||||
}
|
||||
class Logger_Stdout extends Logger_Filehandle
|
||||
{
|
||||
function __construct($minimum, $dateformat = "r")
|
||||
{
|
||||
return parent::__construct($minimum, STDOUT, $dateformat);
|
||||
}
|
||||
}
|
||||
?>
|
168
lib/resolver.php
Normal file
168
lib/resolver.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
include_once("config.php");
|
||||
include_once("utils.php");
|
||||
|
||||
/* Todo:
|
||||
✔️ setup logging
|
||||
✔️ read config.file
|
||||
|
||||
✔?️ improve error handling
|
||||
✔️? secure urlencoding/urldecoding
|
||||
✔️? don't allow browsing
|
||||
|
||||
- check source ip-range
|
||||
- check HTTPHeader for known BrowserTypes
|
||||
|
||||
- Could use some more test-cases, especially error ones
|
||||
*/
|
||||
class Resolver {
|
||||
private $isDirty = FALSE;
|
||||
private $cache = array();
|
||||
private $config;
|
||||
//private $logger;
|
||||
function __construct($config) {
|
||||
//global $logger;
|
||||
$this->config = $config;
|
||||
//$this->logger = $logger;
|
||||
if(file_exists($this->config['main']['cache_filename'])) {
|
||||
$this->cache = unserialize(file_get_contents($config['main']['cache_filename']));
|
||||
} else {
|
||||
$this->buildCleanCache();
|
||||
}
|
||||
}
|
||||
function __destruct() {
|
||||
// $this->printCache()
|
||||
if ($this->isDirty) {
|
||||
if (!file_put_contents($this->config['main']['cache_filename'], serialize($this->cache))) {
|
||||
$this->log_error_and_throw("Could not write to file '".$this->config['cache_filename']."' at Resolver::destruct");
|
||||
}
|
||||
}
|
||||
}
|
||||
function log_error_and_throw($message) {
|
||||
global $logger;
|
||||
$logger->log('LOG_ERROR', $message);
|
||||
throw new Exception($message);
|
||||
}
|
||||
function log_debug($message) {
|
||||
global $logger;
|
||||
$logger->log('LOG_DEBUG', $message);
|
||||
}
|
||||
function searchForFile($filename) {
|
||||
foreach($this->config['subdirs'] as $key => $value) {
|
||||
if ($key === "firmware" || $key === "tftproot" ) {
|
||||
continue;
|
||||
}
|
||||
$path = realpath($this->config['main']['base_path'] . "/" . $value['path'] . "/$filename");
|
||||
if (file_exists($path)) {
|
||||
$this-> addFile($filename, $path);
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
$this->log_error_and_throw("File '$filename' does not exist");
|
||||
}
|
||||
function buildCleanCache() {
|
||||
foreach($this->config['subdirs'] as $key =>$value) {
|
||||
if ($key === "tftproot") {
|
||||
continue;
|
||||
}
|
||||
$path = $this->config['main']['base_path'] . "/" . $value['path'] . "/";
|
||||
$dir_iterator = new RecursiveDirectoryIterator($path);
|
||||
$iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
|
||||
foreach ($iterator as $file) {
|
||||
if ($file->isFile()) {
|
||||
if ($value['strip']) {
|
||||
$this->addFile($file->getFileName(), $file->getPathname());
|
||||
} else {
|
||||
$subdir = basename(dirname($file->getPathname()));
|
||||
$this->addFile('$subpath/'.$file->getFileName(), $file->getPathname());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->isDirty = TRUE;
|
||||
}
|
||||
function addFile($requestpath, $truepath) {
|
||||
//$this->logger->log('LOG_DEBUG', "Adding $requestpath");
|
||||
$this->log_debug("Adding $requestpath");
|
||||
$this->cache[$requestpath] = $truepath;
|
||||
$this->isDirty =TRUE;
|
||||
}
|
||||
function removeFile($requestpath) {
|
||||
$this->log_debug("Removing $hash");
|
||||
unset($this->cache[$requestpath]);
|
||||
$this->isDirty = TRUE;
|
||||
}
|
||||
function validateRequest($request) {
|
||||
/* make sure request does not startwith or contain: "/", "../" or "/./" */
|
||||
/* make sure request only starts with filename or one of $config[$subdir]['locale'] or $config[$subdir]['wallpaper'] */
|
||||
/* check uri/url decode */
|
||||
if (!is_string($request)) {
|
||||
$this->log_error_and_throw("Request is not a string");
|
||||
}
|
||||
$this->log_debug($request . ":" . escapeshellarg($request) . ":" . utf8_urldecode($request) . "\n");
|
||||
$escaped_request = escapeshellarg(utf8_urldecode($request));
|
||||
if ($escaped_request !== "'" . $request . "'") {
|
||||
$this->log_error_and_throw("Request '$request' contains invalid characters");
|
||||
}
|
||||
if (strstr($escaped_request, "..")) {
|
||||
$this->log_error_and_throw("Request '$request' containst '..'");
|
||||
}
|
||||
}
|
||||
function resolve($request) /* canthrow */ {
|
||||
$this->validateRequest($request);
|
||||
$path = '';
|
||||
if (array_key_exists($request, $this->cache)) {
|
||||
if ($path = $this->cache[$request]) {
|
||||
if (!file_exists($path)) {
|
||||
$this->removeFile($request);
|
||||
$this->log_error_and_throw("File '$request' does not exist on FS");
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
if ($this->searchForFile($request)) {
|
||||
return $this->cache[$request];
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
/* temporary */
|
||||
function printCache() {
|
||||
print_r($this->cache);
|
||||
}
|
||||
}
|
||||
|
||||
// Testing
|
||||
if(defined('STDIN') ) {
|
||||
$resolver = new Resolver($config);
|
||||
|
||||
$test_cases = Array(
|
||||
Array('request' => 'jar70sccp.9-4-2ES26.sbn', 'expected' => '/tftpboot/firmware/7970/jar70sccp.9-4-2ES26.sbn', 'throws' => FALSE),
|
||||
Array('request' => 'Russian_Russian_Federation/be-sccp.jar', 'expected' => '/tftpboot/locales/languages/Russian_Russian_Federation/be-sccp.jar', 'throws' => FALSE),
|
||||
Array('request' => 'Spain/g3-tones.xml', 'expected' => '/tftpboot/locales/countries/Spain/g3-tones.xml', 'throws' => FALSE),
|
||||
Array('request' => '320x196x4/Chan-SCCP-b.png', 'expected' => '/tftpboot/wallpapers/320x196x4/Chan-SCCP-b.png', 'throws' => FALSE),
|
||||
Array('request' => 'XMLDefault.cnf.xml', 'expected' => '/tftpboot/settings/bak/XMLDefault.cnf.xml', 'throws' => FALSE),
|
||||
Array('request' => '../XMLDefault.cnf.xml', 'expected' => '', 'throws' => TRUE),
|
||||
Array('request' => 'XMLDefault.cnf.xml/../../text.xml', 'expected' => '', 'throws' => TRUE),
|
||||
|
||||
);
|
||||
foreach($test_cases as $test) {
|
||||
try {
|
||||
$result = $resolver->resolve($test['request']);
|
||||
if ($result !== $base_path . $test['expected']) {
|
||||
print("Error: expected result does not match what we got\n");
|
||||
print("request:'".$test['request']."', result:'" . $base_path . $test['expected'] . "'\n");
|
||||
} else {
|
||||
print("'" . $test['request'] . "' => '" . $result . "'\n");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
if (!$test['throws']) {
|
||||
print("Error: request was expected to throw: $e\n");
|
||||
} else {
|
||||
print("'" . $test['request'] . "' => throws error as expected\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($resolver);
|
||||
#unlink($CACHEFILE_NAME);
|
||||
}
|
||||
?>
|
10
lib/utils.php
Normal file
10
lib/utils.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
//
|
||||
// Helper functions
|
||||
//
|
||||
|
||||
function utf8_urldecode($str) {
|
||||
$str = preg_replace("/%u([0-9a-f]{3,4})/i","&#x\\1;",urldecode($str));
|
||||
return html_entity_decode($str,null,'UTF-8');;
|
||||
}
|
||||
?>
|
@@ -1,13 +0,0 @@
|
||||
[main]
|
||||
debug = on ; The output in the browser window for more information
|
||||
tftproot = /tftpboot
|
||||
;default_language = English_United_States
|
||||
|
||||
firmware = firmware
|
||||
settings = settings
|
||||
wallpapers = wallpapers
|
||||
ringtones = ringtones
|
||||
locales = locales
|
||||
countries = countries
|
||||
languages = languages
|
||||
;log = /tftpboot/provision.log
|
@@ -1,308 +1,67 @@
|
||||
<?php
|
||||
//
|
||||
// Written by Alex / github.com/PhantomVI
|
||||
//
|
||||
include_once("../lib/config.php");
|
||||
include_once("../lib/resolver.php");
|
||||
$request = $_REQUEST ?? null;
|
||||
|
||||
$base_path = realpath($_SERVER['DOCUMENT_ROOT']);
|
||||
$base_config = Array(
|
||||
'debug' => 1,
|
||||
'tftproot' => $base_path,
|
||||
'default_language' => 'English_United_States',
|
||||
'firmware' => 'firmware', 'settings' => 'settings', 'wallpapers' => 'wallpapers', 'ringtones' => 'ringtones',
|
||||
'locales' => 'locales', 'countries' => 'countries', 'languages' => 'languages'
|
||||
);
|
||||
$base_tree = Array('settings' => 'tftproot', 'wallpapers' => 'tftproot', 'ringtones'=>'tftproot',
|
||||
'locales' => 'tftproot', 'firmware' => 'tftproot', 'languages' => 'locales',
|
||||
'countries' => 'locales', 'default_language' => 'locales');
|
||||
|
||||
# Merge config
|
||||
$ini_array = parse_ini_file('index.cnf');
|
||||
if (!empty($ini_array)) {
|
||||
$config = array_merge($base_config, $ini_array);
|
||||
function send_fallback_html($message) {
|
||||
while (ob_get_level()) {ob_end_clean();}
|
||||
if (ob_get_length() === false) {
|
||||
ob_start();
|
||||
header('Content-Description: README');
|
||||
header('Content-Type: text/html');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
}
|
||||
$content="
|
||||
<html>
|
||||
<header>
|
||||
</header>
|
||||
<body>
|
||||
<h1>provision_sccp</h1>
|
||||
<p>Request:" . json_encode($request) . "</p>
|
||||
<p>Message:" . $message . "</p>
|
||||
</body>
|
||||
</html>
|
||||
";
|
||||
print ($content);
|
||||
ob_flush();
|
||||
flush();
|
||||
}
|
||||
|
||||
foreach ($base_tree as $key => $value) {
|
||||
if (!empty($config[$key])) {
|
||||
if (substr($config[$key],0,1) != "/") {
|
||||
$config[$key] = $config[$value].'/'.$config[$key];
|
||||
}
|
||||
}
|
||||
function sendfile($file) {
|
||||
if (file_exists($file)) {
|
||||
while (ob_get_level()) {ob_end_clean();}
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename=' . basename($file));
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . filesize($file));
|
||||
|
||||
/* want to stream out, so don't use file_get_contents() in this case */
|
||||
if ($fd = fopen($file, 'rb')) {
|
||||
while (!feof($fd)) {
|
||||
print fread($fd, 1024);
|
||||
}
|
||||
fclose($fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#$config['tftproot'] = (!empty($config['tftproot'])) ? $config['tftproot'] : '/tftpboot';
|
||||
|
||||
# Fixup debug
|
||||
$print_debug = (!empty($config['debug'])) ? $config['debug'] : 'off';
|
||||
$print_debug = ($print_debug == 1) ? 'on' : $print_debug;
|
||||
|
||||
# Parse request
|
||||
$request = $_REQUEST;
|
||||
$req_file = !empty($request['id']) ? $request['id'] : '';
|
||||
|
||||
# directory content extensions map
|
||||
$fw_suffix = array('.bin', '.loads', '.sbn', '.sb2', '.sbin', '.zz', '.zup', '.loads');
|
||||
|
||||
//$settings_suffix = array('cnf.xml');
|
||||
|
||||
$ringtones_list = array('distinctive.xml', 'ringlist.xml','distinctiveringlist.xml');
|
||||
$ringtones_suffix = array('.raw', '.pcm', '.rwb');
|
||||
|
||||
$locale_list = array('-dictionary.', 'dictionary-ext.', '-dictionary.utf-8.', '-kate.xml', '-font.xml', '-font.dat','-tones.xml',
|
||||
'be-sccp.jar', 'tc-sccp.jar', 'td-sccp.jar', 'ipc-sccp.jar', 'mk-sccp.jar', '_locale.loads', 'i-button-help.xml',
|
||||
'tc-sip.jar', 'td-sipp.jar');
|
||||
|
||||
# Show debug output
|
||||
if ($print_debug == 'on') {
|
||||
print_r("<br> Config:<pre>");
|
||||
print_r($config);
|
||||
print("</pre>");
|
||||
print_r("<br> Request:<br><pre>");
|
||||
print_r($request);
|
||||
print("</pre>");
|
||||
if (!$request || empty($request) || !array_key_exists('filename',$request) || empty($request['filename'])) {
|
||||
send_fallback_html("Empty request sent");
|
||||
exit();
|
||||
}
|
||||
|
||||
# Start parsing the request
|
||||
$req_file_full_path = '' ;
|
||||
|
||||
if (!empty($req_file)) {
|
||||
$signed = FALSE;
|
||||
$req_data_ar = explode('/', $req_file);
|
||||
$req_data_len = count($req_data_ar) - 1;
|
||||
|
||||
$orig_req_file_name = end($req_data_ar);
|
||||
$req_file_name = $orig_req_file_name;
|
||||
|
||||
if (strpos('.sgn;', strtolower($orig_req_file_name).';') !== FALSE) { // handle signed files
|
||||
$signed = TRUE;
|
||||
$req_file_name = basename($orig_req_file_name, '.sgn'); // strip signed part
|
||||
}
|
||||
|
||||
|
||||
if (file_exists($config['tftproot'].'/'.$req_file_name)) // prevent "/../...//" browsing - (eliminate back door)
|
||||
{
|
||||
$req_file_full_path = $config['tftproot'].'/'.$req_file_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tmp_file = explode('.', $req_file_name);
|
||||
|
||||
if (strpos_array($req_file_name, $fw_suffix,'any') !== FALSE) { // Firmware file was requested
|
||||
$firmware_list = find_all_files($config['firmware']);
|
||||
$pos2 = strpos_array($firmware_list, $req_file_name, 'any'); // case unsensitive
|
||||
if ($pos2 !== FALSE) { // Request Firmware
|
||||
$req_file_full_path = $firmware_list[$pos2];
|
||||
}
|
||||
if ($print_debug == 'on'){ print_r('<br>Requested Firmware: '. $req_file_full_path. '<br>');}
|
||||
}
|
||||
else
|
||||
{
|
||||
$tmp_file = '';
|
||||
|
||||
//if (strpos_array($req_file_name, $settings_suffix, 'any') !== FALSE) { // Request Settings
|
||||
if (strpos(strtolower($req_file_name), '.cnf.xml') !== FALSE) { // Request Settings
|
||||
$tmp_file = $config['settings'].'/'.$req_file_name;
|
||||
}
|
||||
else if (strpos(strtolower($req_file), 'desktops/') !== FALSE) { // Request Wallpapers
|
||||
$tmp_file = $config['wallpapers'].'/'. $req_data_ar[$req_data_len-1].'/'. $req_file_name;
|
||||
}
|
||||
else if (strpos_array($ringtones_list, $req_file_name, 'any') !== FALSE) { // Request RingTones
|
||||
$tmp_file = $config['ringtones'].'/'.$req_file_name;
|
||||
if (!file_exists($tmp_file)) {
|
||||
$tmp_file = $config['ringtones'].'/ringlist.xml';
|
||||
}
|
||||
}
|
||||
else if(strpos_array($req_file_name, $ringtones_suffix,'any') !== FALSE) { // Firmware file was requested
|
||||
$tmp_file = $config['ringtones'].'/'.$req_file_name;
|
||||
}
|
||||
else if (strpos_array($req_file, $locale_list, 'any') !== FALSE) { // Request Languages
|
||||
if (!empty($req_data_ar[$req_data_len-1])) {
|
||||
$tmp_file = $config['languages'].'/'. $req_data_ar[$req_data_len-1].'/'. $req_file_name;
|
||||
} else {
|
||||
$tmp_file = $config['default_language'].'/'. $req_file_name;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
else if (strpos(strtolower($req_file), '-tones.xml') !== FALSE) { // Request Countries
|
||||
$tmp_file = $config['countries'].'/'. $req_data_ar[$req_data_len-1].'/'. $req_data_ar[$req_data_len];
|
||||
}
|
||||
|
||||
else if (strpos(strtolower($req_file), '-dictionary.') !== FALSE) { // Request Countries
|
||||
$tmp_file = $config['languages'].'/'. $req_data_ar[$req_data_len-1].'/'. $req_data_ar[$req_data_len];
|
||||
}
|
||||
|
||||
else if (strpos_array($req_file, $locale_list, 'any') !== FALSE) { // Request Languages
|
||||
$tmp_file = $config['languages'].'/'. $req_data_ar[$req_data_len-1].'/'. $req_data_ar[$req_data_len];
|
||||
}
|
||||
|
||||
else if (strpos(strtolower($req_file), '-dictionary.jar') !== FALSE) { // Request Countries
|
||||
$tmp_file = $config['languages'].'/'. $req_data_ar[$req_data_len-1].'/'. $req_data_ar[$req_data_len];
|
||||
}
|
||||
*/
|
||||
if ($print_debug == 'on'){ print_r('<br>File : '. $orig_req_file_name. ' not found.<br>');}
|
||||
if (empty($tmp_file)) {
|
||||
if (!empty($config['log'])) { to_log(array('GET ('.$req_file.'):'.$orig_req_file_name, 'no match found'),'E',$config['log']); }
|
||||
header("HTTP/1.0 404 Not Found");
|
||||
die('ERROR: no match found.');
|
||||
}
|
||||
$req_file_full_path = $tmp_file;
|
||||
}
|
||||
}
|
||||
if (!empty($config['log'])) { to_log(array('GET ('.$req_file.') :'.$orig_req_file_name, 'Remap :'.$req_file_full_path),'i',$config['log']); }
|
||||
|
||||
if (!empty($req_file_full_path)) {
|
||||
if ($signed) {
|
||||
$req_file_full_path .= '.sgn';
|
||||
}
|
||||
if (!file_exists($req_file_full_path)) {
|
||||
header("HTTP/1.0 404 Not Found");
|
||||
die('Could not find:'. $req_file_full_path);
|
||||
}
|
||||
if ($print_debug == 'on'){ print_r('<br>Returning: '. $req_file_full_path. '<br>');}
|
||||
file_force_download($req_file_full_path);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper functiosn
|
||||
*/
|
||||
function file_force_download($file) {
|
||||
if (file_exists($file)) {
|
||||
|
||||
if (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename=' . basename($file));
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . filesize($file));
|
||||
|
||||
if ($fd = fopen($file, 'rb')) {
|
||||
while (!feof($fd)) {
|
||||
print fread($fd, 1024);
|
||||
}
|
||||
fclose($fd);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
try {
|
||||
$req_filename=$request['filename'];
|
||||
$resolver = new Resolver($config);
|
||||
if (($filename = $resolver->resolve($req_filename))) {
|
||||
sendfile($filename);
|
||||
}
|
||||
unset($resolver);
|
||||
} catch(Exception $e) {
|
||||
send_fallback_html($e->getMessage());
|
||||
}
|
||||
|
||||
/*
|
||||
* Founds any string from array in array
|
||||
*/
|
||||
function strpos_array($haystack, $needles, $mode='any') {
|
||||
if (is_array($needles)) {
|
||||
foreach ($needles as $str) {
|
||||
$pos = strpos_array($haystack, $str, $mode);
|
||||
if ($pos !== FALSE) {
|
||||
return $pos;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_array($haystack)) {
|
||||
foreach ($haystack as $key => $subtr) {
|
||||
$pos = strpos_array($subtr, $needles, $mode);
|
||||
if ($pos !== FALSE) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
} else {
|
||||
if ($mode == 'any') {
|
||||
return strpos(strtolower($haystack), strtolower($needles));
|
||||
} else {
|
||||
if ($mode == 'full') {
|
||||
if ($haystack == $needles) {
|
||||
return 0;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
return strpos($haystack, $needles);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function to_log($text, $level='i', $file) {
|
||||
switch (strtolower($level)) {
|
||||
case 'e':
|
||||
case 'error':
|
||||
$level='ERROR';
|
||||
break;
|
||||
case 'i':
|
||||
case 'info':
|
||||
$level='INFO';
|
||||
break;
|
||||
case 'd':
|
||||
case 'debug':
|
||||
$level='DEBUG';
|
||||
break;
|
||||
default:
|
||||
$level='INFO';
|
||||
}
|
||||
if (is_array($text)) {
|
||||
$to_log = '';
|
||||
foreach ($text as $value) {
|
||||
$to_log .= $value."\t";
|
||||
}
|
||||
} else {
|
||||
$to_log .= $text;
|
||||
}
|
||||
$_txt = date('d.m.Y h:i:s')."\t[".$level."]\t ".$to_log."\n";
|
||||
if (empty($file)) {
|
||||
error_log($_txt, 0);
|
||||
} else {
|
||||
error_log($_txt, 3, $file);
|
||||
}
|
||||
}
|
||||
|
||||
function find_all_files($dir, $file_mask=null, $mode='full'){
|
||||
|
||||
$result = NULL;
|
||||
if (empty($dir) || (!file_exists($dir))) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$root = scandir($dir);
|
||||
foreach($root as $value) {
|
||||
if($value === '.' || $value === '..') {continue;}
|
||||
if(is_file("$dir/$value")) {
|
||||
$filter = FALSE;
|
||||
if (!empty($file_mask)) {
|
||||
if (is_array($file_mask)) {
|
||||
foreach ($file_mask as $k){
|
||||
if (strpos(strtolower($value), strtolower($k)) !== FALSE) {$filter = true;}
|
||||
}
|
||||
} else {
|
||||
if (strpos(strtolower($value), strtolower($file_mask)) !== FALSE) {$filter = true;}
|
||||
}
|
||||
} else {$filter = true;}
|
||||
if ($filter) {
|
||||
if ($mode=='fileonly'){
|
||||
$result[]="$value";
|
||||
} else {
|
||||
$result[]="$dir/$value";
|
||||
}
|
||||
} else {$result[]=null;}
|
||||
continue;
|
||||
}
|
||||
$sub_fiend = find_all_files("$dir/$value", $file_mask, $mode);
|
||||
if (!empty($sub_fiend)) {
|
||||
foreach($sub_fiend as $sub_value) {
|
||||
if (!empty($sub_value)) {
|
||||
$result[]=$sub_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
?>
|
@@ -6,7 +6,7 @@ if [ ! -z "`ls *.pcm 2>/dev/null`" ]; then
|
||||
basename=`basename ${filename} .pcm`
|
||||
echo -e "\t<Ring>" >>$outfile
|
||||
echo -e "\t\t<DisplayName>${basename}</DisplayName>" >>$outfile
|
||||
echo -e "\t\t<FileName>ringtones\${filename}</FileName>" >>$outfile
|
||||
echo -e "\t\t<FileName>ringtones\\${filename}</FileName>" >>$outfile
|
||||
echo -e "\t</Ring>" >>$outfile
|
||||
done
|
||||
fi
|
||||
@@ -15,7 +15,7 @@ if [ ! -z "`ls *.raw 2>/dev/null`" ]; then
|
||||
basename=`basename ${filename} .raw`
|
||||
echo -e "\t<Ring>" >>$outfile
|
||||
echo -e "\t\t<DisplayName>${basename}</DisplayName>" >>$outfile
|
||||
echo -e "\t\t<FileName>ringtones\${filename}</FileName>" >>$outfile
|
||||
echo -e "\t\t<FileName>ringtones\\${filename}</FileName>" >>$outfile
|
||||
echo -e "\t</Ring>" >>$outfile
|
||||
done
|
||||
fi
|
||||
|
Reference in New Issue
Block a user