<?php

##################################################
##################################################

// START PROCEDURAL BLOCK

##################################################
##################################################

GLOBAL $dbconn, $NETJUKE_SESSION_VARS, $ICONS, $NETJUKE_MODULES, $NETJUKE_THEME_LIST, $NETJUKE_LICENSES;

##################################################

// CHECK THE VERSION OF PHP BEING RUN

if (((int) substr (PHP_VERSION, 0, 1)) <  4 || ((int) substr (PHP_VERSION, 2, 1)) < 1) {
  die ("Fatal error : You must upgrade your installation of PHP from " . PHP_VERSION . " to 4.1.0 or higher.\n");
}

##################################################

// GRAB THE PATH TO NETJUKE
define ('FS_PATH', separatorCleanup (DefineRootPath ()));

// TRY TO ENSURE COMPATABILITY WITH OLDER PHP BUILDS

require_once (FS_PATH . '/lib/inc-legacy.php');


// LOAD OTHER LIBRARIES

require_once (FS_PATH . '/lib/inc-utility.php');
require_once (FS_PATH . '/lib/inc-html.php');

##################################################

// DEFINE IDEAL PATH TO NETJUKE PREFERENCE FILE

define( 'PATH_TO_PREFS', '/etc/inc-prefs.php' );

##################################################

// SETUP THE APPROPRIATE ERROR REPORTING LEVEL

SetErrorLevel ();

##################################################

// DEFINE FS AND WEB PATHS TO NETJUKE ROOT

DefineNetjukePaths();

##################################################

// LOCATE, LOAD AND VERIFY NETJUKE PREFERENCE FILE

$NETJUKE_MODULES = array ();
LoadPrefsFile();

##################################################

// LOAD LANGUAGE PREFERENCE FILE.
// INCLUDE APPROPRIATE LANGUAGE PACK.

LoadLanguagePack();

##################################################

// INITIALIZE GLOBAL DATABASE CONNECTION

$dbconn = InitDbConn();

##################################################

// INITIALIZE GLOBAL RANDOM SEED

srand((double)microtime()*1000000);

##################################################

// PERFORM HOUSEKEEPING

PerformHousekeeping ();

##################################################

// INITIALIZE NETJUKE SESSION

netjuke_session('start');

##################################################

// LOAD THEME CLASS
require_once (FS_PATH . '/lib/inc-theme.php');

##################################################

// DEFINE DEFAULTS

if (! isset($_REQUEST['netjuke_remember'])) $_REQUEST['netjuke_remember'] = 0;

##################################################

// LOGIN IF REQUESTED

if (isset($_REQUEST['netjuke_login'])) {

  netjuke_login($_REQUEST['netjuke_login'],$_REQUEST['netjuke_password'], $_REQUEST['netjuke_remember']);

}  elseif (isset($_REQUEST['netjuke_logout'])) {

  netjuke_session('update');
  netjuke_session('delete', 1);

}  elseif (isset($_REQUEST['netjuke_redir'])) {

  header ("Location: ".WEB_PATH."/index.php?null=".time());

}

##################################################

// PERFORM SECURITY CHECK

SecurityCheck();

##################################################

// CHECK FOR ENVIRONMENT

LoadEnvironment();

##################################################

// define site wide time limit based onsafe mode status

if (ini_get("safe_mode") == 0) {
  define("TIME_LIMIT",43200);
  set_time_limit(TIME_LIMIT);
}

##################################################
##################################################

// START OF FUNCTION BLOCK

##################################################
##################################################

