1 <?php
require_once('./http_auth.php'); /*Delete this line to disable password protection*/ ?
>
2 <?php
$exec_time = round(microtime(true), 3); /*
4 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6 * 0.3.5 - Fixed security bug - directory traversal in filelisting (upgrade recommended)
7 * 0.3.4 - Generating playlist for flashplayer, searching for bugs, cleaning code and preparing for new version release
8 * 0.3.3 - Shorter URLs for flashplayer (due to discussion at #skola ;o), nicer national characters handling
9 * 0.3.2 - Better support for national charsets, few small bugfixes, css improvements, modular search engines
10 * 0.3.1 - Buckfickses in m3u generation, better navigation, magic_quotes_gpc handled, css improvements
11 * 0.3 - Migrated to standalone WPAudioPlayer (better, nicer, with more functions)
12 * 0.2 - Few new functions (search playlist, random,...)
13 * 0.1.1 - Few little fixups, written help.html in Czech language ;o)
14 * 0.1 - All functions works - TODO: bugfix & replace ugly code
15 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 $title = 'Harvie\'s JuKe!Box'; //Title of jukebox
20 $music_dir = './music'; //Local path to directory with music
21 $music_dir_url = 'http://your-server.net/jukebox/music'; //URL path to the same directory
22 $cache_passwd = 'renew123'; //You need this passwd to refresh search cache
23 $sort = 3; //Sort? 0 = none, 1 = playlists, 2 = 1+listings; 3 = 2+search-EXPERIMENTAL! (sorting could eat lot of memory)
24 $access_limit = 40; //How many files could be accessed without using cache (while searching)
27 $charset = 'UTF-8'; //Charset for page
28 $national_characters = 1; //Support searching in filenames with national characters? 0 = no; 1 = yes; (may slowdown search a little)
31 $playlist_name = 'playlist.m3u'; //Name of downloaded pl
32 $m3u_exts = 'ogg|mp[0-9]|wma|wmv|wav'; //Allow only these files
33 $default_random_count = 30; //How many random songs by defaul?
36 $indexlist = array('index.html', 'index.txt'); //Search for this file in each directory
37 $bonus_dir = './jbx'; //Misc. files directory
39 $search_cache = $bonus_dir.'/cache.db'; //Database for searching music (php +rw) - .htaccess: Deny from all!!!
40 $css_file = $bonus_dir.'/themes/default/jukebox.css'; //CSS (Design)
41 $favicon_file = './favicon.png'; //favicon
42 $header_file = $bonus_dir.'/header.html'; //header file
43 $footer_file = $bonus_dir.'/footer.html'; //footer file
45 //Search engines extend search experience
46 $search_engines = array(
47 'Google.com' => 'http://google.com/search?q=',
48 'Images' => 'http://google.com/images?q=',
49 'Karaoke-Lyrics.net' => 'http://www.karaoke-lyrics.net/index.php?page=find&q=',
50 'Jyxo.cz multimedia' => 'http://jyxo.cz/s?d=mm&q=',
51 'Centrum.cz mp3' => 'http://search.centrum.cz/index.php?sec=mp3&q=',
52 'YOUTube.com' => 'http://youtube.com/results?search_query='
55 //Flash MusicPlayer (info about settings: http://wpaudioplayer.com/standalone)
56 $flash_player_swf = $bonus_dir.'/player.swf'; //path to musicplayer
57 $flash_player_frame = 'playframe-show'; //FlashPlayer Target (playframe-show|playframe-hide) - usefull for compatibility with old music player
58 $flash_player_options = '?bg=000099&loader=000000&tracker=AAAAFF&skip=FFFFFF' //.'&leftbg=000077&rightbg=000077&righticon=999999'
59 .'&autostart=yes&initialvolume=100&soundFile='; //& arguments (urlencoded song url will be added)
62 error_reporting(0); //This will disable error reporting, wich can pass sensitive data to users
64 //External configuration file (overrides index.php configuration)
65 @include
('./_config.php');
67 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
71 @ini_set
('magic_quotes_gpc' , 'off');
72 if(get_magic_quotes_gpc()) die("Error: magic_quotes_gpc needs to be disabled!\n");
75 $useflash = is_file($flash_player_swf);
77 //Little magic with directories ;o)
78 $current_dir = ereg_replace('/+', '/', '/'.$_GET['dir'].'/');
79 if(eregi('(/|\\\\)\\.\\.(/|\\\\)', $current_dir)) { //check for directory traversal ;)
80 header('Location: ?');
81 die('Error - directory not found!');
83 $dir = $music_dir.$current_dir;
84 $url = $music_dir_url.$current_dir;
85 $parent_dir = dirname($current_dir);
88 function serve_download($filename) {
89 header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
90 header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
91 header('Pragma: no-cache');
93 //header('Content-Type: application/force-download');
94 header('Content-Type: audio/x-mpegurl');
95 header("Content-Disposition: attachment; filename={$filename}");
96 header('Content-Transfer-Encoding: binary');
98 header('X-PHP-Application: Harvie\'s JuKe!Box');
101 $nchars_f = array('Á','Ä','Č','Ç','Ď','É','Ě','Ë','Í','Ň','Ó','Ö','Ř','Š','Ť','Ú','Ů','Ü','Ý','Ž','á','ä','č','ç','ď','é','ě','ë','í','ň','ó','ö','ř','š','ť','ú','ů','ü','ý','ž');
102 $nchars_t = array('A','A','C','C','D','E','E','E','I','N','O','O','R','S','T','U','U','U','Y','Z','a','a','c','c','d','e','e','e','i','n','o','o','r','s','t','u','u','u','y','z');
104 function unational($text) {
105 if(!$GLOBALS['national_characters']) return $text;
106 return(str_replace($GLOBALS['nchars_f'], $GLOBALS['nchars_t'], $text));
109 function generate_m3u($dir, $prefix='', $recursive=0, $nl="\r\n", $doubleenc=0) {
111 if(isset($_GET['newline'])) $nl = $_GET['newline'];
112 if(!isset($_GET['search'])) {
114 while(($item = readdir($dd)) != false) {
115 if($item == '.' ||
$item == '..') continue;
116 if( is_file($dir.$item) && eregi(('\.('.$GLOBALS['m3u_exts'].')$'), $item) ) {
117 if($GLOBALS['sort'] > 0) {
120 $item=($prefix.'/'.str_replace('%2F', '/', (rawurlencode($dir.$item))).$nl);
121 if($doubleenc) $item = rawurlencode($item);
125 if($recursive && is_dir($dir.$item)) {
126 generate_m3u($dir.$item, $prefix, $recursive, $nl, $doubleenc);
130 if(!($searchfp = fopen($GLOBALS['search_cache'], 'r')))
131 die("Cannot read cache from $outfile<br />Refresh cache or set permissions properly!<br />\n");
132 while(!feof($searchfp)) {
133 $line = trim(fgets($searchfp));
134 if(@eregi
(str_replace(' ', '(.*)', unational($_GET['search'])), unational($line))) {
135 $line=(dirname($GLOBALS['music_dir_url']).'/'.str_replace('%2F', '/', (rawurlencode($line))).$nl);
136 if($doubleenc) $line = rawurlencode($line);
142 if($GLOBALS['sort'] > 0) {
144 foreach($temp as $item) {
145 $temp=($prefix.'/'.str_replace('%2F', '/', (rawurlencode($dir.$item))).$nl);
146 if($doubleenc) $temp = rawurlencode($temp);
152 function write_search_cache($dir, $outfp) {
155 while($item = readdir($dd)) {
156 if($item == '.' ||
$item == '..') continue;
157 if( is_file($dir.$item) && eregi(('\.('.$GLOBALS['m3u_exts'].')$'), $item) ) {
158 fwrite($outfp, $dir.$item."\n");
160 if(is_dir($dir.$item)) {
161 write_search_cache($dir.$item, $outfp);
166 function generate_search_cache($dir, $outfile) {
167 echo("Generating search cache. Please wait...<br />\n"); flush();
168 @chmod
($outfile, 0755); //At least i tryed ;D
169 if(!($outfp = fopen($outfile, 'w')))
170 die("Cannot write cache to $outfile<br />You probably haven't set the permissions properly!<br />\n");
171 write_search_cache($dir, $outfp);
173 $osize = filesize($outfile); clearstatcache();
174 if($GLOBALS['sort'] > 2) {
175 echo("Sorting search cache. Please wait...<br />\n"); flush();
177 $items = file($outfile); @sort
($items);
178 $total = ' ('.sizeof($items).' files)';
179 file_put_contents($outfile, @implode
('', $items));
181 if(abs(filesize($outfile)-$osize) > 2)
182 die('ERROR! Please disable sorting of search cache ($sort < 3)<br />'."\nSorted only ".
183 filesize($outfile).' of '.$osize.' bytes!!!\n');
185 echo('Total: '.filesize($outfile).' of '.$osize.' bytes'.$total.' <a href="?">DONE!</a>'.'<br /><META http-equiv="refresh" content="2;URL=?">'."\n");
188 function render_file_line($dir, $item, $dir_url, $index, $filesize, $parent = false) {
189 $parclass=($index%2?
'even':'odd'); $parcolor=($index%2?
'lightblue':'white');
190 $temp=str_replace('&', '%26', dirname($dir_url)).'/'.str_replace('%2F', '/', (rawurlencode($dir.$item)));
191 if(is_numeric($filesize)) $filesize = round($filesize/(1024*1024), 2);
192 echo("<tr class=\"$parclass\" bgcolor=\"$parcolor\">".'<td><a href="#up">'.$index.'</a></td><td class="btntd">');
193 echo('<a href="?download&song='.rawurlencode($temp).'" class="icon iplay">P</a>');
195 echo('/<a href="?dir='.
196 substr(str_replace(array('&','%2F'), array('%26','/'), (rawurlencode(dirname($dir.$item)))), strlen($GLOBALS['music_dir'])).
197 '" class="icon ifolder">D</a>');
199 if($GLOBALS['useflash'] && eregi(('\.('.$GLOBALS['m3u_exts'].')$'), $item)) {
200 echo('/<a href="?f&song='.rawurlencode($temp).
201 '" target="'.$GLOBALS['flash_player_frame'].'" class="icon ifplay">F</a>/'.
202 '<a href="?blank" target="'.$GLOBALS['flash_player_frame'].'" class="icon ifstop">S</a>');
204 echo(' </td><td><a href="'.$temp.'">'.unxss(str_replace('_', ' ', $item)).'</a></td><td>'.$filesize." MiB </td></tr>\n");
207 function render_tr_playframe_show() {
208 if($GLOBALS['flash_player_frame'] == 'playframe-show' && $GLOBALS['useflash']) { ?
>
209 <tr id
="playframe-tr">
210 <td
><a href
="?blank" target
="playframe-show" title
="Stop playback">S
</a
></td
>
214 name
="playframe-show"
217 style
="border: none;"
218 transparentpagebg
="yes"
223 function render_footer() {
225 'This is NOT advertisments. This is just good text to think about... Remove it if you want!',
226 'Downloading without sharing and other forms of leeching equals STEALING! ;P',
227 'Do NOT support Microsoft!!! Use Linux! ;D',
228 'Don\'t steal! Steal and share!!! ;P',
229 'Linux is not matter of price, it\'s matter of freedom!',
230 'This software brought to you by <a href="http://blog.Harvie.cz">Harvie</a> free of charge! Of course...',
231 'Don\'t be looser, use GNU/Linux! ;P',
232 'Make love and not war!',
233 'Take your chance! Prove yourself!',
234 'This software is free of charge. If you wan\'t to donate, please send some money to children in Africa/etc...'
237 echo('<span id="quote" style="float: left;"><i><small>'.$quotes[rand(0,sizeof($quotes)-1)]."</small></i></span>\n");
238 echo('<span id="exectime" style="float: right;"><small>Page was generated in '.(round(microtime(true), 3) - $GLOBALS['exec_time']).'
239 seconds</small></span>');
240 @readfile
($GLOBALS['footer_file']);
241 echo('</body></html>');
244 function unxss($string) {
245 return htmlspecialchars($string);
248 function explode_path($dir) {
249 $dir = substr($dir, strlen($GLOBALS['music_dir'])+
1);
250 $temp = split('/', ereg_replace('/+', '/', $dir));
252 for($j=sizeof($temp)-1;$j>0;$j--) {
254 for($i=0;$i<(sizeof($temp)-$j);$i++
) {
257 $out.='<a href="?dir='.rawurlencode($dir).'">'.unxss($temp[$i-1]).'</a>/';
259 return('<a href="?">.</a>/'.$out);
262 function flash_mp3_player() {
264 <html
><head
><title
><?
=$GLOBALS['title']?
>: Flash Music Player Plugin
</title
>
265 <style
> * { margin
: 0; padding
: 0; border
: 0; } </style
></head
><body
>
266 <object width
="100%" height
="344">
268 echo($GLOBALS['flash_player_swf'].$GLOBALS['flash_player_options']);
269 if(isset($_GET['song'])) echo(rawurlencode($_GET['song']));
270 if(isset($_GET['playlist'])) generate_m3u($GLOBALS['dir'], dirname($GLOBALS['music_dir_url']), isset($_GET['recursive']), ',', true);
272 type
="application/x-shockwave-flash"
273 allowscriptaccess
="never"
274 allowfullscreen
="true"
275 transparentpagebg
="yes"
277 width
="100%" height
="24px"
278 >You need Adobe Flash enabled browser to play records directly in website
.</embed
>
279 </object></body
></html
>
284 if(isset($_GET['download'])) serve_download($playlist_name);
285 if(isset($_GET['f'])) flash_mp3_player();
286 if(isset($_GET['song'])) {
287 die($_GET['song']."\r\n");
292 if($_POST['cache-refresh'] == $cache_passwd) {
293 generate_search_cache($music_dir, $search_cache);
297 if(isset($_GET['playlist'])) {
298 generate_m3u($dir, dirname($music_dir_url), isset($_GET['recursive']));
302 if(isset($_GET['random'])) {
304 if(!($searchfp = fopen($search_cache, 'r')))
305 die("Cannot read cache from $outfile<br />Refresh cache or set permissions properly!<br />\n");
306 while(!feof($searchfp)) { fgets($searchfp); $flen++
; }
307 for($i=0; $i<$_GET['random']; $i++
) {
309 for($j=0; $j<rand(0, $flen-1); $j++
) fgets($searchfp);
310 echo(dirname($music_dir_url).'/'.str_replace('%2F', '/', (rawurlencode(trim(fgets($searchfp)))))."\r\n");
315 if(isset($_GET['blank'])) {
317 <link rel
="stylesheet" type
="text/css" href
="<?=$css_file?>" />
318 <body
class="blank"><div
class="blank"><b
>Music player
</b
> <small
><i
>(click
'F' link next to the song name to start
, 'S' to stop
...)</i
></small
></div
></body
>
323 <!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
324 <meta http
-equiv
="Content-Type" content
="text/html; charset=<?=$charset?>" />
327 <link rel
="stylesheet" type
="text/css" href
="<?=$css_file?>" />
328 <link rel
="shortcut icon" href
="<?=$favicon_file?>" />
329 <link href
="<?=$favicon_file?>" rel
="icon" type
="image/gif" />
333 <div align
="right" style
="position: absolute; top: 0; right: 0;">
335 <iframe src
="about:blank" name
="playframe-hide" width
="0" height
="0" style
="border: none;"></iframe
><!-- -----------???
--------------- -->
336 <span
class="icon"><
;</span
> <a href
="javascript: history.go(-1)" class="icon iback">BACK
</a
>
337 |
<a href
="?"><span
class="icon ihome">HOME
</span
> (<?
=$music_dir?
>)</a
>
338 |
<a href
="?help" class="icon ihelp">ABOUT
/HELP
</a
>
339 |
<a href
="?logout" class="icon ilogout">LOGOUT
</a
>
343 if(isset($_GET['help'])) {
344 ?
><h1
>About
/Help
</h1
><?php
345 readfile($bonus_dir.'/help.html');
350 if(!isset($_GET['search'])) {
351 echo('<title>'.$title.': '.unxss($dir).'</title>');
352 echo('<a href="?" style="color: black;"><h1 style="float: left;">'.$title.'</h1></a><h2 style="clear: left; display: inline; float: left;">Index of: '.explode_path($dir).'</h2>');
354 echo('<title>'.$title.': '.unxss($_GET['search']).'</title>');
355 echo('<a href="?" style="color: black;"><h1 style="float: left;">'.$title.'</h1></a><h2 style="clear: left; display: inline; float: left;">Searching for: '.unxss($_GET['search']).'</h2>');
363 <span style
="float: right;">
364 <form action
="?" method
="GET" align
="right" style
="display: inline;">
365 <input type
="hidden" name
="download" value
="" />
366 <input type
="text" name
="random" value
="<?=$default_random_count?>" />
367 <input type
="submit" value
="random" title
="Generate random music playlist..." />
369 <form action
="?" method
="GET" align
="right" style
="display: inline;">
370 <input type
="text" name
="search"
371 title
="Search in music/google/lyrics/mp3/youtube; Hint: You can use regular expressions in search query..."
372 value
="<?=unxss($_GET['search'])?>"
374 <input type
="submit" value
="search" title
="Search in this JuKe!Box..." />
378 if(!isset($_GET['search'])) {
379 echo('<br style="clear: both;" />');
383 <span style
="float: right;">
384 <form action
="?" method
="POST" align
="right">
385 <input type
="password" name
="cache-refresh" value
="" title
="Password for refreshing - good for avoiding DoS Attacks!!!" />
386 <input type
="submit" value
="refresh cache" title
="You should refresh cache each time when you add new music or upgrade to newer version of JuKe!Box !!!" />
390 <div align
="right" style
="clear: right;" title
="Aditional search engines...">
394 foreach($search_engines as $search_desc => $search_link) {
395 if(!$search_prefix) {
396 echo(unxss($_GET['search'])." @\n");
399 echo('<a href="'.$search_link.rawurlencode($_GET['search']).'">'.$search_desc."</a>;\n");
402 </div
><br style
="clear: both;" />
404 echo('<small>Search DB size: '.(filesize($search_cache)/1024)." kB<br /></small>\n");
406 if(!($searchfp = fopen($search_cache, 'r')))
407 die("Cannot read cache from $outfile<br />Refresh cache or set permissions properly!<br />\n");
410 echo('<table border="1" width="100%">');
411 render_tr_playframe_show();
412 echo('<tr><td>S</td><td><a href="?download&playlist&search='.unxss($_GET['search']).'">P</a>');
413 if($GLOBALS['useflash']) echo('/<a href="?f&playlist&search='.unxss($_GET['search']).'" target="'.$GLOBALS['flash_player_frame'].'">F</a>');
414 echo('</td><td colspan="100%">Search: '.unxss($_GET['search']).'</td></tr>');
416 while(!feof($searchfp)) {
417 $line = trim(fgets($searchfp));
418 $parclass=($i%2?
'even':'odd'); $parcolor=($i%2?
'lightblue':'white');
419 if(@eregi
(str_replace(' ', '(.*)', unational($_GET['search'])), unational($line))) {
421 $filesize = 0; if($i <= $access_limit) $filesize = filesize($line); else $filesize = 'n/a';
422 render_file_line('', $line, $music_dir_url, $i, $filesize, true);
425 echo('<tr><td colspan="100%">Total: '.$i.' results...</td></tr></table>');
426 render_footer(); die();
429 @readfile
($header_file);
430 foreach($indexlist as $index) @readfile
($dir.$index);
433 <table border
="1" width
="100%">
434 <?php
render_tr_playframe_show(); ?
>
436 <tr
class="directory"><td
>>
;</td
>
437 <td
><a href
="?download&playlist&dir=<?=str_replace('%2F', '/', rawurlencode($current_dir))?>">P
</a
>/<a
438 href
="?download&recursive&playlist&dir=<?=str_replace('%2F', '/', rawurlencode($current_dir))?>">R
</a
><?php
439 if($GLOBALS['useflash']) echo('/<a href="?f&playlist&dir='.str_replace('%2F', '/', rawurlencode($current_dir)).'" target="'.$GLOBALS['flash_player_frame'].'">F</a>'); ?
>
441 <td colspan
="100%"><?
=unxss($dir)?
></td
></tr
>
442 <tr
><td
>^
</td
><td
> 
;</td
><td colspan
="100%" class="directory"><span
class="icon ifolder">[DIR
]</span
> <a href
="?dir=<?=rawurlencode($parent_dir)?>">.. (<?
=$parent_dir?
>)</a
></td
></tr
>
447 for($s=2;$s;$s--) { while(($item = readdir($dd)) != false) {
448 if($item == '.' ||
$item == '..') continue;
449 if(($s==2 && is_file($dir.$item)) ||
($s!=2 && is_dir($dir.$item))) continue;
451 $parclass=($i%2?
'even':'odd'); $parcolor=($i%2?
'lightblue':'white');
452 if(is_file($dir.$item)) {
457 render_file_line($dir, $item, $music_dir_url, $i, filesize($dir.$item));
460 if(is_dir($dir.$item)) {
461 $temp=str_replace('%2F', '/', rawurlencode($current_dir)).rawurlencode($item);
462 echo("<tr class=\"$parclass directory\" bgcolor=\"$parcolor\">".
463 '<td><a href="#up">'.$i.'</a></td><td class="btntd"><a href="?download&playlist&dir='.$temp.'" class="icon iplay">P</a>/'.
464 '<a href="?download&recursive&playlist&dir='.$temp.'">R</a>');
465 if($GLOBALS['useflash']) echo('/<a href="?f&playlist&dir='.$temp.'" target="'.$GLOBALS['flash_player_frame'].'" class="icon ifplay">F</a>');
466 echo('</td><td colspan="100%"><span class="icon ifolder">[DIR]</span> <a href="?dir='.$temp.'">'.unxss(str_replace('_', ' ', $item))."</a></td></tr>\n");
471 foreach($items as $item) {
473 render_file_line($dir, $item, $music_dir_url, $i, filesize($dir.$item));