Hi Bob,
I went ahead and made a few quick changes so that when you search, the search 
results will display the file licenses.   I'll release a cleaned up version of 
this in v 2.0 but if you want to test it out I've attached the three modified 
files.  These go in directory WEBDIR.  To see the real WEBDIR path, login to 
fossology with admin privileges (user fossy is the default) then on the main 
menu choose Help > Debug > Global Variables.  It is probably 
/usr/share/fossology/www. 

Put the common- files in the "common" directory, and search.php in the 
"plugins" directory.  These will replace existing files so you might want to 
move the old versions into another directory in case these not well tested 
changes have bugs.  You need to move the old files out, not just rename them 
because otherwise you will get name collisions.

Bob Gobeille

<?php
/***********************************************************
 Copyright (C) 2008 Hewlett-Packard Development Company, L.P.

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.

 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 more details.

 You should have received a copy of the GNU General Public License along
 with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ***********************************************************/

/************************************************************
 These are common functions used by analysis agents.
 Analysis Agents should register themselves in the menu structure under the
 top-level "Agents" menu.

 Every analysis agent should have a function called "AgentAdd()" that takes
 an Upload_pk and an optional array of dependent agents ids.

 Every analysis agent should also have a function called "AgentCheck($uploadpk)"
 that determines if the agent has already been scheduled.
 This function should return:
 0 = not scheduled
 1 = scheduled
 2 = completed
 ************************************************************/
/*
 * NOTE: neal says the name is wrong...should be Analysis...
 * TODo: change the name and all users of it.
 */

/**
 AgentCheckBoxMake
 \brief Generate a checkbox list of available agents.

 Only agents that are not already scheduled are added. If
 $upload_pk == -1, then list all.  User agent preferences will be
 checked as long as the agent is not already scheduled.

 @return string containing HTML-formatted checkbox list
 */
function AgentCheckBoxMake($upload_pk,$SkipAgent=NULL) {

  global $Plugins;
  global $DB;

  $AgentList = menu_find("Agents",$Depth);
  $V = "";

  if (!empty($AgentList)) {
    // get user agent preferences
    $userName = $_SESSION['User'];
    $SQL = "SELECT user_name, user_agent_list FROM users WHERE
				    user_name='$userName';";
    $uList = $DB->Action($SQL);

    // Ulist should never be empty, if it is, something really wrong,
    // like the user_agent_list column is missing.
    if(empty($uList))
    {
      $text = _("Fatal! Query Failed getting user_agent_list for user");
      return("<h3 style='color:red'>$text $UserName</h3>");
    }
    $list = explode(',',$uList[0]['user_agent_list']);

    foreach($AgentList as $AgentItem) {
      $Agent = &$Plugins[plugin_find_id($AgentItem->URI)];
      if (empty($Agent)) {
        continue;
      }
      if ($Agent->Name == $SkipAgent) {
        continue;
      }
      if ($upload_pk != -1) {
        $rc = $Agent->AgentCheck($upload_pk);
      }
      else {
        $rc = 0;
      }
      if ($rc == 0) {
        $Name = htmlentities($Agent->Name);
        $Desc = htmlentities($AgentItem->Name);

        // display user agent preferences

        if(in_array($Name, $list))
        {
          $Selected = " checked ";
        }
        else
        {
          $Selected = "";
        }
        $V .= "<input type='checkbox' name='Check_$Name' value='1' $Selected />$Desc<br />\n";
      }
    }
  }
  return($V);
} // AgentCheckBoxMake()

/************************************************************
 AgentCheckBoxDo(): Assume someone called AgentCheckBoxMake() and
 submitted the HTML form.  Run AgentAdd() for each of the checked agents.
 Because input comes from the user, validate that everything is
 legitimate.
 ************************************************************/
function AgentCheckBoxDo($upload_pk)
{
  global $Plugins;
  $AgentList = menu_find("Agents",$Depth);
  $V = "";
  if (!empty($AgentList)) {
    foreach($AgentList as $AgentItem) {
      /*
       The URI below contains the agent name e.g agent_license, this is
       not be confused with the Name attribute in the class, for example,
       the Name attribute for agent_license is: Schedule License Analysis
       */
      $Agent = &$Plugins[plugin_find_id($AgentItem->URI)];
      if (empty($Agent)) {
        continue;
      }
      $rc = $Agent->AgentCheck($upload_pk);
      $Name = htmlentities($Agent->Name);
      $Parm = GetParm("Check_" . $Name,PARM_INTEGER);
      if (($rc == 0) && ($Parm == 1)) {
        $Agent->AgentAdd($upload_pk);
      }
    }
  }
  return($V);
} // AgentCheckBoxDo()

/**
 * bucketPools
 * \brief make a checkbox list of bucket pools.  Only 1 box can be selected
 *
 * @return string $html html formatted checkboxes
 */
function bucketPools()
{

  /*
   * need a way to determine a bucket agent from other agents.....
   */
  global $DB;

  $html = "";
  $SQL = "SELECT bucketpool_pk, bucketpool_name FROM bucketpool" .
	        " ORDER BY bucketpool_pk;";
  $pools = $DB->Action($SQL);
  DBCheckResult($pools, $SQL, __FILE__, __LINE__);


  return(TRUE);
}

/**
 * CheckEnotification
 *
 * Check if email notification is on for this user
 *
 * @return boolean, true or false.
 */

function CheckEnotification() {
  if(array_key_exists('UserEnote', $_SESSION))
  {
    if ($_SESSION['UserEnote'] == 'y')
    {
      return(TRUE);
    }
    else
    {
      return(FALSE);
    }
  }
  return(FALSE);
}

/**
 * FindDependent
 *
 * find the jobs in the job and jobqueue table to be dependent on
 *
 * @param int $UploadPk the upload PK
 * @param array $list an optional array of jobs to use instead of all jobs
 *        associated with the upload
 * @return array $depends, array of dependencies
 */
function FindDependent($UploadPk, $list=NULL) {
  /*
   * Find the jobs that fo_notify should depend on. fo_notify is
   * dependent on the following agents:
   *   copyright
   *   nomos
   *   package
   *   bucket
   *
   *   Determine if the above agents are scheduled and create a list of
   *   jq_pk for each agent.
   *
   */
  global $DB;

  $Depends = array();
  /* get job list for this upload */

  // get the list of jobs for this upload
  $Sql = "SELECT job_upload_fk, job_pk, job_name FROM job WHERE " .
  "job_upload_fk = $UploadPk order by job_pk desc;";
  $Jobs = $DB->Action($Sql);

  $jobList = array();
  foreach($Jobs as $Row) {
    if($Row['job_name'] == 'Copyright Analysis') {
      $jobList[] = $Row['job_pk'];
    }
    elseif($Row['job_name'] == 'Bucket Analysis')
    {
      $jobList[] = $Row['job_pk'];
    }
    elseif($Row['job_name'] == 'Package Agents')
    {
      $jobList[] = $Row['job_pk'];
    }
    elseif($Row['job_name'] == 'Nomos License Analysis')
    {
      $jobList[] = $Row['job_pk'];
    }
  }

  // get the jq_pk's for each job, retrun the list of jq_pk's
  foreach($jobList as $job)
  {
    $Sql = "SELECT jq_pk, jq_job_fk FROM jobqueue WHERE jq_job_fk = $job " .
					 " order by jq_pk desc;";
    $Q = $DB->Action($Sql);
    $Depends[] = $Q[0]['jq_pk'];
  }
  return($Depends);
} // FindDependent