function DefineNetjukePaths() {

  // define filesystem path

  $netjuke_str = '/netjuke|';

  // use two pre-defined variables in case the platform doesn't have one...
  if (isset($_SERVER['PATH_TRANSLATED'])) {
    $path_info = $_SERVER['PATH_TRANSLATED'];
  } else {
    $path_info = $_SERVER['SCRIPT_FILENAME'];
  }

  // translate windows \\ to unix /, and kill potential //
  $path_info = separatorCleanup($path_info);

  $temp_vals = explode('/',$path_info);
  $unused = array_pop($temp_vals); // drop filename
  $path_info = implode('/',$temp_vals);

  // check if netjuke is installed at root (ya never know!)
  if ($path_info == '/') {
     $path_info = ''; // if so - set path to null
  }

  $temp_path_info = strtolower($path_info).'|';

  $pop_cnt = 0;

  if (strstr($temp_path_info, $netjuke_str)) {

    // This works when the directory is still called netjuke.
    // This can potentially speed up the app on some systems.

    $pos = strpos($temp_path_info, $netjuke_str);

    $path_info = substr(  $path_info, 0, $pos + (strlen($netjuke_str) - 1)  );

    unset ( $pos );

  } else {

    // This works when app is installed at root or in dir other than netjuke.

    $temp_vals = explode('/',$path_info);

    if ($temp_vals[count($temp_vals) - 1] == 'admin') {

      $unused = array_pop($temp_vals);

      $pop_cnt++;

    } elseif (!@file_exists($path_info.PATH_TO_PREFS)) {

      while (!@file_exists($path_info.PATH_TO_PREFS)) {

        if ($pop_cnt >= 25) break;  // failsafe in case of infinite loop...

        $unused = array_pop($temp_vals);

        $pop_cnt++;

      }

    }

    $path_info = implode('/',$temp_vals);

  }

  $path_info = separatorCleanup($path_info);

  // ensure the path was correctly detected
  if (! @file_exists ($path_info.PATH_TO_PREFS)) {

     // attempt to detect the path an alternate way
     $path_info = DefineRootPath ();

    }

  #define( 'FS_PATH', $path_info );

  // define web path

  DefineWebPath($pop_cnt);

  unset( $temp_val, $path_info, $temp_path_info, $temp_vals, $unused, $cnt );

}

##################################################

function separatorCleanup($path = '') {

  # translate windows \\ to unix /, kill potential //
  # and trash trailing /

  $proto_sep = '://';

  if (strstr($path,$proto_sep)) list($proto, $path) = split($proto_sep,$path);

  #$path = db_to_raw($path);

  if (strstr($path,"\\")) $path = str_replace("\\","/",$path);

  $path = str_replace("//","/",$path);

  if (isset($proto)) $path = $proto.$proto_sep.$path;

  if (substr($path,-1) == '/') $path = rtrim($path,'/');

  return $path;

}

##################################################

function DefineRootPath () {

    // This is a clever way to have PHP hand us the installed root path of Netjuke
    $path_info = substr (dirname (__FILE__), 0, -4);
    $path_info = separatorCleanup($path_info);

    return ($path_info);

}

##################################################

function DefineWebPath($pop_cnt = 0) {
  global $HTTP_SERVER_VARS;

  $proto = 'http';
  if (isset ($HTTP_SERVER_VARS['HTTPS']) && $HTTP_SERVER_VARS['HTTPS'] == 'on') $proto .= 's';
  $server_info = $proto."://".$_SERVER['HTTP_HOST'];

  // use two pre-defined variables in case the platform doesn't have one...
  if (isset($_SERVER['PHP_SELF'])) {
    $path_info = $_SERVER['PHP_SELF'];
  } else {
    $path_info = $_SERVER['SCRIPT_NAME'];
  }

  $temp_vals = explode('/',$path_info);
  $unused = array_pop($temp_vals); // drop filename

  $cnt = 0;

  while ($cnt < $pop_cnt) {

    $unused = array_pop($temp_vals);

    $cnt++;

  }

  $path_info = implode('/',$temp_vals);

  $path_info = separatorCleanup($path_info);
  define( 'WEB_PATH_FROM_ROOT', $path_info );
  define( 'WEB_PATH', $server_info.WEB_PATH_FROM_ROOT );

}

##################################################

