<?
////////////////////////////////////////////////////////////////////////
/*SMI - SHOUTcast Management Interface
A web based shoutcast server management program
Founding Author: Scott D. Harvanek <hide@address.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.*/
////////////////////////////////////////////////////////////////////////
// id3.class.php utilized in scan_directory_recursively()
/***********************************************************
* Class: ID3
* Version: 1.0
* Date: Janeiro 2004
* Author: Tadeu F. Oliveira
* Contact: hide@address.com
* Use: Extract ID3 Tag information from mp3 files
***********************************************************/
//////////////////////////////////////////////////
//
//Include our configuration file and db class
//
//////////////////////////////////////////////////
require_once('db.inc.php');
//////////////////////////////////////////////////
//
// Create connection with MySQLDB class
//
//////////////////////////////////////////////////
function dbConnect()
{
$dataset = new MySQLDB(DB_SERVER, DB_NAME, DB_USERNAME, DB_PASSWORD);
return $dataset;
}
//////////////////////////////////////////////////
//
// Function to verify a user login
//
//////////////////////////////////////////////////
function login_check($username,$password) {
$db = dbConnect();
$password = md5($password);
$cond = array('username' => sprintf("%s", mysql_real_escape_string($username)));
$row = $db->getRow('members', $cond);
if($username == $row['username'] && $password == $row['password']) {
$login_check = true;
} else {
$login_check = false;
}
return $login_check;
}
//////////////////////////////////////////////////
//
// Here we setup our function to connect to our MySQL server
// FIXME: Can be removed when db class use is implemented
//////////////////////////////////////////////////
function connectdb() {
require('config.php');
global $dbhost, $dbuser, $dbpass, $dbname, $db;
$db = mysql_connect("$dbhost", "$dbuser", "$dbpass") or die('Script Could not connect to database');
mysql_select_db("$dbname",$db);
return $db;
}
//////////////////////////////////////////////////
//
//Here is the disconnect function
// FIXME: Can be removed when db class use is implemented
//////////////////////////////////////////////////
function disconnectdb() {
//global $db;
//if($db != false) {
// mysql_close($db);
//}
//$db = false;
}
//////////////////////////////////////////////////
//
// Function to add event to log database table
//
//////////////////////////////////////////////////
function addevent($user, $event) {
$timestamp = "".strftime('%T')." ".date('Y-m-d')."";
$db = dbConnect();
$insert = array( 'event_user' => $user,
'event' => $user.$event,
'timestamp' => $timestamp );
$db->insert('events', $insert);
}
//////////////////////////////////////////////////
//
// Function to check if running OS is Windows
//
//////////////////////////////////////////////////
function iswin() {
if (strtoupper(substr(PHP_OS, 0, 3)) == "WIN") {
return true;
} else {
return;
}
}
//////////////////////////////////////////////////
//
// Function to GET a web URL and return the reponse
//
//////////////////////////////////////////////////
function webget($url) {
$handle = curl_init($url);
curl_setopt ($handle, CURLOPT_HEADER, 0);
curl_setopt ($handle, CURLOPT_USERAGENT, "User-Agent: SMI (Mozilla Compatible)");
//curl_setopt ($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($handle, CURLOPT_CONNECTTIMEOUT, 120);
curl_setopt ($handle, CURLOPT_TIMEOUT, 120);
ob_start();
curl_exec($handle);
curl_close($handle);
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
//////////////////////////////////////////////////
//
// Function to check the stats of a server for
// listeners, peak listeners and max listeners
//
//////////////////////////////////////////////////
function checklistener($port, $id) {
$config = settings();
$dataset = webget($config['host_addr'].":".$port."/7.html");
if($dataset == "") {
echo "N/A";
} else {
$entries = explode(",",$dataset);
$listener=$entries[0];
$status=$entries[1];
$listenerpeak = $entries[2];
$maxlisteners=$entries[3];
$totallisteners=$entries[4];
$bitrate=$entries[5];
$songtitel=$entries[6];
echo "$listener / $listenerpeak / $maxlisteners";
}
}
//////////////////////////////////////////////////
//
// Function to get aggregate listeners
//
//////////////////////////////////////////////////
function getagg() {
$db = dbConnect();
$config = settings();
$null = NULL;
$servers = $db->getRows('servers','','PortBase, id', 'PortBase', 'ASC');
foreach ($servers as $row) {
$port = $row[0];
$id = $row[1];
$dataset = webget($config['host_addr'].":".$port."/7.html");
if ($dataset == "") {
$db->update('servers', array('listeners' => '0'), array('id' => $id));
} else {
$dataset = preg_replace("/.*<body>/", "", $dataset);
$dataset = preg_replace("/<\/body>.*/", "", $dataset);
$entries = explode(",",trim($dataset));
$listener = $entries[0];
$db->update('servers', array('listeners' => $listener), array('PortBase' => $port));
}
$row = $db->getRow("SELECT SUM(listeners) FROM servers");
return "$row[0]\n0\n".$null."\n".$config['host_addr'];
}
}
//////////////////////////////////////////////////
//
// function called every time a server is added or
// deleted so that it can generate a new mrtg configuration file
//
//////////////////////////////////////////////////
function generatemrtg() {
// Spawn MySQLDB
$db = dbConnect();
// Get settings from database
$config = settings();
// Stop MRTG in case it is running
stopmrtg();
// (Re)generate new mrtg.cfg and restart if MRTG is enabled and we have servers
if ($config['mrtg'] == "on" && $db->numRows('servers') > 0) {
$db = dbConnect();
deletefile($config['smi_path']."/mrtg/mrtg.cfg");
$header = "#MRTG Config File\n"
. "WorkDir: ".$config['smi_path']."/mrtg\n"
. "Interval: ".$config['mrtg_interval']."\n"
. "RunAsDaemon: yes\n\n";
$fd = fopen($config['smi_path']."/mrtg/mrtg.cfg", "w+");
fputs($fd, $header . "\n\n");
fclose($fd);
$servers = $db->getRows('servers','','PortBase, id', 'PortBase');
foreach ($servers as $row) {
$port = $row[0];
$id = $row[1];
$header = "#MRTG Config for port ".$port."\n"
. "WithPeak[$port$id]: ymw\n"
. "Target[$port$id] : `php ".$config['smi_path']."/mrtg/getlisteners.php ".$port." ".$id." ".$config['host_addr']."`\n"
. "Title[$port$id]: Total $port Listeners\n"
. "PageTop[$port$id]: <H1> Listeners on port $port (server #$id)</H1>\n"
. "MaxBytes[$port$id]: 100\n"
. "XSize[$port$id]: 500\n"
. "YSize[$port$id]: 150\n"
. "ShortLegend[$port$id]: listeners\n"
. "YLegend[$port$id]: total listeners\n"
. "Legend1[$port$id]:\n"
. "Legend2[$port$id]:\n"
. "Legend3[$port$id]:\n"
. "LegendI[$port$id]: tuned in:\n"
. "LegendO[$port$id]:\n"
. "Options[$port$id]: gauge,growright,nopercent\n";
$fd = fopen($config['smi_path']."/mrtg/mrtg.cfg", "a+");
fputs($fd, $header . "\n\n");
fclose($fd);
}
// Here we form the aggregate graph
$header = "#MRTG Aggregate Config File\n"
. "WithPeak[aggregate]: ymw\n"
. "Target[aggregate]: `php ".$config['smi_path']."/mrtg/getTotal.php`\n"
. "Title[aggregate]: Total Listeners\n"
. "PageTop[aggregate]: <H1> Listeners on all ports </H1>\n"
. "MaxBytes[aggregate]: 100\n"
. "XSize[aggregate]: 500\n"
. "YSize[aggregate]: 150\n"
. "ShortLegend[aggregate]: listeners\n"
. "YLegend[aggregate]: total listeners\n"
. "Legend1[aggregate]:\n"
. "Legend2[aggregate]:\n"
. "Legend3[aggregate]:\n"
. "LegendI[aggregate]: tuned in:\n"
. "LegendO[aggregate]:\n"
. "Options[aggregate]: gauge,growright,nopercent\n";
$fd = fopen($config['smi_path']."/mrtg/mrtg.cfg", "a+");
fputs($fd, $header."\n\n");
fclose($fd);
// Start MRTG
startmrtg();
}
}
//////////////////////////////////////////////////
//
// function to start the MRTG daemon
//
//////////////////////////////////////////////////
function startmrtg() {
$config = settings();
if (iswin()) {
$output = start_proc("wperl ".$_SERVER['DOCUMENT_ROOT']."/mrtg/bin/mrtg --logging=eventlog ".$config['smi_path']."/mrtg/mrtg.cfg \n");
} else {
$output =shell_exec("nohup env LANG=C /usr/bin/mrtg ".$config['smi_path']."/mrtg/mrtg.cfg > /dev/null & echo $!");
}
return $output;
}
//////////////////////////////////////////////////
//
// function to stop MRTG from running
//
//////////////////////////////////////////////////
function stopmrtg() {
$config = settings();
( iswin() ) ? ( $pidfile = 'mrtg.cfg_l' ) : ( $pidfile = 'mrtg.pid' );
if ($mrtgpid = getcontent($config['smi_path']."/mrtg/".$pidfile)) {
if (iswin()) {
proc_kill(trim($mrtgpid));
} else {
shell_exec("kill -9 ".trim($mrtgpid));
}
}
// Delete MRTG PID file
deletefile($config['smi_path']."/mrtg/".$pidfile);
return 1;
}
//////////////////////////////////////////////////
//
// function to clean up the mrtg files from a deleted server
//
//////////////////////////////////////////////////
function cleanmrtg($port) {
$config = settings();
$path = $config['smi_path']."/mrtg";
if ($handle = opendir($path)) {
// Read contents of 'mrtg/' directory
while ($file=readdir($handle)) {
if (is_file($file) && substr($file, 0, strlen($port)) == $port) {
// If filename begins with $port, delete it
deletefile($path."/".$file);
}
}
}
}
//////////////////////////////////////////////////
//
// function to create/edit crontab file
//
//////////////////////////////////////////////////
function updatecrontab() {
// USE RunAsDaemon: yes INSTEAD
// $config = settings();
// $crontab = $config['smi_path']."/mrtg/mrtg.cron";
// $mrtg = "*/".$config['mrtg_interval']." * * * * env LANG=C /usr/bin/mrtg ".$config['smi_path']."/mrtg/mrtg.cfg";
/*
// Remove old crontab if it exists
if (file_exists($crontab)) {
unlink($crontab);
}
// Set MRTG update enabled or disabled based on settings
($config['mrtg'] == "on") ? ($mrtg = $mrtg) : ($mrtg = "# ".$mrtg);
// Create new crontab file
$fd = fopen($crontab, "a+");
fputs($fd, $mrtg."\n");
fclose($fd);
// Process CRON changes
shell_exec("crontab ".$crontab);
*/
}
//////////////////////////////////////////////////
//
// Function to fetch configuration settings group
//
//////////////////////////////////////////////////
function confgroups() {
$db = dbConnect();
return $db->getRows('config_groups');
}
//////////////////////////////////////////////////
//
// Function to fetch settings for a particular group
//
//////////////////////////////////////////////////
function groupsettings($group) {
$db = dbConnect();
return $db->getRows('config', array('groupid' => $group));
}
//////////////////////////////////////////////////
//
// Function to fetch config_sets for a setting
//
//////////////////////////////////////////////////
function settingoptions($setting) {
$db = dbConnect();
return $db->getRows('config_sets', array('configid' => $setting));
}
//////////////////////////////////////////////////
//
// Function to update settings from an array set
//
//////////////////////////////////////////////////
function updatesettings($update) {
$db = dbConnect();
foreach ($update as $setting => $value)
{
$db->update('config', array('value' => $value), array('setting' => $setting));
}
/*
/ Stuff that should be done each time settings are updated
*/
generatemrtg(); // Build mrtg.cfg and restart MRTG if enabled
}
//////////////////////////////////////////////////
//
// Function to return all settings and values as an associative array
// getRows(<table>, [<condition array> [, <fields> [, <orderfields> [, <ordertype> [, <fetch_type>]]]]])
//////////////////////////////////////////////////
function settings() {
$db = dbConnect();
// Get settings from the config table and place them in array $return
$settings = $db->getRows('config', '', 'setting, value', 'id', 'ASC', MYSQL_ASSOC);
foreach ($settings as $id => $values)
{
$return[$values['setting']] = $values['value'];
}
return $return;
}
//////////////////////////////////////////////////
//
// Add user function
//
//////////////////////////////////////////////////
function adduser($username, $password, $fname, $lname, $email, $level) {
$db = dbConnect();
$insert = array( 'username' => $username,
'password' => $password,
'fname' => $fname,
'lname' => $lname,
'email' => $email,
'access' => $level );
$db->insert('members', $insert);
addevent($_SESSION['username'], " added ".$username." as a registered user");
echo "Added ".$username." successfully!";
}
//////////////////////////////////////////////////
//
// Delete user function
//
//////////////////////////////////////////////////
function deluser($id, $username) {
$db = dbConnect();
$db->delete('members', array('user_id' => $id));
addevent($_SESSION['username'], " deleted user ".$username);
echo "Deleted ".$username." successfully!";
}
//////////////////////////////////////////////////
//
// Edit user function
//
//////////////////////////////////////////////////
function edituser($id, $username, $password, $fname, $lname, $email, $level) {
$db = dbConnect();
$update = array( 'username' => $username,
'password' => $password,
'fname' => $fname,
'lname' => $lname,
'email' => $email,
'access' => $level );
$db->update('members', $update, array('user_id' => $id));
addevent($_SESSION['username'], " updated ".$username);
echo "Updated ".$username." successfully!";
}
//////////////////////////////////////////////////
//
// Get user access level function
//
//////////////////////////////////////////////////
function useraccess($username) {
$db = dbConnect();
$row = $db->getRow('members', array('username' => $username));
return $row['access'];
}
//////////////////////////////////////////////////
//
// Get user id function
//
//////////////////////////////////////////////////
function getuid($username) {
$db = dbConnect();
$row = $db->getRow('members', array('username' => $username));
return $row['user_id'];
}
/////////////////////////////////////////////////
//
// Get owner by server port and id
//
/////////////////////////////////////////////////
function getowner_byport($port,$id) {
$db = dbConnect();
$cond = array('PortBase' => $port, 'id' => $id);
$row = $db->getRow('servers', $cond);
return $row['owner'];
}
/////////////////////////////////////////////////
//
// Get owner by server id
//
/////////////////////////////////////////////////
function getowner_by($id) {
$db = dbConnect();
$row = $db->getRow('servers', array('id' => $id));
return $row['owner'];
}
/////////////////////////////////////////////////
//
// Server restart function
//
/////////////////////////////////////////////////
function restart_server($portbase,$srvname) {
$db = dbConnect();
$config = settings();
shell_exec("kill `cat ".$config['smi_path']."/servers/".$portbase."".$srvname.".pid`");
$db->update('servers', array('enabled' => '1'), array('PortBase' => $portbase, 'servername' => $srvname));
$pid = shell_exec("nohup ".$config['sc_serv']." ".$config['smi_path']."/servers/".$portbase."".$srvname.".conf > /dev/null & echo $!");
$cleanpid = trim($pid);
exec("echo $cleanpid > ".$config['smi_path']."/servers/".$portbase."".$srvname.".pid");
$cond = array ('PortBase' => $portbase, 'servername' => $srvname);
$autodj = $db->getRow('servers', $cond, 'autodj');
if($autodj[0] == "1"){
//restartstream($portbase, $srvname, $djpassword, $id);
}
}
/////////////////////////////////////////////////
//
// Get PID from server's .pid file
//
/////////////////////////////////////////////////
function getpid($portbase, $srvname) {
$config = settings();
$filename = $config['smi_path']."/servers/".$portbase.$srvname.".pid";
if (file_exists($filename)) {
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
return trim($contents);
} else {
return false;
}
}
/////////////////////////////////////////////////
//
// Generic function to read from a file
//
/////////////////////////////////////////////////
function getcontent($fullpath) {
if (file_exists($fullpath) && filesize($fullpath) > 0) {
$handle = fopen($fullpath, "r");
$contents = fread($handle, filesize($fullpath));
fclose($handle);
return trim($contents);
} else {
return false;
}
}
/////////////////////////////////////////////////
//
// Software Version
//
/////////////////////////////////////////////////
function softwarever() {
$db = dbConnect();
$row = $db->getRow('smi');
$filename = "revision.txt";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
return $row['version']."-r".$contents;
}
/////////////////////////////////////////////////
//
// Get media directory
//
/////////////////////////////////////////////////
function getmediapath() {
$db = dbConnect();
$config = settings();
return $config['media_path'];
}
/////////////////////////////////////////////////
//
// Parse media directory
//
/////////////////////////////////////////////////
function reloadmedia($i) {
$db = dbConnect();
$directory = $i;
scan_directory_recursively($directory, "mp3");
// Check if files listed in the DB exist in given path
$dbmedia = $db->getRows('media','','*','id');
foreach ((array)$dbmedia as $row) {
if(file_exists($i."/".basename($row[1]))) {
$db->update('media', array('files' => $i."/".basename($row[1])), array('id' => $row[0]));
} else {
$db->delete('media','id',$row[0]);
$db->delete('playlist_content', 'fid', $row[0]);
}
}
}
/////////////////////////////////////////////////
//
// Recursively parse media directory
//
/////////////////////////////////////////////////
function scan_directory_recursively($directory,$filter) {
require_once('id3.class.php');
$db = dbConnect();
// if the path has a slash at the end we remove it here
if(substr($directory,-1) == '/') {
$directory = substr($directory,0,-1);
}
// if the path is not valid or is not a directory ...
if(!file_exists($directory) || !is_dir($directory)) {
// ... we return false and exit the function
return FALSE;
// ... else if the path is readable
} elseif(is_readable($directory)) {
// we open the directory
$directory_list = opendir($directory);
// and scan through the items inside
while (FALSE !== ($file = readdir($directory_list))) {
// if the filepointer is not the current or parent directory
if($file != '.' && $file != '..') {
// we build the new path to scan
$path = $directory.'/'.$file;
// if the path is readable
if(is_readable($path)) {
// we split the new path by directories
$subdirectories = explode('/',$path);
// if the new path is a directory
if(is_dir($path)) {
// add the directory details to the file list
$directory_tree[] = array(
'path' => $path,
'name' => end($subdirectories),
'kind' => 'directory',
// we scan the new path by calling this function
'content' => scan_directory_recursively($path, $filter));
// if the new path is a file
} elseif(is_file($path)) {
// get the file extension by taking everything after the last dot
$extension = end(explode('.',end($subdirectories)));
// if there is no filter set or the filter is set and matches
if($filter === FALSE || $filter == $extension) {
// add the file details to the file list
$directory_tree[] = array(
'path' => $path,
'name' => end($subdirectories),
'extension' => $extension,
'size' => filesize($path),
'kind' => 'file');
if($db->numRows('media', array('files' => $path)) > 0) {
// Do nothing
} else {
// Extract data from ID3 tag
$mp3 = "$path"; //MP3 file to be read
$id3 = new ID3($mp3);
$id3->getInfo();
($id3->getArtist() == '') ? $artist = ' ' : $artist = $id3->getArtist();
($id3->getTitle() == '') ? $song = ' ' : $song = $id3->getTitle();
// If song is empty, use filename
if ($song == ' ') {
$tempsong = split("[/.]", $mp3);
$song = $tempsong[sizeof($tempsong) - 2];
}
($id3->getAlbum() == '') ? $album = ' ' : $album = $id3->getAlbum();
($id3->getYear() == '') ? $year = 0 : $year = $id3->getYear();
($id3->getGender() == '') ? $genre = 255 : $genre = ereg_replace('[()]', '', $id3->getGender());
// If genre is not numeric, try reverse lookup in table 'genres'
if (!is_numeric($genre)) {
if ($db->numRows('genres', array('genreTitle' => $genre)) > 0) {
$genre = $g[0];
} else {
$genre = 255;
}
} elseif ($genre < 0 || $genre > 255) {
$genre = 255;
}
($id3->tags['COMM'] == '') ? $comment = ' ' : $comment = $id->tags['COMM'];
$insert = array( 'files' => addslashes($path),
'song' => addslashes($song),
'artist' => addslashes($artist),
'album' => addslashes($album),
'year' => addslashes($year),
'comment' => addslashes($comment),
'genre' => addslashes($genre) );
$db->insert('media', $insert);
}
}
}
}
}
}
// close the directory
closedir($directory_list);
}
} // end function
/////////////////////////////////////////////////
//
// Rewrite the playlist file
//
/////////////////////////////////////////////////
function rebuildPlaylist($i) {
$db = dbConnect();
$cond = array( 'playlist_content.pid' => $i,
'playlist_content.fid' => 'media.id',
'playlist_content.pid' => 'playlist.id' );
$file = $db->getRow('media, playlist_content, playlist', $cond, 'media.files, playlist.name, playlist.uid');
$fd = fopen("playlists/$file[2]$file[1].pls", "w+");
fputs($fd, $file[0] . "\n");
fclose($fd);
}
/////////////////////////////////////////////////
//
// Delete the playlist file
//
/////////////////////////////////////////////////
function deletePlaylist($pid,$uid) {
$db = dbConnect();
$cond = array( 'uid' => $uid,
'id' => $pid );
$row = $db->getRow('playlist', $cond, 'uid, name');
unlink("playlists/$row[0]$row[1].pls");
}
/////////////////////////////////////////////////
//
// Start a stream server
//
/////////////////////////////////////////////////
function startstream($id) {
$db = dbConnect();
$stream = $db->getRow('servers', array('id' => $id), 'PortBase, servername, autodj');
$port = $stream['PortBase'];
$srvname = $stream['servername'];
$config = settings();
$sc_conf = $config['smi_path']."/servers/".$port."".$srvname.".conf";
// Check that config file exists before trying to launch
if(file_exists($sc_conf)) {
if (iswin()) {
$cmdstr = $config['sc_serv'];
// sc_serv.exe needs Windows path with backslashes
$cfg_path = str_replace("/", "\\", $sc_conf);
$cmdstr .= " ".$cfg_path;
debug($cmdstr);
$pid = start_proc($cmdstr);
} else {
// POSIX launch procedure
$cmdstr = "nohup ".$config['sc_serv']." ".$config['smi_path']."/servers/".$port."".$srvname.".conf";
$cmdstr .= " > /dev/null & echo $!";
$pid = shell_exec($cmdstr);
}
$cleanpid = trim($pid);
// Write PID to file
$fd = fopen($config['smi_path']."/servers/".$port."".$srvname.".pid", "w+");
fputs($fd, $cleanpid);
fclose($fd);
// Flag server as enabled in database
$db->update('servers', array('enabled' => '1'), array('PortBase' => $port, 'id' => $id));
if($stream['autodj'] == "1") {
$ices = geticesloc();
$pid = shell_exec("$ices -c ".$config['smi_path']."/ices/".$id.".".$port.".conf > /dev/null & echo $!");
$cleanpid = trim($pid);
system("echo $cleanpid > ".$config['smi_path']."/ices/".$id.".".$port.".pid");
}
$username = $_SESSION['username'];
$event = " Started server on port $port";
addevent($username,$event);
} else {
// $sc_conf does not exist
echo "Server configuration file is missing: ".$sc_conf."<br>";
exit;
}
}
/////////////////////////////////////////////////
//
// Stop a stream server
//
/////////////////////////////////////////////////
function stopstream($id) {
$db = dbConnect();
$stream = $db->getRow('servers', array('id' => $id), 'PortBase, servername, autodj');
$port = $stream['PortBase'];
$srvname = $stream['servername'];
$config = settings();
$db->update('servers', array('enabled' => '0'), array('PortBase' => $port, 'id' => $id));
// Try to read PID from .pid-file
if ($pid = trim(getpid($port, $srvname))) {
if (iswin()) {
proc_kill($pid);
} else {
shell_exec("kill -9 ".$pid);
}
// Delete .pid-file
deletefile("".$config['smi_path']."/servers/".$port."".$srvname.".pid");
if($stream['autodj'] == "1") {
if (file_exists($config['smi_path']."/ices/".$id.".".$port.".pid")) {
shell_exec("kill `cat ".$config['smi_path']."/ices/".$id.".".$port.".pid`");
unlink("".$config['smi_path']."/ices/".$id.".".$port.".pid");
}
}
$username = $_SESSION['username'];
$event = " Stopped server on port $port";
addevent($username,$event);
}
}
/////////////////////////////////////////////////
//
// restart a stream server if AutoDJ is enabled
//
/////////////////////////////////////////////////
function reloadstream($id) {
$db = dbConnect();
$config = settings();
$adj = $db->getRow('servers', array('id' => $id), 'autodj, PortBase');
if(file_exists("".$config['smi_path']."/ices/".$id.".".$adj[1].".pid")) {
stopstream($id);
startstream($id);
}
}
////////////////////////////////////////////////
//
// Generate ices0 configuration file
//
////////////////////////////////////////////////
function genIces0Conf($id, $port, $pls, $random) {
$db = dbConnect();
$config = settings();
$iq = $db->getRows('servers', array('id' => $id, 'PortBase' => $port));
foreach ($iq as $i) {
$p = $db->getRow('playlist', array('id' => $pls));
$iconf = ""
. "<ices:Configuration xmlns:ices=\"http://www.icecast.org/projects/ices\">\n"
. "<Playlist>\n"
. "<File>".$p[0]."</File>\n"
. "<Randomize>".$random."</Randomize>\n"
. "<Type>script</Type>\n"
. "<Module>".$config['smi_path']."/ices/$id.pls.php</Module>\n"
. "<Crossfade>5</Crossfade>\n"
. "</Playlist>\n"
. "<Execution>\n"
. "<Background>0</Background>\n"
. "<Verbose>0</Verbose>\n"
. "<BaseDirectory>".$config['smi_path']."/ices</BaseDirectory>\n"
. "</Execution>\n"
. "<Stream>\n"
. "<Server>\n"
. "<Hostname>".$config['host_addr']."</Hostname>\n"
. "<Port>".$port."</Port>\n"
. "<Password>".$i[3]."</Password>\n"
. "<Protocol>icy</Protocol>\n"
. "</Server>\n"
. "<Mountpoint>/</Mountpoint>\n"
. "<Name>".$i[44]."</Name>\n"
. "<Genre>".$i[43]."</Genre>\n"
. "<Description></Description>\n"
. "<URL>".$i[44]."</URL>\n"
. "<Public>1</Public>\n"
. "<Bitrate>128</Bitrate>\n"
. "<Reencode>1</Reencode>\n"
. "</Stream>\n"
. "</ices:Configuration>\n";
$fd = fopen("".$config['smi_path']."/ices/$id.$port.conf", "a+");
fputs($fd, $iconf . "\n\n");
fclose($fd);
}
}
////////////////////////////////////////////////
//
// Get last server added id
//
////////////////////////////////////////////////
function getserverid() {
$db = dbConnect();
$row = $db->getRow("SELECT MAX(id) FROM ranch");
return $row[0];
}
////////////////////////////////////////////////
//
// Get Ices0 Path
//
////////////////////////////////////////////////
function geticesloc() {
$config = settings();
return $config['ices_path'];
}
////////////////////////////////////////////////
//
// Get service title
//
////////////////////////////////////////////////
function serviceTitle() {
$config = settings();
echo $config['site_title'];
}
////////////////////////////////////////////////
//
// User list -> dropdown function
//
////////////////////////////////////////////////
function userlist() {
$db = dbConnect();
$users = $db->getRows('members', '', 'user_id, username', 'user_id');
foreach ($users as $user)
{
echo "<option value=\"".$user[0]."\">".$user[1]."</option>";
}
}
////////////////////////////////////////////////
//
// Create Javascript status dialog box
//
////////////////////////////////////////////////
function msgbox($message, $return='home.php') {
$js = "<script type=\"text/javascript\">\n";
$js .= " alert(\"".$message."\");\n";
$js .= " window.location=\"".$return."\";\n";
$js .= "</script>\n";
return $js;
}
////////////////////////////////////////////////
//
// Create playlist select field values
//
////////////////////////////////////////////////
function playlist() {
// Create instance of MySQLDB class
$db = dbConnect();
// If query returns nothing, feed foreach an empty array to supress PHP warning
($rows = $db->getRows('playlist', '', '*', 'name', 'ASC')) ? ($rows = $rows) : ($rows[] = '');
// Build HTML option list
foreach ($rows as $row)
{
echo "<option value=\"".$row[0]."\">".$row[3]."</option>";
}
}
////////////////////////////////////////////////
//
// Generate playlist script for ices
//
////////////////////////////////////////////////
function genicespls($sid,$rand) {
require("config.php");
connectdb();
delicespls($sid);
$config = settings();
if($rand == "0") {
$rconf = ""
. "#!/usr/bin/php\n"
. "<?\n"
. "// Turn off all error reporting\n"
. "error_reporting(0);\n"
. "\$db = mysql_connect(\"$dbhost\", \"$dbuser\", \"$dbpass\") or die('Script Could not connect to database');\n"
. "mysql_select_db(\"$dbname\",\$db);\n"
. "\$query = mysql_query(\"SELECT * FROM requests WHERE sid=".$sid." ORDER BY id ASC LIMIT 1\");\n"
. "\n"
. "if(!\$row = mysql_fetch_row(\$query)){\n"
. "\$pq = mysql_query(\"SELECT playlist FROM servers WHERE id=".$sid."\");\n"
. "\$p = mysql_fetch_row(\$pq);\n"
. "\$cq = mysql_query(\"SELECT current_fid,fid,id FROM playlist_cache WHERE pid='\".\$p[0].\"'\");\n"
. "\$c = mysql_fetch_row(\$cq);\n"
. "\n"
. "if(!\$c){\n"
. "\$pos = \"0\";\n"
. "\$lq = mysql_query(\"SELECT fid FROM playlist_content WHERE pid='\".\$p[0].\"' AND position>'\".\$pos.\"' ORDER BY position ASC LIMIT 1\");\n"
. "\$l = mysql_fetch_row(\$lq);\n"
. "\$fid = \$l[0];\n"
. "mysql_query(\"INSERT INTO playlist_cache VALUES('','\".\$fid.\"','\".\$p[0].\"','1')\");\n"
. "}else{\n"
. "\$lq = mysql_query(\"SELECT fid FROM playlist_content WHERE pid='\".\$p[0].\"' AND position>'\".\$c[0].\"' ORDER BY position ASC LIMIT 1\");\n"
. "\$l = mysql_fetch_row(\$lq);\n"
. "\n"
. "if(!\$l){\n"
. "\$pos = \"0\";\n"
. "\$lq = mysql_query(\"SELECT fid FROM playlist_content WHERE pid='\".\$p[0].\"' AND position>'\".\$pos.\"' ORDER BY position ASC LIMIT 1\");\n"
. "\$l = mysql_fetch_row(\$lq);\n"
. "\$fid = \$l[0];\n"
. "mysql_query(\"UPDATE playlist_cache SET current_fid='1' WHERE pid='\".\$p[0].\"'\");\n"
. "}else{\n"
. "\$fid = \$l[0];\n"
. "\$adv = \$c[0] + 1;\n"
. "mysql_query(\"UPDATE playlist_cache SET current_fid='\".\$adv.\"' WHERE id='\".\$c[2].\"'\");\n"
. "\n"
. "}}\n"
. "\n"
. "\n"
. "}else{\n"
. "\$query = mysql_query(\"SELECT * FROM requests WHERE sid='".$sid."' ORDER BY id ASC LIMIT 1\");\n"
. "\$row = mysql_fetch_row(\$query);\n"
. "\$fid = \$row[1];\n"
. "mysql_query(\"DELETE FROM requests WHERE id=\".\$row[0].\"\");\n"
. "}\n"
. "\$query2 = mysql_query(\"SELECT * FROM media WHERE id=\".\$fid.\"\");\n"
. "\$row2 = mysql_fetch_row(\$query2);\n"
. "echo \$row2[1];\n"
. "?>\n";
}
if($rand == "1"){
$rconf = ""
. "#!/usr/bin/php\n"
. "<?\n"
. "// Turn off all error reporting\n"
. "error_reporting(0);\n"
. "\$db = mysql_connect(\"$dbhost\", \"$dbuser\", \"$dbpass\") or die('Script Could not connect to database');\n"
. "mysql_select_db(\"$dbname\",\$db);\n"
. "\$query = mysql_query(\"SELECT * FROM requests WHERE sid=".$sid." ORDER BY id ASC LIMIT 1\");\n"
. "\n"
. "if(!\$row = mysql_fetch_row(\$query)){\n"
. "\$pq = mysql_query(\"SELECT playlist FROM servers WHERE id=".$sid."\");\n"
. "\$p = mysql_fetch_row(\$pq);\n"
. "\$sq = mysql_query(\"SELECT fid from playlist_content where pid=\".\$p[0].\" ORDER BY RAND()\");\n"
. "\$s = mysql_fetch_row(\$sq);\n"
. "\$fid = \$s[0];\n"
. "}else{\n"
. "\$query = mysql_query(\"SELECT * FROM requests WHERE sid=137 ORDER BY id ASC LIMIT 1\");\n"
. "\$reg = mysql_fetch_row(\$query);\n"
. "\$fid = \$reg[1];\n"
. "mysql_query(\"DELETE FROM requests WHERE fid=\".\$fid.\" ORDER BY id LIMIT 1\");\n"
. "}\n"
. "\$query2 = mysql_query(\"SELECT * FROM media WHERE id=\".\$fid.\"\");\n"
. "\$row2 = mysql_fetch_row(\$query2);\n"
. "echo \$row2[1];\n"
. "?>\n";
}
$fd = fopen("".$config['smi_path']."/ices/$sid.pls.php", "a+");
fputs($fd, $rconf . "\n");
fclose($fd);
shell_exec("chmod +x ".$config['smi_path']."/ices/$sid.pls.php");
}
////////////////////////////////////////////////
//
// Remove playlist script for ices
//
////////////////////////////////////////////////
function delicespls($sid){
$config = settings();
if (file_exists($config['smi_path']."/ices/$sid.pls.php")) {
unlink($config['smi_path']."/ices/$sid.pls.php");
}
}
////////////////////////////////////////////////
//
// Find the next vacant portbase by method
// $method="high" - find next vacant port
// $method="low" - find lowest vacant port
//
////////////////////////////////////////////////
function nextport()
{
$db = dbConnect();
$config = settings();
$newport = $config['start_portbase'];
$row = $db->getRow("SELECT MAX(PortBase) AS LastPort FROM servers");
if ($row['LastPort'] < $newport) {
return $newport;
} else if (strtolower($config['nextport_method']) == "high") {
return $row['LastPort'] + 2; // Use highest port number + 2
} else {
$servers = $db->getRows('servers','','PortBase','PortBase');
$lastport = $config['start_portbase'] - 2;
foreach ($servers as $row) {
if($row[0] > $lastport + 2) {
$newport = $lastport + 2;// Use the lowest vacant port
break;
} else {
$lastport = $row[0];
$newport = $lastport + 2;
}
}
}
return $newport;
} // function end
////////////////////////////////////////////////
//
// Check if a portbase already is in use
//
////////////////////////////////////////////////
function portexists($checkport)
{
$db = dbConnect();
return $db->numRows('servers', array('PortBase' => $checkport));
}
////////////////////////////////////////////////
//
// Delete a file after checking that is exists
//
////////////////////////////////////////////////
function deletefile($path)
{
if (file_exists($path)) {
unlink($path);
return true;
} else {
return false;
}
}
////////////////////////////////////////////////
//
// Rename a file after checking that is exists
//
////////////////////////////////////////////////
function renamefile($oldpath, $newpath)
{
if (file_exists($oldpath)) {
rename($oldpath, $newpath);
}
}
/////////////////////////////////////////////////
//
// Check and see if the install.php file has been removed
//
/////////////////////////////////////////////////
function check_install() {
if(file_exists('./install/install.php')){
$fe = '1';
} else {
$fe = '0';
}
return $fe;
}
/*
Get our configuration settings from the database
Return as an array
FIXME: Remove this when new settings scheme works
*/
function get_settings() {
connectdb();
$query = mysql_query('SELECT * FROM config');
$result = mysql_fetch_row($query);
return $result;
}
/********************************************************************/
/********************************************************************/
function start_proc ( $comm ) {
$config = settings();
$dn=dirname(__FILE__);
$descriptorspec = array(
0 => array('pipe', 'r'), // stdin
1 => array('pipe', 'w'), // stdout
2 => array('pipe', 'w') // stderr
);
$cmd = "start /b ".$config['smi_path']."/wintools/psexec.exe -d";
$fpr = proc_open($cmd.' '.$comm, $descriptorspec, $pipes, $dn);
fclose($pipes[0]);
fclose($pipes[1]);
$stderr = '';
while(!feof($pipes[2])) { $stderr .= fgets($pipes[2], 128); }
fclose($pipes[2]);
proc_close ($fpr);
$pid =FALSE;
if ( preg_match ( "/process ID ([\d]{1,10})\./im", $stderr, $matches ) )
$pid = $matches[1];
else $pid=FALSE;
return $pid;
}
/********************************************************************/
/********************************************************************/
function proc_isalive ( $pid ){
$config = settings();
$alive=FALSE;
$dn=dirname(__FILE__);
$descriptorspec = array(
0 => array('pipe', 'r'), // stdin
1 => array('pipe', 'w'), // stdout
2 => array('pipe', 'w') // stderr
);
$cmd = "start /b ".$config['smi_path']."/wintools/pslist.exe";
$fpr = proc_open( $cmd.' '.$pid, $descriptorspec, $pipes, $dn );
fclose($pipes[0]);
$stdout = '';
while(!feof($pipes[1])) { $stdout .= fgets($pipes[1], 128); }
fclose($pipes[1]);
$stderr = '';
while(!feof($pipes[2])) { $stderr .= fgets($pipes[2], 128); }
fclose($pipes[2]);
proc_close ($fpr);
if ( strpos($stdout, 'not found') === FALSE ) $alive=TRUE;
return $alive;
}
/********************************************************************/
/********************************************************************/
function proc_kill ( $pid ){
$config = settings();
$succ=FALSE;
$dn=dirname(__FILE__);
$descriptorspec = array(
0 => array('pipe', 'r'), // stdin
1 => array('pipe', 'w'), // stdout
2 => array('pipe', 'w') // stderr
);
$fpr = proc_open( 'start /b '.$config['smi_path'].'/wintools/pskill.exe '.$pid, $descriptorspec, $pipes, $dn );
fclose($pipes[0]);
$stdout = '';
while(!feof($pipes[1])) { $stdout .= fgets($pipes[1], 128); }
fclose($pipes[1]);
$stderr = '';
while(!feof($pipes[2])) { $stderr .= fgets($pipes[2], 128); }
fclose($pipes[2]);
proc_close ($fpr);
if ( strpos($stdout, 'killed') !== FALSE ) $succ=TRUE;
return $succ;
}
/*
Function for dumping debug messages to the system log
Comment this out to disable
*/
function debug($msg) {
error_log("[SMI] ".$msg);
}
?>