/**
 * GetAgentKey
 * \brief, get the agent_pk for a given agent,
 *  This needs to match the C version of same function in libfossagent
 *
 * @param string $agentName the name of the agent e.g. nomos
 * @param string agentDesc the agent_desc colunm
 *
 * @return -1 or agent_pk
 */

function GetAgentKey($agentName, $agentDesc)
{
  global $PG_CONN;

  /* get the exact agent rec requested */
  $sqlselect = "SELECT agent_pk FROM agent WHERE agent_name ='$agentName' order by agent_ts desc limit 1";
  $result = pg_query($PG_CONN, $sqlselect);
  DBCheckResult($result, $sqlselect, __FILE__, __LINE__);

  if (pg_num_rows($result) == 0)
  {
    /* no match, so add an agent rec */
    $sql = "INSERT INTO agent (agent_name,agent_desc,agent_enabled) VALUES ('$agentName',E'$agentDesc',1)";
    $result = pg_query($PG_CONN, $sqlselect);
    DBCheckResult($result, $sql, __FILE__, __LINE__);

    /* get inserted agent_pk */
    $result = pg_query($PG_CONN, $sqlselect);
    DBCheckResult($result, $sqlselect, __FILE__, __LINE__);
  }

  $row = pg_fetch_assoc($result);
  return $row["agent_pk"];

} // GetAgentKey

/**
 * AgentARSList
 * \brief
 *  The purpose of this function is to return an array of
 *  _ars records for an agent so that the latest agent_pk(s)
 *  can be determined.
 *
 *  This is for _ars tables only, for example, nomos_ars and bucket_ars.
 *  The _ars tables have a standard format but the specific agent ars table
 *  may have additional fields.
 *
 * @param string  $TableName - name of the ars table (e.g. nomos_ars)
 * @param int     $upload_pk
 * @param int     $limit - limit number of rows returned.  0=No limit
 * @param int     $agent_fk - ARS table agent_fk, optional
 * @param string  $ExtraWhere - Optional, added to where clause.
 *                   eg: "and bucketpool_fk=2"
 *
 * @return assoc array of _ars records.
 *         or FALSE on error, or no rows
 */
function AgentARSList($TableName, $upload_pk, $limit, $agent_fk=0, $ExtraWhere="")
{
  global $DB, $PG_CONN;
  if (!$PG_CONN) { $dbok = $DB->db_init(); if (!$dbok) echo "NO DB connection"; }

  $LimitClause = "";
  if ($limit > 0) $LimitClause = " limit $limit";
  if ($agent_fk)
  $agentCond = " and agent_fk='$agent_fk' ";
  else
  $agentCond = "";

  $sql = "SELECT * FROM $TableName, agent
           WHERE agent_pk=agent_fk and ars_success=true and upload_fk='$upload_pk' and agent_enabled=true
           $agentCond $ExtraWhere
           order by agent_ts desc $LimitClause";
  $result = pg_query($PG_CONN, $sql);
  DBCheckResult($result, $sql, __FILE__, __LINE__);
  $resultArray =  pg_fetch_all($result);
  pg_free_result($result);
  return $resultArray;
}


/**
 * AgentSelect
 * \brief
 *  The purpose of this function is to return a pulldown select list for users
 *  to be able to select the dataset results they want to see.
 *
 *  This is for _ars tables only, for example, nomos_ars and bucket_ars.
 *  The _ars tables have a standard format with optional agent_fk's named
 *  agent_fk2, agent_fk3, ...
 *
 * @param string  $TableName - name of the ars table (e.g. nomos_ars)
 * @param int     $upload_pk
 * @param boolean $DataOnly  - If false, return the latest agent AND agent revs
 *                             that have data for this agent.  Note the latest agent may have
 *                             no entries in $TableName.
 *                             If true (default), return only the agent_revs with ars data.
 * @param string  $SLName    - select list element name
 * @param string  $SLID      - select list element id
 * @param string  *SelectedKey - selected key (optional)
 *                              If absent and $DataOnly is true
 *                              then the latest agent with results is selected.
 *                              If absent and $DataOnly is false
 *                              then the latest agent is selected.
 *
 * @return agent select list
 *      or 0 on error
 */
function AgentSelect($TableName, $upload_pk, $DataOnly=true,
$SLName, $SLID, $SelectedKey="")
{
  echo "DO NOT USE: PRELIMINARY AND INCOMPLETE<br>";
  /*
   / get the agent recs /
   $sql = "SELECT * FROM $TableName, agent
   WHERE upload_fk='$upload_pk' and agent_enabled=true order by agent_ts desc";
   $result = pg_query($PG_CONN, $sql);
   DBCheckResult($result, $sql, __FILE__, __LINE__);

   / Create an assoc array to build the select list from.
   * "{agent_pk} [,{agent_pk} ...] => {agent name} ( {agentrevision} ), ... [ NO DATA]
   * For example:
   *   123 => nomos(rev 1)
   *   111,123 => bucket(rev 5), nomos(rev 7)
   *   112,179 => bucket(latest rev), nomos(latest rev) NO DATA
   or one could just use the ars_pk instead of the pk list, but that is another
   indirection.
   /
   while ($row = pg_fetch_assoc($result))
   {
   }
   $AgentList = GetAgentDataList($AgentName, $upload_pk, $tablename);
   $SelArray = array();

   if ($SelectedKey == "") $SelectedKey = $AgentList[0]['agent_pk'];

   / create key/val array for pulldown /
   foreach($AgentList as $AgentRec)
   {
   $DataInd = ($AgentRec['data']) ? "" : ", NO DATA";
   $SelArray[$AgentRec['agent_pk']] = "$AgentRec[agent_name] rev: $AgentRec[agent_rev]$DataInd";
   }
   return "Results from:" . Array2SingleSelect($SelArray, $SLName, $SelectedKey, false, false);
   */
}

/**
 * Largestjq_pk
 *
 * Find the largest jq_pk for the job or jobs.
 *
 * For a single job, returns the largest jobqueue_pk (jq_pk).  For multiple
 * jobs, returns the largest jq_pk of the set.
 *
 * @param $Jobs, either an int or an array of int's.
 * @return int $largest the largest jq_pk
 *
 */