function LoadPrefsFile() {

  $Location = FS_PATH.PATH_TO_PREFS;

  if (!@file_exists($Location)) {

    echo <<<____EOS
      <div style="font-family: sans-serif;">
        <b style="color: #FF0000;">PREFERENCE FILE NOT FOUND IN ${Location}.</b>
        <br><br>
        You probably need to run the <a href="./installer/installer.php">netjuke-installer</a> (or use an existing copy of the generated preference file) to activate this copy.
        <br><br>
        View the provided <a href="./docs/INSTALL.txt" target="_blank">INSTALL.txt</a> file for more info.
        <br><br>
        You can download the netjuke, netjuke-installer, and optional netjuke-toolkit from the following web sites.
        <br><br>
        <li type=square>Preferred Site: <a href="http://netjuke.sourceforge.net/" target="_blank">http://netjuke.sourceforge.net/</a></li>
        <li type=square>Official Site: <a href="http://netjuke.artekopia.org/" target="_blank">http://netjuke.artekopia.org/</a></li>
        <li type=square>Alternate Site: <a href="http://netjuke.tekartists.com/" target="_blank">http://netjuke.tekartists.com/</a></li>
        <br><br>
        Thank you for trying and / or using the Artekopia Netjuke
      </div>
____EOS;

    exit;

  }

  require_once($Location);

  if (headers_sent()) {

    echo <<<____EOS
      <div style="font-family: sans-serif;">
        <b style="color: #FF0000;">PREFERENCE FILE ERROR: HEADER SENT.</b>
        <br><br>
        You must cleanup the generated preference file for the Netjuke to function properly.
        <br><br>
        Just open the file in any text editor, and remove ANYTHING before the top &lt;? and after the bottom ?&gt;.
        <br><br>
        Sorry, but <i>some</i> browsers just don't want to play fair when saving the text file...
        <br><br>
        View the provided <a href="./docs/INSTALL.txt" target="_blank">INSTALL.txt</a> file for more info.
        <br><br>
        Thank you for trying and / or using the Artekopia Netjuke
      </div>
____EOS;

    exit;

  }

}

##################################################

function LoadLanguagePack() {

  global $NETJUKE_SESSION_VARS;

  // Never let anyone leave without a language :)
  if (isset ($NETJUKE_SESSION_VARS['language']))
    $lang = $NETJUKE_SESSION_VARS['language'];
  else
    $lang = LANG_PACK;

  require_once(FS_PATH.'/etc/locale/'.$lang.'/inc-langprefs.php');

  require_once(FS_PATH."/etc/locale/".$lang."/inc-lib_inc-common.php");

}

##################################################

function InitDbConn() {

  GLOBAL $dbconn;

  require_once(FS_PATH."/lib/adodb/adodb.inc.php");
  require_once(FS_PATH."/lib/adodb/adodb-time.inc.php");

  $dbconn = &ADONewConnection(DB_TYPE);

  # define if we can use persistent connections
  # for the selected database type
  switch (strtolower(DB_TYPE)) {
    case "postgres":
      if (ini_get("pgsql.allow_persistent") == 1) $persistent = 1;
      break;
    case "postgres7":
      if (ini_get("pgsql.allow_persistent") == 1) $persistent = 1;
      break;
    case "mysql":
      if (ini_get("mysql.allow_persistent") == 1) $persistent = 1;
      break;
  }

  # connect using PConnect or Connect and print error if any.
  if ($persistent == 1) {
    if ( !$dbconn->PConnect(DB_HOST,DB_USER,obfuscate_undo(DB_PASS),DB_NAME) ) {
      alert( COMMON_ERR_DBCONN . " (\$dbconn->PConnect)" );
    }
  } else {
    if ( !$dbconn->Connect(DB_HOST,DB_USER,obfuscate_undo(DB_PASS),DB_NAME) ) {
      alert( COMMON_ERR_DBCONN . " (\$dbconn->Connect)" );
    }
  }

  return $dbconn;

}

##################################################

