Merging changes from nighthawk; added support for dumb terminals
authorDan
Fri, 15 Aug 2008 23:49:00 -0400
changeset 34 3b817b961984
parent 33 3b4aef1efff6 (diff)
parent 31 48004643a8a5 (current diff)
child 35 8040903d25de
Merging changes from nighthawk; added support for dumb terminals
functions.php
greyhound.php
webserver.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);
+  }
 }
 
 /**
--- 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);
+    }
+  }
+}
--- 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
--- 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
           }
         }
       }