function Largestjq_pk($Jobs) {

  global $DB;

  if (is_array($Jobs)) {
    $largest = 0;
    foreach ($Jobs as $job) {
      $Sql = "SELECT jq_pk, jq_job_fk FROM jobqueue WHERE " .
             "jq_job_fk = $job order by jq_pk desc limit 1;";
      $JobQueue = $DB->Action($Sql);
      if ($largest < $JobQueue[0]['jq_pk']) {
        $largest = $JobQueue[0]['jq_pk'];
      }
    }
    return($largest);
  }
  else {
    $Sql = "SELECT jq_pk, jq_job_fk FROM jobqueue WHERE " .
           "jq_job_fk = $Jobs order by jq_pk desc limit 1;";
    $JobQueue = $DB->Action($Sql);
    return($JobQueue[0]['jq_pk']);
  }
}
/**
 * MostRows
 *
 * Find the largest jq_pk for the job that has the most rows
 *
 * This routine is used to determine who the caller should be dependent on based
 * on the number of jobqueue items for the list of jobs supplied.  The job with
 * the largest number of jobqueue items, largest jq_pk is returned.
 *
 * @param $Jobs, an array of int's representing job_pk items
 * @return int $largest the largest jq_pk with the most rows
 *
 */
function MostRows($Jobs) {

  global $DB;

  if (is_array($Jobs)) {
    $rows = 0;
    $MostRows = 0;
    $largest = 0;
    foreach ($Jobs as $job) {
      $Sql = "SELECT jq_pk, jq_job_fk FROM jobqueue WHERE " .
             "jq_job_fk = $job order by jq_pk desc;";
      $JobQueue = $DB->Action($Sql);
      $rows = count($JobQueue);
      if ($MostRows < $rows) {
        $MostRows = $rows;
        $largest = $JobQueue[0]['jq_pk'];
      }
    }
    //print "  MR: MostRows is:$MostRows\n<br>Largest Jq:$largest\n<br>";
    return($largest);
  }
}
/**
 * ScheduleEmailNotification
 *
 * Schedule email notification for analysis results
 *
 * ScheduleEmailNotification determines the proper job dependency and schedules
 * the email agent notify to send the message.
 *
 * This routine is called from a number of UI plugins and cp2foss.  The optional
 * parameters are to accomdate the UI upload_srv_files and the agent_ add
 * plugins.
 *
 * This routine should only be called if the user wants to be notified by email
 * of analysis results. See CheckEnotification().
 *
 * @param int $upload_pk the upload_pk of the upload
 * @param string $Email, an optional email address to pass on to fo-notify.
 * @param string $UserName, an optional User name to pass on to fo-notify.
 * @param array, $Depends array of jq_pk's that fo_notify will be dependent on
 * can be empty (no dependencies).
 *
 * @return NULL on success, string on failure.
 */

function scheduleEmailNotification($upload_pk,$webServer,$Email=NULL,
$UserName=NULL,$Depends) {

  global $DB;
  $SysConf = array();

  if (empty($DB)) {
    return;
  }

  if (empty($upload_pk)) {
    $text = _("Invalid parameter (upload_pk)");
    return ($text);
  }

  // should we die if webServer is empty?  For now just make a stab at it.
  if(empty($webServer))
  {
    $webServer = $_SERVER['SERVER_NAME'];
  }

  /* set up input for fo-notify */
  $Nparams = '';
  $To = NULL;
  
  if (empty($webServer)) $webServer = "localhost"; /* -w web-server, it is required, but deprecated */ 
  $Nparams .= "-w $webServer ";
  /* FOSSology_URL, e.g. fossolog.org/repo/ */
  /* Initialize global system configuration variables $SysConfig[] */
  $SysConf = ConfigInit();
  $FOSSology_URL = @$SysConf["FOSSologyURL"];
  $Nparams .= "-p $FOSSology_URL ";
  /* If email is passed in, favor that over the session */
  if(!empty($Email)) {
    $To = " -e $Email";
  }
  elseif (!empty($_SESSION['UserEmail'])) {
    $To = " -e {$_SESSION['UserEmail']}";
    //print "  SEN: Setting To to Email in session To:$To\n";
  }
  if(empty($To)) {
    $text = _("FATAL: Email Notification: no email address supplied, cannot send mail, common-agents::scheduleEmailNotification Your job should be scheduled, you will not get email notifying you it is done");
    return($text);
  }
  $Nparams .= "$To";
  /* Upload Pk */
  $upload_id = trim($upload_pk);
  $UploadId = "-u $upload_id";
  $Nparams .= " $UploadId";
  /*
   * UserName is NOT the email address it's the description for the user field
   * in the Add A User screen..... need to fix that screen....
   */
  if (!empty($UserName)) {
    $Nparams .= " -n $UserName";
  }

  /* Prepare the job: job "fo-notify" */
  $jobpk = JobAddJob($upload_pk,"fo_notify",-1);
  if (empty($jobpk) || ($jobpk < 0)) {
    $text = _("Failed to insert job record, job fo_notify not created");
    return($text);
  }

  /* Prepare the job: job fo-notify has jobqueue item fo-notify */
  $jobqueuepk = JobQueueAdd($jobpk,"fo_notify","$Nparams","no",NULL,
  $Depends,TRUE);
  if (empty($jobqueuepk)) {
    $text = _("Failed to insert task 'fo_notify' into job queue");
    return($text);
  }

  return(NULL);
}

/**
 * userAgents
 * \brief read the UI form and format the user selected agents into a
 * comma separated list
 *
 * @return string $agentsChecked
 *
 */

function userAgents()
{
  global $Plugins;
  global $DB;

  $agentsChecked = "";

  $AgentList = menu_find("Agents",$Depth);
  if (!empty($AgentList)) {
    foreach($AgentList as $AgentItem) {
      /*
       The URI below contains the agent name e.g agent_license, this is
       not be confused with the Name attribute in the class, for example,
       the Name attribute for agent_license is: Schedule License Analysis
       */
      $Agent = &$Plugins[plugin_find_id($AgentItem->URI)];
      if (empty($Agent)) {
        continue;
      }
      $Name = htmlentities($Agent->Name);
      $Parm = GetParm("Check_" . $Name,PARM_INTEGER);
      if ($Parm == 1) {
        // save the name
        $agentsChecked .= $Name . ',';
      }
    }
    // remove , from last name
    $agentsChecked = trim($agentsChecked, ',');
  }
  return($agentsChecked);
}

function userDefaultAgents($upload_pk)
{
  global $Plugins;
  global $DB;

  //echo "<pre>UDA: upload pk is:$upload_pk\n</pre>";
  if(empty($upload_pk))
  {
    return;
  }

  /*
   * foreach agent in the list
   *   agentCheck on the upload_pk
   *    if OK: AgentAdd
   */
  // get the default agents selected by the user
  $userName = $_SESSION['User'];
  $SQL = "SELECT user_name, user_agent_list FROM users WHERE
            user_name='$userName';";
  $uList = $DB->Action($SQL);

  // Ulist can be empty if the user does not have the correct permissions
  // or has not selected any default/preferred agents or sql failed.
  if(empty($uList))
  {
    return;       // nothing to schedule or sql failed....

  }
  $agentList = explode(',',$uList[0]['user_agent_list']);

  foreach($agentList as $agent)
  {
    $agentRef = &$Plugins[plugin_find_id($agent)];
    if (empty($agentRef))
    {
      continue;
    }
    $rc = $agentRef->AgentCheck($upload_pk);
    if ($rc == 0)
    {
      $agentRef->AgentAdd($upload_pk);
    }
  }
  return;
} // userDefaultAgents
?>
<?php
/***********************************************************
 Copyright (C) 2008-2011 Hewlett-Packard Development Company, L.P.

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.

 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 more details.

 You should have received a copy of the GNU General Public License along
 with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
***********************************************************/