function netjuke_session ($do, $force = 0) {

  GLOBAL $dbconn, $NETJUKE_SESSION_VARS;

  // test existence and support for cookies

  if ( isset ($_COOKIE['NETJUKE_SESSION_ID']) &&   (strlen($_COOKIE['NETJUKE_SESSION_ID']) != 32)
       && isset ($_REQUEST['098f6bcd']) && ($_REQUEST['098f6bcd'] != 1) ) {

    if (!@headers_sent()) {

      $real_query_string = array();

      foreach ($_REQUEST as $key => $val) {
        $real_query_string[] = rawurlencode(trim($key)).'='.rawurlencode(trim($val));
      }

      @setcookie ('NETJUKE_SESSION_ID', md5( microtime() . encode_security_key(SECURITY_KEY) ), time() + 60*60*24*365*20);

      @header('Location:'.$_SERVER['PHP_SELF'].'?098f6bcd=1&'.implode('&',$real_query_string));

    }

  }

  if (isset ($_COOKIE['NETJUKE_SESSION_ID']) && strlen($_COOKIE['NETJUKE_SESSION_ID']) == 32) {

    // This works if the user-agent ACCEPTS COOKIES.
    // Most secure and reliable.
    $NETJUKE_SESSION_VARS['session_id'] = $_COOKIE['NETJUKE_SESSION_ID'];

  } else {

    global $HTTP_SERVER_VARS;

    // Generate session id for user-agents REFUSING OR NOT SUPPORTING
    // COOKIES. The challenge is to generate an id that the server can
    // reproduce 99% of the times, but is hard enough to figure out from
    // remote.
    // Less secure or reliable but makes sure that we have a sessions id.
    // This is important with spiders and tools like curl, wget, etc.
    $NETJUKE_SESSION_VARS['session_id'] = md5( SECURITY_KEY
                                             . $_SERVER['REMOTE_ADDR']  // Removed -- this was causing problems with firewalled users
                                             . $HTTP_SERVER_VARS['PATH']
                                             . $_SERVER["HTTP_USER_AGENT"]
                                             . $HTTP_SERVER_VARS['PATH'] );

  }

  switch ($do) {

    case "start":
      netjuke_session('select');
      if (count($NETJUKE_SESSION_VARS) == 1) {
        netjuke_session('insert');
        netjuke_session('select');
      }
      break;

    case "insert":
      $NETJUKE_SESSION_VARS['remote_addr'] = $_SERVER['REMOTE_ADDR'];
      $NETJUKE_SESSION_VARS["gr_id"] = 4; // assumes anonymous @ session start
      $NETJUKE_SESSION_VARS['created'] = adodb_date("Y-m-d H:i:s");
      $NETJUKE_SESSION_VARS['updated'] = adodb_date("Y-m-d H:i:s");
      if (!isset($NETJUKE_SESSION_VARS['email'])) $NETJUKE_SESSION_VARS['email'] = "";

      $cols = $vals = array();
      foreach ($NETJUKE_SESSION_VARS as $key => $value) {
        if ( ($key == 'name') || ($key == 'nickname') ) $value = raw_to_db($value);
        array_push($cols, $key);
        array_push($vals, $value);
      }
      $sql = "insert into netjuke_sessions (".join(",",$cols).") values ('".join("','",$vals)."')";
      $dbconn->Execute($sql);

      UpdateAppearance();
      break;

    case "update":
      $NETJUKE_SESSION_VARS['updated'] = adodb_date("Y-m-d H:i:s");
      $update = array();
      foreach ($NETJUKE_SESSION_VARS as $key => $value) {
        if ( ($key == 'name') || ($key == 'nickname') ) $value = raw_to_db($value);
				if ( $value == "" ) {
					array_push($update, $key." = null");
				} else {
        	array_push($update, $key." = '".$value."'");
				}
      }
      $sql = "update netjuke_sessions set ".join(",",$update)." where session_id = '".$NETJUKE_SESSION_VARS['session_id']."'";
			$dbconn->Execute($sql);
      break;

    case "delete":
      if ($NETJUKE_SESSION_VARS['static'] == 'f' || $force == true) {

      	$sql = "delete from netjuke_sessions where session_id = '".$NETJUKE_SESSION_VARS['session_id']."'";
      	$dbconn->Execute($sql);
      	$NETJUKE_SESSION_VARS = "";
      	@setcookie ('NETJUKE_SESSION_ID', 0, time() - 30);
     	  # purges the netjuke_sessions table of all sessions that are
      	# older than (now - 24hrs), and that have not been handled by
  	    # the above netjuke_session('delete').
      	$dbconn->Execute( " delete from netjuke_sessions where updated < '".adodb_date("Y-m-d H:i:s",(time() - 7200))."' AND static = 'f'" );
    	  header ("Location: ".WEB_PATH."/login.php?netjuke_redir=1\n\n");

      }
      break;

    default:
      $sql = "select * from netjuke_sessions where session_id = '".$NETJUKE_SESSION_VARS['session_id']."'";
      $dbrs = $dbconn->Execute($sql);
      if ($dbrs->RecordCount() == 1) {
        // We found an entry for the session_id string
        $fields = $dbrs->GetRowAssoc();
        foreach ($fields as $name => $value) {
          $NETJUKE_SESSION_VARS[strtolower($name)] = $value;
        }
      } elseif (substr($_SERVER['SCRIPT_FILENAME'],-8) == 'play.php') {
        // We didn't find a matching session_id,
        // but we are dealing with the player.
        $sql = "select session_id from netjuke_sessions where remote_addr = '".$_SERVER['REMOTE_ADDR']."'";
        $dbrs = $dbconn->SelectLimit($sql,1);
        if ($dbrs->RecordCount() > 0) {
          // We found a matching remote address. Could be 2 diff users behind
          // the same firewall, but this is handled in play.php. Avoids
          // having one session_id per track launched when the netjuke is
          // running in "Protect Media" mode.
          $NETJUKE_SESSION_VARS['session_id'] = $dbrs->fields[0];
          $NETJUKE_SESSION_VARS['remote_addr'] = $_SERVER['REMOTE_ADDR'];
        } else {
          $NETJUKE_SESSION_VARS['session_id'] = 0;
        }
      } else {
        // We didn't find a matching session_id.
        // We are NOT dealing with the player.
        $NETJUKE_SESSION_VARS['session_id'] = 0;
      }

  }

  //echo $sql;

}

