<?php
-set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . '/../src/');
-$fullUri = $_SERVER['REQUEST_URI'];
-if (isset($_SERVER['REDIRECT_URL'])) {
- $path = $_SERVER['REDIRECT_URL'];
-} else {
- $path = '/';
-}
-$dataDir = __DIR__ . '/../data/';
-$varDir = realpath(__DIR__ . '/../var') . '/';
-$host1 = 'http://radio567.vtuner.com/';
-$host2 = 'http://radio5672.vtuner.com/';
-if ($_SERVER['HTTP_HOST'] !== '') {
- $host1 = 'http://' . $_SERVER['HTTP_HOST'] . '/';
- $host2 = 'http://' . $_SERVER['HTTP_HOST'] . '/';
-}
-$cfgFile = $dataDir . 'config.php';
-if (file_exists($cfgFile)) {
- include $cfgFile;
-}
-
-if (strtolower($fullUri) == '/setupapp/radio567/asp/browsexpa/loginxml.asp?token=0') {
- //initial login for "internet radio" and podcasts
- //lowercase tags
- header('Content-type: text/html');
- readfile($dataDir . 'initial-login.xml');
- exit();
-} else if ($fullUri == '/RadioNativeLogin.php') {
- //initial login for "My noxon"
- //this one wants CamelCased tags
+require_once __DIR__ . '/../src/header.php';
+
+if (strtolower($fullUri) == '/setupapp/radio567/asp/browsexpa/loginxml.asp?token=0'
+ || $fullUri == '/RadioNativeLogin.php'
+) {
+ //initial login for "internet radio", podcasts and "my noxon"
header('Content-type: text/html');
- readfile($dataDir . 'login-mynoxon.xml');
+ readfile($dataDir . 'login-camelcase.xml');
exit();
} else if ($path == '/setupapp/radio567/asp/BrowseXPA/LoginXML.asp') {
//"Internet Radio"
} else if ($path == '/RadioNativeFavorites.php') {
//Favorites, defined via web interface
sendMessage('Unsupported');
-} else if (substr($path, 0, 9) == '/play-url') {
- //play a given URL, but first follow all redirects
- //noxon iRadio Cube does not like too many redirections
- // 3 redirects did not work.
- $url = $_GET['url'];
- header('HTTP/1.0 301 Moved Permanently');
- header('Location: ' . getFinalUrl($url));
- exit();
}
handleRequest(ltrim($path, '/'));
function handleRequest($path)
{
global $varDir;
- if (strpos($path, '..') !== false) {
+ if (strpos($path, '/../') !== false) {
sendMessage('No');
return;
}
if (substr($path, 0, 14) == 'internetradio/') {
require_once 'mediatomb.php';
- handleRequestMediatomb($path, 'internetradio/');
+ handleMediatomb('browse', $path, 'internetradio/');
+ return;
+ } else if (substr($path, 0, 11) == '.mt-single/') {
+ require_once 'mediatomb.php';
+ handleMediatomb('single', $path, '.mt-single/');
return;
}
return;
}
+ $ext = pathinfo($path, PATHINFO_EXTENSION);
if (is_dir($fullPath)) {
sendDir($path);
- } else if (substr($path, -4) == '.url') {
+ } else if ($ext == 'url') {
require_once 'podcasts.php';
sendPodcast($path);
- } else if (substr($path, -4) == '.txt') {
+ } else if ($ext == 'txt') {
sendTextFile($path);
+ } else if (is_executable($fullPath)) {
+ sendScript($path);
} else {
sendMessage('Unknown file type');
}
}
+function pathEncode($urlPath)
+{
+ return str_replace('%2F', '/', rawurlencode($urlPath));
+}
+
function sendDir($path)
{
global $varDir;
$listItems = array();
- addPreviousItem($listItems, $path);
+ $enablePaging = true;
$entries = glob(str_replace('//', '/', $varDir . rtrim($path, '/') . '/*'));
$count = 0;
+ $noCache = false;
foreach ($entries as $entry) {
- $urlPath = substr($entry, strlen($varDir));
+ $urlPath = pathEncode(substr($entry, strlen($varDir)));
+ $ext = pathinfo($entry, PATHINFO_EXTENSION);
+
+ $titleBase = basename($entry);
+ $titleBase = preg_replace('#^[0-9]+_#', '', $titleBase);
if (is_dir($entry)) {
++$count;
- $listItems[] = getDirItem(basename($entry), $urlPath . '/');
- } else if (substr($entry, -4) == '.url') {
+ $listItems[] = getDirItem($titleBase, $urlPath . '/');
+ } else if ($ext == 'url') {
//podcast
++$count;
- $listItems[] = getPodcastItem(basename($entry, '.url'), $urlPath);
- } else if (substr($entry, -4) == '.txt') {
+ $listItems[] = getPodcastItem(basename($titleBase, '.url'), $urlPath);
+ } else if (is_executable($entry)
+ && strpos(basename($entry), '.auto') !== false
+ ) {
+ //automatically execute script while listing this directory
+ addScriptOutput($listItems, $entry);
+ $enablePaging = false;
+ } else if ($ext == 'txt' || is_executable($entry)) {
//plain text file
++$count;
- $listItems[] = getDirItem(basename($entry, '.txt'), $urlPath);
+ $listItems[] = getDirItem(basename($titleBase, '.' . $ext), $urlPath);
+ } else if (basename($entry) == 'nocache') {
+ $noCache = true;
}
}
if (!$count) {
$listItems[] = getMessageItem('No files or folders');
}
- sendListItems($listItems);
+ sendListItems(
+ $listItems, buildPreviousItem($path),
+ $enablePaging, $noCache
+ );
+}
+
+function sendScript($path)
+{
+ global $varDir;
+
+ $listItems = array();
+
+ $fullPath = $varDir . $path;
+ addScriptOutput($listItems, $fullPath);
+ sendListItems($listItems, buildPreviousItem($path), false);
+}
+
+function addScriptOutput(&$listItems, $fullPath)
+{
+ exec($fullPath . ' 2>&1', $output, $retVal);
+
+ if ($retVal == 0) {
+ addTextLines($listItems, $output);
+ } else {
+ $listItems[] = getMessageItem('Error executing script');
+ addTextLines($listItems, $output);
+ }
}
function sendTextFile($path)
{
global $varDir;
$listItems = array();
- addPreviousItem($listItems, $path);
$lines = file($varDir . $path);
+ addTextLines($listItems, $lines);
+ sendListItems($listItems, buildPreviousItem($path));
+}
+
+function addTextLines(&$listItems, $lines)
+{
foreach ($lines as $line) {
- $listItems[] = getDisplayItem($line);
+ $line = trim($line);
+ if ($line != '') {
+ $listItems[] = getDisplayItem($line);
+ }
}
- sendListItems($listItems);
}
function getDisplayItem($line)
{
+ $line = preg_replace('#\s+#', ' ', $line);
return '<Item>'
. '<ItemType>Display</ItemType>'
- . '<Display>' . utf8_decode(htmlspecialchars(trim($line))) . '</Display>'
+ . '<Display>' . nox_esc($line) . '</Display>'
. '</Item>';
}
global $host1, $host2;
return '<Item>'
. '<ItemType>Dir</ItemType>'
- . '<Title>' . utf8_decode(htmlspecialchars($title)) . '</Title>'
- . '<UrlDir>' . $host1 . utf8_decode(htmlspecialchars($urlPath)) . '</UrlDir>'
- . '<UrlDirBackUp>' . $host2 . utf8_decode(htmlspecialchars($urlPath)) . '</UrlDirBackUp>'
+ . '<Title>' . nox_esc($title) . '</Title>'
+ . '<UrlDir>' . $host1 . nox_esc($urlPath) . '</UrlDir>'
+ . '<UrlDirBackUp>' . $host2 . nox_esc($urlPath) . '</UrlDirBackUp>'
. '</Item>';
}
{
return '<Item>'
. '<ItemType>ShowEpisode</ItemType>'
- . '<ShowEpisodeName>' . utf8_decode(htmlspecialchars($title)) . '</ShowEpisodeName>'
- . '<ShowEpisodeURL>' . $fullUrl . '</ShowEpisodeURL>'
- . '<ShowDesc>' . utf8_decode(htmlspecialchars($desc)) . '</ShowDesc>'
+ . '<ShowEpisodeName>' . nox_esc($title) . '</ShowEpisodeName>'
+ . '<ShowEpisodeURL>' . htmlspecialchars($fullUrl) . '</ShowEpisodeURL>'
+ . '<ShowDesc>' . nox_esc($desc) . '</ShowDesc>'
. '<ShowMime>' . $type . '</ShowMime>'
. '</Item>';
}
global $host1;
return '<Item>'
. '<ItemType>ShowOnDemand</ItemType>'
- . '<ShowOnDemandName>' . utf8_decode(htmlspecialchars($title)) . '</ShowOnDemandName>'
- . '<ShowOnDemandURL>' . $host1 . utf8_decode(htmlspecialchars($urlPath)) . '</ShowOnDemandURL>'
+ . '<ShowOnDemandName>' . nox_esc($title) . '</ShowOnDemandName>'
+ . '<ShowOnDemandURL>' . $host1 . nox_esc($urlPath) . '</ShowOnDemandURL>'
. '</Item>';
}
{
return '<Item>'
. '<ItemType>Message</ItemType>'
- . '<Message>' . utf8_decode(htmlspecialchars($msg)) . '</Message>'
+ . '<Message>' . nox_esc($msg) . '</Message>'
. '</Item>';
}
global $host1, $host2;
return '<Item>'
. '<ItemType>Previous</ItemType>'
- . '<UrlPrevious>' . $host1 . utf8_decode(htmlspecialchars($urlPath)) . '</UrlPrevious>'
- . '<UrlPreviousBackUp>' . $host1 . utf8_decode(htmlspecialchars($urlPath)) . '</UrlPreviousBackUp>'
+ . '<UrlPrevious>' . $host1 . nox_esc($urlPath) . '</UrlPrevious>'
+ . '<UrlPreviousBackUp>' . $host1 . nox_esc($urlPath) . '</UrlPreviousBackUp>'
. '</Item>';
}
-function addPreviousItem(&$listItems, $urlPath)
+function buildPreviousItem($urlPath)
{
$parentDir = dirname($urlPath) . '/';
if ($parentDir == '/') {
- return;
+ return null;
}
- $listItems[] = getPreviousItem($parentDir);
+ return getPreviousItem($parentDir);
}
-function getFinalUrl($url)
+function nox_esc($string)
{
- $ctx = stream_context_set_default(
- array('http' => array('method' => 'HEAD'))
- );
- //get_headers follows redirects automatically
- $headers = get_headers($url, 1);
- if ($headers !== false && isset($headers['Location'])) {
- return end($headers['Location']);
- }
- return $url;
+ return utf8_decode(htmlspecialchars($string));
}
function sendMessage($msg)
sendListItems(array(getMessageItem($msg)));
}
-function sendListItems($listItems)
-{
+function sendListItems(
+ $listItems, $previous = null, $enablePaging = true, $noCache = false
+) {
$startitems = 1;
- $enditems = 10;
+ $enditems = 100000;
if (isset($_GET['startitems'])) {
$startitems = (int) $_GET['startitems'];
}
if (isset($_GET['enditems'])) {
$enditems = (int) $_GET['enditems'];
}
- //TODO: limit list
+
+ if ($enablePaging) {
+ $itemCount = count($listItems);
+ } else {
+ $itemCount = -1;
+ }
+ if ($previous !== null) {
+ $previous .= "\n";
+ }
$xml = '<?xml version="1.0" encoding="iso-8859-1"?>' . "\n";
$xml .= '<?xml-stylesheet type="text/xsl" href="/html.xsl"?>' . "\n";
$xml .= '<ListOfItems>' . "\n";
+ if ($noCache) {
+ $xml .= "<NoCache>1</NoCache>\n";
+ }
+ $xml .= '<ItemCount>' . $itemCount . '</ItemCount>' . "\n";
+ $xml .= $previous;
+
+ $num = 0;
foreach ($listItems as $item) {
- $xml .= $item . "\n";
+ ++$num;
+ if (!$enablePaging || ($num >= $startitems && $num <= $enditems)) {
+ $xml .= $item . "\n";
+ }
}
$xml .= "</ListOfItems>\n";
- header('Content-type: text/xml');
+ header('Content-type: text/xml; charset=iso-8859-1');
echo $xml;
}
?>