function Isdir($mode) { return(($mode & 1<<18) + ($mode & 0040000) != 0); }
function Isartifact($mode) { return(($mode & 1<<28) != 0); }
function Iscontainer($mode) { return(($mode & 1<<29) != 0); }

/************************************************
 Bytes2Human(): Convert a number of bytes into
 a human-readable format.
 ************************************************/
function Bytes2Human  ($Bytes)
{
  if ($Bytes < 1024) { return($Bytes); }
  $Bytes = $Bytes / 1024;
  $Bint = intval($Bytes * 100.0) / 100.0;
  if ($Bytes < 1024) { return("$Bint KB"); }
  $Bytes = $Bytes / 1024;
  $Bint = intval($Bytes * 100.0) / 100.0;
  if ($Bytes < 1024) { return("$Bint MB"); }
  $Bytes = $Bytes / 1024;
  $Bint = intval($Bytes * 100.0) / 100.0;
  if ($Bytes < 1024) { return("$Bint GB"); }
  $Bytes = $Bytes / 1024;
  $Bint = intval($Bytes * 100.0) / 100.0;
  if ($Bytes < 1024) { return("$Bint TB"); }
  $Bytes = $Bytes / 1024;
  $Bint = intval($Bytes * 100.0) / 100.0;
  return("$Bint PB");
} // Bytes2Human()

/************************************************************
 DirMode2String(): Convert a mode to string values.
 ************************************************************/
function DirMode2String($Mode)
{
  $V="";
  if (Isartifact($Mode)) { $V .= "a"; } else { $V .= "-"; }
  if (($Mode & 0120000) == 0120000) { $V .= "l"; } else { $V .= "-"; }
  if (Isdir($Mode)) { $V .= "d"; } else { $V .= "-"; }

  if ($Mode & 0000400) { $V .= "r"; } else { $V .= "-"; }
  if ($Mode & 0000200) { $V .= "w"; } else { $V .= "-"; }
  if ($Mode & 0000100)
    {
    if ($Mode & 0004000) { $V .= "s"; } /* setuid */
    else { $V .= "x"; }
    }
  else
    {
    if ($Mode & 0004000) { $V .= "S"; } /* setuid */
    else { $V .= "-"; }
    }

  if ($Mode & 0000040) { $V .= "r"; } else { $V .= "-"; }
  if ($Mode & 0000020) { $V .= "w"; } else { $V .= "-"; }
  if ($Mode & 0000010)
    {
    if ($Mode & 0002000) { $V .= "s"; } /* setgid */
    else { $V .= "x"; }
    }
  else
    {
    if ($Mode & 0002000) { $V .= "S"; } /* setgid */
    else { $V .= "-"; }
    }

  if ($Mode & 0000004) { $V .= "r"; } else { $V .= "-"; }
  if ($Mode & 0000002) { $V .= "w"; } else { $V .= "-"; }
  if ($Mode & 0000001)
    {
    if ($Mode & 0001000) { $V .= "t"; } /* sticky bit */
    else { $V .= "x"; }
    }
  else
    {
    if ($Mode & 0001000) { $V .= "T"; } /* setgid */
    else { $V .= "-"; }
    }

  return($V);
} // DirMode2String()

/************************************************************
 DirGetNonArtifact(): Given an artifact directory (uploadtree_pk),
 return the first non-artifact directory (uploadtree_pk).
 TBD: "username" will be added in the future and it may change
 how this function works.
 NOTE: This is recursive!
 ************************************************************/
$DirGetNonArtifact_Prepared=0;
function DirGetNonArtifact($UploadtreePk)
{
  global $Plugins;
  global $DB;
  if (empty($DB)) { return; }

  /* Get contents of this directory */
  global $DirGetNonArtifact_Prepared;
  if (!$DirGetNonArtifact_Prepared)
    {
    $DirGetNonArtifact_Prepared=1;
    $DB->Prepare("DirGetNonArtifact",'SELECT * FROM uploadtree LEFT JOIN pfile ON pfile_pk = pfile_fk WHERE parent = $1;'); 
    }
  $Children = $DB->Execute("DirGetNonArtifact",array($UploadtreePk));
  $Recurse=NULL;
  foreach($Children as $C)
    {
    if (empty($C['ufile_mode'])) { continue; }
    if (!Isartifact($C['ufile_mode']))
      {
      return($UploadtreePk);
      }
    if (($C['ufile_name'] == 'artifact.dir') ||
        ($C['ufile_name'] == 'artifact.unpacked'))
      {
      $Recurse = DirGetNonArtifact($C['uploadtree_pk']);
      }
    }
  if (!empty($Recurse))
    {
    return(DirGetNonArtifact($Recurse));
    }
  return($UploadtreePk);
} // DirGetNonArtifact()


/************************************************************
 _DirCmp(): Compare function for usort() on directory items.
 ************************************************************/
function _DirCmp($a,$b)
{
  return(strcasecmp($a['ufile_name'],$b['ufile_name']));
} // _DirCmp()

/************************************************************
 DirGetList(): Given a directory (uploadtree_pk),
 return the directory contents but resolve artifacts.
 TBD: "username" will be added in the future and it may change
 how this function works.
 Returns array of uploadtree records sorted by file name
 ************************************************************/
$DirGetList_Prepared=0;
function DirGetList($Upload,$UploadtreePk)
{ 
  global $Plugins;
  global $DB;
  if (empty($DB)) { return; }
    
  /* Get the basic directory contents */
  global $DirGetList_Prepared;
  if (!$DirGetList_Prepared) 
  {   
    $DirGetList_Prepared=1;
    $DB->Prepare("DirGetList_1",'SELECT * FROM uploadtree LEFT JOIN pfile ON pfile.pfile_pk = uploadtree.pfile_fk WHERE upload_fk = $1 AND uploadtree.parent IS NULL ORDER BY ufile_name ASC;');
    $DB->Prepare("DirGetList_2",'SELECT * FROM uploadtree LEFT JOIN pfile ON pfile.pfile_pk = uploadtree.pfile_fk WHERE upload_fk = $1 AND uploadtree.parent = $2 ORDER BY ufile_name ASC;');

  }
  if (empty($UploadtreePk)) 
  { 
    $Results=$DB->Execute("DirGetList_1",array($Upload)); 
  }
  else 
  { 
    $Results=$DB->Execute("DirGetList_2",array($Upload,$UploadtreePk)); 
  }
  usort($Results,'_DirCmp');

  /* Replace all artifact directories */
  foreach($Results as $Key => $Val)
  {
    /* if artifact and directory */
    $R = &$Results[$Key];
    if (Isartifact($R['ufile_mode']) && Iscontainer($R['ufile_mode']))
    {
      $R['uploadtree_pk'] = DirGetNonArtifact($R['uploadtree_pk']);
    }
  }
  return($Results);
} // DirGetList()