##################################################

function netjuke_login($login_email,$login_password,$remember) {

  GLOBAL $dbconn, $NETJUKE_SESSION_VARS;

  $dbrs = $dbconn->Execute( " SELECT name, gr_id, nickname "
                           ." FROM netjuke_users "
                           ." WHERE email = '".$login_email."' "
                           ." AND password = '".md5($login_password)."' ");

  if ($dbrs->RecordCount() === 1) {

    if (    (abs(substr(SECURITY_MODE,2,1)) == 2)
         && (abs($dbrs->fields[1]) != 1) ) {

       alert (COMMON_ACCESS_DENIED_1);

       exit;

    } else {

      $NETJUKE_SESSION_VARS["email"]     = $login_email;
      $NETJUKE_SESSION_VARS["name"]      = db_to_raw($dbrs->fields[0]);
      $NETJUKE_SESSION_VARS["gr_id"]     = $dbrs->fields[1];
      $NETJUKE_SESSION_VARS["nickname"]  = db_to_raw($dbrs->fields[2]);

      if ($remember) {

        $NETJUKE_SESSION_VARS['static'] = 't';
      }

      netjuke_session('update');

      $dbconn->Execute("update netjuke_users set last_login = now(), login_cnt = login_cnt + 1 where email = '".$login_email."'");

      if (substr($_SERVER['SCRIPT_NAME'],-9) == 'login.php') {
        header('Location: ./index.php');
      }

    }

  } else {

    alert (COMMON_ACCESS_DENIED_2);

    exit;

  }

  $dbrs->Close();

  UpdateAppearance();
}

##################################################

function SecurityCheck() {

  GLOBAL $NETJUKE_SESSION_VARS;

  switch (abs(substr(SECURITY_MODE,0,1))) {

    case 1:

      if ($NETJUKE_SESSION_VARS["email"] == "") {

        if (    (substr($_SERVER['SCRIPT_NAME'],-9) != 'login.php')
             && (substr($_SERVER['SCRIPT_NAME'],-11) != 'account.php')
             && (substr($_SERVER['SCRIPT_NAME'],-11) != 'inc-css.php')
             && (substr($_SERVER['SCRIPT_NAME'],-15) != 'inc-jscript.php') ) {

          if (    (substr($_SERVER['SCRIPT_NAME'],-8) == 'play.php')
               && ($_REQUEST['do'] == 'dispatch') ) {

             break;

          } else {

             header ("Location: ".WEB_PATH."/login.php");
             exit;

          }

        } elseif (    (abs(substr(SECURITY_MODE,2,1)) > 0)
                   && (substr($_SERVER['SCRIPT_NAME'],-11) == 'account.php')
                   && ($_REQUEST['do'] != 'login') ) {

           header ("Location: ".WEB_PATH."/login.php");
           exit;

        }

      }

      break;

    default:

      if ( (PRIVATE == true) && ($NETJUKE_SESSION_VARS["email"] == "") ) {

           header ("Location: ".WEB_PATH."/login.php");
           exit;

      }

  }

}

