# HG changeset patch # User Dan # Date 1218858540 14400 # Node ID 3b817b961984d4fef22539caf044cc20892f9d37 # Parent 3b4aef1efff6270a5144de1693174a5bb33789c3# Parent 48004643a8a52a747dea289f7279d56c426d7bb7 Merging changes from nighthawk; added support for dumb terminals diff -r 48004643a8a5 -r 3b817b961984 functions.php --- a/functions.php Fri Aug 15 23:29:37 2008 -0400 +++ b/functions.php Fri Aug 15 23:49:00 2008 -0400 @@ -24,23 +24,39 @@ function burnout($msg) { + global $use_colors; $h = @fopen('php://stderr', 'w'); - fwrite($h, "\x1B[31;1m[Greyhound] fatal: \x1B[37;1m"); - fwrite($h, "$msg\x1B[0m\n"); + if ( $use_colors ) + { + fwrite($h, "\x1B[31;1m[Greyhound] fatal: \x1B[37;1m"); + fwrite($h, "$msg\x1B[0m\n"); + } + else + { + fwrite($h, "[Greyhound] fatal: $msg\n"); + } fclose($h); exit(1); } /** - * Print a stylized status message, compatible with Linux consoles + * Print a stylized status message, compatible with Linux consoles. Falls back to no control characters if on unsupported terminal. * @param string Status message */ function status($msg) { + global $use_colors; $h = @fopen('php://stderr', 'w'); $label = ( defined('HTTPD_WS_CHILD') ) ? 'Child ' . substr(strval(getmypid()), -3) : 'Greyhound'; - fwrite($h, "\x1B[32;1m[$label] \x1B[32;0m$msg\x1B[0m\n"); + if ( $use_colors ) + { + fwrite($h, "\x1B[32;1m[$label] \x1B[32;0m$msg\x1B[0m\n"); + } + else + { + fwrite($h, "[$label] $msg\n"); + } fclose($h); } @@ -51,8 +67,16 @@ function warning($msg) { + global $use_colors; $h = @fopen('php://stderr', 'w'); - fwrite($h, "\x1B[33;1m[Greyhound] \x1B[0m\x1B[33mWarning:\x1B[0m $msg\n"); + if ( $use_colors ) + { + fwrite($h, "\x1B[33;1m[Greyhound] \x1B[0m\x1B[33mWarning:\x1B[0m $msg\n"); + } + else + { + fwrite($h, "[Greyhound] Warning: $msg\n"); + } fclose($h); } @@ -94,9 +118,12 @@ function rebuild_playlist() { // import what we need - global $homedir, $playlist; + global $playlist, $amarok_home; // sync and load the playlist file $playlist_file = dcop_action('playlist', 'saveCurrentPlaylist'); + // do we have amarok's home? + if ( !$amarok_home ) + $amarok_home = dirname($playlist_file); // check MD5 - if it's not changed, exit to save CPU cycles global $playlist_last_md5; $effective_md5 = md5_playlist_file($playlist_file); @@ -134,6 +161,12 @@ ); $playlist[] = $item; } + // if we're a child process, signal the parent to update + if ( defined('HTTPD_WS_CHILD') ) + { + global $httpd; + posix_kill($httpd->parent_pid, SIGUSR1); + } } /** diff -r 48004643a8a5 -r 3b817b961984 greyhound.php --- a/greyhound.php Fri Aug 15 23:29:37 2008 -0400 +++ b/greyhound.php Fri Aug 15 23:49:00 2008 -0400 @@ -23,6 +23,7 @@ // trap SIGTERM pcntl_signal(SIGTERM, 'sigterm'); pcntl_signal(SIGINT, 'sigterm'); + pcntl_signal(SIGUSR1, 'handle_refresh_signal'); } // @@ -63,9 +64,12 @@ // create directories @mkdir('./compiled'); +// what kind of terminal do we have? +$use_colors = ( @in_array(@$_SERVER['TERM'], array('linux', 'xterm', 'vt100')) ) ? true : false; + // start up... -status('Starting Greyhound Web Control v0.1a1'); +status('Starting Greyhound Web Control v0.1a3'); status('loading files'); require('webserver.php'); @@ -76,17 +80,6 @@ require(GREY_ROOT . '/ajax.php'); require(GREY_ROOT . '/imagetools.php'); -status('doing home directory detection'); - -// get home directory - -if ( !isset($_ENV['HOME']) ) -{ - burnout('Could not get your home directory'); -} - -$homedir =& $_ENV['HOME']; - // signal handler function sigterm($signal) { @@ -111,6 +104,7 @@ // init playlist object $playlist = array(); +$amarok_home = false; rebuild_playlist(); // startup webserver @@ -159,5 +153,29 @@ } catch( Exception $e ) { + if ( strstr(strval($e), "Could not bind") ) + { + burnout("Could not bind to the port $ip:$port. Is Greyhound already running? Sometimes browsers don't close off their connections until Greyhound has been dead for about a minute, so try starting Greyhound again in roughly 60 seconds. If that doesn't work, type \"killall -9 php\" at a terminal and try starting Greyhound again in 60 seconds."); + } burnout("Exception caught while running webserver:\n$e"); } + +function handle_refresh_signal() +{ + global $httpd; + if ( !is_object($httpd) ) + // we're not serving yet. + return false; + + // we've got an httpd instance; rebuild the playlist + rebuild_playlist(); + + // if this is the parent, also ask the children to rebuild. + if ( !defined('HTTPD_WS_CHILD') ) + { + foreach ( $httpd->child_list as $pid ) + { + posix_kill($pid, SIGUSR1); + } + } +} diff -r 48004643a8a5 -r 3b817b961984 playlist.php --- a/playlist.php Fri Aug 15 23:29:37 2008 -0400 +++ b/playlist.php Fri Aug 15 23:49:00 2008 -0400 @@ -66,7 +66,7 @@ function artwork_request_handler($httpd, $socket) { - global $homedir; + global $amarok_home; if ( !isset($_GET['artist']) || !isset($_GET['album']) ) { @@ -75,7 +75,7 @@ } // get hash $artwork_hash = md5( strtolower(trim($_GET['artist'])) . strtolower(trim($_GET['album'])) ); - $artwork_dir = "$homedir/.kde/share/apps/amarok/albumcovers"; + $artwork_dir = "$amarok_home/albumcovers"; if ( file_exists("$artwork_dir/large/$artwork_hash") ) { // artwork file found - scale and convert to PNG diff -r 48004643a8a5 -r 3b817b961984 webserver.php --- a/webserver.php Fri Aug 15 23:29:37 2008 -0400 +++ b/webserver.php Fri Aug 15 23:49:00 2008 -0400 @@ -18,7 +18,7 @@ * @const string */ -define('HTTPD_VERSION', '0.1b1'); +define('HTTPD_VERSION', '0.1b4'); /** * Length of keep-alive connections @@ -160,6 +160,20 @@ var $socket_initted = false; /** + * The list of child processes spawned by this server. + * @var array + */ + + var $child_list = array(); + + /** + * The parent process's PID + * @var int + */ + + var $parent_pid = 0; + + /** * Constructor. * @param string IPv4 address to bind to * @param int Port number @@ -254,6 +268,7 @@ $this->bind_address = $address; $this->server_string = "PhpHttpd/" . HTTPD_VERSION . " PHP/" . PHP_VERSION . "\r\n"; + $this->parent_pid = getmypid(); // create a UUID $uuid_base = md5(microtime() . ( function_exists('mt_rand') ? mt_rand() : rand() )); @@ -337,6 +352,7 @@ { // we are the parent, continue listening socket_close($remote); + $this->child_list[] = $pid; continue; } else @@ -355,22 +371,33 @@ // read request $last_line = ''; $client_headers = ''; - // $last_finish_time - while ( $line = @socket_read($remote, 1024, PHP_NORMAL_READ) ) + if ( defined('HTTPD_WS_CHILD') ) + { + @socket_set_timeout($remote, HTTPD_KEEP_ALIVE_TIMEOUT); + } + if ( $line = @socket_read($remote, 1024, PHP_NORMAL_READ) ) { - $line = str_replace("\r", "", $line); - if ( empty($line) ) - continue; - if ( $line == "\n" && $last_line == "\n" ) - break; - $client_headers .= $line; - $last_line = $line; - if ( isset($last_finish_time) && defined('HTTPD_WS_CHILD') && $last_finish_time + HTTPD_KEEP_ALIVE_TIMEOUT < microtime(true) ) + do { - if ( defined('HTTPD_WS_CHILD') ) + $line = str_replace("\r", "", $line); + if ( empty($line) ) + continue; + if ( $line == "\n" && $last_line == "\n" ) + break; + $client_headers .= $line; + $last_line = $line; + } + while ( $line = @socket_read($remote, 1024, PHP_NORMAL_READ) ); + } + else + { + if ( defined('HTTPD_WS_CHILD') ) + { + $md = @socket_get_status($remote); + if ( @$md['timed_out'] ) { status('[debug] keep-alive connection timed out'); - continue 2; // will jump back to the start of the loop and kill the child process + continue; // will jump back to the start of the loop and kill the child process } } }