greyhound.php
author Dan
Tue, 01 Jul 2008 04:17:46 -0400
changeset 23 08225c2eb0b6
parent 21 74edc873234f
child 25 5c377ceb0e4c
permissions -rwxr-xr-x
Added support for multipart forms, file uploads, and fatal exceptions in PhpHttpd; fixed wrong license tag on WebServer class

#!/usr/bin/env php
<?php

/**
 * Greyhound - real web management for Amarok
 * Copyright (C) 2008 Dan Fuhry
 *
 * This program is Free Software; you can redistribute 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 details.
 */

// Try to trap termination signals to cleanly close the socket when needed
// AmaroK sends a SIGTERM when it is shut down or the user requests to stop
// the script
if ( function_exists('pcntl_signal') )
{
  // required for signal handling to work
  declare(ticks=1);
  
  // trap SIGTERM
  pcntl_signal(SIGTERM, 'sigterm');
  pcntl_signal(SIGINT,  'sigterm');
}

//
// CONFIGURATION
//

// Listen on all interfaces. If this is false, it will only listen on
// 127.0.0.1 (the loopback interface)
$public = true;
// Allow control of playback. By default this is turned on but if you
// set this to false, it will only display the playlist.
$allowcontrol = true;
// The default theme. This should be a name of a directory in ./themes.
$theme = 'funkymonkey';
// Allow forking when an HTTP request is received. This has advantages
// and disadvantages. If this experimental option is enabled, it will
// result in faster responses and load times but more memory usage.
$allow_fork = false;
// set to true to enable authentication
// WARNING: THIS HAS SOME SERIOUS SECURITY PROBLEMS RIGHT NOW. I don't
// know what's causing it to not prompt for authentication from any
// client after the first successful auth.
$use_auth = false;
// valid users and passwords
$auth_data = array(
    'funky' => 'monkey',
    'fast' => 'forward'
  );

@ini_set('display_errors', 'on');

// include files
require('functions.php');

// get the root
define('GREY_ROOT', dirname(__FILE__));

// create directories
@mkdir('./compiled');

// start up...

status('Starting Greyhound Web Control v0.1a1');
status('loading files');

require('webserver.php');
define('SMARTY_DIR', GREY_ROOT . '/smarty/');
require(GREY_ROOT . '/smarty/Smarty.class.php');
require(GREY_ROOT . '/playlist.php');
require(GREY_ROOT . '/json.php');
require(GREY_ROOT . '/ajax.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)
{
  global $httpd;
  status("Caught SIGTERM, cleaning up.");
  exit(0);
}

status('initializing playlist');

// init playlist object
$playlist = array();
rebuild_playlist();

// startup webserver
$ip = ( $public ) ? '0.0.0.0' : '127.0.0.1';
$port = 7447;

try
{
  status('starting PhpHttpd');
  status('doing PHP capabilities check');
  if ( !function_exists('pcntl_signal') )
  {
    warning('System does not support POSIX functions. Termination signals will result in unclean shutdown.');
  }
  $httpd = new WebServer($ip, $port);
  
  // setup handlers
  status('initializing handlers');
  $httpd->add_handler('index',                'function', 'amarok_playlist');
  $httpd->add_handler('action.json',          'function', 'ajax_request_handler');
  $httpd->add_handler('scripts',              'dir',      GREY_ROOT . '/scripts');
  $httpd->add_handler('favicon.ico',          'file',     GREY_ROOT . '/amarok_icon.ico');
  $httpd->add_handler('apple-touch-icon.png', 'file',     GREY_ROOT . '/apple-touch-icon.png');
  // load all themes if forking is enabled
  // Themes are loaded when the playlist is requested. This is fine for
  // single-threaded operation, but if the playlist handler is only loaded
  // in a child process, we need to preload all themes into the parent before
  // children can respond to theme resource requests.
  if ( $allow_fork )
  {
    status('Preloading themes');
    
    $dh = @opendir(GREY_ROOT . '/themes');
    if ( !$dh )
      burnout('Could not open themes directory');
    while ( $dir = @readdir($dh) )
    {
      if ( $dir == '.' || $dir == '..' )
        continue;
      if ( is_dir( GREY_ROOT . "/themes/$dir" ) )
        load_theme($dir);
    }
  }
  $httpd->allow_dir_list = true;
  $httpd->allow_fork = ( $allow_fork ) ? true : false;
  $httpd->default_document = 'index';
  
  status("Entering main server loop - ^C to interrupt, listening on port $port");
  $httpd->serve();
}
catch( Exception $e )
{
  burnout("Exception caught while running webserver:\n$e");
}