/************************************************************
 Dir2Path(): given an uploadtree_pk, return an array containing
 the path (with no artifacts).  Each element in the path is an array containing
 uploadtree records for $UploadtreePk and its parents.
 The path begins with the UploadtreePk record.
 ************************************************************/
function Dir2Path($UploadtreePk)
{
  global $Plugins;
  global $PG_CONN;

  if ((empty($UploadtreePk))) { return array(); }

  $sql = "SELECT * from uploadtree2path($UploadtreePk) ORDER BY lft ASC";
  $result = pg_query($PG_CONN, $sql);
  DBCheckResult($result, $sql, __FILE__, __LINE__);
  $Rows = pg_fetch_all($result);
  pg_free_result($result);

  return($Rows);
} // Dir2Path()

/************************************************************
 Dir2Browse(): given an uploadtree_pk, return a
 string listing the browse paths.
  $Mod - Module name (e.g. "browse")
  $UploadtreePk
  $LinkLast - create link (a href) for last item and use LinkLast as the module name
  $ShowMicro - show micro menu
  $Enumerate - if >= zero number the folder/file path (the stuff in the yellow bar)
    starting with the value $Enumerate 
  $PreText - additional text to preceed the folder path
  $PostText - text to follow the folder path
 ************************************************************/
function Dir2Browse ($Mod, $UploadtreePk, $LinkLast=NULL,
		     $ShowBox=1, $ShowMicro=NULL, $Enumerate=-1, $PreText='', $PostText='')
{
  global $Plugins;
  global $DB;

  $V = "";
  if ($ShowBox)
  {
    $V .= "<div style='border: thin dotted gray; background-color:lightyellow'>\n";
  }

  if ($Enumerate >= 0)
  {
    $V .= "<table border=0 width='100%'><tr><td width='5%'>";
    $V .= "<font size='+2'>" . number_format($Enumerate,0,"",",") . ":</font>";
    $V .= "</td><td>";
  }

  $Opt = Traceback_parm_keep(array("folder","show"));
  $Uri = Traceback_uri() . "?mod=$Mod";

  /* Get array of upload recs for this path, in top down order.
     This does not contain artifacts.
   */
  $Path = Dir2Path($UploadtreePk);
  $Last = &$Path[count($Path)-1];

  $V .= "<font class='text'>\n";

  /* Add in additional text */
  if (!empty($PreText)) { $V .= "$PreText<br>\n"; }

  /* Get the FOLDER list for the upload */
  $text = _("Folder");
  $V .= "<b>$text</b>: ";
  if (array_key_exists(0, $Path))
  {
    $List = FolderGetFromUpload($Path[0]['upload_fk']);
    $Uri2 = Traceback_uri() . "?mod=browse" . Traceback_parm_keep(array("show"));
    for($i=0; $i < count($List); $i++)
    {
      $Folder = $List[$i]['folder_pk'];
      $FolderName = htmlentities($List[$i]['folder_name']);
      $V .= "<b><a href='$Uri2&folder=$Folder'>$FolderName</a></b>/ ";
    }
  }

  $FirstPath=1; /* every firstpath belongs on a new line */

  /* Print the upload, itself (on the next line since it is not a folder) */
  if (count($Path) == -1)
    {
    $Upload = $Path[0]['upload_fk'];
    $UploadName = htmlentities($Path[0]['ufile_name']);
    $UploadtreePk =  $Path[0]['uploadtree_pk'];
    $V .= "<br><b><a href='$Uri2&folder=$Folder&upload=$Upload&item=$UploadtreePk'>$UploadName</a></b>";
    // $FirstPath=0;
    }
  else
    $V .= "<br>";
  
  /* Show the path within the upload */
  if ($FirstPath!=0)
    {
    for($p=0; !empty($Path[$p]['uploadtree_pk']); $p++)
      {
      $P = &$Path[$p];
      if (empty($P['ufile_name'])) { continue; }
      $UploadtreePk = $P['uploadtree_pk'];

      if (!$FirstPath) { $V .= "/ "; }
      if (!empty($LinkLast) || ($P != $Last))
	{
        if ($P == $Last)
	  {
	    $Uri = Traceback_uri() . "?mod=$LinkLast";
	  }
	$V .= "<a href='$Uri&upload=" . $P['upload_fk'] . $Opt . "&item=" . $UploadtreePk . "'>";
	}

      if (Isdir($P['ufile_mode']))
	{
        $V .= $P['ufile_name'];
	}
      else
	{
        if (!$FirstPath && Iscontainer($P['ufile_mode']))
	  {
	    $V .= "<br>\n&nbsp;&nbsp;";
	  }
	$V .= "<b>" . $P['ufile_name'] . "</b>";
	}

      if (!empty($LinkLast) || ($P != $Last))
	{
	  $V .= "</a>";
	}
      $FirstPath = 0;
      }
    }
  $V .= "</font>\n";

  if (!empty($ShowMicro))
    {
    $MenuDepth = 0; /* unused: depth of micro menu */
    $V .= menu_to_1html(menu_find($ShowMicro,$MenuDepth),1);
    }


  if ($Enumerate >= 0)
  {
    if ($PostText) $V .= "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$PostText";
    $V .= "</td></tr></table>";
  }

  if ($ShowBox)
    {
    $V .= "</div>\n";
    }
  return($V);
} // Dir2Browse()

/************************************************************
 Dir2BrowseUpload(): given an upload_pk, return a string listing
 the browse paths.
 This calls Dir2Browse().
 ************************************************************/
function Dir2BrowseUpload ($Mod, $UploadPk, $LinkLast=NULL, $ShowBox=1, $ShowMicro=NULL)
{
  global $DB;
  /* Find the file associated with the upload */
  $SQL = "SELECT uploadtree_pk FROM upload INNER JOIN uploadtree ON upload_fk = '$UploadPk' AND parent is null;";
  $Results = $DB->Action($SQL);
  $UploadtreePk = $Results[0]['uploadtree_pk'];
  return(Dir2Browse($Mod,$UploadtreePk,$LinkLast,$ShowBox,$ShowMicro));
} // Dir2BrowseUpload()

/************************************************************
 Dir2FileList(): Given an array of pfiles/uploadtree, sorted by
 pfile, list all of the breadcrumbs for each file.
 If the pfile is a duplicate, then indent it.
   $Listing = array from a database selection.  The SQL query should
	use "ORDER BY pfile_fk" so that the listing can indent duplicate pfiles
   $IfDirPlugin = string containing plugin name to use if this is a directory.
                  or any other container
   $IfFilePlugin = string containing plugin name to use if this is a file
   $Count = first number for indexing the entries (may be -1 for no count)
 Returns string containing the listing.
 ************************************************************/