##################################################


function UpdateAppearance() {

  GLOBAL $dbconn, $NETJUKE_SESSION_VARS;

  $NETJUKE_SESSION_VARS["inv_icn"]       = INV_ICN;
  $NETJUKE_SESSION_VARS["icon_set"]      = DEFAULT_ICON_SET;
  $NETJUKE_SESSION_VARS["theme"]         = DEFAULT_THEME;

  if (  ($NETJUKE_SESSION_VARS["email"] != "")
      && (USER_THEMES == 't') ) {

    $from = "netjuke_userprefs";
    $where = "us_email = '".$NETJUKE_SESSION_VARS["email"]. "'";

    $dbrs = $dbconn->Execute( " SELECT inv_icn, icon_set, theme"
                             . " FROM ".$from
                             . " WHERE ".$where );

    $NETJUKE_SESSION_VARS["inv_icn"] = $dbrs->fields[0];
    $NETJUKE_SESSION_VARS["icon_set"] = $dbrs->fields[1];
    $NETJUKE_SESSION_VARS["theme"] = $dbrs->fields[2];

  }

  netjuke_session('update');
}

function LoadEnvironment() {
  global $NETJUKE_SESSION_VARS, $ICONS, $NETJUKE_LICENSES;

  if (!isset($NETJUKE_SESSION_VARS["icon_set"]))
    $NETJUKE_SESSION_VARS["icon_set"] = "default";

  if (!isset($NETJUKE_SESSION_VARS["inv_icn"]))
    $NETJUKE_SESSION_VARS["inv_icn"] = "f";

  $ICONS = array( 'play'   => array('x' => 8  , 'y' => 8)
                , 'dload'  => array('x' => 7  , 'y' => 8)
                , 'info'   => array('x' => 8  , 'y' => 8)
                , 'filter' => array('x' => 29 , 'y' => 10)
                , 'image'  => array('x' => 10 , 'y' =>  8)
                , 'artist' => array('x' => 16 , 'y' => 10)
                , 'album'  => array('x' => 16 , 'y' => 10)
                , 'genre'  => array('x' => 16 , 'y' => 10)
                , 'randplay'    => array('x' => 8 , 'y' => 8)
                , 'check'       => array('x' => 7 , 'y' => 7)
                , 'file'        => array('x' => 14 , 'y' => 16)
                , 'dir'         => array('x' => 15 , 'y' => 16)
                , 'edit'   => array('x' => 8, 'y' => 8)
                , 'down-arrow' => array('x' => 17, 'y' => 11)
                , 'up-arrow' => array('x' => 17, 'y' => 11)
                , 'edit' => array('x' => 8, 'y' => 8)
                , 'xml' => array('x' => 36, 'y' => 14) );

  // Allow the icon sets to adjust their sizes
  if ($NETJUKE_SESSION_VARS["icon_set"] != "default") {

    $icon_set = FS_PATH.'/var/html/icons/'.$NETJUKE_SESSION_VARS["icon_set"].'/icon_set.php';
    $code = @file_get_contents ($icon_set);
    if ($code != '') {

        eval ($code);

    }

  }

  foreach ($ICONS as $key => $value) {

    // Fall back to default for icons not in icon_set
    if (file_exists (FS_PATH . '/var/html/icons/'.$NETJUKE_SESSION_VARS["icon_set"].'/icon.' . $key . '.gif')) {

        $set = $NETJUKE_SESSION_VARS["icon_set"];

    } else {

        $set = 'default';

    }

    if ($NETJUKE_SESSION_VARS["inv_icn"] == 't' && file_exists (FS_PATH.'/var/html/icons/'.$set.'/icon.'.$key.'.inv.gif')) {

      $ICONS[$key]['url'] = WEB_PATH.str_replace("//","/",'/var/html/icons/'.$set.'/icon.' . $key . '.inv.gif');

    } else {

      $ICONS[$key]['url'] = WEB_PATH.str_replace("//","/",'/var/html/icons/'.$set.'/icon.' . $key . '.gif');

    }

  }

  // Load the licenses
  require_once (FS_PATH.'/lib/cc_license/cc_license.php');
  $NETJUKE_LICENSES = get_licenses ();

}

?>
