uiconfig.php
author Dan
Fri, 12 Jun 2009 13:50:13 -0400
changeset 78 08f8a72b1f7b
parent 71 8663af0e27c7
permissions -rw-r--r--
Added Offline Mode - automatically turned on and off based on connectivity to server. Version bumped to 0.1a5.

<?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.
 */

// rebooting doesn't work at this point
define('REBOOT_SUPPORT', false);

function greyhound_config($httpd, $socket)
{
  global $use_auth;
  
  // validate the session
  if ( !session_check() )
  {
    $httpd->header('HTTP/1.1 307 Temporary Redirect');
    $httpd->header('Location: /login');
    
    return;
  }
  
  $tried = false;
  $success = false;
  $needpass = false;
  $error = false;
  
  // if a config password is set, make sure it matches.
  $authed = false;
  if ( empty($GLOBALS['configpass']) )
  {
    $authed = true;
  }
  else
  {
    $needpass = true;
    if ( isset($_POST['configpass']) && sha1($_POST['configpass']) === $GLOBALS['configpass'] )
    {
      $authed = true;
      $tried = true;
    }
    else if ( isset($_POST['configpass']) )
    {
      $error = 'You didn\'t enter the right configuration password, so the changes weren\'t saved.';
      $tried = true;
    }
  }
  
  if ( $authed && isset($_POST['submit']) )
  {
    $tried = true;
    $need_reboot = ( isset($_POST['public']) !== $GLOBALS['public'] ||
                     isset($_POST['ipv6']) !== $GLOBALS['enable_ipv6'] ||
                     isset($_POST['allow_fork']) !== $GLOBALS['allow_fork']);
    
    // compile the new config file
    $public = ( isset($_POST['public']) ) ? 'true' : 'false';
    $allowcontrol = ( isset($_POST['allowcontrol']) ) ? 'true' : 'false';
    $allow_fork = ( isset($_POST['allow_fork']) ) ? 'true' : 'false';
    $use_auth = ( isset($_POST['use_auth']) ) ? 'true' : 'false';
    $ipv6_settings = ( isset($_POST['ipv6']) ) ? '$GLOBALS[\'enable_ipv4\'] = false;
$GLOBALS[\'enable_ipv6\'] = true;' : '$GLOBALS[\'enable_ipv4\'] = true;
$GLOBALS[\'enable_ipv6\'] = false;';
    $GLOBALS['enable_ipv6'] = isset($_POST['ipv6']);
    
    // for auth_data, we're going to merge the data from POST with the current auth_data array.
    $auth_data = $GLOBALS['auth_data'];
    $auth_changed = false;
    if ( isset($_POST['users']) )
    {
      foreach ( $auth_data as $user => $pass )
      {
        if ( !in_array($user, $_POST['users']) )
        {
          $auth_changed = true;
          unset($auth_data[$user]);
        }
      }
    }
    else
    {
      if ( !empty($auth_data) )
      {
        $auth_data = array();
        $auth_changed = true;
        $use_auth = false;
      } 
    }
    if ( isset($_POST['users_add']) )
    {
      foreach ( $_POST['users_add'] as $user => $pass )
      {
        $auth_changed = true;
        $auth_data[$user] = $pass;
      }
    }
    $auth_data = var_export_string($auth_data);
    
    $new_configpass = ( isset($_POST['newconfigpass']) && is_string($_POST['newconfigpass']) && $_POST['newconfigpass'] != '____________________' ) ? sha1($_POST['newconfigpass']) : $GLOBALS['configpass'];
    if ( isset($_POST['newconfigpass']) && $_POST['newconfigpass'] === true )
      $new_configpass = '';
    
    $needpass = ( $new_configpass != '' );
    
    $config_file = <<<EOF
<?php

//
// GREYHOUND CONFIGURATION
//

// Listen on all interfaces. If this is false, it will only listen on
// 127.0.0.1 (the loopback interface)
\$GLOBALS['public'] = $public;

// Allow control of playback. By default this is turned on but if you
// set this to false, it will only display the playlist.
\$GLOBALS['allowcontrol'] = $allowcontrol;

// The default theme. This should be a name of a directory in ./themes.
\$GLOBALS['theme'] = 'grey';

// 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.
\$GLOBALS['allow_fork'] = $allow_fork;

// set to true to enable authentication
// this uses cookies, so make sure they're enabled in your browser
\$GLOBALS['use_auth'] = $use_auth;

// valid users and passwords
\$GLOBALS['auth_data'] = $auth_data;

// password for site configuration
\$GLOBALS['configpass'] = '$new_configpass';

// IPv4 and IPv6
$ipv6_settings

EOF;
    $error = 'Couldn\'t write to the config file (./greyhound-config.php).';
    
    $fp = @fopen('./greyhound-config.php', 'w');
    if ( $fp )
    {
      fwrite($fp, $config_file);
      fclose($fp);
      
      $passblurb = $auth_changed ? "\n<small>If you changed your own password, you've been logged out so you'll need to log back in again.</small>" : '';
      if ( REBOOT_SUPPORT )
      {
        $rebootblurb = $need_reboot ? "\n<small>Since you changed some core configuration values, the Greyhound server has been restarted.</small>\n<small>If Greyhound doesn't respond, wait 20 seconds and then restart it using Amarok's script manager.</small>" : '';
      }
      else
      {
        $rebootblurb = $need_reboot ? "\n<small>Please restart Greyhound using Amarok's script manager for public IP, multithreading, and IPv6 options to take effect.</small>" : '';
      }
      $success = "Configuration changes successful.{$passblurb}{$rebootblurb}";
      if ( $httpd->threader->is_child() )
      {
        $httpd->threader->ipc_send(array('action' => 'reloadconfig', 'propagate' => true));
      }
      else
      {
        grey_reload_config();
      }
      
      if ( $need_reboot && REBOOT_SUPPORT )
      {
        if ( $GLOBALS['enable_ipv6'] )
        {
          $addr = isset($_POST['public']) ? '::' : '::1';
        }
        else
        {
          $addr = isset($_POST['public']) ? '0.0.0.0' : '127.0.0.1';
        }
        $fork = isset($_POST['allow_fork']);
        $httpd->reboot($addr, null, $fork);
      }
    }
  }
  
  $message = false;
  
  // Rebuild options
  $pathinfo = @substr(@substr($_SERVER['REQUEST_URI'], 1), @strpos(@substr($_SERVER['REQUEST_URI'], 1), '/')+1);
  switch($pathinfo)
  {
    case 'rebuild/artwork':
      global $amarok_home;
      $artwork_dir = "$amarok_home/albumcovers";
      
      if ( $dp = opendir($artwork_dir) )
      {
        while ( $dh = @readdir($dp) )
        {
          if ( preg_match('/^collage_[0-9]+\.(?:map|png)$/', $dh) )
          {
            unlink("$artwork_dir/$dh");
          }
        }
        closedir($dp);
      }
      
      $message = 'Successfully cleared album art cache';
      break;
    case 'rebuild/playlist':
      rebuild_playlist(true);
      $message = 'Successfully rebuilt playlist cache';
      break;
  }
  
  global $theme;
  $iphone = ( ( strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone') ||
       strpos($_SERVER['HTTP_USER_AGENT'], 'iPod') ||
       strpos($_SERVER['HTTP_USER_AGENT'], 'BlackBerry') ||
       isset($_GET['m']) )
       && !isset($_GET['f'])
       );
  $theme_id = ( $iphone ) ? 'iphone' : $theme;
  
  $smarty = load_theme($theme_id);
  $smarty->assign('theme', $theme_id);
  $smarty->assign('greyhound_version', GREY_VERSION);
  $smarty->assign('tried', $tried);
  $smarty->assign('success', $success);
  $smarty->assign('message', $message);
  $smarty->assign('needpass', $needpass);
  $smarty->assign('use_auth', $use_auth);
  $smarty->assign('public', $GLOBALS['public']);
  $smarty->assign('ipv6', $GLOBALS['enable_ipv6']);
  $smarty->assign('allowcontrol', $GLOBALS['allowcontrol']);
  $smarty->assign('allow_fork', $GLOBALS['allow_fork']);
  $smarty->assign('use_auth', $GLOBALS['use_auth']);
  $smarty->assign('users', $GLOBALS['auth_data']);
  $smarty->assign('reboot_support', REBOOT_SUPPORT);
  $smarty->assign('error', $error);
  $smarty->display('config.tpl');
}