function Dir2FileList	(&$Listing, $IfDirPlugin, $IfFilePlugin, $Count=-1, $ShowPhrase=0)
{
  $LastPfilePk = -1;
  $V = "";
  for($i=0; !empty($Listing[$i]['uploadtree_pk']); $i++)
  {
    $R = &$Listing[$i];
    if (array_key_exists("licenses", $R))
      $Licenses = $R["licenses"];
    else
      $Licenses = '';

    $Phrase='';
    if ($ShowPhrase && !empty($R['phrase_text']))
      {
$text = _("Phrase");
      $Phrase = "<b>$text:</b> " . htmlentities($R['phrase_text']);
      }

    if ((IsDir($R['ufile_mode'])) || (Iscontainer($R['ufile_mode'])))
	{
	$V .= "<P />\n";
	$V .= Dir2Browse("browse",$R['uploadtree_pk'],$IfDirPlugin,1,
		NULL,$Count,$Phrase, $Licenses) . "\n";
	}
    else if ($R['pfile_fk'] != $LastPfilePk)
	{
	$V .= "<P />\n";
	$V .= Dir2Browse("browse",$R['uploadtree_pk'],$IfFilePlugin,1,
		NULL,$Count,$Phrase, $R['licenses']) . "\n";
	$LastPfilePk = $R['pfile_fk'];
	}
    else
	{
	$V .= "<div style='margin-left:2em;'>";
	$V .= Dir2Browse("browse",$R['uploadtree_pk'],$IfFilePlugin,1,
		NULL,$Count,$Phrase, $R['licenses']) . "\n";
	$V .= "</div>";
	}
    $Count++;
  }
  return($V);
} // Dir2FileList()


/* Function: GetNonArtifactChildren
 *
 * Find the non artifact children of an uploadtree pk.
 * If any children are artifacts, resolve them until you get
 * to a non-artifact.
 *
 * This function replaces DirGetList()
 *
 * @param int  $uploadtree_pk
 *
 * @return list of child uploadtree recs + pfile_size + pfile_mimetypefk on success.
 *         list may be empty if there are no children.
 * Child list is sorted by ufile_name.
 */
function GetNonArtifactChildren($uploadtree_pk)
{
  global $PG_CONN;
  
  $foundChildren = array();

  /* Find all the children */
  $sql = "select uploadtree.*, pfile_size, pfile_mimetypefk from uploadtree 
          left outer join pfile on (pfile_pk=pfile_fk)
          where parent=$uploadtree_pk";
  $result = pg_query($PG_CONN, $sql);
  DBCheckResult($result, $sql, __FILE__, __LINE__);
  if (pg_num_rows($result) == 0)
  {
    pg_free_result($result);
    return $foundChildren;
  }
  $children = pg_fetch_all($result);
  pg_free_result($result);

  /* Loop through each child and replace any artifacts with their 
     non artifact child.  Or skip them if they are not containers.
   */
  foreach($children as $key => $child)
  {
    if (Isartifact($child['ufile_mode']))
    {
      if (Iscontainer($child['ufile_mode']))
      {
        unset($children[$key]);
        $NonAChildren = GetNonArtifactChildren($child['uploadtree_pk']);
        if ($NonAChildren)
          $foundChildren = array_merge($foundChildren, $NonAChildren);
      }
      else
        unset($children[$key]);
    }
    else
      $foundChildren[$key] = $child;
  }
  uasort($foundChildren, '_DirCmp');
  return $foundChildren;
}


/************************************************************
 Uploadtree2PathStr(): 
   Return string representation of uploadtree path.
   Use Dir2Path to get $PathArray.
 ************************************************************/
function Uploadtree2PathStr ($PathArray)
{
  $Path = "";
  if (count($PathArray))
    foreach($PathArray as $PathRow) $Path .= "/" . $PathRow['ufile_name'];
  return $Path;
}

?>
<?php
/***********************************************************
 Copyright (C) 2010 Hewlett-Packard Development Company, L.P.

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.

 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 more details.

 You should have received a copy of the GNU General Public License along
 with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ***********************************************************/

/*************************************************
 Restrict usage: Every PHP file should have this
 at the very beginning.
 This prevents hacking attempts.
 *************************************************/
global $GlobalReady;
if (!isset($GlobalReady)) { exit; }

define("TITLE_search", _("Search"));

class search extends FO_Plugin
{
  var $Name       = "search";
  var $Title      = TITLE_search;
  var $Version    = "1.0";
  var $MenuList   = "";
  var $Dependency = array("db","view","browse");
  var $DBaccess   = PLUGIN_DB_READ;
  var $LoginFlag  = 0;

  /***********************************************************
   GetUploadtreeFromTag(): Given a tag, return all uploadtree.
   ***********************************************************/
  function GetUploadtreeFromTag($Item,$tag,$Page,$searchtype)
  {
    global $DB;
    global $PG_CONN;
    $Max = 50;

    /* Find lft and rgt bounds for this $Uploadtree_pk  */
    $sql = "SELECT lft,rgt,upload_fk FROM uploadtree WHERE uploadtree_pk = $Item;";
    $result = pg_query($PG_CONN, $sql);
    DBCheckResult($result, $sql, __FILE__, __LINE__);
    if (pg_num_rows($result) < 1)
    {
      pg_free_result($result);
      $text = _("Invalid URL, nonexistant item");
      return "<h2>$text $Uploadtree_pk</h2>";
    }
    $row = pg_fetch_assoc($result);
    $lft = $row["lft"];
    $rgt = $row["rgt"];
    $upload_pk = $row["upload_fk"];
    pg_free_result($result);

    $SQL = "SELECT * FROM uploadtree INNER JOIN (SELECT * FROM tag_file INNER JOIN tag ON tag_pk = tag_fk AND (tag = '$tag' OR tag LIKE '$tag')) T ON uploadtree.pfile_fk = T.pfile_fk WHERE uploadtree.upload_fk = $upload_pk AND uploadtree.lft >= $lft AND uploadtree.rgt <= $rgt UNION SELECT * FROM uploadtree INNER JOIN (SELECT * FROM tag_uploadtree INNER JOIN tag ON tag_pk = tag_fk AND (tag = '$tag' OR tag LIKE '$tag')) T ON uploadtree.uploadtree_pk = T.uploadtree_fk WHERE uploadtree.upload_fk = $upload_pk AND uploadtree.lft >= $lft AND uploadtree.rgt <= $rgt";
    $Offset = $Page * $Max;

    /* search only containers of all files */
    if ($searchtype == 'package')
    {
      $SQL .= " AND ((ufile_mode & (1<<29))!=0) AND ((ufile_mode & (1<<28))=0)";
    }
    $SQL .= " ORDER BY ufile_name LIMIT $Max OFFSET $Offset;";
    $Results = $DB->Action($SQL);

    $V = "";
    $Count = count($Results);
    //$V .= "<pre>" . htmlentities($SQL) . "</pre>\n";

    if (($Page > 0) || ($Count >= $Max))
    {
      $Uri = Traceback_uri() . "?mod=" . $this->Name;
      $Uri .= "&upload=$upload_pk";
      $Uri .= "&item=$Item";
      $Uri .= "&tag=" . urlencode($tag);
      $Uri .= "&searchtype=" . urlencode($searchtype);
      $VM = MenuEndlessPage($Page, ($Count >= $Max),$Uri) . "<P />\n";
      $V .= $VM;
    }
    else
    {
      $VM = "";
    }

    if ($Count == 0)
    {
      $V .= _("No results.\n");
      return($V);
    }

    if ($Page==0)
    {
      $SQL = preg_replace('/\*/','COUNT(*) AS count',$SQL,1);
      $SQL = preg_replace('/ ORDER BY .*;/',';',$SQL);
      $Count = $DB->Action($SQL);
      $text = _("Total matched:");
      $V .= "$text " . number_format($Count[0]['count'],0,"",",") . "<br>\n";
    }

    $V .= Dir2FileList($Results,"browse","view",$Page*$Max + 1);

    /* put page menu at the bottom, too */
    if (!empty($VM)) { $V .= "<P />\n" . $VM; }
    return($V);
  }

  /***********************************************************
   GetUploadtreeFromName(): Given a filename, return all uploadtree.
   ***********************************************************/
  function GetUploadtreeFromName($Item,$Filename,$tag,$Page,$MimetypeNot,$Mimetype,$SizeMin,$SizeMax,$searchtype)
  {
    global $DB;
    $Max = 50;
    global $PG_CONN;

    /* Find lft and rgt bounds for this $Uploadtree_pk  */
    $sql = "SELECT lft,rgt,upload_fk, pfile_fk FROM uploadtree WHERE uploadtree_pk = $Item;";
    $result = pg_query($PG_CONN, $sql);
    DBCheckResult($result, $sql, __FILE__, __LINE__);
    if (pg_num_rows($result) < 1)
    {
      pg_free_result($result);
      $text = _("Invalid URL, nonexistant item");
      return "<h2>$text $Uploadtree_pk</h2>";
    }
    $row = pg_fetch_assoc($result);
    $lft = $row["lft"];
    $rgt = $row["rgt"];
    $upload_pk = $row["upload_fk"];
    $pfile_pk = $row["pfile_fk"];
    pg_free_result($result);

    $Filename = str_replace("'","''",$Filename); // protect DB
    $SQL = "SELECT * FROM uploadtree INNER JOIN pfile ON pfile_pk = pfile_fk AND ufile_name like '$Filename'";
    $NeedAnd=0;
    if (!empty($Mimetype) && ($Mimetype >= 0))
    {
      if ($NeedAnd) { $SQL .= " AND"; }
      else { $SQL .= " WHERE"; }
      $SQL .= " (pfile.pfile_mimetypefk ";
      if ($MimetypeNot != 0) { $SQL .= "!"; }
      $SQL .= "= $Mimetype";
      if ($MimetypeNot != 0) { $SQL .= " OR pfile.pfile_mimetypefk IS NULL)"; }
      $NeedAnd=1;
    }
    if (!empty($SizeMin) && ($SizeMin >= 0))
    {
      if ($NeedAnd) { $SQL .= " AND"; }
      else { $SQL .= " WHERE"; }
      $SQL .= " pfile.pfile_size > $SizeMin";
      $NeedAnd=1;
    }
    if (!empty($SizeMax) && ($SizeMax >= 0))
    {
      if ($NeedAnd) { $SQL .= " AND"; }
      else { $SQL .= " WHERE"; }
      $SQL .= " pfile.pfile_size < $SizeMax";
      $NeedAnd=1;
    }
    $Offset = $Page * $Max;

    $SQL .= "  AND upload_fk = $upload_pk AND lft >= $lft AND rgt <= $rgt";
    /* search only containers of all files */
    if ($searchtype == 'package')
    {
      $SQL .= " AND ((ufile_mode & (1<<29))!=0) AND ((ufile_mode & (1<<28))=0)";
    }

    $SQL .= " ORDER BY pfile_fk,ufile_name LIMIT $Max OFFSET $Offset;";

    if (!empty($tag))
    {
      $TagSQL = "SELECT * FROM (";
      $TagSQL .= substr($SQL,0,-1);
      $TagSQL .= ") U INNER JOIN (SELECT * FROM tag_file INNER JOIN tag ON tag_pk = tag_fk AND (tag = '$tag' OR tag LIKE '$tag')) T ON U.pfile_fk = T.pfile_fk";
      $SQL = $TagSQL;
    }

    $Results = $DB->Action($SQL);

    /* get last nomos agent_pk that has data for this upload */
    $Agent_name = "nomos";
    $AgentRec = AgentARSList("nomos_ars", $upload_pk, 1);
    $nomosagent_pk = $AgentRec[0]["agent_fk"];
    if ($nomosagent_pk)
    {
      /* add licenses to results */
      foreach ($Results as &$utprec) 
      {
        $utprec['licenses'] = GetFileLicenses_string($nomosagent_pk, $utprec['pfile_fk'], 0);
      }
    }

    $V = "";
    $Count = count($Results);
    //$V .= "<pre>" . htmlentities($SQL) . "</pre>\n";

    if (($Page > 0) || ($Count >= $Max))
    {
      $Uri = Traceback_uri() . "?mod=" . $this->Name;
      $Uri .= "&upload=$upload_pk";
      $Uri .= "&item=$Item";
      $Uri .= "&filename=" . urlencode($Filename);
      $Uri .= "&tag=" . urlencode($tag);
      $Uri .= "&searchtype=" . urlencode($searchtype);
      $Uri .= "&sizemin=$SizeMin";
      $Uri .= "&sizemax=$SizeMax";
      $Uri .= "&notmimetype=$MimetypeNot";
      $Uri .= "&mimetype=$Mimetype";
      $VM = MenuEndlessPage($Page, ($Count >= $Max),$Uri) . "<P />\n";
      $V .= $VM;
    }
    else
    {
      $VM = "";
    }

    if ($Count == 0)
    {
      $V .= _("No results.\n");
      return($V);
    }

    if ($Page==0)
    {
      $SQL = preg_replace('/\*/','COUNT(*) AS count',$SQL,1);
      $SQL = preg_replace('/ ORDER BY .*;/',';',$SQL);
      $Count = $DB->Action($SQL);
      $text = _("Total matched:");
      $V .= "$text " . number_format($Count[0]['count'],0,"",",") . "<br>\n";
    }

    $V .= Dir2FileList($Results,"browse","view",$Page*$Max + 1);

    /* put page menu at the bottom, too */
    if (!empty($VM)) { $V .= "<P />\n" . $VM; }
    return($V);
  } // GetUploadtreeFromName()

  /***********************************************************
   RegisterMenus(): Customize submenus.
   ***********************************************************/
  function RegisterMenus()
  {
    // For all other menus, permit coming back here.
    $URI = $this->Name . Traceback_parm_keep(array(
      "show",
      "format",
      "page",
      "upload",
      "item",
    ));
    $Item = GetParm("item", PARM_INTEGER);
    $Upload = GetParm("upload", PARM_INTEGER);
    if (!empty($Item) && !empty($Upload)) {
      if (GetParm("mod", PARM_STRING) == $this->Name) {
        menu_insert("Browse::Search", 1);
      }
      else {
        $text = _("Search");
        menu_insert("Browse::Search", 1, $URI, $text);
      }
    }
  } // RegisterMenus()

  /***********************************************************
   Output(): Display the loaded menu and plugins.
   ***********************************************************/
  function Output()
  {
    $uTime = microtime(true);
    if ($this->State != PLUGIN_STATE_READY) { return; }
    $V="";
    $Upload = GetParm("upload",PARM_INTEGER);
    $Item = GetParm("item",PARM_INTEGER);
    global $Plugins;
    global $DB;
    switch($this->OutputType)
    {
      case "XML":
        break;
      case "HTML":
        /************************/
        /* Show the folder path */
        /************************/
        $V .= Dir2Browse($this->Name,$Item,NULL,1,"Browse") . "<P />\n";

        $searchtype = GetParm("searchtype",PARM_STRING);
        $Filename = GetParm("filename",PARM_STRING);
        $tag = GetParm("tag",PARM_STRING);
        $SizeMin = GetParm("sizemin",PARM_TEXT) . 'x';
        if ($SizeMin != 'x') { $SizeMin=intval($SizeMin); }
        else { $SizeMin = -1; }
        if ($SizeMin < 0) { $SizeMin=-1; }
        $SizeMax = GetParm("sizemax",PARM_TEXT) . 'x';
        if ($SizeMax != 'x') { $SizeMax=intval($SizeMax); }
        else { $SizeMax = -1; }
        if ($SizeMax < 0) { $SizeMax=-1; }
        $MimetypeNot = GetParm("notmimetype",PARM_INTEGER);
        $Mimetype = GetParm("mimetype",PARM_INTEGER);
        $Page = GetParm("page",PARM_INTEGER);

        $V .= "<form action='" . Traceback_uri() . "?mod=" . $this->Name . "' method='POST'>\n";
        $V .= "<ul>\n";
        $text = _("Search for");
        $text1 = _("Containers only(rpms,tars,isos,etc).");
        $text2 = _("All Files");

        if ($searchtype == 'package')
        {
          $SelectedP = " checked ";
        }else{
          $SelectedP = "";
        }
        $V .= "<li>$text: <input type='radio' name='searchtype' value='package' $SelectedP>$text1 \n";
        if ($searchtype == 'file')
        {
          $Selected = " checked ";
        }else{
          $Selected = "";
        }
        $V .= "<input type='radio' name='searchtype' value='file' $Selected>$text2\n";
        $text = _("Enter the filename to find: ");
        $V .= "<li>$text";
        $V .= "<INPUT type='text' name='filename' size='40' value='" . htmlentities($Filename) . "'>\n";
        $V .= _("You can use '%' as a wild-card.\n");

        $text = _("Tag to find");
        $V .= "<li>$text:  <input name='tag' size='30' value='" . htmlentities($tag) . "'>\n";

        $text = _("Mimetype ");
        $V .= "<li>$text";
        $V .= "<select name='notmimetype'>\n";
        if ($MimetypeNot == 0)
        {
          $text = _("IS");
          $V .= "<option value='0' selected>$text</option>\n";
          $text = _("IS NOT");
          $V .= "<option value='1'>$text</option>\n";
        }
        else
        {
          $text = _("IS");
          $V .= "<option value='0'>$text</option>\n";
          $text = _("IS NOT");
          $V .= "<option value='1' selected>$text</option>\n";
        }
        $V .= "</select>\n";
        $V .= "<select name='mimetype'>\n";
        $Results = $DB->Action("SELECT * FROM mimetype ORDER BY mimetype_name;");
        $text = _("Select mimetype...");
        $V .= "<option value='-1'>$text</option>\n";
        for($i=0; !empty($Results[$i]['mimetype_pk']); $i++)
        {
          if ($Results[$i]['mimetype_pk'] == $Mimetype)
          {
            $V .= "<option value='" . $Results[$i]['mimetype_pk'] . "' selected>";
          }
          else
          {
            $V .= "<option value='" . $Results[$i]['mimetype_pk'] . "'>";
          }
          $V .= $Results[$i]['mimetype_name'];
          $V .= "</option>\n";
        }
        $V .= "</select>\n";
        $Value=$SizeMin; if ($Value < 0) { $Value=''; }
        $text = _("File size is");
        $text1 = _(" bytes\n");
        $V .= "<li>$text &gt; <input name='sizemin' size=10 value='$Value'>$text1";
        $Value=$SizeMax; if ($Value < 0) { $Value=''; }
        $text = _("File size is");
        $text1 = _(" bytes\n");
        $V .= "<li>$text &lt; <input name='sizemax' size=10 value='$Value'>$text1";

        $V .= "</ul>\n";
        $V .= "<input type='hidden' name='item' value='$Item'>\n";
        $V .= "<input type='hidden' name='upload' value='$Upload'>\n";
        $text = _("Search");
        $V .= "<input type='submit' value='$text!'>\n";
        $V .= "</form>\n";

        if (!empty($Filename))
        {
          if (empty($Page)) { $Page = 0; }
          $V .= "<hr>\n";
          $text = _("Files matching");
          $V .= "<H2>$text " . htmlentities($Filename) . "</H2>\n";
          $V .= $this->GetUploadtreeFromName($Item,$Filename,$tag,$Page,$MimetypeNot,$Mimetype,$SizeMin,$SizeMax,$searchtype);
        } else {
          if (!empty($tag))
          {
            if (empty($Page)) { $Page = 0; }
            $V .= "<hr>\n";
            $text = _("Files matching");
            $V .= "<H2>$text " . htmlentities($Filename) . "</H2>\n";
            $V .= $this->GetUploadtreeFromTag($Item,$tag,$Page,$searchtype);
          }
        }
        break;
      case "Text":
        break;
      default:
        break;
    }
    if (!$this->OutputToStdout) { return($V); }
    print($V);
    $Time = microtime(true) - $uTime;  // convert usecs to secs
    $text = _("Elapsed time: %.2f seconds");
    printf( "<p><small>$text</small>", $Time);
    return;
  } // Output()

};
$NewPlugin = new search;
$NewPlugin->Initialize();

?>
_______________________________________________
fossology mailing list
fossology@fossology.org
http://fossology.org/mailman/listinfo/fossology

Reply via email to