phpgroupware-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Phpgroupware-cvs] old/anthill CHANGES, 1.1 enterbug.php, 1.1 faq.php, 1


From: skwashd
Subject: [Phpgroupware-cvs] old/anthill CHANGES, 1.1 enterbug.php, 1.1 faq.php, 1.1 editversions.php, 1.1 editusers.php, 1.1 editproducts.php, 1.1 gpgupload.php, 1.1 index.php, 1.1 postbug.php, 1.1 newuser.php, 1.1 logout.php, 1.1 login.php, 1.1 editcomponents.php, 1.1 createattachment.php, 1.1 README.1st, 1.1 README, 1.1 COPYING, 1.1 README.OSX, 1.1 THANKS, 1.1 buglist.php, 1.1 admin.php, 1.1 activity.php, 1.1 TODO, 1.1 pref.php, 1.1 TRANSLATORS, 1.1 query.php, 1.1 textreport.php, 1.1 reports.php, 1.1 showattachment.php, 1.1 setup.php, 1.1
Date: Thu, 5 May 2005 02:34:00 +0200

Update of old/anthill

Added Files:
     Branch: MAIN
            CHANGES 
            enterbug.php 
            faq.php 
            editversions.php 
            editusers.php 
            editproducts.php 
            gpgupload.php 
            index.php 
            postbug.php 
            newuser.php 
            logout.php 
            login.php 
            editcomponents.php 
            createattachment.php 
            README.1st 
            README 
            COPYING 
            README.OSX 
            THANKS 
            buglist.php 
            admin.php 
            activity.php 
            TODO 
            pref.php 
            TRANSLATORS 
            query.php 
            textreport.php 
            reports.php 
            showattachment.php 
            setup.php 

Log Message:
retiring app

====================================================
Index: CHANGES
Anthill Changelog

0.3.0 - current
============================================================================
+ if only one version exists, select it by default when entering a bug
+ Added new sessions schema
- Changed user table to use unix timestamps
+ Added anthill_* table prefix
+ Started working on new mini api for phpgw integration
  + reworked sessions and accounts
  + added index2.php - will soon replace index.php
  + changed login to use mini api
+ Probably broke a few things - will be fixed soon
+ Removed config.inc.php and replaced it with sample-config.inc.php - also 
updated README :)

0.2.3 - June 6th, 2003
============================================================================
+ update index page to show all bugs requiring validation (TOVALIDATE)
+ new function d_DrawRules(): loads t_rules() (from theme.php) which
  displays the rules for submitting new bugs prior to allowing a user to
  enter a new bug
+ updated FAQ in template to reference new status types
+ two new status types: TOVALIDATE and NEEDSWORK; should aid in QA
  participation in a bug cycle
- when listing components and versions in editproducts, sort by name
- don't double addslashes() attachment descriptions
- fix bug #62 (improper meta syntax for charset)

0.2.2 - May 15th, 2003
============================================================================
- force order of bugs in case the database is inconsistent (always sort by
  bid ascending)
- update README
- update README.OSX
- be more strict with setting cookies
- a bug that prevented a user who had been deleted, and re-registered and
  was subsequently unable to login again has been fixed
- make comment text entry box larger for comments and initial bug submision
- fix language detection so now languages other than english will be
  displayed
- patch from Dan Lark to make the query page display better in IE

0.2.1 - December 24th, 2002
============================================================================
- NOTE: you will need to modify your config.inc.php and change
  $_CONF['cookie_domain'] from $SERVER_NAME to $_SERVER['SERVER_NAME'] if you
  don't explicitly set it
+ allow admin or owner of component to change the short description of a bug
+ add a test to make sure we are using PHP 4.1.0 or higher
+ new function: do_configtest() which tests config stuff to make sure
  Anthill will work properly
- use $_SERVER['REMOTE_ADDR'] instead of $REMOTE_ADDR (now Anthill works
  with php 4.2.3+)
- use $_COOKIE instead of $HTTP_COOKIE_VARS
- use $_SERVER['SERVER_NAME'] instead of $SERVER_NAME
+ add component as prefix in bug mails (ie. [Bug #100] [tcl] short desc)

0.2.0 - October 19th, 2002
============================================================================
- added dutch language file (thanks to Arnold Ligtvoet
+ added README.OSX which contains info for Mac OS X users
- fixed bug showing htmlspecialchars in bug text (again)

0.2.0rc3 - September 19th, 2002
============================================================================
+ add ability to list bugs by specifying a range of fixed versions (re:
  Arnold Ligtvoet)
+ add ability to list bugs by specifying product (re: Arnold Ligtvoet)
+ add entry to allow specifying what version a bug is fixed in (free-form)
  (re: Arnold Ligtvoet)
- don't allow null values for components, products, or versions
- editing products no longer shows deleted components/versions
- set Return-Path on diff messages
- cleanup creation of attachments a little

0.2.0rc2 - September 7th, 2002
============================================================================
- lots of setting variables to NULL as this apparently makes Anthill work on
  Win32 where otherwise lots of errors come up (thanks to Oleg
  <address@hidden> for the great help in testing Anthill on Win32
+ new config variable $_CONF['meta_lang'] to set the value of the meta
  charset tag in the page headers
- redirect empty requests on buglist.php to query.php so our query form is
  only in one place
- rewrote d_mailUser() from scratch; it works on a system where the old
  function did not work previously
- fix bad HTML in preferences page that makes IE display it a little off and
  Konqueror nearly unuseable to change user preferences
- fix bug #37; should work with register_globals=Off now
- don't call htmlspecialchars() on user comments before and after saving to
  the dbase as it messes up how comments look (displaying &quot; instead of
  ")
- fix typeo in setcookie() call in user.inc.php
- fix bug in showattachment.php where the mimetype was not being properly
  passed to the browser
- when marking a bug duplicate, run the diff on the other bug as well since
  it's description is also updated
- the same version number can now be used in mutiple products
- fix bug #42
- fix some minor problems with d_mailUser() (used in the cron email script)
- new test: if safe_mode is on, make sure that diff is in safe_mode_exec_dir
  otherwise we get an inexplicable return error of 127 which diff could never
  generate; so now we test that, if in safe_mode, that safe_mode_exec_dir is
  a) set, and b) that the config option "difftool" is in there
  (unfortunately, it's not too specific as it's a simple regex, but it should
  be fine)
- fix test on whether mdaemonreplyto is set so we don't end up with an extra
  (and empty) Reply-To: header
- make the cc work again in the diff mails
- fix a typeo in the SQL upgrade script

0.2.0rc1 - July 24, 2002
============================================================================
+ new functions to the database abstraction layer (postgres support is still
  horrible)
- minor bugfixes
+ add Ali Ziad's awesome super industrial strength query engine (with some
  modifications)
- allow quotes in comments

0.2.0pre3 - July 19, 2002
============================================================================
+ new configurable option: $_CONF['difftool'] which contains the full path
  and filename to the diff utility (defaults to /usr/bin/diff)
+ rework diff-handling so that it will work with PHP's safe_mode.
+ put a default .htaccess in include/ that denies access to all of the .php
  files stored there for some extra safety
+ add a new configurable admin option: mailer daemon reply-to address; if
  set all diff messages will be tagged with the address specified in the
  Reply-To header (useful for mailing lists if people want to reply to the
  daemon's messages since the daemon itself may not be a "real" email
  address)
- if the To: and CC: fields are identical, drop the CC; if the CC contains
  the same address more than once (ie. reporter adds themself to the CC list),
  filter the CC list so it only sends one email to the address (see bug #22)
+ do duplicate checking for components, versions, and products
+ you can no longer remove the administrator user
+ if deleting a user who is the owner of some components, reassign the
  components to another user
+ if deleting a user who is the owner of some bugs, reassign the bugs to
  another user
+ no longer really delete components, products, or versions; we just flag
  them deleted (like users)
+ we now check to make sure that the gpg dir, attachments dir, tmp dir, and
  shadow dir are writable by the webserver user (ie. apache, etc.).  If any of
  these directories are not writable, we print a warning in bold red at the
  very top of any given page to indicate the problem, but don't "shut off" the
  site (this will help narrow down some mis-configurations)
+ we no longer really delete users; we simply "flag" them as deleted.  This
  keeps the user information available, but the user is unable to login.
  Duplicate checking is not done against deleted users, so to "re-enable" a
  deleted user, they must create a new account
+ new column in bugdesc: system; set to 1 if this is a system-written
  comment (and thus trusted), 0 if this is user-supplied (untrusted).  We do
  all the sanitizing on user comments but leave system comments alone so that
  we can embed HTML tags (ie. for duplicate bugs we can link directly to the
  bug, etc.)
- fixed bug #40
- fixed contributor email not showing up in diff reports
+ owners and admins can now change the resolution priority and severity of
  bugs (see bug #27 and #32)
+ add support for automatic email CC based on component; this can only be
  modified by a site admin in the preferences for that component.  It allows
  multiple users who may not be the owner of the component to get cc'd on new
  bugs reported on that component by automatically adding them to the bug's
  autocc list (see bug #33)
- reports should only show developers; basic users cannot own bugs so no
  point in listing them
- fix closed site settings; now we check if the site is closed AND if a user
  is logged in, instead of OR
- make sure that all include() that contain variables (ie. $rincdir) check
  that the file exists before opening
+ only list developers who can own bugs when submitting a new bug (instead
  of everyone)
- fixed bug #38
- fixed bug #39
+ minimum requirement: PHP 4.1; now we use $_REQUEST to get POST/GET
  variables so that safemode will work if enabled
- fix some more stupid typeos
- fix text reporting (was using the old config vars for the date/time
  formats)
- really fix the new user registration bug (no more sessions stored in users
  table)

0.2.0pre2 - June 13, 2002
============================================================================
- some other small typeo fixes
- liberally use htmlspecialchars() all over the place to prevent things like
  cross-site scripting vulnerabilities; ie. all user input is untrusted and
  should be treated as such.  As an aside, Anthill was featured on bugtraq
  with this problem, here are the references:
    http://www.vmlinuz.ca/archives/bugtraq/2002-04/msg00100.html
    http://online.securityfocus.com/bid/4443
    http://online.securityfocus.com/bid/4442
  These issues are now resolved with this release
- add some more fixes to prevent un-authenticated users from getting into
  reports, bug entries, and bug listings.
- changed index page to not display the Problem Tracking column if the
  global preferences are set to "Closed Site" (aka no new users allowed)
- changed d_DrawNav() to use index.php as home instead of $webroot
+ added include/reportengine.php, etc/testreportengine.php, textreport.php,
  contributed by John Ham.  The reportengine.php file is a set of routines
  to ease generation of a text mode report suitable for printing on almost
  any printer.  The testreportengine.php script can be run stand-alone with
  a php executable to test the report engine code.  It serves as a trivial
  example of how to use the reportengine.php routines.  The textreport.php
  file actually implements a full dump of the bug information for all bugs
  in the database as a text mode report using reportengine.php, and shows
  what would be a more typical use of the reportengine.php code.  Thanks
  John for this beautiful reporting code!
+ add developer and basic user access levels:  basic users can open bug
  reports, report on them, etc.  developers actually get to own bug reports
  (users can no longer assign themselves bugs)
- fixes to session support
+ add user-definable session timeouts
- fixed a bug that changes to a bug would be comitted even if the user's
  session expired (auto-logout)
- fixed some password changing bugs that were due to old session support

0.2.0pre1 - February 22, 2002
============================================================================
+ added README.1st for very important (ie. security-like) info
+ added three mailing lists:  address@hidden (announcements,
  read-only), address@hidden (development list), and
  address@hidden (user discussion list).  To subscribe, email
  address@hidden (ie. address@hidden)
+ optimized GPG upload code; now we make sure that what is uploaded is a
  valid GPG or PGP keyfile before saving it
- fixed bug where keyword search would print a PHP error on no matching
  keywords (ie. if return list is empty)
+ new session support for logins based on GeekLog session support
+ support for marking bugs CLOSED (not resolved), VERIFIED (fix in
  progress), and UNCONFIRMED (don't know if it's valid or not)... the status
  types have been in there forever, we just never used them (this will help
  to better track the life of a bug)
+ don't ask for product if only one defined product on the system
+ support for creating attachments associated with bugs
- fix HTML code parsing in comments; sanitize comments when saving them to
  the dbase instead of when displaying, this allows us to use HTML tags in
  system comments, etc.
+ make duplicate bugs link to each other in comments
+ cron script to mail users periodically with NEW and UNRESOLVED status bugs
  (contributed by Donncha O Caoimh <address@hidden>); this is a PHP script
  executed on the commandline so users must have a standalone PHP executable
  in order to use it
+ new file: upgradepw.php which will generate new passwords for users and
  email them (new md5 passwords); this file is located in etc/ and should be
  removed after the upgrade
+ use md5 passwords instead of crypt passwords
+ add database abstraction layer (only support MySQL for now, but the layer
  is there to add support for others); based on phplib
+ add website URL to new user/new password email messages so people know
  what site the message is coming from
+ all configuration variables are now wrapped in the _CONF array to make it
  easier to access (also makes code easier to understand); NOTE: you will
  need to reconfigure Anthill's config.inc.php because of this
+ new config file: config.inc.php; all configuration options will be here
  and here alone (no more mixing with site initialization)

0.1.6.1 - February 18, 2002
============================================================================
- fixed bad bug where if the admin changes a user's settings but does not
  change the password (ie. password fields are blank) the user's password
  would be set to a NULL value, allowing the user to login without entering a
  password
- don't parse HTML code in comments during display as the code may mess up
  page displays
- fixed README to include info regarding ownership of shadow/, tmp/ and gpg/
  directories
- fixed bug when posting new bug with URL entry having a leading space
- fix bug#12 (http://anthill.vmlinuz.ca/anthill/query.php?bug=12); List all
  bugs for user in buglist.php uses the input drop box for List all bugs
  reported by

0.1.6 - January 26, 2002
============================================================================
+ show Product in the buglist view
- fixed bug where comments would be lost when re-assigning the ownership of
  a bug
- fixed annoying bug that would change creation time of the bug to the
  current time whenever you changed a bugs status (this is due to having two
  timestamp fields in the bugs dbase instead of one.. creation is now
  varchar(16) and modified remains timestamp (modified was not being updated
  because creation appeared in the dbase first))
- modified anthill.css to use pixels not points (draw back is it looks good
  in Mozilla/Galeon but very small in Netscape)
+ Reported column on reports page to see how many bugs each user has
  reported (re: Donncha O Caoimh)
+ email diffs are now cc'd to the person who reported the bug (re: Donncha O
  Caoimh)
+ added info in README regarding pre-req of gettext support in PHP
+ added chinese translation courtesy of Joe Man <address@hidden>

0.1.5 - October 6, 2001
============================================================================
- made it so anonymous users cannot post bug reports (index page displayed
  link for all and submission did not check to see if a user was logged in)
+ implemented history tracking per bug (tracks status changes, state
  changes, user reassignments, etc.)
- made unassigned bugs on reports page show up as "Unassigned"
- removed gettext() calls from generated diff emails (everything goes out in
  english now)... the problem was the strings in the diff files were being
  written and translated depending on the user's language settings (big
  mess)
+ added "view all unresolved bugs" to main page and buglist
+ added italian translation courtesy of Mandelli Alesandro
  <address@hidden>
+ added french translation courtesy of Christophe Gonnet
  <address@hidden>

0.1.4 - September 19, 2001
============================================================================
- moved password salt from site.inc.php to site preferences page
- moved Admin Access Level definition to site preferences page
+ added ability to use HTTP_AUTH to validate users instead of requiring
  internal mechanism
- change password storage from plaintext to crypt
- fix language processing so that if it is english first, we don't set
  $LANGUAGE or bind to a domain (prevents things like en:es:en showing
  spanish instead of english)
+ added reports per product
+ added reporternew type to buglist (reports new bugs you reported)
+ added menu to index page
+ added support for storing GPG/PGP keys on server
- changed sorting of comments to by date not by id
- rewrote language system, use gettext() now instead of defines
- fixed search problems
- fixed bug with changing user preferences
+ added support to edit user access levels
+ added URL field for bugs
+ implemented new template system
- language system is now per-user, not system-wide (based on language
  preference selected in user's browser)
+ added default bug state (private/public)
+ added autocc for automatic cc's of each bug (good for ml's)
+ added admin user editing form
+ added new user selection (allow or disallow)
+ added private/public bug types
+ use CSS for templates
- use *.inc.php for includes instead of *.inc (protection from external
  viewing)
- fixed URLs (do not assume http://)
+ add URL field for bugs
+ added support to re-open bugs
- finished admin interface


0.1.3 - May 20, 2001
============================================================================
- first functional semi-public release

$Id: CHANGES,v 1.1 2005/05/05 00:34:03 skwashd Exp $

====================================================
Index: enterbug.php
<?
  // Anthill
  // $Id: enterbug.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['reporter']))  { $reporter  = $_REQUEST['reporter']; }  
else { $reporter  = NULL; }
  if (isset($_REQUEST['version']))   { $version   = $_REQUEST['version']; }   
else { $version   = NULL; }
  if (isset($_REQUEST['component'])) { $component = $_REQUEST['component']; } 
else { $component = NULL; }
  if (isset($_REQUEST['prior']))     { $prior     = $_REQUEST['prior']; }     
else { $prior     = NULL; }
  if (isset($_REQUEST['sever']))     { $sever     = $_REQUEST['sever']; }     
else { $sever     = NULL; }
  if (isset($_REQUEST['assigned']))  { $assigned  = $_REQUEST['assigned']; }  
else { $assigned  = NULL; }
  if (isset($_REQUEST['shortdesc'])) { $shortdesc = $_REQUEST['shortdesc']; } 
else { $shortdesc = NULL; }
  if (isset($_REQUEST['url']))       { $url       = $_REQUEST['url']; }       
else { $url       = NULL; }
  if (isset($_REQUEST['longdesc']))  { $longdesc  = $_REQUEST['longdesc']; }  
else { $longdesc  = NULL; }
  if (isset($_REQUEST['product']))   { $product   = $_REQUEST['product']; }   
else { $product   = NULL; }
  if (isset($_REQUEST['pid']))       { $pid       = $_REQUEST['pid']; }       
else { $pid       = NULL; }
  if (isset($_REQUEST['ebug']))      { $ebug      = $_REQUEST['ebug']; }      
else { $ebug      = NULL; }

  d_StartPage(gettext("Submit a Bug"));
  d_DrawNav($_USER['uname']);
  d_DrawHeader(gettext("Submit a Bug"));

  if (!isset($ebug) && !isset($pid)) {  // show the rules for entering a report
    d_DrawRules();
    d_DrawFooter();
    exit;
  }

  $db->query("SELECT * FROM products");
  if ($db->num_rows() == 1) {
    $db->next_record();
    $pid = $db->record['pid'];
  }
  $db->free();

  if (!isset($pid)) {
?>

  <p><b><? print(gettext("You must first select a product in which to enter 
your new bug")); ?>:</b></p>

  <table border="0" cellpadding="2" cellspacing="0">
    <?  $db->query("SELECT * FROM products WHERE deleted = '0' ORDER BY name");
        while ($db->next_record()) {
    ?>
          <tr>
            <td width="20%" align="right">
              <a href="enterbug.php?pid=<? print($db->record['pid']); ?>"><? 
print($db->record['name']); ?></a>:
            </td>
            <td width="80%">
              <? print(stripslashes($db->record['description'])); ?>
            </td>
          </tr>
    <?
        }
        $db->free();
    ?>
    </tr>
  </table>

<?
  } else {
    if (!isset($_USER['uid'])) {
      // this is anonymous user; no posting permitted
      print("<p>" . gettext("You must login first if you wish to submit a 
bug.") . "</p>");
      d_DrawFooter();
      exit;
    }
?>

  <p><? print(gettext("This page lets you enter a new bug into Anthill.")); 
?></p>

  <form method="post" action="postbug.php">
  <table border="0" cellpadding="0" cellspacing="0">
    <tr>
      <td width="10%" align="right">
        <b><? print(gettext("Reporter")); ?>:</b>
      </td>
      <td width="40%">
        <? print($_USER['email']); ?>
        <input type="hidden" name="reporter" value="<? print($_USER['uid']); 
?>">
      </td>
      <td width="10%" align="right">
        <b><? print(gettext("Product")); ?>:</b>
      </td>
      <td width="40%">
        <?  $db->query("SELECT * FROM products WHERE pid = '$pid'");
            $db->next_record();
            print($db->record['name']);
            $db->free();
        ?>
      </td>
    </tr>
    <tr>
      <td width="10%" align="right">
        <b><? print(gettext("Version")); ?>:</b>
      </td>
      <td width="40%">
        <select name="version" size="5">
        <?  $db->query("SELECT * FROM versions WHERE (product = '$pid') AND 
(deleted = '0') ORDER BY name");
            while ($db->next_record()) {
              print(sprintf("<option 
value=\"%s\">%s</option>\n",$db->record['vid'],$db->record['name']));
            }
            $db->free();
        ?>
        </select>
      </td>
      <td width="10%" align="right">
        <b><? print(gettext("Component")); ?>:</b>
      </td>
      <td width="40%">
        <select name="component" size="5">
        <?  $db->query("SELECT * FROM components WHERE (product = '$pid') AND 
(deleted = '0') ORDER BY name");
            while ($db->next_record()) {
              print(sprintf("<option 
value=\"%s\">%s</option>\n",$db->record['cid'],$db->record['name']));
            }
            $db->free();
        ?>
        </select>
      </td>
    </tr>
    <tr>
      <td width="10%" align="right">
        <b><? print(gettext("Resolution Priority")); ?>:</b>
      </td>
      <td width="40%">
        <select name="prior">
        <?  $db->query("SELECT * FROM priority_d");
            while ($db->next_record()) {
              if ($db->record['s_def'] == 1) {
                $def = "SELECTED";
              } else {
                $def = "";
              }
              print(sprintf("<option value=\"%s\" 
%s>%s</option>\n",$db->record['id'],$def,$db->record['name']));
            }
            $db->free();
        ?>
        </select>
      </td>
      <td width="10%" align="right">
        <b><? print(gettext("Severity")); ?>:</b>
      </td>
      <td width="40%">
        <select name="sever">
        <?  $db->query("SELECT * FROM severity_d");
            while ($db->next_record()) {
              if ($db->record['s_def'] == 1) {
                $def = "SELECTED";
              } else {
                $def = "";
              }
              print(sprintf("<option value=\"%s\" 
%s>%s</option>\n",$db->record['id'],$def,$db->record['name']));
            }
            $db->free();
        ?>
        </select>
      </td>
    </tr>
    <tr>
      <td width="10%" align="right">
        <b><? print(gettext("Assigned To")); ?>:</b>
      </td>
      <td colspan="3" width="90%">
        <select name="assigned" size="5">
        <?  $db->query("SELECT * FROM users WHERE (access >= '" . 
$config['devac'] . "') AND (deleted = '0') ORDER BY uname");
            print("<option value=\"0\">" . gettext("Owner of Component") . 
"</option>");
            while ($db->next_record()) {
              print(sprintf("<option 
value=\"%s\">%s</option>\n",$db->record['uid'],$db->record['email']));
            }
            $db->free();
        ?>
        </select> <span class="tiny">(<? print(gettext("Leave at default to 
assign to component owner")); ?>)</span>
      </td>
    </tr>
    <tr>
      <td width="10%" align="right">
        <b><? print(gettext("Summary")); ?>:</b>
      </td>
      <td colspan="3" width="90%">
        <input type="text" name="shortdesc" size="76" maxlength="100">
      </td>
    </tr>
    <tr>
      <td width="10%" align="right">
        <b>URL:</b>  (<? print(gettext("include prefix")); ?>)
      </td>
      <td colspan="3" width="90%">
        <input type="text" name="url" size="76" maxlength="128">
      </td>
    </tr>
    <tr>
      <td width="10%" align="right">
        <b><? print(gettext("Description")); ?>:</b>
      </td>
      <td colspan="3" width="90%">
        <textarea name="longdesc" cols="76" rows="10" wrap="hard"></textarea>
      </td>
    </tr>
    <tr>
      <td width="10%" align="right">
        &nbsp;
      </td>
      <td colspan="3" width="90%">
        <input type="hidden" name="product" value="<? print($pid); ?>">
        &nbsp;&nbsp;&nbsp;&nbsp;
        <input type="submit" value="     <? print(gettext("Commit")); ?>     ">
        &nbsp;&nbsp;&nbsp;&nbsp;
        <input type="reset" value="<? print(gettext("Reset")); ?>">
  </table>
  </form>

<?

  }

  d_DrawFooter();
?>

====================================================
Index: faq.php
<?
  // Anthill
  // $Id: faq.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  d_StartPage(gettext("Anthill FAQ"));
  d_DrawNav($_USER['uname']);
  d_DrawHeader(gettext("Anthill FAQ"));
  t_faq();
  d_DrawFooter();

?>

====================================================
Index: editversions.php
<?
  // Anthill
  // $Id: editversions.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['action'])) { $action = $_REQUEST['action']; } else { 
$action = NULL; }
  if (isset($_REQUEST['pid']))    { $pid    = $_REQUEST['pid']; }    else { 
$pid    = NULL; }
  if (isset($_REQUEST['name']))   { $name   = $_REQUEST['name']; }   else { 
$name   = NULL; }
  if (isset($_REQUEST['vid']))    { $vid    = $_REQUEST['vid']; }    else { 
$vid    = NULL; }

  d_StartPage(gettext("Select Version"));

  if (!do_checkacs($_USER['access'])) exit;

  d_DrawNav($_USER['uname']);

  // form to add new version
  if ($action == "add") {
    d_DrawHeader(gettext("Add Version"));
    d_DrawEditVer("insert",0,$pid);
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // insert new version
  if ($action == "insert") {
    d_DrawHeader(gettext("Add Version"));
    // check if version already exists
    $db->query("SELECT * FROM versions WHERE (name = '$name') AND (deleted = 
'0') AND (product = '$pid')");
    if ($db->num_rows() > 0) {
      print("<p>" . gettext("A version by this name already exists.") . "</p>");
    } else {
      if ($name == "") {
        print("<p>" . gettext("ERROR: You submitted an empty field.") . "</p>");
      } else {
        $query  = "INSERT INTO versions (vid, product, name) VALUES ";
        $query .= "(NULL, '" . $pid . "', '";
        $query .= addslashes(htmlspecialchars($name)) . "')";
        $db->query($query);
        $db->free();
        print("<span class=\"text\"><center>" . gettext("Version added 
successfully.") . "</center></span>");
      }
    }
    print("<p>" . sprintf(gettext("Return to <a 
href=\"editversions.php?pid=%s\">versions</a>."), $pid) . "<br />");
    print(gettext("Return to <a href=\"editproducts.php\">products and 
components</a>.") . "</p>");
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // form to delete version
  if ($action == "del") {
    d_DrawHeader(gettext("Delete Version"));
    $db->query("SELECT * FROM versions WHERE vid = '$vid'");
    $db->next_record();
    $db->free();
?>
  <form method="post" action="editversions.php">
  <p><? print(sprintf(gettext("Are you sure you want to delete the version 
<b>%s</b>?"), stripslashes($db->record['name']))); ?>
  </p>
  <input type="submit" value="<? print(gettext("Delete")); ?>">
  <input type="hidden" name="vid" value="<? print($vid); ?>">
  <input type="hidden" name="pid" value="<? print($pid); ?>">
  <input type="hidden" name="action" value="delete">
  </form>
<?
    d_DrawFooter();
    exit;
  }

  // perform delete
  if ($action == "delete") {
    d_DrawHeader(gettext("Delete Version"));
    $db->query("UPDATE versions SET deleted = '1' WHERE vid = '$vid'");
    $db->free();
    print("<span class=\"text\"><center>" . gettext("Version removed.") . 
"</center></span>");
    print("<p>" . sprintf(gettext("Return to <a 
href=\"editversions.php?pid=%s\">versions</a>."), $pid) . "<br />");
    print(gettext("Return to <a href=\"editproducts.php\">products and 
components</a>.") . "</p>");
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // form to edit version
  if ($action == "edit") {
    d_DrawHeader(gettext("Change Version"));
    d_DrawEditVer("change",$vid,$pid);
    d_DrawFooter();
    exit;
  }

  // change version
  if ($action == "change") {
    d_DrawHeader(gettext("Change Version"));
    $query  = "UPDATE versions SET name = '" . 
addslashes(htmlspecialchars($name)) . "' ";
    $query .= "WHERE vid = '$vid'";
    $db->query($query);
    $db->free();
    print("<span class=\"text\"><center>" . gettext("Version changed.") . 
"</center></span>");
    print("<p>" . sprintf(gettext("Return to <a 
href=\"editversions.php?pid=%s\">versions</a>."), $pid) . "<br />");
    print(gettext("Return to <a href=\"editproducts.php\">products and 
components</a>.") . "</p>");
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // default action
  d_DrawHeader(gettext("Select Version"));
  $db->query("SELECT * FROM versions WHERE (product = '$pid') AND (deleted = 
'0')");

?>
  <table border="0" cellpadding="0" cellspacing="0" width="30%">
    <tr bgcolor="#8b95a8">
      <td width="20%">
        <? print(gettext("Version")); ?>
      </td>
      <td width="10%">
        <? print(gettext("Action")); ?>
      </td>
    </tr>
<?
  while ($db->next_record()) {
    $vid = $db->record['vid'];
?>
    <tr>
      <td width="20%">
        <? print(sprintf("<a 
href=\"editversions.php?vid=%s&pid=%s&action=edit\">%s</a>",$vid,$pid,stripslashes($db->record['name'])));
 ?>
      </td>
      <td width="10%">
        <? print(sprintf("<a 
href=\"editversions.php?vid=%s&pid=%s&action=del\">" . gettext("Delete") . 
"</a>",$vid,$pid)); ?>
      </td>
    </tr>
<?
  }
  $db->free();
?>
    <tr>
      <td width="20%">
        <? print(gettext("Add a new version")); ?>
      </td>
      <td width="10%">
        <a href="editversions.php?pid=<? print($pid); ?>&action=add"><? 
print(gettext("Add")); ?></a>
      </td>
    </tr>
  </table>

<?
  print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
  d_DrawFooter();
?>

====================================================
Index: editusers.php
<?
  // Anthill
  // $Id: editusers.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['action']))    { $action    = $_REQUEST['action']; }    
else { $action    = NULL; }
  if (isset($_REQUEST['moduserid'])) { $moduserid = $_REQUEST['moduserid']; } 
else { $moduserid = NULL; }
  if (isset($_REQUEST['name']))      { $name      = $_REQUEST['name']; }      
else { $name      = NULL; }
  if (isset($_REQUEST['uname']))     { $uname     = $_REQUEST['uname']; }     
else { $uname     = NULL; }
  if (isset($_REQUEST['email']))     { $email     = $_REQUEST['email']; }     
else { $email     = NULL; }
  if (isset($_REQUEST['access']))    { $access    = $_REQUEST['access']; }    
else { $access    = NULL; }
  if (isset($_REQUEST['pass1']))     { $pass1     = $_REQUEST['pass1']; }     
else { $pass1     = NULL; }
  if (isset($_REQUEST['pass2']))     { $pass2     = $_REQUEST['pass2']; }     
else { $pass2     = NULL; }
  if (isset($_REQUEST['owner']))     { $owner     = $_REQUEST['owner']; }     
else { $owner     = NULL; }
  if (isset($_REQUEST['bugowner']))  { $bugowner  = $_REQUEST['bugowner']; }  
else { $bugowner  = NULL; }

  d_StartPage(gettext("Select User"));

  if (!do_checkacs($_USER['access'])) exit;

  d_DrawNav($_USER['uname']);

  // form to delete user
  if ($action == "del") {
    d_DrawHeader(gettext("Delete User"));
    $db->query("SELECT * FROM users WHERE uid = '$moduserid'");
    $db->next_record();
    $db->free();
    if ($db->record['uid'] == 1) {
      print("<p>" . gettext("You cannot delete the administrator account.") . 
"</p>");
      d_DrawFooter();
      exit;
    }
    print("<form method=\"post\" action=\"editusers.php\">");
    print("<p>" . sprintf(gettext("Are you sure you want to delete the user 
<b>%s</b>?"), stripslashes($db->record['name'])) . "</p>");
    // check if this user owns any components
    $db->query("SELECT * FROM components WHERE (owner = '$moduserid') AND 
(deleted = '0')");
    if ($db->num_rows() > 0) {
      print("<p>" . gettext("This user owns the following components:") . 
"</p>");
      while ($db->next_record()) {
        print("<b>" . $db->record['name'] . "</b><br />");
      }
      $db->free();
      print("<p>" . gettext("If you want to delete this user, you should 
reassign their components to someone else.") . "</p>");
      print("<p>" . gettext("Select a new component owner:") . "</p>");
      print("<select name=\"owner\" value=\"1\">");
      $db->query("SELECT * FROM users WHERE (access >= '" . $config['devac'] . 
"') AND (deleted = '0')");
        while ($db->next_record()) {
          $user = $db->record;
          print(sprintf("<option 
value=\"%s\">%s</option>\n",$user['uid'],$user['email']));
        }
      print("</select>");
    }
    // check if this user owns any bugs
    $db->query("SELECT * FROM bugs WHERE assigned = '$moduserid'");
    if ($db->num_rows() > 0) {
      $db2         = new db_Sql();
      $db2->host   = $_CONF['db_host'];
      $db2->dbase  = $_CONF['db_name'];
      $db2->user   = $_CONF['db_user'];
      $db2->passwd = $_CONF['db_pw'];
      $db2->connect();
      print("<p>" . gettext("This user owns the following bugs:") . "</p>");
      while ($db->next_record()) {
        $db2->query("SELECT name FROM status_d WHERE id = '" . 
$db->record['status'] . "'");
        $db2->next_record();
        $status = $db2->record['name'];
        $db2->free();
        print(sprintf("<b>%s</b>: %s (%s)<br />",$db->record['bid'], 
$db->record['shortdesc'], $status));
      }
      $db->free();
      print("<p>" . gettext("If you want to delete this user, you should 
reassign their bugs to someone else.") . "</p>");
      print("<p>" . gettext("Select a new component owner:") . "</p>");
      print("<select name=\"bugowner\" value=\"1\">");
      $db->query("SELECT * FROM users WHERE (access >= '" . $config['devac'] . 
"') AND (deleted = '0')");
        while ($db->next_record()) {
          $user = $db->record;
          print(sprintf("<option 
value=\"%s\">%s</option>\n",$user['uid'],$user['email']));
        }
      print("</select>");
    }
    print("<br /><br /><input type=\"submit\" value=\"" . gettext("Delete 
User") . "\">");
    print("<input type=\"hidden\" name=\"moduserid\" value=\"$moduserid\">");
    print("<input type=\"hidden\" name=\"action\" value=\"delete\">");
    print("</form>");
    d_DrawFooter();
    exit;
  }

  // perform delete (we don't actually really delete the user)
  if ($action == "delete") {
    d_DrawHeader(gettext("Delete User"));
    $db->query("UPDATE users SET deleted = '1' WHERE uid = '$moduserid'");
    $db->free();
    print("<span class=\"text\"><center>" . gettext("User removed.") . 
"</center></span>");
    if (isset($owner)) {
      $db->query("UPDATE components SET owner = '$owner' WHERE (owner = 
'$moduserid') AND (deleted = '0')");
      $db->free();
      print("<p>" . gettext("Components re-assigned.") . "</p>");
    }
    if (isset($bugowner)) {
      $db->query("UPDATE bugs SET assigned = '$bugowner' WHERE assigned = 
'$moduserid'");
      $db->free();
      print("<p>" . gettext("Bugs re-assigned.") . "</p>");
    }
    print("<p>" . gettext("Return to <a href=\"editusers.php\">user list</a>.") 
. "</p>");
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // form to edit user
  if ($action == "edit") {
    d_DrawHeader(gettext("Edit User"));
    d_DrawEditUser($moduserid);
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // change user
  if ($action == "change") {
    d_DrawHeader(gettext("Edit User"));
    $query  = "UPDATE users SET name = '" . addslashes(htmlspecialchars($name)) 
. "' ";
    $query .= "WHERE uid = '$moduserid'";
    $db->query($query);
    $db->free();
    $query  = "UPDATE users SET uname = '" . 
addslashes(htmlspecialchars($uname)) . "' ";
    $query .= "WHERE uid = '$moduserid'";
    $db->query($query);
    $db->free();
    $query  = "UPDATE users SET email = '" . 
addslashes(htmlspecialchars($email)) . "' ";
    $query .= "WHERE uid = '$moduserid'";
    $db->query($query);
    $db->free();
    $db->query("UPDATE users SET access = '$access' WHERE uid = '$moduserid'");
    $db->free();

    if ($pass1 != "") {
      if ($pass1 == $pass2) {
        $cpass  = md5($pass1);
        $query  = "UPDATE users SET passwd = '" . $cpass . "' ";
        $query .= "WHERE uid = '$moduserid'";
        $db->query($query);
        $db->free();
      } else {
        print("<span class=\"text\"><font color=\"red\"><center>" . 
gettext("Passwords do not match; no change to user's password.") . 
"</center></font></span>");
      }
    }

    print("<span class=\"text\"><center>" . gettext("User information 
changed.") . "</center></span>");
    print("<p>" . gettext("Return to <a href=\"editusers.php\">user list</a>.") 
. "</p>");
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // default action
  d_DrawHeader(gettext("Select User"));
  $db->query("SELECT * FROM users WHERE deleted = '0'");

?>
  <table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr bgcolor="#8b95a8">
      <td width="5%">
        <? print(gettext("User ID")); ?>
      </td>
      <td width="15%">
        <? print(gettext("Real Name")); ?>
      </td>
      <td width="10%">
        <? print(gettext("User Name")); ?>
      </td>
      <td width="30%">
        <? print(gettext("Email Address")); ?>
      </td>
      <td width="20%">
        <? print(gettext ("Last Login")); ?>
      </td>
      <td width="10%">
        <? print(gettext("Access Level")); ?>
      </td>
      <td width="10%" align="right">
        <? print(gettext("Action")); ?>
      </td>
    </tr>
<?
  while ($db->next_record()) {
?>
    <tr>
      <td width="5%">
        <? print($db->record['uid']); ?>
      </td>
      <td width="15%">
        <? print(sprintf("<a 
href=\"editusers.php?moduserid=%s&action=edit\">%s</a>",$db->record['uid'],stripslashes($db->record['name'])));
 ?>
      </td>
      <td width="10%">
        <? print($db->record['uname']); ?>
      </td>
      <td width="30%">
        <? print($db->record['email']); ?>
      </td>
      <td width="20%">
        <? print($db->record['laston']); ?>
      </td>
      <td width="10%">
        <? print($db->record['access']); ?>
      </td>
      <td width="10%" align="right">
        <? print(sprintf("<a href=\"editusers.php?moduserid=%s&action=del\">" . 
gettext("Delete") . "</a>",$db->record['uid'])); ?>
      </td>
    </tr>
<?
  }
?>
    <tr>
      <td width="20%" colspan="2">
        <? print(gettext("Add a new user")); ?>
      </td>
      <td width="10%">
        <a href="newuser.php?admin=1"><? print(gettext("Add")); ?></a>
      </td>
    </tr>
  </table>

<?
  print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
  d_DrawFooter();
?>

====================================================
Index: editproducts.php
<?
  // Anthill
  // $Id: editproducts.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['action']))      { $action      = $_REQUEST['action']; }  
    else { $action      = NULL; }
  if (isset($_REQUEST['name']))        { $name        = $_REQUEST['name']; }    
    else { $name        = NULL; }
  if (isset($_REQUEST['description'])) { $description = 
$_REQUEST['description']; } else { $description = NULL; }
  if (isset($_REQUEST['pid']))         { $pid         = $_REQUEST['pid']; }     
    else { $pid         = NULL; }

  d_StartPage(gettext("Select Product"));

  if (!do_checkacs($_USER['access'])) exit;

  d_DrawNav($_USER['uname']);

  // form to add new product
  if ($action == "add") {
    d_DrawHeader(gettext("Add Product"));
    d_DrawEditProd("insert",0);
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // insert new product
  if ($action == "insert") {
    d_DrawHeader(gettext("Add Product"));
    // make sure product doesn't already exist
    $db->query("SELECT * FROM products WHERE (name = '$name') AND (deleted = 
'0')");
    if ($db->num_rows() > 0) {
      print("<p>" . gettext("A product by this name already exists.") . "</p>");
    } else {
      if ($name == "") {
        print("<p>" . gettext("ERROR: You submitted an empty field.") . "</p>");
      } else {
        $query  = "INSERT INTO products (pid, name, description) VALUES ";
        $query .= "(NULL, '" . addslashes($name) . "', '";
        $query .= addslashes(htmlspecialchars($description)) . "')";
        $db->query($query);
        $db->free();
        print("<span class=\"text\"><center>" . gettext("Product added 
successfully") . "</center></span>");
      }
    }
    print("<p>" . gettext("Return to <a href=\"editproducts.php\">products and 
components</a>.") . "</p>");
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // form to delete product
  if ($action == "del") {
    d_DrawHeader(gettext("Delete Product"));
    $db->query("SELECT * FROM products WHERE pid = '$pid'");
    $db->next_record();
    $db->free();
?>
  <form method="post" action="editproducts.php">
  <p><? print(sprintf(gettext("Are you sure you want to delete the product 
<b>%s</b>?"), stripslashes($db->record['name']))); ?>
  </p>
  <input type="submit" value="<? print(gettext("Delete")); ?>">
  <input type="hidden" name="pid" value="<? print($pid); ?>">
  <input type="hidden" name="action" value="delete">
  </form>
<?
    d_DrawFooter();
    exit;
  }

  // perform "delete"
  if ($action == "delete") {
    d_DrawHeader(gettext("Delete Product"));
    $db->query("UPDATE products SET deleted = '1' WHERE pid = '$pid'");
    $db->free();
    print("<span class=\"text\"><center>" . gettext("Product removed.") . 
"</center></span>");
    print("<p>" . gettext("Return to <a href=\"editproducts.php\">products and 
components</a>.") . "</p>");
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // form to edit product
  if ($action == "edit") {
    d_DrawHeader(gettext("Change Product"));
    d_DrawEditProd("change",$pid);
?>
    <table border="0" cellpadding="0" cellspacing="0" width="100%">
      <tr>
        <td width="50%" align="right" valign="top">
          <a href="editcomponents.php?pid=<? print($pid); ?>"><? 
print(gettext("Edit components")); ?>:</a>
        </td>
        <td width="50%">
          <? $db->query("SELECT * FROM components WHERE (product = '$pid') AND 
(deleted = '0') ORDER BY name");
             while ($db->next_record()) {
               print(sprintf("<b>%s</b>: %s<br 
/>",stripslashes($db->record['name']),stripslashes($db->record['description'])));
             }
             $db->free();
          ?>
        </td>
      </tr>
      <tr>
        <td width="50%" align="right" valign="top">
          <a href="editversions.php?pid=<? print($pid); ?>"><? 
print(gettext("Edit versions")); ?>:</a>
        </td>
        <td width="50%">
          <? $db->query("SELECT * FROM versions WHERE (product = '$pid') AND 
(deleted = '0') ORDER BY name");
             while ($db->next_record()) {
               print(sprintf("<b>%s</b><br />",$db->record['name']));
             }
             $db->free();
          ?>
        </td>
      </tr>
    </table>
<?
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // change product
  if ($action == "change") {
    d_DrawHeader(gettext("Change Product"));
    $query  = "UPDATE products SET name = '" . 
addslashes(htmlspecialchars($name)) . "' ";
    $query .= "WHERE pid = '$pid'";
    $db->query($query);
    $db->free();
    $query  = "UPDATE products SET description = '" . 
addslashes(htmlspecialchars($description)) . "' ";
    $query .= "WHERE pid = '$pid'";
    $db->query($query);
    $db->free();
    print("<span class=\"text\"><center>" . gettext("Product changed.") . 
"</center></span>");
    print("<p>" . gettext("Return to <a href=\"editproducts.php\">products and 
components</a>.") . "</p>");
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // default action
  d_DrawHeader(gettext("Select Product"));

  $db2         = new db_Sql();
  $db2->host   = $_CONF['db_host'];
  $db2->dbase  = $_CONF['db_name'];
  $db2->user   = $_CONF['db_user'];
  $db2->passwd = $_CONF['db_pw'];
  $db2->connect();

  $db->query("SELECT * FROM products WHERE deleted = '0'");

?>
  <table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr bgcolor="#8b95a8">
      <td width="20%">
        <? print(gettext("Product")); ?>
      </td>
      <td width="60%">
        <? print(gettext("Description")); ?>
      </td>
      <td width="10%">
        <? print(gettext("Bugs")); ?>
      </td>
      <td width="10%">
        <? print(gettext("Action")); ?>
      </td>
    </tr>
<?
  while ($db->next_record()) {
    $pid = $db->record['pid'];
?>
    <tr>
      <td width="20%">
        <? print(sprintf("<a 
href=\"editproducts.php?pid=%s&action=edit\">%s</a>",$pid,stripslashes($db->record['name'])));
 ?>
      </td>
      <td width="60%">
        <? print(stripslashes($db->record['description'])); ?>
      </td>
      <td width="10%">
        <? $db2->query("SELECT * FROM bugs WHERE product='$pid'");
           $bugs  = $db2->num_rows();
           print($bugs);
        ?>
      </td>
      <td width="10%">
        <? print("<a href=\"editproducts.php?pid=$pid&action=del\">" . 
gettext("Delete") . "</a>"); ?>
      </td>
    </tr>
<?
  }
  $db->free();
?>
    <tr>
      <td colspan="3" width="90%">
        <? print(gettext("Add a new product")); ?>
      </td>
      <td width="10%">
        <a href="editproducts.php?action=add"><? print(gettext("Add")); ?></a>
      </td>
    </tr>
  </table>

  <p><? print(gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.")); ?></p>

<?
  d_DrawFooter();
?>

====================================================
Index: gpgupload.php
<?
  // Anthill
  // $Id: gpgupload.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_FILES['gfile']['size']))     { $gfile_size  = 
$_FILES['gfile']['size']; }     else { $gfile_size  = NULL; }
  if (isset($_FILES['gfile']['name']))     { $gfile_name  = 
$_FILES['gfile']['name']; }     else { $gfile_name  = NULL; }
  if (isset($_FILES['gfile']['tmp_name'])) { $gfile       = 
$_FILES['gfile']['tmp_name']; } else { $gfile       = NULL; }
  if (isset($_FILES['gfile']['type']))     { $gfile_type  = 
$_FILES['gfile']['type']; }     else { $gfile_type  = NULL; }
  if (isset($_FILES['gfile']['error']))    { $gfile_error = 
$_FILES['gfile']['error']; }    else { $gfile_error = NULL; }

  d_StartPage(gettext("Upload GPG/PGP Keyfile"));
  d_DrawNav($_USER['uname']);
  d_DrawHeader(gettext("Upload GPG/PGP Keyfile"));

  if ($gfile == "none") {
    print("<p>" . gettext("No keyfile uploaded.") . "</p>");
    d_DrawFooter();
    exit;
  }
  if ($gfile_size == 0) {
    print("<p>" . gettext("The keyfile uploaded is zero bytes.") . "</p>");
    d_DrawFooter();
    exit;
  }
// .asc files come up with Type: <none>
//  if ($gfile_type != "text/plain") {
//    print("<p>" . gettext("The keyfile uploaded is not a text file.") . 
"</p>");
//    d_DrawFooter();
//    exit;
//  }
  if (!is_uploaded_file($gfile)) {
    print("<p>" . gettext("The keyfile was not uploaded... possible file upload 
attack?") . "</p>");
    d_DrawFooter();
    exit;
  }

  $newfile = $_CONF['root'] . $_CONF['gpgdir'] . "/" . $_USER['uid'] . ".asc";

  print("<p>" . gettext("Keyfile uploaded successfully!") . "</p>");

  /// read in the keyfile
  $fp   = fopen($gfile, "r");
  $data = fread($fp, filesize($gfile));
  fclose($fp);

  // let's make sure it's a valid PGP/GPG key first
  if (ereg("^-----BEGIN PGP PUBLIC KEY BLOCK-----",$data)) {
    if (ereg("-----END PGP PUBLIC KEY BLOCK-----",$data, $array)) {
      $valid = 1;
    } else {
      $valid = 0;
    }
  } else {
    $valid = 0;
  }

  if ($valid == 0) {
    print("<p><font color=\"red\">" . gettext("The file you uploaded is not a 
valid PGP/GPG key file.") . "</font></p>");
  } else {
    $data = strip_tags($data);
    print("<p>" . gettext("The keyfile uploaded contains") . ":</p>");
    print("<pre>" . $data . "</pre>");

    // write the keyfile
    $fp   = fopen($newfile, "w");
    fwrite($fp, $data);
    fclose($fp);
    $gname  = $_CONF['gpgdir'] . "/" . $_USER['uid'] . ".asc";
    $db->query("UPDATE users SET gpg = '$gname' WHERE uid = '" . $_USER['uid'] 
. "'");
    $db->free();
  }

  print("<p><a href=\"pref.php\">" . gettext("Return to Preferences") . 
"</a></p>");

  d_DrawFooter();

?>

====================================================
Index: index.php
<?php
  /****************************************************************************
   * Anthill                                                                  *
   * http://anthill.vmlinuz.ca                                                *
   *                                                                          *
   * Written by Vincent Danen address@hidden                              *
   *   and Dave Hall [skwashd AT phpgroupware.org]                            *
   * ------------------------------------------------------------------------ *
   * This program is free software; you can redistribute it 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.                                               *
   * ------------------------------------------------------------------------ *
   ****************************************************************************/
   // $Id: index.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

    $GLOBALS['phpgw_info']['flags'] = array
    (
        'currentapp' => 'anthill',
        'noheader'   => True,
        'nonavbar'   => True
    );
    include('../header.inc.php');

   $GLOBALS['phpgw']->redirect_link('/index.php', array('menuaction' => 
'anthill.uianthill.index'));
   exit;
?>

====================================================
Index: postbug.php
<?
  // Anthill
  // $Id: postbug.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['reporter']))  { $reporter  = $_REQUEST['reporter']; }  
else { $reporter  = NULL; }
  if (isset($_REQUEST['product']))   { $product   = $_REQUEST['product']; }   
else { $product   = NULL; }
  if (isset($_REQUEST['version']))   { $version   = $_REQUEST['version']; }   
else { $version   = NULL; }
  if (isset($_REQUEST['component'])) { $component = $_REQUEST['component']; } 
else { $component = NULL; }
  if (isset($_REQUEST['prior']))     { $prior     = $_REQUEST['prior']; }     
else { $prior     = NULL; }
  if (isset($_REQUEST['sever']))     { $sever     = $_REQUEST['sever']; }     
else { $sever     = NULL; }
  if (isset($_REQUEST['status']))    { $status    = $_REQUEST['status']; }    
else { $status    = NULL; }
  if (isset($_REQUEST['assigned']))  { $assigned  = $_REQUEST['assigned']; }  
else { $assigned  = NULL; }
  if (isset($_REQUEST['shortdesc'])) { $shortdesc = $_REQUEST['shortdesc']; } 
else { $shortdesc = NULL; }
  if (isset($_REQUEST['longdesc']))  { $longdesc  = $_REQUEST['longdesc']; }  
else { $longdesc  = NULL; }
  if (isset($_REQUEST['url']))       { $url       = $_REQUEST['url']; }       
else { $url       = NULL; }

  d_StartPage(gettext("Posting Bug"));
  d_DrawNav($_USER['uname']);
  d_DrawHeader(gettext("Posting Bug"));

  if (!isset($_USER['uid'])) {
    print("<p>" . gettext("You must login to access this page.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // reporter (uid), product (pid), version (vid), component (cid)
  // priority, severity, assigned (uid), shortdesc, longdesc

  // get the default status
  $db->query("SELECT * FROM status_d WHERE s_def = '1'");
  $db->next_record();
  $status = $db->record['id'];
  $db->free();

  if ($assigned == 0) { // chosen to assign to component owner
    $db->query("SELECT * FROM components WHERE cid = '$component'");
    $db->next_record();
    $assigned = $db->record['owner'];
    $db->free();
  }

  $db->query("SELECT * FROM users WHERE uid = '$assigned'");
  $db->next_record();
  if ($db->record['access'] < $config['devac']) { // assigned user's access is 
lower than developer access
    print("<span class=\"text\"><center>" . gettext("ERROR: You have assigned 
the bug to someone unauthorized to own bugs.") . "</center></span><br />");
    d_drawFooter();
    exit;
  }

  if ($shortdesc == "") { // no short description entered
    print("<span class=\"text\"><center>" . gettext("ERROR: You need to include 
a summary of the bug.") . "</center></span><br />");
    d_drawFooter();
    exit;
  }

  if ($longdesc == "") { // no long description entered
    print("<span class=\"text\"><center>" . gettext("ERROR: You need to include 
a description of the bug.") . "</center></span><br />");
    d_drawFooter();
    exit;
  }

  if ($version == 0) { // no version chosen
    print("<span class=\"text\"><center>" . gettext("ERROR: You need to select 
a version for this bug.") . "</center></span><br />");
    d_drawFooter();
    exit;
  }

  if ($component == 0) { // no component chosen
    print("<span class=\"text\"><center>" . gettext("ERROR: You need to select 
a component for this bug.") . "</center></span><br />");
    d_drawFooter();
    exit;
  }

  // create the autocc string
  $query    = "SELECT autocc from components WHERE cid = '$component'";
  $db->query($query);
  $db->next_record();
  $autocc   = $db->record['autocc'];
  $db->free();
  if ($config['autocc'] != "") {
    if ($autocc != "") {
      $autocc = $config['autocc'] . ", " . $autocc;
    } else {
      $autocc = $config['autocc'];
    }
  }
  $creation = date("YmdGis");  // use same format as timestamp
  $query    = "INSERT INTO bugs (bid, assigned, severity, status, creation, ";
  $query   .= "modified, shortdesc, priority, product, reporter, version, ";
  $query   .= "component, resolution, cc, private, url) VALUES ";
  $query   .= "(NULL,'$assigned','$sever','$status', ";
  $query   .= "'$creation', NULL, '" . addslashes($shortdesc) . "', ";
  $query   .= "'$prior','$product','$reporter','$version','$component', ";
  $query   .= "NULL, '$autocc', ". $config['defpriv'] . ", ";
  $query   .= "'" . trim(addslashes($url)) . "')";
  $db->query($query);
  $db->free();
  $db->query("SELECT * FROM bugs ORDER BY bid DESC");
  $db->next_record();
  $bugnum   = $db->record['bid'];
  $db->free();
  $query    = "INSERT INTO bugdesc (did, bid, user, date, system, description) 
VALUES ";
  $query   .= "(NULL,'$bugnum','$reporter',NULL,0,";
  $query   .= "'" . addslashes($longdesc) . "')";
  $db->query($query);
  $db->free();

  d_doDiff($bugnum);

  print("<p><b>" . sprintf(gettext("Bug #%s posted"), $bugnum) . ".</b></p>");
  print("<p><a href=\"query.php?bug=$bugnum\">" . sprintf(gettext("Back to Bug 
#%s"), $bugnum) . "</a>&nbsp;&nbsp;&nbsp;&nbsp;");
  print("<a href=\"enterbug.php\">" . gettext("Enter another bug") . 
"</a>&nbsp;&nbsp;&nbsp;&nbsp;</p>");

  d_DrawFooter();
?>

====================================================
Index: newuser.php
<?
  // Anthill
  // $Id: newuser.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['go']))    { $go    = $_REQUEST['go']; }    else { $go    
= NULL; }
  if (isset($_REQUEST['email'])) { $email = $_REQUEST['email']; } else { $email 
= NULL; }
  if (isset($_REQUEST['uname'])) { $uname = $_REQUEST['uname']; } else { $uname 
= NULL; }
  if (isset($_REQUEST['rname'])) { $rname = $_REQUEST['rname']; } else { $rname 
= NULL; }

  d_StartPage(gettext("New User Registration"));

  // generate new password for existing user
  if ($go == "newpass") {
    // $email, $uname
    d_DrawNav($_USER['uname']);
    d_DrawHeader(gettext("New User Registration"));

    $db->query("SELECT * FROM users WHERE (uname = '$uname') AND 
(deleted='0')");
    $db->next_record();
    $user  = $db->record;
    $db->free();

    if (!isset($user['uname'])) {
      print("<p>" . gettext("The username supplied does not exist on this 
system.") . "</p>");
      d_DrawFooter();
      exit;
    }

    if ($user['email'] == $email) {
      $newpass  = do_newPass($uname);
      $cpass    = md5($newpass);
      $db->query("UPDATE users SET passwd = '$cpass' WHERE (uid=" . 
$user['uid'] . ") ");
      $db->free();

      // get the maximum string length to format the email nicely
      $msg[0]   = gettext("Login name");
      $msg[1]   = gettext("Password");
      $limit    = count($msg);
      $size     = 0;
      for ($i=0; $i < $limit; $i++) {
        if (strlen($msg[$i]) > $size) {
          $size = strlen($msg[$i]);
        }
      }
      for ($i=0; $i < $limit; $i++) {
        $buff = $size - strlen($msg[$i]);
        if ($buff > 0) {
          $msg[$i] = $msg[$i] . str_repeat(" ", $buff);
        }
      }

      $message  = gettext("In order to use Anthill, you must use the following 
to log in") . ":\n\n";
      $message .= $msg[0] . ": " . $user['uname'] . "\n";
      $message .= $msg[1] . ": " . $newpass . "\n\n";
      $message .= gettext("To change your password, log in and go to 
\"Preferences\".") . "\n";
      $message .= "\n--\n" . $_CONF['webroot'] . "\n";
      $retval   = @mail($user['name'] . " <" . $user['email'] . ">",
                  gettext("Your Anthill password") , $message,
                  "From: " . $config['mdaemon'] . " <" . $config['memail'] . 
">\nReturn-Path: <" . $config['memail'] . ">\nX-Mailer: " . _NAME . " " . 
_VERSION);
      print("<p>" . sprintf(gettext("A new password has been emailed to %s."), 
$email) . "</p>");
    } else {
      print("<p>" . sprintf(gettext("The username you entered: <b>%s</b> does 
not match the supplied email address: <b>%s</b>."), $uname, $email));
      print(sprintf(gettext("Please go back and enter your proper email address 
and user name.  If you have forgotten your username, please email the <a 
href=\"mailto:%s\";>administrator</a>."), $config['adminemail']) . "</p>");
    }
    d_DrawFooter();
    exit;
  }

  // generate new user
  if ($go == "newuser") {
    $msg = do_checkUser($uname, $email, 0, 0);
    if (!isset($msg)) {
      if (isset($_USER['uid']) && $_USER['access'] >= $config['adminac']) {
        $msg = "<span class=\"text\"><center>" . sprintf(gettext("Password has 
been emailed to %s.  You can return to <a href=\"editusers.php\">Edit User 
Preferences</a>."), $email);
      } else {
        $msg = "<span class=\"text\"><center>" . sprintf(gettext("Thank you for 
registering.  A password has been emailed to %s.  Use this password to log into 
%s."), $email, $config['sitename']) . "</center></span>";
      }

      $newpass  = do_newPass($uname);
      $now      = date(sprintf("%s %s",$_CONF['datefmt'],$_CONF['timefmt']));
      $cpass    = md5($newpass);

      $query    = "INSERT INTO users (uid, name, uname, email, passwd, ";
      $query   .= "access, laston) VALUES ";
      $query   .= "(NULL,'" . addslashes(htmlspecialchars($rname)) . "',";
      $query   .= "'" . addslashes(htmlspecialchars($uname)) . "',";
      $query   .= "'" . addslashes(htmlspecialchars($email)) . "',";
      $query   .= "'$cpass','1','$now') ";
      $db->query($query);
      $db->free();

      // get the maximum string length to format the email nicely
      $emsg[0]  = gettext("Login name");
      $emsg[1]  = gettext("Password");
      $limit    = count($emsg);
      $size     = 0;
      for ($i=0; $i < $limit; $i++) {
        if (strlen($emsg[$i]) > $size) {
          $size = strlen($emsg[$i]);
        }
      }
      for ($i=0; $i < $limit; $i++) {
        $buff = $size - strlen($emsg[$i]);
        if ($buff > 0) {
          $emsg[$i] = $emsg[$i] . str_repeat(" ", $buff);
        }
      }

      $message  = gettext("In order to use Anthill, you must use the following 
to log in") . ":\n\n";
      $message .= $emsg[0] . ": " . $uname . "\n";
      $message .= $emsg[1] . ": " . $newpass . "\n\n";
      $message .= gettext("To change your password, log in and go to 
\"Preferences\".") . "\n";
      $message .= "\n--\n" . $_CONF['webroot'] . "\n";
      $retval   = @mail($rname . " <" . $email . ">",
                  gettext("Your Anthill password"), $message,
                  "From: " . $config['mdaemon'] . " <" . $config['memail'] . 
">\nReturn-Path: <" . $config['memail'] . ">\nX-Mailer: " . _NAME . " " . 
_VERSION);
    }
    d_DrawNav($_USER['uname']);
    d_DrawHeader(gettext("New User Registration"));
    print($msg);

    d_DrawFooter();
    exit;
  }

  // load form
  d_DrawNav($_USER['uname']);
  d_DrawHeader(gettext("New User Registration"));

  if ($config['newusers'] == 1 || $admin == 1) {
    d_DrawNewUser();
  } else {
?>
  <p><? print(sprintf(gettext("We're sorry... this is a private site and new 
users must be added by the administrator.  Try sending an email to request 
access to <a href=\"mailto:%s\";>%s</a>."), $config['adminemail'], 
$config['adminemail'])); ?></p>
<?
  }

  d_DrawFooter();
?>

====================================================
Index: logout.php
<?
  /****************************************************************************
   * Anthill                                                                  *
   * http://anthill.vmlinuz.ca                                                *
   *                                                                          *
   * Written by Vincent Danen address@hidden                              *
   *   and Dave Hall [skwashd AT phpgroupware.org]                            *
   * ------------------------------------------------------------------------ *
   * This program is free software; you can redistribute it 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.                                               *
   * ------------------------------------------------------------------------ *
   ****************************************************************************/
   /* $Id: logout.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $ */

  include('./inc/config.inc.php');

  $GLOBALS['anthill']->sessions->destroy($_GET['sessionod'], $_GET['checksum']);
  Header('Location: login.php?error_id=2');

?>

====================================================
Index: login.php
<?
  /****************************************************************************
   * Anthill                                                                  *
   * http://anthill.vmlinuz.ca                                                *
   *                                                                          *
   * Written by Vincent Danen address@hidden                              *
   *   and Dave Hall [skwashd AT phpgroupware.org]                            *
   * ------------------------------------------------------------------------ *
   * This program is free software; you can redistribute it 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.                                               *
   * ------------------------------------------------------------------------ *
   ****************************************************************************/
   /* $Id: login.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $ */

  include('./inc/config.inc.php');

  $error_id = $_GET['error_id'];

  if ($GLOBALS['anthill_info']['mode'] == 'anthill')
  {
    if (isset($_POST['login']))
    {
      if ($GLOBALS['anthill']->sessions->create($_POST['uname'], 
$_POST['passwd']))
      {
        Header('Location: ' . $GLOBALS['anthill']->link('/index.php', 
array('menuaction' => 'anthill.ui.index')));
        exit();
      }
      else
      {
        $error_id = 1;
      }
    }
  }
  else //no auth for phpgw
  {
    Header('Location: ' . $GLOBALS['anthill']->link('/index.php', 
array('menuaction' => 'anthill.ui.index')));
    exit;
  }
  switch($error_id)
  {
    case 1:
      $msg = lang('Login failed.  You entered an invalid username or incorrect 
password');
      break;

    case 2:
      $msg = lang('logout sucessful');
      break;
    default:
      $msg = '';
      break;
  }

  page_header(lang('login'));

  $GLOBALS['anthill']->tpl->set_file('login', 'login.tpl');
  $GLOBALS['anthill']->tpl->set_var('form_action', $_SERVER['PHP_SELF']);
  $GLOBALS['anthill']->tpl->set_var('msg', $msg);
  $GLOBALS['anthill']->tpl->set_var('lang_username', lang('username'));
  $GLOBALS['anthill']->tpl->set_var('last_login', @$_COOKIE['last_loginid']);
  $GLOBALS['anthill']->tpl->set_var('lang_password', lang('password'));
  $GLOBALS['anthill']->tpl->set_var('lang_login', lang('login'));
  $GLOBALS['anthill']->tpl->set_var('lang_username', lang('username'));
  $GLOBALS['anthill']->tpl->set_var('url_new_user', 
$GLOBALS['anthill_info']['path']['root'] . '/register.php');
  $GLOBALS['anthill']->tpl->set_var('lang_new_user', lang('If you do not have a 
password, or have forgotten it, then please fill out the registration page.'));
  $GLOBALS['anthill']->tpl->set_var('url_anon', 
(@$GLOBALS['anthill_info']['path']['root'] . '/index2.php'));
  $GLOBALS['anthill']->tpl->set_var('lang_anon', lang('Or, you can browse 
without having to reigster.'));
  $GLOBALS['anthill']->tpl->pfp('out', 'login');

  page_footer();
?>

====================================================
Index: editcomponents.php
<?
  // Anthill
  // $Id: editcomponents.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['action']))      { $action      = $_REQUEST['action']; }  
    else { $action      = NULL; }
  if (isset($_REQUEST['pid']))         { $pid         = $_REQUEST['pid']; }     
    else { $pid         = NULL; }
  if (isset($_REQUEST['cid']))         { $cid         = $_REQUEST['cid']; }     
    else { $cid         = NULL; }
  if (isset($_REQUEST['name']))        { $name        = $_REQUEST['name']; }    
    else { $name        = NULL; }
  if (isset($_REQUEST['owner']))       { $owner       = $_REQUEST['owner']; }   
    else { $owner       = NULL; }
  if (isset($_REQUEST['description'])) { $description = 
$_REQUEST['description']; } else { $description = NULL; }

  d_StartPage(gettext("Select Component"));

  if (!do_checkacs($_USER['access'])) exit;

  d_DrawNav($_USER['uname']);

  // form to add new component
  if ($action == "add") {
    d_DrawHeader(gettext("Add Component"));
    d_DrawEditComp("insert",0,$pid);
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // insert new component
  if ($action == "insert") {
    d_DrawHeader(gettext("Add Component"));
    // make sure a component by this name doesn't already exist
    $db->query("SELECT * FROM components WHERE (name = '$name') AND (deleted = 
'0') AND (product = '$pid')");
    if ($db->num_rows() > 0) {
      print("<p>" . gettext("A component by this name already exists.") . 
"</p>");
    } else {
      if ($name == "") {
        print("<p>" . gettext("ERROR: You submitted an empty field.") . "</p>");
      } else {
        // clean up the autocc string
        $tmp    = explode(",",$autocc);
        $x      = count($tmp);
        for ($i=0; $i<$x; $i++) {
          $tmp[$i] = trim($tmp[$i]);
        }
        $autocc = implode($tmp,", ");
        $query  = "INSERT INTO components (cid, name, product, ";
        $query .= "owner, description, autocc) VALUES ";
        $query .= "(NULL, ";
        $query .= "'" . addslashes(htmlspecialchars($name)) . "', '" . $pid . 
"', ";
        $query .= "'" . addslashes(htmlspecialchars($owner)) . "', ";
        $query .= "'" . addslashes(htmlspecialchars($description)) . "',";
        $query .= "'" . addslashes(htmlspecialchars($autocc)) . "')";
        $db->query($query);
        $db->free();
        print("<span class=\"text\"><center>" . gettext("Component added 
successfully.") . "</center></span>");
      }
    }
    print("<p>" . sprintf(gettext("Return to <a 
href=\"editcomponents.php?pid=%s\">components</a>."), $pid) . "<br />");
    print(gettext("Return to <a href=\"editproducts.php\">products and 
components</a>.") . "</p>");
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // form to delete component
  if ($action == "del") {
    d_DrawHeader(gettext("Delete Component"));
    $db->query("SELECT * FROM components WHERE cid = '$cid'");
    $db->next_record();
    $db->free();
?>
  <form method="post" action="editcomponents.php">
  <p><? print(sprintf(gettext("Are you sure you want to delete the component 
<b>%s</b>?"), stripslashes($db->record['name']))); ?>
  </p>
  <input type="submit" value="<? print(gettext("Delete")); ?>">
  <input type="hidden" name="cid" value="<? print($cid); ?>">
  <input type="hidden" name="pid" value="<? print($pid); ?>">
  <input type="hidden" name="action" value="delete">
  </form>
<?
    d_DrawFooter();
    exit;
  }

  // perform delete
  if ($action == "delete") {
    d_DrawHeader(gettext("Delete Component"));
    $db->query("UPDATE components SET deleted = '1' WHERE cid = '$cid'");
    $db->free();
    print("<span class=\"text\"><center>" . gettext("Component removed.") . 
"</center></span>");
    print("<p>" . sprintf(gettext("Return to <a 
href=\"editcomponents.php?pid=%s\">components</a>."), $pid)) . "<br />";
    print(gettext("Return to <a href=\"editproducts.php\">products and 
components</a>.") . "</p>");
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // form to edit component
  if ($action == "edit") {
    d_DrawHeader(gettext("Change Component"));
    d_DrawEditComp("change",$cid,$pid);
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // change component
  if ($action == "change") {
    d_DrawHeader(gettext("Change Component"));
    // clean up the autocc string
    $tmp    = explode(",",$autocc);
    $x      = count($tmp);
    for ($i=0; $i<$x; $i++) {
      $tmp[$i] = trim($tmp[$i]);
    }
    $autocc = implode($tmp,", ");
    $query  = "UPDATE components SET name = '" . 
addslashes(htmlspecialchars($name)) . "' ";
    $query .= "WHERE cid = '$cid'";
    $db->query($query);
    $db->free();
    $query  = "UPDATE components SET owner = '" . 
addslashes(htmlspecialchars($owner)) . "' ";
    $query .= "WHERE cid = '$cid'";
    $db->query($query);
    $db->free();
    $query  = "UPDATE components SET description = '" . 
addslashes(htmlspecialchars($description)) . "' ";
    $query .= "WHERE cid = '$cid'";
    $db->query($query);
    $db->free();
    $query  = "UPDATE components SET autocc = '" . 
addslashes(htmlspecialchars($autocc)) . "' ";
    $query .= "WHERE cid = '$cid'";
    $db->query($query);
    $db->free();
    print("<span class=\"text\"><center>" . gettext("Component changed.") . 
"</center></span>");
    print("<p>" . sprintf(gettext("Return to <a 
href=\"editcomponents.php?pid=%s\">components</a>."), $pid) . "<br />");
    print(gettext("Return to <a href=\"editproducts.php\">products and 
components</a>.") . "</p>");
    print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // default action
  d_DrawHeader(gettext("Select Component"));

  $db2         = new db_Sql();
  $db2->host   = $_CONF['db_host'];
  $db2->dbase  = $_CONF['db_name'];
  $db2->user   = $_CONF['db_user'];
  $db2->passwd = $_CONF['db_pw'];
  $db2->connect();

  $db->query("SELECT * FROM components WHERE (product = '$pid') AND (deleted = 
'0')");

?>
  <table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr bgcolor="#8b95a8">
      <td width="20%">
        <? print(gettext("Component")); ?>
      </td>
      <td width="50%">
        <? print(gettext("Description")); ?>
      </td>
      <td width="20%">
        <? print(gettext("Initial Owner")); ?>
      </td>
      <td width="10%">
        <? print(gettext("Action")); ?>
      </td>
    </tr>
<?
  while ($db->next_record()) {
    $cid = $db->record['cid'];
?>
    <tr>
      <td width="20%">
        <? print(sprintf("<a 
href=\"editcomponents.php?cid=%s&pid=%s&action=edit\">%s</a>",$cid,$pid,stripslashes($db->record['name'])));
 ?>
      </td>
      <td width="50%">
        <? print(stripslashes($db->record['description'])); ?>
      </td>
      <td width="20%">
        <? $db2->query("SELECT * FROM users WHERE uid = '" . 
$db->record['owner'] . "'");
           $db2->next_record();
           print(stripslashes($db2->record['email']));
           $db2->free();
        ?>
      </td>
      <td width="10%">
        <? print(sprintf("<a 
href=\"editcomponents.php?cid=%s&pid=%s&action=del\">" . gettext("Delete") . 
"</a>",$cid,$pid)); ?>
      </td>
    </tr>
<?
  }
?>
    <tr>
      <td width="20%">
        <? print(gettext("Add a new component")); ?>
      </td>
      <td width="10%">
        <a href="editcomponents.php?pid=<? print($pid); ?>&action=add"><? 
print(gettext("Add")); ?></a>
      </td>
    </tr>
  </table>

<?
  print("<p>" . gettext("Return to <a href=\"admin.php\">Anthill 
Preferences</a>.") . "</p>");
  d_DrawFooter();
?>

====================================================
Index: createattachment.php
<?
  // Anthill
  // $Id: createattachment.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['bug']))             { $bug         = $_REQUEST['bug']; } 
            else { $bug         = NULL; }
  if (isset($_REQUEST['doit']))            { $doit        = $_REQUEST['doit']; 
}            else { $doit        = NULL; }
  if (isset($_REQUEST['type']))            { $type        = $_REQUEST['type']; 
}            else { $type        = NULL; }
  if (isset($_REQUEST['description']))     { $description = 
$_REQUEST['description']; }     else { $description = NULL; }
  if (isset($_FILES['afile']['size']))     { $afile_size  = 
$_FILES['afile']['size']; }     else { $afile_size  = NULL; }
  if (isset($_FILES['afile']['name']))     { $afile_name  = 
$_FILES['afile']['name']; }     else { $afile_name  = NULL; }
  if (isset($_FILES['afile']['tmp_name'])) { $afile       = 
$_FILES['afile']['tmp_name']; } else { $afile       = NULL; }
  if (isset($_FILES['afile']['type']))     { $afile_type  = 
$_FILES['afile']['type']; }     else { $afile_type  = NULL; }
  if (isset($_FILES['afile']['error']))    { $afile_error = 
$_FILES['afile']['error']; }    else { $afile_error = NULL; }

  d_StartPage(gettext("Upload Attachment"));
  d_DrawNav($_USER['uname']);
  d_DrawHeader(gettext("Upload Attachment"));

  $db->query("SELECT * FROM bugs WHERE bid = $bug");
  $db->next_record();
  $private = $db->record['private'];
  $db->free();

  if ($private == 1 && !isset($_USER['uid'])) {
      print(gettext("The bug you selected is marked private and is not 
available to unregistered users."));
      d_DrawFooter();
      exit;
  }

  if (isset($doit)) { // attachment to upload
    if ($description == "") {
      print("<p>" . gettext("You need to enter a description of the 
attachment.") . "</p>");
      d_DrawFooter();
      exit;
    }
    if ($type == "") {
      print("<p>" . gettext("You need to enter a MIME type.") . "</p>");
      d_DrawFooter();
      exit;
    }
    if ($afile_error == "4") { // UPLOAD_ERR_NO_FILE
      print("<p>" . gettext("No attachment uploaded.") . "</p>");
      d_DrawFooter();
      exit;
    }
    if ($afile_size == 0) {
      print("<p>" . gettext("The attachment uploaded is zero bytes.") . "</p>");
      d_DrawFooter();
      exit;
    }
    if ($afile_error == "2") { // UPLOAD_ERR_FORM_SIZE
      print("<p>" . gettext("The attachment uploaded is too large.") . "</p>");
      d_DrawFooter();
      exit;
    }
    if ($afile_error == 1) { // UPLOAD_ERR_INI_SIZE
      print("<p>" . gettext("The attachment is larger than the system-wide 
maximum upload file size.") . "</p>");
      d_DrawFooter();
      exit;
    }
    if ($afile_error == 3) { //UPLOAD_ERR_PARTIAL
      print("<p>" . gettext("The attachment was not completely uploaded.") . 
"</p>");
      d_DrawFooter();
      exit;
    }
    if (!is_uploaded_file($afile)) {
      print("<p>" . gettext("The attachment was not uploaded... possible file 
upload attack?") . "</p>");
      d_DrawFooter();
      exit;
    }
    // final safety check
    if ($afile_error != 0) {
      print("<p>" . gettext("There was an unknown error with your attachment 
upload.") . "</p>");
      d_DrawFooter();
      exit;
    }

    // get the next name for the attachment
    $db->query("SELECT * FROM attachidx");
    if ($db->num_rows() == 0) {
      $count = 1;
      $nextattach = 1;
    } else {
      while ($db->next_record()) {
        $count = $db->record['atid'];
      }
      $count++;
      $nextattach = $count;
    }
    $db->free();
    $newfile = $_CONF['root'] . $_CONF['attachdir'] . "/" . $nextattach;
    // make sure the file doesn't exist
    if (is_file($newfile)) {
      // if it does, try to increment by one.. if that fails, send error
      $count++;
      $nextattach = $count;
      $newfile = $_CONF['root'] . $_CONF['attachdir'] . "/" . $nextattach;
      if (is_file($newfile)) {
        print("<p>" . gettext("ERROR: Attachment filename already exists.  
Upload aborted.") . "</p>");
        print("<p>" . gettext("Please notify the administrator of this site of 
this error.") . "</p>");
        d_DrawFooter();
        exit;
      }
    }

    $newfile = $_CONF['root'] . $_CONF['attachdir'] . "/" . $nextattach;
    if (!move_uploaded_file($afile, $newfile)) {
      print("<p>" . gettext("Problem copying attachment.  Aborting.") . "</p>");
      d_DrawFooter();
      exit;
    }

    $update = date("YmdGis");
    $fname  = $afile_name;
    if ($type == "patch") {
      $type = "text/plain";
    }
    if ($type == "othertype") {
      $type = $othertype;
    }
    if (!ereg("^([a-z-]+)/([a-z-]+)$", $type)) {
      print("<p>" . sprintf(gettext("You must select a legal mime type.  
'<i>%s</i>' is not acceptable."), $type) . "</p>");
      d_DrawFooter();
      exit;
    }

    $fp   = fopen($newfile, "r");
    $data = fread($fp, filesize($newfile));
    fclose($fp);

    print("<p>" . gettext("Attachment uploaded successfully!") . "</p>");

    $url   = sprintf("showattachment.php?id=%s", $nextattach);
    $cmnt  = sprintf(gettext("<a href=\"%s\">Created an attachment 
(id=%s)</a>\n"), $url, $nextattach);
    $cmnt2 = gettext("Description of attachment") . " #$nextattach: " . 
$description;

    $query  = "INSERT INTO bugdesc (did, bid, user, date, system, description) 
VALUES ";
    $query .= "(NULL,'$bug','" . $_USER['uid'] . "',NULL,1,";
    $query .= "'" . addslashes($cmnt) . "')";
    $db->query($query);
    $db->free();
    $query  = "INSERT INTO bugdesc (did, bid, user, date, system, description) 
VALUES ";
    $query .= "(NULL,'$bug','" . $_USER['uid'] . "',NULL,0,";
    $query .= "'" . addslashes($cmnt2) . "')";
    $db->query($query);
    $db->free();

    $query  = "INSERT INTO bugactivity (aid, bid, user, date, what) ";
    $query .= "VALUES (NULL, '$bug', '" . $_USER['uid'] . "', ";
    $query .= "NULL, '5')";
    $db->query($query);
    $db->free();

    $query  = "INSERT INTO attachidx (atid, bid, date, mimetype, filename, 
user)";
    $query .= " VALUES ('$nextattach', '$bug', '$update', '$type', '$fname', ";
    $query .= "'" . $_USER['uid'] . "')";
    $db->query($query);
    $db->free();

    d_doDiff($bug);

    print("<p><a href=\"query.php?bug=$bug\">" . sprintf(gettext("Return to bug 
#%s"), $bug) . "</a>.</p>");

    d_DrawFooter();

  } else {
    if (!isset($bug)) {
      print("<p>" . gettext("Error: you must select a bug to associate 
attachment with!") . "</p>");
      d_DrawFooter();
      exit;
    }

    $db->query("SELECT * FROM bugs WHERE bid = '$bug'");
    $db->next_record();

    // if status RESOLVED or CLOSED and not owner or admin, disallow
    // creating attachments
    if ($db->record['status'] == "4" || $db->record['status'] == "6") {
      if ($_USER['uid'] != $db->record['assigned'] || $_USER['access'] < 
$config['adminac']) {
        print("<p>" . gettext("This bug is CLOSED or RESOLVED and you may not 
create an attachment.") . "</p>");
        d_DrawFooter();
        exit;
      }
    }

    if (!isset($_USER['uid'])) { // not logged in
      print("<p>" . gettext("You must be logged in first.") . "</p>");
      d_DrawFooter();
      exit;
    }

    d_DrawCAttach($bug);

    d_DrawFooter();
  }
?>

====================================================
Index: README.1st
$Id: README.1st,v 1.1 2005/05/05 00:34:03 skwashd Exp $

IMPORTANT:

This file contains some information that you *must* read.  Skip over this at
your peril.

Anthill is powerful and has some powerful options that allow it to work
properly.  There are also optional components that you will need to be aware
of.

1) Permissions

The Anthill webtree contains four directories that must be writable by the
web user (usually apache or nobody).  These directories are: shadow/, tmp/,
gpg/, and attachments/.  Please do not make the directories world-writable
unless you have to; if at all possible, chown them as the web user, ie:

  # cd anthill
  # chown apache.apache shadow tmp gpg attachments

2) Upgrading (0.2.x)

In the etc/ directory is a script called upgradepw.php which is used to
upgrade 0.1.x crypt-based passwords to 0.2.x md5-based passwords.  This must
be executed once during the upgrade; after it has been executed and the
passwords have been changed, please *delete* this file!  It is only needed
once.  This file has absolutely no access checks because the of the
difference in password matching.  Once you upgrade to 0.2.x you will be
effectively logged out, so this file cannot have access protection.  Right
after you upgrade the files, visit http://yoursite/etc/upgradepw.php and
once it is complete *delete* the file!

3) System scripts

Also in etc/ is a script called anthill-emailuserscron.php.  This *must*
exist outside of the web tree.  It has no access checks on it (as it is
meant to be run via cron) and as a result, a user could flood your
developers mailboxes by repeatedly loading the page.  Please read README for
more information on this script, but you should move this script immediately
after upgrading or installing 0.2.x versions of Anthill.

4) Read README

Some boring stuff, some good stuff...  I recommend giving it a quick read.

====================================================
Index: README
$Id: README,v 1.1 2005/05/05 00:34:03 skwashd Exp $

Anthill Bug Tracking System
---------------------------

Welcome to Anthill!

First, I would like to thank you for downloading and giving Anthill a shot.
I hope you find that it meets your needs.

Anthill is free software and is released under the GNU GPL License version
2.0 (see the COPYING file for details).

Anthill is the product of a need that Bugzilla could not fill.  Quite
frankly, I found Bugzilla to be bulky and overly-complex for what I needed.
And configuring Bugzilla to look different turned out to an overly-huge
ordeal that I couldn't be bothered with.  At the time, I thought writing my
own software in PHP would be easier and faster.  I was right on the first
count, wrong on the second.  The time it took for the first public release
of Anthill was roughly six months.  I'm sure in that time I could have
configured Bugzilla the way I wanted to, but then you wouldn't have this
really cool software to play with.  =)

Anthill is not yet complete.  If you find a feature lacking, or you find a
bug, please let me know.  I would be more than happy to include worthwhile
features and extremely grateful for any bug reports.  I have tried to make
Anthill feature-rich while reducing it's complexity.  In short, I wanted a
bug tracking database system with few pre-requisites (additional software
like PHPlib), and one that was quick and easy to get up and running.  I
think I've accomplished that, but your feedback will let me know for sure.

Anthill was written to handle the MandrakeSoft Secteam bug-tracking
interface, but I've done it in such a way that it should be able to handle
most other projects as well.  It is free software, and as such comes without
warranty of any kind and no technical support.  While I'll try to help in as
many ways as possible, please understand that Anthill is a project of my
spare time and will be treated as such.


Requirements
------------

Anthill requires a webserver (such as Apache) and PHP 4.1 or higher.  Your
PHP *must* have gettext support compiled in.  This is not something you can
enable or disable "on the fly".  PHP must have been built with:

  ./configure --with-gettext

You can easily check if you have gettext support by issuing on the
commandline:

  echo "<? phpinfo(); ?>"|/usr/bin/php|grep gettext

Of course, change the path to the php executable to whereever it is
installed on your system.  If nothing is returned by grep, gettext support
is not compiled into the PHP installed on your system and will require you
to recompile PHP with gettext support prior to using Anthill.

Finally, Anthill requires a database backend.  Currently only MySQL is fully
supported.  Plans are in place to use a database abstraction layer so
that other backends like PostgreSQL can be used.

You must also have your PHP configured to allow short open tags; you can
verify this by editing your php.ini file and make sure that:

short_open_tag = On

is set.

Installation
------------

The installation of Anthill is quite simple.  Take the distribution archive
(anthill-[version].tar.bz2) and unarchive it in your web root directory.  It
will create a sub-directory called anthill-[version].  Rename that directory
to anthill/ or whatever you wish to call it.

Change to that directory and edit include.php.  Change the path in the
include_once() function to the your config.inc.php file (typically the full
path to the current directory, and then the include/ sub-directory, followed
by the filename itself).  Once you have saved this file, change to the
include/ directory.  Copy the sample-config.inc.php to config.inc.php, and edit
config.inc.php.  This file contains a number of variables that must be defined.
Instructions as to what each variable means is detailed in the file itself.

Once you have completed this and defined the database name for Anthill, you
need to create the database structure.  Currently, Anthill only supports
MySQL and PostgreSQL.


MySQL Setup
-----------
Create the database you plan to use (defined as $_CONF['db_name'] in
config.inc.php) by issuing:

        mysqladmin -u root -p create anthill

if "anthill" is the name of the database you chose.  This will create the
database.  Next, import the database structure using:

        cd anthill/etc
        mysql -u root -p anthill <sql.dump

Log into MySQL to give your anthill user access to the database:

        mysql -u root -p

        >> GRANT ALL ON anthill.* TO address@hidden IDENTIFIED BY "pass";

Obviously, change "anthill@" to the user you defined as $_CONF['db_user'] in
config.inc.php and "pass" to the password defined as $_CONF['db_pw'].


PostgreSQL Setup
----------------
First, please note that PostgreSQL support is not 100% and cannot even be
used currently.  Hooks are in place, but work needs to be done to rewrite
the SQL queries to be a little friendler for non-MySQL databases.  If you
would like to help with make the necessary adjustments for Anthill to work
on PostgreSQL, your help would be appreciated.  The following info is for
those who do want to work on making Anthill work with PostgreSQL.

Create the user that will be accessing the PostgreSQL server.  This is the
user defined in $_CONF['db_user'], so issue (as a privileged psql user):

        createuser -D -A -P anthill

This will create the user anthill, and prevent it from creating new users or
databases.  It will also prompt you for a password; this must be the same as
that defined in $_CONF['db_pw'] in config.inc.php.  As the privileged user,
now create the database (defined as $_CONF['db_name'] in config.inc.php):

        createdb anthill

if "anthill" is the name of the database you chose.  This will create the
database.  Next, import the database structure using:

        cd anthill/etc
        psql -d anthill -f pgsql.dump

Finally, give the anthill user access to the database by using:

        psql -d anthill -c "GRANT ALL on config TO anthill"
        psql -d anthill -c "GRANT ALL on users TO anthill"
        psql -d anthill -c "GRANT ALL on bugs TO anthill"
        psql -d anthill -c "GRANT ALL on bugdesc TO anthill"
        psql -d anthill -c "GRANT ALL on products TO anthill"
        psql -d anthill -c "GRANT ALL on versions TO anthill"
        psql -d anthill -c "GRANT ALL on components TO anthill"
        psql -d anthill -c "GRANT ALL on status_d TO anthill"
        psql -d anthill -c "GRANT ALL on severity_d TO anthill"
        psql -d anthill -c "GRANT ALL on priority_d TO anthill"
        psql -d anthill -c "GRANT ALL on resolve_d TO anthill"
        psql -d anthill -c "GRANT ALL on bugactivity TO anthill"
        psql -d anthill -c "GRANT ALL on attachidx TO anthill"
        psql -d anthill -c "GRANT ALL on sessions TO anthill"

Obviously, change "anthill" to the user you defined as $_CONF['db_user'] in
config.inc.php.  Unfortunately, PostgreSQL doesn't seem to have a "*" to
cover all tables in a database so you have to do them one by one (someone
please correct me if I'm wrong, I've not used PostgreSQL that much).


Post-Database Installation
--------------------------

There is a default "admin" user with the password "test123" (without quotes).
Be sure to log in as that user and edit your preferences to change the
password and also configure some Anthill configuration basics.

Before making your Anthill installation public, you will have to take care
of a few permissions issues.  There are four directories that need to be
owned by the user running your webserver (ie. "nobody" or "apache") in the
Anthill directory tree:  shadow/, tmp/, gpg/, and attachments/.  To do this,
go into your Anthill root directory and execute:

        cd anthill
        chown apache.apache shadow tmp gpg attachments

Replace "apache.apache" with "nobody.nobody" if your webserver runs as the
user "nobody" (or any other user name it may run as).  The other option is
to make those directories world writeable, but that presents security risks.
It is better to have the directories owned by the user running the webserver
because Anthill needs to write to each of these directories.  The
directories should likewise only be mode 700, so only the webserver user can
read, write, and execute in the directory.  You can make that modification
by executing:

        chmod 700 shadow tmp gpg attachments

Starting with 0.2.0pre3, a .htaccess file is included in the include/
sub-directory to protect configuration files and other files that should not
be accessed by a browser directly.  It is a very simple .htaccess denying
all access to the .php files in that directory.  It does not affect how the
rest of the site works, so I recommend leaving it alone.


Notes on using PHP's safe_mode
------------------------------

Every effort has been made to allow Anthill to work with PHP's safe_mode
enabled.  For this to work, however, you must make a few additional changes.
Firstly, the entire Anthill web tree should be owned by the user running the
web server (ie. apache).  You can accomplish this by doing:

        cd anthill
        chown -R apache.apache *

The permissions for the shadow, tmp, gpg, and attachments directories should
still be 700, writable only by the user apache.

You will have to modify /etc/php.ini and set safe_mode_execdir to the
location of where the diff utility is stored.  For example:

        safe_mode_execdir = "/usr/bin"

If this is too loose for you (a *lot* of stuff is in /usr/bin), you can
always move the diff utility to a special directory that *only* contains the
diff tool and set safe_mode_exec_dir to that special directory.

Finally, you should also be able to use Anthill with register_globals turned
Off.


Upgrading
---------

If you are upgrading from a previous version of Anthill, use the upgrade
script in etc/.  It will take the format of [old_ver]-[new_ver].sql (so to
upgrade 0.1.4 to 0.1.5 the file would be 0.1.4-0.1.5.sql).  To use it,
simply execute:

        cd anthill/etc
        mysql -u root -p anthill <[upgrade_file].sql

After this, copy all of the files over your existing files with the
exception of anthill/include.php and anthill/include/config.inc.php.  Compare
your files to the new files to see if there are any changes to be made.  Of
course, replace "root" with the username you are using to access the Anthill
database and "anthill" with the name of the database.

If you are upgrading from a really old version (ie. 0.1.5), you should do,
one after the other, each upgrade file.  For instance, if you are running
0.1.5, you should run the 0.1.5-0.1.6.sql and 0.1.6-0.2.0pre1.sql, etc.
files, one after the other.


Upgrading From Anthill 0.1.x to 0.2.x
-------------------------------------

If you are upgrading from Anthill version 0.1.x to version 0.2.x you must
load the upgradepw.php script in the etc/ directory.  This will send out
emails to all of your users with new generated passwords.  This is required
due to 0.1.x using crypt()-based passwords and 0.2.x using md5-based
passwords.  Your users will be unable to login until you execute this file.
You can do so by pointing your browser to:

        http://yoursite.com/etc/upgradepw.php

I *highly* recommend you delete this file after you have executed it.  This
file has *NO* access checks because if you upgrade Anthill while you are not
logged in, you will be unable to execute the script without resetting the
admin password manually.  Because of this, anyone who can reach this file
can re-generate and wipe out your user's old passwords, creating an annoying
situation.  It will not delete or otherwise harm your users, but they will
need to login with the regenerated passwords and re-set them to their own
(big PITA).  So, for sanity's sake, remove etc/upgradepw.php once you have
executed it.

In 0.1.x, the file site.inc.php was used to store configuration information.
This has now been changed, in 0.2.x do not touch the site.inc.php, but
modify config.inc.php instead.  config.inc.php stores all of the
configuration information and should be used from this point forward.


Optional Components
-------------------

Anthill has a new feature in 0.2.x that allows the system to email users who
have open bug reports with a reminder to deal with the bug associated with
them.  This is done via the anthill-emailuserscron.php in the etc/
directory.  You will need to edit the script to point to your Anthill
implementation's include.php file and you may also choose to tell it what
statuses should be mailed (by default NEW and UNRESOLVED bugs are emailed).
This should be installed in your crontab and stored somewhere *outside* of
the webtree as there are no access checks, so people can flood your
developer's mailboxes with reminder messages by repeatedly accessing the
page.  If you do not wish to use this feature, please delete the file.


Miscellaneous
-------------

IMPORTANT NOTE:

The order of some status types (like those listed in status_d, resolve_d,
priority_d, etc.) are significant!  If you change the order, Anthill will
not work as it should.  For instance, if you decide to change the DUPLICATE
entry in resolve_d from id 3 to id 2, Anthill will *break*.  The reason I
chose not to hardcode the status codes into Anthill itself was so that it
could easily be changed to suit your particular language (ie. change
DUPLICATE to whatever the equivalent French word is if you run a french
site).  Please keep this in mind if you decide to make changes to the SQL
data.


Known Bugs
----------

For some reason, and I believe it is how cookies are managed, access Anthill
via http://localhost or http://server, etc. (despite having Apache
configured to handle this properly, and having Anthill configured the same)
you will be unable to login.  While the login looks like it works properly,
when you are returned to the index page, Anthill will still show you as not
being logged in.  I'm quite certain this has to do with the (mis-)management
of cookies, but don't know of a good way to work around it.  You must access
Anthill via something like http://myserver.mydomain.com in order for
everything to work properly.


Support
-------

Anthill is provided without any warranty of any sort.  I don't warrant that
it works or that it doesn't.  I don't provide commercial support for
Anthill.  I will try to help you figure out any problems you may have, but
please don't be upset if I don't respond immediately.  I have many other
things to do than deal with Anthill support.

As a result, a few mailing lists have been created to provide some
discussion, direction, and support on future Anthill versions.  The lists
include:

  anthill-announce: announcements only (read-only, very low traffic);
  subscribe by emailing address@hidden

  anthill-workers: discussion of development versions of Anthill, new
  features, code, etc.; subscribe by emailing
  address@hidden

  anthill-users: support and discussion for Anthill installations,
  configuration, themes, etc.; subscribe by emailing
  address@hidden

The main Anthill homepage is http://anthill.vmlinuz.ca/

You can submit bugs at http://anthill.vmlinuz.ca/anthill/

There is a demo site of the latest stable or unstable version of Anthill at
http://anthill.vmlinuz.ca/demo/


And that's all there is to it!  Enjoy!

-- Vincent Danen <address@hidden>

====================================================
Index: COPYING
                    GNU GENERAL PUBLIC LICENSE
                       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.
                    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,

    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

                            NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

                     END OF TERMS AND CONDITIONS


====================================================
Index: README.OSX
$Id: README.OSX,v 1.1 2005/05/05 00:34:03 skwashd Exp $

Instructions on using Anthill on Mac OS X

To update PHP for Apache 1.x
----------------------------

Anthill will work with very few changes from the Linux instructions
(default, and detailed in README), but there are a few significant
differences.  First, Apple ships with Apache itself and does not configure
it to use PHP out of the box, although PHP is installed.  However, Apple's
PHP, while having support for MySQL, does not have support for gettext.
Marc Liyanage has contributed a binary libphp4.so for OS X users on his web
site:

http://www.entropy.ch/software/macosx/php/

Now, his module doesn't have gettext support either, which is essential for
Anthill to operate.  You will have to rebuild PHP yourself.  Marc has some
good instructions on how to build PHP at the end of his page as well,
including a patch to apply to 4.2.3 (which was used for testing Anthill on
OS X).  The following is the ./configure line I used to build my copy of PHP
4.2.3 which works fine with Anthill:

  ./configure --with-apxs --with-mysql --with-gd=/sw --with-png-dir=/sw \
    --with-zlib-dir=/usr --with-jpeg-dir=/sw --with-freetype-dir=/sw \
    --with-t1lib=/sw --enable-trans-sid --enable-exif --with-xml \
    --enable-wddx --with-curl=/sw --enable-ftp --enable-mbstring \
    --enable-mbstr-enc-trans --enable-sockets --enable-dbx --enable-dbase \
    --with-gettext=/sw

You will need some additional libraries if you want some of the features
like gd, t1lib, etc.  I found the best way to install these is to use Fink
(http://fink.sourceforge.net/) and build the latest versions from unstable
sources.  When you build PHP and if it complains about being unable to find
something, you must install the corresponding libraries or remove the call
from your configure line.  You will have to install gettext via Fink prior
to building PHP.  There are no other functions in Anthill, at this time,
that require any external libraries.  All of the configuration options
pointing to /sw are Fink packages.

If you don't want to compile PHP, you can download a libphp4.so from the
Anthill website.  You can install it by executing:

  $ curl -O http://anthill.vmlinuz.ca/files/libphp4.so.bz2
  $ bunzip2 libphp4.so.bz2
  $ sudo cp libphp4.so /usr/libexec/httpd
  $ sudo apxs -e -a -n php4 libexec/httpd/libphp4.so
  $ echo 'echo "AddType application/x-httpd-php .php" >> \
    /etc/httpd/httpd.conf' | sudo sh -s
  $ sudo apachectl graceful

You will need to modify /etc/httpd/httpd.conf and change the DirectoryIndex
line to also contain index.php, for example:

<IfModule mod_dir.c>
  DirectoryIndex index.html index.php
</IfModule>


To update PHP for Apache 2.x
----------------------------

Alternatively, you can use Apache2 instead of Apache1 which OS X comes with.
Server Logistics have created a very nice set of packages for Apache2 and
PHP (compiled for Apache2).  So if you're looking for the easier way to
install PHP, and don't mind using Apache2, this is a better choice.  You can
get Apache2 from:

http://www.aaronfaby.com/apache2.php

You can get PHP compiled for Apache2 at:

http://www.aaronfaby.com/php4.php

Installation of both packages is extremely straight-forward and you should
be up and running in a few minutes.  This PHP package does have gettext
support compiled in, along with many other modules.

Using Apache2 with Anthill works great; if at all possible, I advise using
Apache2+PHP using Server Logistic's excellent packages.


Sendmail in OS X
----------------

One final note.  sendmail in OS X (I don't know about OS X Server) doesn't
really work with PHP out of the box.  By default, you may get deferred
connections in your mail.log because it can't connect to the localhost to
deliver mail.  To do this, you will need to either install another MTA if
you can't stand sendmail (like me), or else get sendmail to start on boot.
You can get more info on sendmail on Mac OS X from:

http://www.macdevcenter.com/pub/a/mac/2002/06/07/sendmail_1015.html

This article will tell you what you need to do to start sendmail on boot in
OS X and some of how to configure it to get it working properly.


Installing MySQL in OS X
------------------------

To get MySQL installed, use fink (http://fink.sourceforge.net/).

Everything else is identical to the Linux installation so follow
instructions in README.

====================================================
Index: THANKS
Thanks go first and foremost to my Lord Jesus Christ for giving me the gift
to be able to do something like this (as trivial as it may seem to some).
Sincerely appreciated!

Others who deserve mentioning are:

Angela Danen <address@hidden> for the Anthill logo and button

Fabian Mandelbaum <address@hidden> for helping translate the
language file to spanish, and Sergio Korlowsky <address@hidden> for
finishing the translation for 0.1.x.  Fabian also finished the 0.2.0
translations.

Mandelli Alesandro <address@hidden> for translating the language file
to Italian for 0.1.x.

Christophe Gonnet <address@hidden> for translating the language file to
French for 0.1.x and 0.2.0.

Joe Man <address@hidden> for translating the language file to Chinese
for 0.1.x.

John Ham for his excellent report engine and making the ability for users to
download nicely formatted text reports.

Phil Kenoyer for porting the mysql connection class to work with postgresql,
and for submitting an initial pgsql dump.

Arnold Ligtvoet <address@hidden> for translating the language file to
Dutch for 0.2.0.

Anton Lykob <address@hidden> for translating the language file to Russian for
0.2.0.

And, of course, to the MandrakeSoft secteam who use Anthill on an almost
daily basis for tracking security bugs.  That project inspired Anthill, and
the team helped track down bugs in it as well.  Thanks folks!

$Id: THANKS,v 1.1 2005/05/05 00:34:03 skwashd Exp $

====================================================
Index: buglist.php
<?
  // Anthill
  // $Id: buglist.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['type']))     { $type     = $_REQUEST['type']; }     else 
{ $type     = NULL; }
  if (isset($_REQUEST['search']))   { $search   = $_REQUEST['search']; }   else 
{ $search   = NULL; }
  if (isset($_REQUEST['allclass'])) { $allclass = $_REQUEST['allclass']; } else 
{ $allclass = NULL; }
  if (isset($_REQUEST['myclass']))  { $myclass  = $_REQUEST['myclass']; }  else 
{ $myclass  = NULL; }
  if (isset($_REQUEST['who']))      { $who      = $_REQUEST['who']; }      else 
{ $who      = NULL; }
  if (isset($_REQUEST['rwho']))     { $rwho     = $_REQUEST['rwho']; }     else 
{ $rwho     = NULL; }
  if (isset($_REQUEST['product']))  { $product  = $_REQUEST['product']; }  else 
{ $product  = NULL; }
  if (isset($_REQUEST['vproduct'])) { $vproduct = $_REQUEST['vproduct']; } else 
{ $vproduct = NULL; }
  if (isset($_REQUEST['sversion'])) { $sversion = $_REQUEST['sversion']; } else 
{ $sversion = NULL; }
  if (isset($_REQUEST['eversion'])) { $eversion = $_REQUEST['eversion']; } else 
{ $eversion = NULL; }
  if (isset($_USER['uid']))         { $uid      = $_USER['uid']; }         else 
{ $uid      = NULL; }

  if (isset($type) || isset($search)) {
    d_StartPage(gettext("Bug List"));
    if (do_checkaccess($config['newusers'], $_USER['uid'], $_USER['uname']) == 
1) { exit; }
    d_DrawNav($user['uname']);

    d_DrawHeader(gettext("Bug List"));

  switch($type) {
    case "all":
      if ($allclass == "all") {
        if (isset($search)) {
          $msg     = sprintf(gettext("Searching for all bugs containing search 
phrase \"<b>%s</b>\""), $search);
        } else {
          $query  = "SELECT * FROM bugs ORDER BY bid ASC";
          $msg    = gettext("Searching for all bugs...");
        }
      } else {
        $query = "SELECT * FROM bugs WHERE status = '$allclass' ORDER BY bid 
ASC";
        $db->query("SELECT * FROM status_d WHERE id = '$allclass'");
        $db->next_record();
        $msg   = sprintf(gettext("Searching for all bugs of status %s..."), 
$db->record['name']);
        $db->free();
      }
      break;
    case "unres":
      $query = "SELECT * FROM bugs WHERE status NOT IN (4,6) ORDER BY bid ASC";
      $msg   = gettext("Searching for all unresolved bugs...");
      break;
    case "mine":
      if ($myclass == "all") {
        $query = "SELECT * FROM bugs WHERE assigned = '$uid' ORDER BY bid ASC";
        $msg   = gettext("Searching for all of your bugs...");
      } elseif ($myclass == "new") {
        $query = "SELECT * FROM bugs WHERE assigned= '$uid' AND status NOT IN 
(4,6) ORDER BY bid ASC";
        $msg   = gettext("Searching for all of your unresolved bugs...");
      } else {
        $query = "SELECT * FROM bugs WHERE assigned = '$uid' AND status = 
'$myclass' ORDER BY bid ASC";
        $db->query("SELECT * FROM status_d WHERE id = '$myclass'");
        $db->next_record();
        $msg   = sprintf(gettext("Searching for all of your bugs of status 
%s..."), $db->record['name']);
        $db->free();
      }
      break;
    case "user":
      $query = "SELECT * FROM bugs WHERE assigned = '$who' ORDER BY bid ASC";
      $db->query("SELECT * FROM users WHERE uid = '$who'");
      $db->next_record();
      $msg   = sprintf(gettext("Searching for all bugs belonging to %s..."), 
$db->record['email']);
      $db->free();
      break;
    case "reporter":
      $query = "SELECT * FROM bugs WHERE reporter = '$uid' ORDER BY bid ASC";
      $db->query("SELECT * FROM users WHERE uid = '$uid'");
      $db->next_record();
      $msg   = sprintf(gettext("Searching for all bugs reported by %s..."), 
$db->record['email']);
      $db->free();
      break;
    case "reporternew":
      $query = "SELECT * FROM bugs WHERE reporter = '$uid' AND status = '1' 
ORDER BY bid ASC";
      $db->query("SELECT * FROM users WHERE uid = '$uid'");
      $db->next_record();
      $msg   = sprintf(gettext("Searching for all new bugs reported by %s..."), 
$db->record['email']);
      $db->free();
      break;
    case "reportby":
      $query = "SELECT * FROM bugs WHERE reporter = '$rwho' ORDER BY bid ASC";
      $db->query("SELECT * FROM users WHERE uid = '$rwho'");
      $db->next_record();
      $msg   = sprintf(gettext("Searching for all bugs reported by %s..."), 
$db->record['email']);
      $db->free();
      break;
    case "product":
      if ($product != "") {
        $query = "SELECT * FROM bugs WHERE product = '$product' ORDER BY bid 
ASC";
        $db->query("SELECT * FROM products WHERE pid = '$product'");
        $db->next_record();
        $msg = sprintf(gettext("Searching for all bugs of product %s..."), 
$db->record['name']);
        $db->free();
      } else {
        $query = "SELECT * FROM bugs ORDER BY bid ASC";
        $msg = gettext("Searching for all bugs of all products...");
      }
      break;
    case "versiondiff":
      d_AskVersion($vproduct);
      $exit = 1;
      break;
    default:
      $msg = gettext("No action specified.");
      $exit = 1;
      break;
  }

  if (isset($exit)) { print($msg); d_DrawFooter(); exit; }

?>
  <table cellpadding="0" cellspacing="0" border="0" width="100%">
    <tr>
      <td>
        <b><? print(gettext("Bug")); ?>#</b>&nbsp;
      </td>
      <td>
        <b><? print(gettext("Product")); ?></b>&nbsp;
      </td>
      <td>
        <b><? print(gettext("Component")); ?></b>&nbsp;
      </td>
      <td>
        <b><? print(gettext("Priority")); ?></b>&nbsp;
      </td>
      <td>
        <b><? print(gettext("Owner")); ?></b>&nbsp;
      </td>
      <td>
        <b><? print(gettext("Status")); ?></b>&nbsp;
      </td>
      <td>
        <b><? print(gettext("Resolution")); ?></b>&nbsp;
      </td>
      <td>
        <b><? print(gettext("Summary")); ?></b>&nbsp;
      </td>
    </tr>
<?

  print("<p>$msg</p>");

  if (isset($search)) {
    $count = d_doSearchList($search);
  } else {
    $count = d_doBugList($query);
  }
?>

  </table>

  <br /><span class="text"><center><? print(sprintf(gettext("%s bugs found"), 
$count)); ?>.</span></center>

  <p><? print(gettext("Return to <a href=\"query.php\">Bug list</a>.")); ?></p>

<?
    d_DrawFooter();
    exit;
  }

  // generate version diffs
  if (isset($sversion) || isset($eversion)) {
    d_StartPage(gettext("Bug List"));
    if (do_checkaccess($config['newusers'], $_USER['uid'], $_USER['uname']) == 
1) { exit; }
    d_DrawNav($user['uname']);

    d_DrawHeader(gettext("Bug List"));
    $db->query("SELECT * FROM products WHERE (pid = '$product') AND (deleted = 
'0')");
    $db->next_record();
    $pname = $db->record['name'];
    $db->free();
    print("<p>" . sprintf(gettext("Listing FIXED bugs for product \"%s\" 
between versions %s and %s"),$pname,$sversion,$eversion) . "</p>");
    $db->query("SELECT * FROM bugs WHERE (fixedver >= '$sversion') AND 
(fixedver <= '$eversion') AND (product = '$product') ORDER BY fixedver");
    print("<table cellpadding=\"0\" cellspacing=\"1\" border=\"0\" 
width=\"100%\">");
    print("<tr><td><b>" . gettext("Bug #") . "</b></td>");
    print("<td><b>" . gettext("Product") . "</b></td>");
    print("<td><b>" . gettext("Fixed Version") . "</b></td>");
    print("<td><b>" . gettext("Summary") . "</b></td></tr>");
    while ($db->next_record()) {
      d_DumpVdiff($pname, $db->record);
    }
    print("</table>");
    d_DrawFooter();
    exit;
  }

  header("Location: " . $_CONF['webroot'] . "/query.php");
?>

====================================================
Index: admin.php
<?
  // Anthill
  // $Id: admin.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['go'])) { $go = $_REQUEST['go']; } else { $go = NULL; }

  d_StartPage(gettext("Edit Anthill Preferences"));

  if (!do_checkacs($_USER['access'])) exit;

  // change user information
  if ($go == "change") {
    for($HTTP_POST_VARS; $k=key($HTTP_POST_VARS);next($HTTP_POST_VARS)) {
      // update configuration
      if ($k == "sitename" || $k == "siteblurb" || $k == "newublurb" || $k == 
"prefblurb") {
        $value = addslashes($HTTP_POST_VARS[$k]);
      } else {
        $value = $HTTP_POST_VARS[$k];
      }
      if ($k != "go") {
        $query  = "UPDATE config set ";
        $query .= "value = '" . $value . "' ";
        $query .= "WHERE name = '" . $k . "'";
        $db->query($query);
        $db->free();
     }
    }
    $msg      = "<span class=\"text\"><center>" . gettext("Your changes have 
been saved.") . "</center></span>";
  }

  // refresh form with new values
  $db->query("SELECT * FROM config");
  $config = array();
  while ($db->next_record()) {
    $a = $db->record;
    $config[$a['name']] = $a['value'];
  }

  d_DrawNav($_USER['uname']);

  d_DrawHeader(gettext("Edit Anthill Preferences"));

  if (isset($msg)) {
    print($msg);
  }
?>
  <p><? print(gettext("Here you are able to configure some operating parameters 
for Anthill.")); ?></p>

  <form method="post" action="admin.php">
  <table border="0" cellpadding="0" cellspacing="0" align="center" 
bgcolor="#000000" width="100%">
    <tr>
      <td>
        <table border="0" cellpadding="0" cellspacing="0" align="center" 
bgcolor="#ffffff" width="100%">
          <tr>
            <td>
              <table border="0" cellpadding="2" cellspacing="2" width="100%">
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Site Name")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="sitename" size="50" 
maxlength="100" value="<? print(stripslashes($config['sitename'])); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Administrator Email")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="adminemail" size="50" 
maxlength="100" value="<? print($config['adminemail']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Default CC")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="autocc" size="50" maxlength="100" 
value="<? print($config['autocc']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Text Color")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="textcol" size="10" maxlength="20" 
value="<? print($config['textcol']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Link Color")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="linkcol" size="10" maxlength="20" 
value="<? print($config['linkcol']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Background Color")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="bgcol" size="10" maxlength="20" 
value="<? print($config['bgcol']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("First Bar Color")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="barcol1" size="10" maxlength="20" 
value="<? print($config['barcol1']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Second Bar Color")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="barcol2" size="10" maxlength="20" 
value="<? print($config['barcol2']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Theme")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <select name="theme">
<?                    $handle = opendir($rtmpldir);
                      while ($file = readdir($handle)) {
                        if ((!ereg("[.]",$file))) {
                          $themelist .= "$file ";
                        }
                      }
                      closedir($handle);
                      $themelist = explode(" ", $themelist);
                      sort($themelist);
                      for ($i=0; $i < sizeof($themelist); $i++) {
                        if ($themelist[$i] != "") {
                          $foo = strtolower($config['theme']) == 
strtolower($themelist[$i]) ? "selected" : "";
                          print(sprintf("<option value=\"%s\" 
%s>%s</option>\n",$themelist[$i],$foo,$themelist[$i]));
                        }
                      }
?>
                    </select>
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Allow New Users")); ?>?</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <select name="newusers">
                      <option value="1" <? if ($config['newusers'] == 1) { 
print("SELECTED"); } ?>><? print(gettext("New Users Can Register")); ?></option>
                      <option value="0" <? if ($config['newusers'] == 0) { 
print("SELECTED"); } ?>><? print(gettext("Closed Site (No New Users)")); 
?></option>
                    </select>
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Default Bug State")); ?></b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <select name="defpriv">
                      <option value="1" <? if ($config['defpriv'] == 1) { 
print("SELECTED"); } ?>>Private</option>
                      <option value="0" <? if ($config['defpriv'] == 0) { 
print("SELECTED"); } ?>>Public</option>
                    </select>
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Administrator Access Level")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="adminac" size="3" maxlength="3" 
value="<? print($config['adminac']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Developer Access Level")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="devac" size="3" maxlength="3" 
value="<? print($config['devac']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Basic User Access Level")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="defaultac" size="3" maxlength="3" 
value="<? print($config['defaultac']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Maximum Attachment File Size")); 
?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="maxfsize" size="9" maxlength="9" 
value="<? print($config['maxfsize']); ?>"> <? print(gettext("bytes")); ?>
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Mailer Daemon's Name")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="mdaemon" size="50" maxlength="100" 
value="<? print($config['mdaemon']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <b><? print(gettext("Mailer Daemon Email")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="memail" size="50" maxlength="100" 
value="<? print($config['memail']); ?>">
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right" valign="top">
                    <b><? print(gettext("Mailer Daemon Reply-To")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <input type="text" name="mdaemonreplyto" size="50" 
maxlength="100" value="<? print($config['mdaemonreplyto']); ?>">
                    <br /><font size="-2"><? print(gettext("(This is useful if 
you want replies to Anthill diff messages to go to a real email address or 
mailing list instead of to the daemon's email address.  This is <b>only</b> 
used with diff messages.)")); ?></font>
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right" valign="top">
                    <b><? print(gettext("Site Text (used in index)")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <textarea name="siteblurb" cols="50" rows="3" 
wrap="Virtual"><? print(stripslashes($config['siteblurb'])); ?></textarea>
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right" valign="top">
                    <b><? print(gettext("New User Text (used in 
registration)")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <textarea name="newublurb" cols="50" rows="3" 
wrap="Virtual"><? print(stripslashes($config['newublurb'])); ?></textarea>
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right" valign="top">
                    <b><? print(gettext("Preferences Text (used in 
preferences)")); ?>:</b>
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    <textarea name="prefblurb" cols="50" rows="3" 
wrap="Virtual"><? print(stripslashes($config['prefblurb'])); ?></textarea>
                  </td>
                </tr>
                <tr>
                  <td bgcolor="#ffffff" width="50%" align="right">
                    <input type="submit" value="<? print(gettext("Change")); 
?>">
                    <input type="hidden" name="go" value="change">
                  </td>
                  <td bgcolor="#ffffff" width="50%">
                    &nbsp;
                  </td>
                </tr>
              </table>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
  </form>

  <p><? print(gettext("Change <a href=\"editproducts.php\">products and 
components</a> information.")); ?></p>
  <p><? print(gettext("Edit <a href=\"editusers.php\">user</a> information and 
add new users.")); ?></p>

<?
  d_DrawFooter();
?>

====================================================
Index: activity.php
<?
  // Anthill
  // $Id: activity.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  $bug = $_REQUEST['bug'];

  d_StartPage(gettext("Activity Log"));
  if (do_checkaccess($config['newusers'], $_USER['uid'], $_USER['uname']) == 1) 
{ exit; }
  d_DrawNav($_USER['uname']);

  d_DrawHeader(gettext("Activity Log"));

  $db2         = new db_Sql();
  $db2->host   = $_CONF['db_host'];
  $db2->dbase  = $_CONF['db_name'];
  $db2->user   = $_CONF['db_user'];
  $db2->passwd = $_CONF['db_pw'];
  $db2->connect();

  if (!isset($bug)) {
    print("<p><font color=\"red\">" . gettext("The bug you selected does not 
exist or is invalid.") . "</font></p>");
    d_DrawFooter();
    exit();
  } else {
    $db->query("SELECT * FROM bugs WHERE bid = '$bug'");
    $db->next_record();
    if ($db->num_rows() == 0) {  // empty bug; non-existant
      print("<p><font color=\"red\">" . gettext("The bug you selected does not 
exist or is invalid.") . "</font></p>");
      d_DrawFooter();
      exit();
    }
    if ($db->record['private'] == 1 && !isset($_USER['uid'])) {
      print("<p><font color=\"red\">" . gettext("The bug you selected is marked 
private and is not available to unregistered users.") . "</font></p>");
      d_DrawFooter();
      exit();
    }
    $db->free();

?>
    <center>
    <table border="0" cellpadding="0" cellspacing="0" width="100%">
      <tr>
        <td width="20%">
          <b><? print(gettext("Activity by")); ?></b>
        </td>
        <td width="20%">
          <b><? print(gettext("Activity")); ?></b>
        </td>
        <td width="20%">
          <b><? print(gettext("Old value")); ?></b>
        </td>
        <td width="20%">
          <b><? print(gettext("New value")); ?></b>
        </td>
        <td width="20%">
          <b><? print(gettext("Date")); ?></b>
        </td>
      </tr>
      <? $db->query("SELECT * FROM bugactivity WHERE bid = '$bug' ORDER BY 
date");
         while ($db->next_record()) {
      ?>
      <tr>
        <td width="20%" valign="top">
          <? $db2->query("SELECT email FROM users WHERE uid = '" . 
$db->record['user'] . "'");
             $db2->next_record();
             print($db2->record['email']);
             $db2->free();
          ?>
        </td>
        <td width="20%" valign="top">
          <? switch($db->record['what']) {
               case 0:
                 print(gettext("Status Change")); break;
               case 1:
                 print(gettext("Reassigned")); break;
               case 2:
                 print(gettext("State Change")); break;
               case 3:
                 print(gettext("Added to CC")); break;
               case 4:
                 print(gettext("Removed from CC")); break;
               case 5:
                 print(gettext("Created Attachment")); break;
               case 6:
                 print(gettext("Resolution Priority Change")); break;
               case 7:
                 print(gettext("Severity Change")); break;
               case 8:
                 print(gettext("Description Change")); break;
             }
          ?>
        </td>
        <td width="20%" valign="top">
          <? print($db->record['oldval']); ?>
        </td>
        <td width="20%" valign="top">
          <? print($db->record['newval']); ?>
        </td>
        <td width="20%" valign="top">
          <? print(d_getTime($db->record['date'])); ?>
        </td>
      </tr>
      <? } ?>
    </table>

<?
    print("<p><a href=\"query.php?bug=$bug\">" . sprintf(gettext("Return to bug 
#%s"), $bug) . "</a>.</p>");
  } // end isset($bug)

  d_DrawFooter();
?>

====================================================
Index: TODO
$Id: TODO,v 1.1 2005/05/05 00:34:03 skwashd Exp $

TODO Items:

- postgresql database abstraction *sucks*; needs a lot of work

====================================================
Index: pref.php
<?
  // Anthill
  // $Id: pref.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['go']))        { $go        = $_REQUEST['go']; }        
else { $go        = NULL; }
  if (isset($_REQUEST['uname']))     { $uname     = $_REQUEST['uname']; }     
else { $uname     = NULL; }
  if (isset($_REQUEST['email']))     { $email     = $_REQUEST['email']; }     
else { $email     = NULL; }
  if (isset($_REQUEST['rname']))     { $rname     = $_REQUEST['rname']; }     
else { $rname     = NULL; }
  if (isset($_REQUEST['gpg']))       { $gpg       = $_REQUEST['gpg']; }       
else { $gpg       = NULL; }
  if (isset($_REQUEST['cookieexp'])) { $cookieexp = $_REQUEST['cookieexp']; } 
else { $cookieexp = NULL; }
  if (isset($_REQUEST['pass1']))     { $pass1     = $_REQUEST['pass1']; }     
else { $pass1     = NULL; }
  if (isset($_REQUEST['pass2']))     { $pass2     = $_REQUEST['pass2']; }     
else { $pass2     = NULL; }
  if (isset($_REQUEST['uid']))       { $uid       = $_REQUEST['uid']; }       
else { $uid       = NULL; }
  if (isset($_REQUEST['epref']))     { $epref     = $_REQUEST['epref']; }     
else { $epref     = NULL; }

  d_StartPage(gettext("Edit User Preferences"));

  if (!isset($_USER['uid'])) {
    d_DrawNav($_USER['uname']);
    d_DrawHeader(gettext("Edit User Preferences"));
    print("<p>" . gettext("You must login to access this page.") . "</p>");
    d_DrawFooter();
    exit;
  }

  // change user information
  if ($go == "change") {
    $msg = do_checkUser($uname, $email, $_USER['uid'], 1);
    if (!isset($msg)) {
      $db->query("UPDATE users SET uname = '$uname' WHERE (uid=" . 
$_USER['uid'] . ")");
      $db->free();
      $db->query("UPDATE users SET name = '$rname' WHERE (uid=" . $_USER['uid'] 
. ")");
      $db->free();
      if (isset($gpg)) {
        $db->query("UPDATE users SET gpg = '$gpg' WHERE (uid=" . $_USER['uid'] 
. ")");
        $db->free();
      }
      $db->query("UPDATE users SET cookietimeout = '$cookieexp' WHERE (uid=" . 
$_USER['uid'] . ")");
      $db->free();
      $db->query("UPDATE users SET email = '$email' WHERE (uid=" . 
$_USER['uid'] . ")");
      $db->free();
      $db->query("UPDATE users SET epref = '$epref' WHERE (uid=" . 
$_USER['uid'] . ")");
      $db->free();
      if ($pass1 == $pass2) {
        if ($pass1 != "") {
          $cpass  = md5($pass1);
          $db->query("UPDATE users SET passwd = '$cpass' WHERE (uid=" . 
$_USER['uid'] . ")");
          $db->free();
        }
        $msg = "<span class=\"text\"><center>" . gettext("Your changes have 
been saved.") . "</center></span>";
      } else {
        $msg = "<span class=\"text\"><center>" . gettext("Your passwords do not 
match.  Go back and try again.") . "</center></span>";
      }
    }
  }
  if ($go == "deletekey") {
    // delete gpg key on file
    $gfile = $_CONF['root'] . $_CONF['gpgdir'] . "/" . $_USER['uid'] . ".asc";
    if (!unlink($gfile)) {
      print("<p>" . gettext("Problem deleting keyfile.  Aborting.") . "</p>");
      d_DrawFooter();
      exit;
    }
    $db->query("UPDATE users SET gpg = NULL WHERE (uid=" . $_USER['uid'] . ")");
    $msg = "<span class=\"text\"><center>" . gettext("Your changes have been 
saved.") . "</center></span>";
  }

  d_DrawNav($_USER['uname']);

  d_DrawHeader(gettext("Edit User Preferences"));

  if (isset($go)) {
    print($msg);
    print("<p><a href=\"pref.php\">" . gettext("Return to Preferences") . 
"</a></p>");
  } else {
    d_DrawPref($_USER['uid']);
    if ($_USER['access'] >= $config['adminac']) {
      print("<p><a href=\"admin.php\">" . gettext("Change Anthill operating 
parameters.") . "</a></p>");
      print("<p>" . gettext("Change <a href=\"editproducts.php\">products and 
components</a> information.") . "</p>");
      print("<p>" . gettext("Edit <a href=\"editusers.php\">user</a> 
information and add new users.") . "</p>");
    }
  }

  d_DrawFooter();
?>

====================================================
Index: TRANSLATORS
Anthill is a Bugzilla-like clone written entirely in PHP.  While not as
comprehensive as Bugzilla, it is much easier to use, setup, and customize.
One such customization is it's built-in comprehensive language support using
PHP's gettext() function.  To make Anthill more appealing to the masses, the
more languages available, the better.  Anthill is entirely open source and
GPL, so your contributions will not be used to make a profit, but will be
there to help others who are looking for quality software in a certain
language.  All language contributions would be extremely appreciated!

$Id: TRANSLATORS,v 1.1 2005/05/05 00:34:03 skwashd Exp $

====================================================
Index: query.php
<?
  // Anthill
  // $Id: query.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['doit']))       { $doit       = $_REQUEST['doit']; }      
 else { $doit       = NULL; }
  if (isset($_REQUEST['bug']))        { $bug        = $_REQUEST['bug']; }       
 else { $bug        = NULL; }
  if (isset($_REQUEST['comment']))    { $comment    = $_REQUEST['comment']; }   
 else { $comment    = NULL; }
  if (isset($_REQUEST['sbutton']))    { $sbutton    = $_REQUEST['sbutton']; }   
 else { $sbutton    = NULL; }
  if (isset($_REQUEST['resolve']))    { $resolve    = $_REQUEST['resolve']; }   
 else { $resolve    = NULL; }
  if (isset($_REQUEST['dup_id']))     { $dup_id     = $_REQUEST['dup_id']; }    
 else { $dup_id     = NULL; }
  if (isset($_REQUEST['reassign']))   { $reassign   = $_REQUEST['reassign']; }  
 else { $reassign   = NULL; }
  if (isset($_REQUEST['priv']))       { $priv       = $_REQUEST['priv']; }      
 else { $priv       = NULL; }
  if (isset($_REQUEST['postassign'])) { $postassign = $_REQUEST['postassign']; 
} else { $postassign = NULL; }
  if (isset($_REQUEST['comment']))    { $comment    = $_REQUEST['comment']; }   
 else { $comment    = NULL; }
  if (isset($_REQUEST['url']))        { $url        = $_REQUEST['url']; }       
 else { $url        = NULL; }
  if (isset($_REQUEST['shortdesc']))  { $shortdesc  = $_REQUEST['shortdesc']; } 
 else { $shortdesc  = NULL; }
  if (isset($_REQUEST['severity']))   { $severity   = $_REQUEST['severity']; }  
 else { $severity   = NULL; }
  if (isset($_REQUEST['priority']))   { $priority   = $_REQUEST['priority']; }  
 else { $priority   = NULL; }
  if (isset($_REQUEST['fixedver']))   { $fixedver   = $_REQUEST['fixedver']; }  
 else { $fixedver   = NULL; }
  if (isset($_REQUEST['btnQuery']))   { $btnQuery   = $_REQUEST['btnQuery']; }  
 else { $btnQuery   = NULL; }
  $resolution = NULL;
  $syscomm    = NULL;

  d_StartPage(gettext("Query Bug"));
  if (do_checkaccess($config['newusers'], $_USER['uid'], $_USER['uname']) == 1) 
{ exit; }
  d_DrawNav($_USER['uname']);

  d_DrawHeader(gettext("Query Bug"));

  $db2         = new db_Sql();
  $db2->host   = $_CONF['db_host'];
  $db2->dbase  = $_CONF['db_name'];
  $db2->user   = $_CONF['db_user'];
  $db2->passwd = $_CONF['db_pw'];
  $db2->connect();

  if (isset($doit)) { // make changes to bug
    // make sure that the user is logged in (ie. not expired somehow) prior
    // to making changes to the bug
    if (empty($_USER['uid'])) {
      print("<p>" . gettext("You must be logged in to make changes to a bug.") 
. "</p>");
      d_DrawFooter();
      exit;
    }
    if ($doit == "add_comment") {
      // add comment to bug
      $query  = "INSERT INTO bugdesc (did, bid, user, date, system, 
description) VALUES ";
      $query .= "(NULL,'$bug','" . $_USER['uid'] . "',NULL,0,";
      $query .= "'" . addslashes($comment) . "')";
      $db->query($query);
      $db->free();

      d_doDiff($bug);
    } elseif ($doit == "add_cc") {
      // add cc to list
      $db->query("SELECT * FROM bugs WHERE bid = '$bug'");
      $db->next_record();
      if ($db->record['cc']) {
        $tmpcc = split(", ", $db->record['cc']);
        for ($i=0; $i < count($tmpcc); $i++) {
          if ($tmpcc[$i] == $_USER['email']) {
            $exists = 1;
          }
        }
        // if user doesn't exist, add to cc list
        if ($exists != 1) { // if user doesn't exist, add to list
          $cc = $db->record['cc'] . ", " . $_USER['email'];
        } else { // if user already in list, use old list
          $cc = $db->record['cc'];
        }
      } else {
        $cc = $_USER['email'];
      }
      $db->free();
      $db->query("UPDATE bugs SET cc = '$cc' WHERE bid = '$bug'");
      $db->free();
      $query  = "INSERT INTO bugactivity (aid, bid, user, date, what) ";
      $query .= "VALUES (NULL, '$bug', '" . $_USER['uid'] . "', ";
      $query .= "NULL, '3')";
      $db->query($query);
      $db->free();
    } elseif ($doit == "rem_cc") {
      // remove cc from list
      $db->query("SELECT * FROM bugs WHERE bid = '$bug'");
      $db->next_record();
      $cc    = split(", ", $db->record['cc']);
      $count = 0;
      for ($i=0; $i < count($cc); $i++) {
        if ($cc[$i] != $_USER['email']) {
          if ($count==0) {
            $newcc = $cc[$i];
            $count++;
          } else {
            $newcc .= ", " . $cc[$i];
            $count++;
          }
        }
      }
      $db->free();
      $db->query("UPDATE bugs SET cc = '$newcc' WHERE bid = '$bug'");
      $db->free();
      $query  = "INSERT INTO bugactivity (aid, bid, user, date, what) ";
      $query .= "VALUES (NULL, '$bug', '" . $_USER['uid'] . "', ";
      $query .= "NULL, '4')";
      $db->query($query);
      $db->free();
    } elseif ($doit == "admin") {
      // do admin
      switch($sbutton) {
        case "nochange":
          // nothing changes
          break;
        case "accept":
          // change bug to "ASSIGNED"
          // get old status
          $db->query("SELECT status FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $ostat   = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '" . 
$ostat['status'] . "'");
          $db->next_record();
          $ostat   = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '2'");
          $db->next_record();
          $nstat   = $db->record;
          $db->free();
          // now do the updates
          $db->query("UPDATE bugs SET status = '2' WHERE bid = '$bug'");
          $db->free();
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '0', '" . $ostat['name'] . "', '" . $nstat['name'] . 
"')";
          $db->query($query);
          $db->free();
          break;
        case "resolve":
          // change bug to "RESOLVED" with resolution status
          // get old status
          $db->query("SELECT status FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '" . 
$ostat['status'] . "'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '4'");
          $db->next_record();
          $nstat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM resolve_d WHERE id = '$resolve'");
          $db->next_record();
          $res    = $db->record;
          $db->free();
          // now do the updates
          $db->query("UPDATE bugs SET status = '4' WHERE bid = '$bug'");
          $db->free();
          $db->query("UPDATE bugs SET resolution = '$resolve' WHERE bid = 
'$bug'");
          $db->free();
          $sdesc  = $nstat['name'] . " (" . $res['name'] . ")";
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '0', '" . $ostat['name'] . "', '$sdesc')";
          $db->query($query);
          $db->free();
          // If FIXED, allow to set the fixed version
          if ($fixedver != "" && $resolve == 0) {
            $db->query("UPDATE bugs SET fixedver = '$fixedver' WHERE bid = 
'$bug'");
            $db->free();
          }
          break;
        case "duplicate":
          // changed bug to "RESOLVED" with resolution status DUPLICATE
          // get old status
          $db->query("SELECT status FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $ostat   = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '" . 
$ostat['status'] . "'");
          $db->next_record();
          $ostat   = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '4'");
          $db->next_record();
          $nstat   = $db->record;
          $db->free();
          $db->query("SELECT name FROM resolve_d WHERE id = '3'");
          $db->next_record();
          $res     = $db->record;
          $db->free();
          // now do the updates
          $db->query("UPDATE bugs SET status = '4' WHERE bid = '$bug'");
          $db->free();
          $db->query("UPDATE bugs SET resolution = '3' WHERE bid = '$bug'");
          $db->free();
          $comm1   = "This bug has been marked as a duplicate of bug #<a 
href=\"query.php?bug=$dup_id\">$dup_id</a>\n";
          $comm2   = "Bug #<a href=\"query.php?bug=$bug\">$bug</a> has been 
marked as a duplicate of this bug.\n";
          $query   = "INSERT INTO bugdesc (did, bid, user, date, system, 
description) VALUES ";
          $query  .= "(NULL,'$dup_id','" . $_USER['uid'] . "',NULL,1,";
          $query  .= "'" . addslashes($comm2) . "')";
          $db->query($query);
          $db->free();
          $query   = "INSERT INTO bugdesc (did, bid, user, date, system, 
description) VALUES ";
          $query  .= "(NULL,'$bug','" . $_USER['uid'] . "',NULL,1,";
          $query  .= "'" . addslashes($comm1) . "')";
          $db->query($query);
          $db->free();
          $sdesc   = $nstat['name'] . " (" . $res['name'] . " (#$dup_id))";
          $query   = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query  .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] 
. "', ";
          $query  .= "NULL, '0', '" . $ostat['name'] . "', '$sdesc')";
          $db->query($query);
          $db->free();
          d_doDiff($dup_id);
          break;
        case "reassign":
          // reassign bug
          // get old owner
          $db->query("SELECT assigned FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $oassg   = $db->record;
          $db->free();
          $db->query("SELECT email FROM users WHERE uid = '" . 
$oassg['assigned'] . "'");
          $db->next_record();
          $oass    = $db->record;
          $db->free();
          // now do the updates
          $db->query("SELECT * FROM users WHERE uid = '$reassign'");
          $db->next_record();
          $tmp     = $db->record;
          $db->free();
          $syscomm = sprintf(gettext("This bug has been reassigned to %s."), 
$tmp['email']) . "\n";
          $db->query("UPDATE bugs SET assigned = '$reassign' WHERE bid = 
'$bug'");
          $db->free();
          $query   = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query  .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] 
. "', ";
          $query  .= "NULL, '1', '" . $oass['email'] . "', '" . $tmp['email'] . 
"')";
          $db->query($query);
          $db->free();
          break;
        case "reassigncomp":
          // reassign to component owner
          // get old owner
          $db->query("SELECT assigned FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $oassg   = $db->record;
          $db->free();
          $db->query("SELECT email FROM users WHERE uid = '" . 
$oassg['assigned'] . "'");
          $db->next_record();
          $oass    = $db->record;
          $db->free();
          // now do the updates
          $db->query("SELECT * FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $tmp     = $db->record;
          $db->free();
          $db->query("SELECT * FROM components WHERE cid = '" . 
$tmp['component'] . "'");
          $db->next_record();
          $tmp     = $db->record;
          $db->free();
          $db->query("SELECT * FROM users WHERE uid = '" . $tmp['owner'] . "'");
          $db->next_record();
          $tmp     = $db->record;
          $db->free();
          $syscomm = sprintf(gettext("This bug has been reassigned to %s."), 
$tmp['email']) . "\n";
          $db->query("UPDATE bugs SET assigned = '" . $tmp['owner'] . "' WHERE 
bid = '$bug'");
          $db->free();
          $query   = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query  .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] 
. "', ";
          $query  .= "NULL, '1', '" . $oass['email'] . "', '" . $tmp['email'] . 
"')";
          $db->query($query);
          $db->free();
          break;
        case "private":
          // make bug private or public
          // get old state
          $db->query("SELECT private FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          if ($db->record['private'] == 0) {
            $opr = gettext("PUBLIC");
          } else {
            $opr = gettext("PRIVATE");
          }
          if ($priv == 0) {
            $npr = gettext("PUBLIC");
          } else {
            $npr = gettext("PRIVATE");
          }
          // now do the updates
          $db->query("UPDATE bugs SET private = '$priv' WHERE bid = '$bug'");
          $db->free();
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '2', '$opr', '$npr')";
          $db->query($query);
          $db->free();
          break;
        case "reopen":
          // re-open bug
          // get old status
          $db->query("SELECT status FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $ostat   = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '" . 
$ostat['status'] . "'");
          $db->next_record();
          $ostat   = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '3'");
          $db->next_record();
          $nstat   = $db->record;
          $db->free();
          // now do the updates
          $db->query("UPDATE bugs SET status = '3' WHERE bid = '$bug'");
          $db->free();
          $db->query("UPDATE bugs SET resolution = NULL WHERE bid = '$bug'");
          $db->free();
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '0', '" . $ostat['name'] . "', '" . $nstat['name'] . 
"')";
          $db->query($query);
          $db->free();
          // zero out fixed-in-version
          $db->query("UPDATE bugs SET fixedver = '' WHERE bid = '$bug'");
          $db->free();
          $fixedver = "";
          break;
        case "close":
          // change bug to "CLOSED"
          // get old status
          $db->query("SELECT status FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '" . 
$ostat['status'] . "'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '6'");
          $db->next_record();
          $nstat  = $db->record;
          $db->free();
          // now do the updates
          $db->query("UPDATE bugs SET status = '6' WHERE bid = '$bug'");
          $db->free();
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '0', '" . $ostat['name'] . "', '". $nstat['name'] . 
"')";
          $db->query($query);
          $db->free();
          break;
        case "passign":
          // change bug to "VERIFIED" or "UNCONFIRMED"
          // get old status
          $db->query("SELECT status FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '" . 
$ostat['status'] . "'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '$postassign'");
          $db->next_record();
          $nstat  = $db->record;
          $db->free();
          // now do the updates
          $db->query("UPDATE bugs SET status = '$postassign' WHERE bid = 
'$bug'");
          $db->free();
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '0', '" . $ostat['name'] . "', '". $nstat['name'] . 
"')";
          $db->query($query);
          $db->free();
          break;
        case "verify":
          // change bug to "VERIFIED"
          // get old status
          $db->query("SELECT status FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '" . 
$ostat['status'] . "'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '5'");
          $db->next_record();
          $nstat  = $db->record;
          $db->free();
          // now do the updates
          $db->query("UPDATE bugs SET status = '5' WHERE bid = '$bug'");
          $db->free();
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '0', '" . $ostat['name'] . "', '". $nstat['name'] . 
"')";
          $db->query($query);
          $db->free();
          break;
        case "tovalidate":
          // change bug to "TOVALIDATE"
          // get old status
          $db->query("SELECT status FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '" . 
$ostat['status'] . "'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '7'");
          $db->next_record();
          $nstat  = $db->record;
          $db->free();
          // now do the updates
          $db->query("UPDATE bugs SET status = '7' WHERE bid = '$bug'");
          $db->free();
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '0', '" . $ostat['name'] . "', '". $nstat['name'] . 
"')";
          $db->query($query);
          $db->free();
          break;
        case "needswork":
          // change bug to "NEEDSWORK"
          // get old status
          $db->query("SELECT status FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '" . 
$ostat['status'] . "'");
          $db->next_record();
          $ostat  = $db->record;
          $db->free();
          $db->query("SELECT name FROM status_d WHERE id = '8'");
          $db->next_record();
          $nstat  = $db->record;
          $db->free();
          // now do the updates
          $db->query("UPDATE bugs SET status = '8' WHERE bid = '$bug'");
          $db->free();
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '0', '" . $ostat['name'] . "', '". $nstat['name'] . 
"')";
          $db->query($query);
          $db->free();
          break;
        case "severity":
          // change severity level
          // get old severity
          $db->query("SELECT severity FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $ostat = $db->record;
          $db->free();
          $db->query("SELECT name FROM severity_d WHERE id = '" . 
$ostat['severity'] . "'");
          $db->next_record();
          $ostat = $db->record;
          $db->free();
          $db->query("SELECT name FROM severity_d WHERE id = '$severity'");
          $db->next_record();
          $nstat = $db->record;
          $db->free();
          // now do the updates
          $db->query("UPDATE bugs SET severity = '$severity' WHERE bid = 
'$bug'");
          $db->free();
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '7', '" . $ostat['name'] . "', '" . $nstat['name'] . 
"')";
          $db->query($query);
          $db->free();
          break;
        case "priority":
          // change resolution priority
          // get old priority
          $db->query("SELECT priority FROM bugs WHERE bid = '$bug'");
          $db->next_record();
          $ostat = $db->record;
          $db->free();
          $db->query("SELECT name FROM priority_d WHERE id = '" . 
$ostat['priority'] . "'");
          $db->next_record();
          $ostat = $db->record;
          $db->free();
          $db->query("SELECT name FROM priority_d WHERE id = '$priority'");
          $db->next_record();
          $nstat = $db->record;
          $db->free();
          // now do the updates
          $db->query("UPDATE bugs SET priority = '$priority' WHERE bid = 
'$bug'");
          $db->free();
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '6', '" . $ostat['name'] . "', '" . $nstat['name'] . 
"')";
          $db->query($query);
          $db->free();
          break;
        default:
          $query = "";
          break;
      }
      if ($comment) {
        $query  = "INSERT INTO bugdesc (did, bid, user, date, system, 
description) VALUES ";
        $query .= "(NULL,'$bug','" . $_USER['uid'] . "',NULL,0,";
        $query .= "'" . addslashes($comment) . "')";
        $db->query($query);
        $db->free();
      }
      // system comment for bug re-assigns
      if ($syscomm) {
        $query  = "INSERT INTO bugdesc (did, bid, user, date, system, 
description) VALUES ";
        $query .= "(NULL,'$bug','" . $_USER['uid'] . "',NULL,1,";
        $query .= "'$syscomm')";
        $db->query($query);
        $db->free();
      }
      if ($url) {
        $db->query("UPDATE bugs SET url = '" . trim(addslashes($url)) . "' 
WHERE bid = '$bug'");
        $db->free();
      }
      if ($shortdesc) {
        $ndesc = trim(addslashes($shortdesc));
        $db->query("SELECT shortdesc FROM bugs WHERE bid = '$bug'");
        $db->next_record();
        $odesc  = $db->record;
        $db->free();
        // make sure that the description has actually changed
        if ($ndesc != trim($odesc['shortdesc'])) {
          $db->query("UPDATE bugs SET shortdesc = '$ndesc' WHERE bid = '$bug'");
          $db->free();
          $query  = "INSERT INTO bugactivity (aid, bid, user, date, what, ";
          $query .= "oldval, newval) VALUES (NULL, '$bug', '" . $_USER['uid'] . 
"', ";
          $query .= "NULL, '8', '" . $odesc['shortdesc'] . "', '$ndesc')";
          $db->query($query);
          $db->free();
        }
      }
      // If resolved, allow to set the fixed version
      $db->query("SELECT product FROM bugs WHERE bid = '$bug'");
      $db->next_record();
      $bugx = $db->record;
      $db->free();
      if ($fixedver != "" && $bugx['status'] == 0 && $resolve == 0) {
        $db->query("UPDATE bugs SET fixedver = '$fixedver' WHERE bid = '$bug'");
        $db->free();
      }

      d_doDiff($bug);
    }
  }

  if (!isset($bug) || isset($btnQuery)) {
    if (isset($btnQuery)) { // we have an advanced query
      $Parameters = z_ParseQueryArguments($HTTP_POST_VARS);
      // $Columns    = z_CheckBoxesArray("show_", $HTTP_POST_VARS);
      $Columns    = z_OrderedListArray("show_",$HTTP_POST_VARS);
      $SortList   = z_OrderedListArray("sort_",$HTTP_POST_VARS);
      // while (list ($k,$v) = each ($SortList) ) print "\n<br> $k => $v ";
      $Query      = z_ComposeQuery($Parameters,$SortList);
      // print("\n <font size=-1 color=blue> <b>[$Query]</font></b> <br> "); 
flush();
      z_PrintResultSet($Columns,$Query);
      print "\n\n<br>";
      d_DrawFooter();
      exit;
    } else { // we have no query, so display our forms
      d_doQuery($_USER['uid']);
      d_DrawFooter();
      exit;
    }
  } else {
    $db->query("SELECT * FROM bugs WHERE bid = '$bug'");
    $db->next_record();
    $bugx = $db->record;
    if ($db->num_rows() == 0) {  // empty bug; non-existant
      print("<p><font color=\"red\">" . gettext("The bug you selected does not 
exist or is invalid.") . "</font></p>");
      d_doQuery($_USER['uid']);
      d_DrawFooter();
      exit();
    }
    if ($bugx['private'] == 1 && !isset($_USER['uid'])) {
      print("<p><font color=\"red\">" . gettext("The bug you selected is marked 
private and is not available to unregistered users.") . "</font></p>");
      d_doQuery($_USER['uid']);
      d_DrawFooter();
      exit();
    }
    $db->free();

    // get product info
    $db->query("SELECT * FROM products WHERE pid = '" . $bugx['product'] . "'");
    $db->next_record();
    $product = $db->record['name'];
    $db->free();

    // get version info
    $db->query("SELECT * FROM versions WHERE vid = '" . $bugx['version'] . "'");
    $db->next_record();
    $version = $db->record['name'];
    $db->free();

    // get component info
    $db->query("SELECT * FROM components WHERE cid = '" . $bugx['component'] . 
"'");
    $db->next_record();
    $component = $db->record['name'];
    $db->free();

    // get user info
    $db->query("SELECT * FROM users WHERE uid = '" . $bugx['reporter'] . "'");
    $db->next_record();
    $email = $db->record['email'];
    if ($db->record['gpg'] != "") {
      $gpg = " [ <a href=\"" . $_CONF['webroot'] . $db->record['gpg'] . 
"\">gpg</a> ] ";
    } else {
      $gpg = "";
    }
    $db->free();

    // get status info
    $db->query("SELECT * FROM status_d WHERE id = '" . $bugx['status'] . "'");
    $db->next_record();
    $status = $db->record['name'];
    $statid = $db->record['id'];
    $db->free();

    // get severity info
    $db->query("SELECT * FROM severity_d WHERE id = '" . $bugx['severity'] . 
"'");
    $db->next_record();
    $severity_id = $db->record['id'];
    $severity    = $db->record['name'];
    $db->free();

    // get resolution info
    if ($bugx['resolution'] != "") {
      $db->query("SELECT * FROM resolve_d WHERE id = '" . $bugx['resolution'] . 
"'");
      $db->next_record();
      $resolution = $db->record['name'];
      $db->free();
    }

    // get priority info
    $db->query("SELECT * FROM priority_d WHERE id = '" . $bugx['priority'] . 
"'");
    $db->next_record();
    $priority_id = $db->record['id'];
    $priority    = $db->record['name'];
    $db->free();

    // get fixed-in-version info (if it exists)
    if ($bugx['fixedver'] != "") {
      $fixinver = $bugx['fixedver'];
    } else {
      $fixinver = NULL;
    }
?>

  <table border="0" cellpadding="0" cellspacing="2" width="100%">
    <tr>
      <td width="20%" align="center" bgcolor=<? print($config['barcol1']); ?>>
        <b><? print(gettext("Product") . " - " . gettext("Version")); ?></b>
      </td>
      <td width="20%" align="center" bgcolor=<? print($config['barcol1']); ?>>
        <b><? print(gettext("Component")); ?></b>
      </td>
      <td width="20%" align="center" bgcolor=<? print($config['barcol1']); ?>>
        <b><? print(gettext("Status")); ?></b>
      </td>
      <td width="40%" bgcolor=<? print($config['barcol1']); ?>>
        <b><? print(gettext("Short Summary")); ?></b>
      </td>
    </tr>
    <tr>
      <td width="20%" align="center" bgcolor=<? print($config['barcol2']); ?>>
        <? print(sprintf("%s - %s",$product,$version)); ?>
      </td>
      <td width="20%" align="center" bgcolor=<? print($config['barcol2']); ?>>
        <? print($component); ?>
      </td>
      <td width="20%" align="center" bgcolor=<? print($config['barcol2']); ?>>
        <? print($status); ?>
      </td>
      <td width="40%" bgcolor=<? print($config['barcol2']); ?>>
        <? print(htmlspecialchars(stripslashes($bugx['shortdesc']))); ?>
      </td>
    </tr>
    <tr>
      <td colspan="4" width="100%">
        <br />
      </td>
    </tr>
    <tr>
      <td width="100%" colspan="4" bgcolor=<? print($config['barcol1']); ?>>
        <b>
        <? $d = d_getTime($bugx['creation']);
           print(sprintf(gettext("Opened by <a href=\"mailto:%s\";>%s</a> %s on 
%s"), $email, $email, $gpg, $d));
        ?>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><? print(gettext("Long Description")); 
?></b>
      </td>
    </tr>
    <tr>
      <td colspan="4" width="100%">
        <? $db->query("SELECT * FROM bugdesc WHERE bid = '" . $bugx['bid'] . "' 
ORDER BY date");
           $count = 0;
           while ($db->next_record()) {
             if ($count > 0) {
               $cdate  = d_getTime($db->record['date']);
               $db2->query("SELECT * FROM users WHERE uid = '" . 
$db->record['user'] . "'");
               $db2->next_record();
               $cemail = $db2->record['email'];
               if ($db2->record['gpg'] != "") {
                 $cgpg = " [ <a href=\"" . $_CONF['webroot'] . 
$db2->record['gpg'] . "\">gpg</a> ] ";
               } else {
                 $cgpg = "";
               }
               $db2->free();
               print("<br />------ ");
               print(sprintf(gettext("Additional comments from <a 
href=\"mailto:%s\";>%s</a> %s on %s"), $cemail, $cemail, $cgpg, $cdate));
               print(" ------<br />");
             }
             if ($db->record['system'] == 1) {
               print(stripslashes($db->record['description']));
             } else {
               // sanitize things, we only addslashes when saving to the
               // database so now we have to make things safe
               $desc = 
nl2br(d_TransURL(htmlspecialchars(stripslashes($db->record['description'])),1));
               print($desc);
             }
             print("<br />");
             $count++;
           }
           $db->free();
        ?>
      </td>
    </tr>
  </table>

  <br />

  <table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr>
      <td colspan="4" width="100%" bgcolor=<? print($config['barcol1']); ?>>
        <b><? print(gettext("Additional Information")); ?></b>
      </td>
    </tr>
    <tr>
      <td width="20%" align="right" valign="top">
        <b><? print(gettext("Bug")); ?>#:</b>
      </td>
      <td width="30%" valign="top">
        <? print($bug); ?>
      </td>
      <td width="20%" align="right" valign="top">
        <b><? print(gettext("Product")); ?>:</b>
      </td>
      <td width="30%" valign="top">
        <? print($product); ?>
      </td>
    </tr>
    <tr>
      <td width="20%" align="right" valign="top">
        <b><? print(gettext("Status")); ?>:</b>
      </td>
      <td width="30%" valign="top">
        <? print($status); ?>
      </td>
      <td width="20%" align="right" valign="top">
        <b><? print(gettext("Component")); ?>:</b>
      </td>
      <td width="30%" valign="top">
        <? print($component); ?>
      </td>
    </tr>
    <tr>
      <td width="20%" align="right" valign="top">
        <b><? print(gettext("Resolution")); ?>:</b>
      </td>
      <td width="30%" valign="top">
        <? print($resolution);
           if(isset($fixinver)) {
             print(" " . sprintf(gettext("(in version %s)"),$fixinver));
           }
        ?>
      </td>
      <td width="20%" align="right" valign="top">
        <b><? print(gettext("Priority")); ?>:</b>
      </td>
      <td width="30%" valign="top">
        <? print($priority); ?>
      </td>
    </tr>
    <tr>
      <td width="20%" align="right" valign="top">
        <b><? print(gettext("Assigned To")); ?>:</b>
      </td>
      <td width="30%" valign="top">
        <? $db->query("SELECT * FROM users WHERE uid = '" . $bugx['assigned'] . 
"'");
           $db->next_record();
           if ($db->record['gpg'] != "") {
             $mgpg = " [ <a href=\"" . $_CONF['webroot'] . $db->record['gpg'] . 
"\">gpg</a> ] ";
           } else {
             $mgpg = "";
           }
           print(sprintf("<a href=\"mailto:%s\";>%s</a> %s", 
$db->record['email'], $db->record['email'], $mgpg));
           $db->free();
        ?>
      </td>
      <td width="20%" align="right" valign="top">
        <b><? print(gettext("Severity")); ?>:</b>
      </td>
      <td width="30%" valign="top">
        <? print($severity); ?>
      </td>
    </tr>
    <tr>
      <td width="20%" align="right" valign="top">
         <b><? print(gettext("Email CC")); ?>:</b>
      </td>
      <td width="30%" valign="top">
         <? print($bugx['cc']); ?>
      </td>
      <td width="20%" align="right" valign="top">
        <b><? print(gettext("Reporter")); ?>:</b>
      </td>
      <td width="30%" valign="top">
        <? print(sprintf("<a href=\"mailto:%s\";>%s</a> %s", $email, $email, 
$gpg)); ?>
      </td>
    </tr>
    <tr>
      <td width="20%" align="right" valign="top">
         <b>URL:</b>
      </td>
      <td width="30%" valign="top">
         <a href="<? print(trim(stripslashes($bugx['url']))); ?>"><? 
print(stripslashes($bugx['url'])); ?></a>
      </td>
      <td width="20%" align="right" valign="top">
        <b><? print(gettext("Type")); ?>:</b>
      </td>
      <td width="30%" valign="top">
        <? if ($bugx['private'] == 0) {
             print(gettext("PUBLIC"));
           } else {
             print(gettext("PRIVATE"));
           }
        ?>
      </td>
    </tr>
    <tr>
      <td width="20%" align="right" valign="top">
        <b>Attachments:</b>
      </td>
      <td width="80%" valign="top" colspan="3">
        <? $db->query("SELECT * FROM attachidx WHERE bid = $bug ORDER BY date 
ASC");
           while ($db->next_record()) {
             $date = d_getTime($db->record['date']);
             print(sprintf("id %s: <a href=\"showattachment.php?id=%s\">%s</a> 
- %s<br />", $db->record['atid'], $db->record['atid'], $date, 
$db->record['filename']));
           }
        ?>
        <a href="createattachment.php?bug=<? print($bug); ?>">Create a new 
attachment</a> (proposed patch, testcase, etc.)
      </td>
    </tr>
  </table>

  <br />
  <center>
  <b><p>[ <a href="activity.php?bug=<? print($bug); ?>"><? print(gettext("View 
Activity Log")); ?></a> ] </p></b>
  </center>
  <br />

<? if (isset($_USER['uid'])) { // only display form to logged in users ?>
  <table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr>
      <td width="100%" align="center">
        <table border="0" cellpadding="0" cellspacing="0">
          <tr>
            <td align="center">
              <form method="post" action="query.php">
              <input type="submit" name="add_cc" value="<? print(gettext("Add 
Me to CC List")); ?>">
              <input type="hidden" name="bug" value="<? print($bug); ?>">
              <input type="hidden" name="doit" value="add_cc">
              </form>
            </td>
            <td align="center">
              <form method="post" action="query.php">
              <input type="submit" name="rem_cc" value="<? 
print(gettext("Remove Me from CC List")); ?>">
              <input type="hidden" name="bug" value="<? print($bug); ?>">
              <input type="hidden" name="doit" value="rem_cc">
              </form>
            </td>
          </tr>
        </table>
      </td>
    </tr>
    <tr>
      <td>&nbsp;</td>
    </tr>
    <tr>
      <td width="100%" bgcolor=<? print($config['barcol1']); ?>>
        <b><? print(gettext("Additional comments from")); ?></b>
      </td>
    </tr>
    <tr>
      <td width="100%" align="center">
        <form method="post" action="query.php">
        <textarea name="comment" cols="76" rows="10" wrap="hard"></textarea><br 
/>
        <span class="tiny"><? print(gettext("NOTE: Please use plaintext only; 
HTML will not be parsed.")); ?></span>
      </td>
    </tr>
<?
    if ($_USER['uid'] == $bugx['assigned'] || $_USER['access'] >= 
$config['adminac']) {
      // we are owner or admin
?>
    <tr>
      <td width="100%">
        <br />
        <? print(gettext("Change URL: (include prefix)")); ?> <input name="url" 
size="76" maxlength="128" value="<? print(trim(stripslashes($bugx['url']))); 
?>">
      </td>
    </tr>
    <tr>
      <td width="100%">
        <br />
        <? print(gettext("Change description:")); ?> <input name="shortdesc" 
size="76" maxlength="128" value="<? 
print(trim(stripslashes($bugx['shortdesc']))); ?>">
      </td>
    </tr>
  </table>

  <br />

  <table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr>
      <td width="100%" bgcolor=<? print($config['barcol1']); ?>>
        <b><? print(gettext("Change State or Resolution")); ?></b> (<? 
print(gettext("only by owner or privileged member")); ?>)
      </td>
    </tr>
    <tr>
      <td width="100%">
        <input type="radio" name="sbutton" value="nochange" CHECKED>
        <? print(sprintf(gettext("Leave as <b>%s</b>"), $status)); ?><br />

        <? if ($statid == "1") { // if status "NEW" ?>
          <input type="radio" name="sbutton" value="accept">
          <?  $db->query("SELECT * FROM status_d WHERE id = '2'");
              $db->next_record();
              print(sprintf(gettext("Accept problem (change status to 
<b>%s</b>)"), $db->record['name']));
              $db->free();
          ?><br />
        <? } ?>

        <? if ($statid == "2") { // if status "ASSIGNED" ?>
          <input type="radio" name="sbutton" value="passign">
          <? print(gettext("Work on bug, changing status to")); ?>
          <select name="postassign">
          <? $db->query("SELECT * FROM status_d WHERE id = '5' OR id = '0'");
             while ($db->next_record()) {
               print(sprintf("<option 
value=\"%s\">%s</option>\n",$db->record['id'],$db->record['name']));
             }
             $db->free();
          ?></select><br />
        <? } ?>

        <? if ($statid == "0") { // if status "UNCONFIRMED" ?>
          <input type="radio" name="sbutton" value="verify">
          <? print(gettext("Verify this unconfirmed bug")); ?><br />
        <? } ?>

        <? if ($statid == "5" || $statid == "8" ) { // if status "VERIFIED" or 
"NEEDSWORK" ?>
          <input type="radio" name="sbutton" value="tovalidate">
          <? print(gettext("Solution requires testing/validation from QA")); 
?><br />
        <? } ?>

        <? if ($statid == "5" || $statid == "7") { // if status "VERIFIED" or 
"TOVALIDATE" ?>
          <input type="radio" name="sbutton" value="needswork">
          <? print(gettext("Bug requires more work or fix not appropriate")); 
?><br />
        <? } ?>

     <? if ($statid != "4" && $statid != "6") { // if not status "RESOLVED" ?>
        <input type="radio" name="sbutton" value="priority">
        <? print(gettext("Change resolution priority to")); ?>
        <select name="priority">
        <? $db->query("SELECT * FROM priority_d");
           while($db->next_record()) {
             if ($db->record['id'] == $priority_id) {
               $def = "SELECTED";
             } else {
               $def = "";
             }
             print(sprintf("<option value=\"%s\" 
%s>%s</option>\n",$db->record['id'],$def,$db->record['name']));
           }
        ?></select><br />
        <input type="radio" name="sbutton" value="severity">
        <? print(gettext("Change bug severity to")); ?>
        <select name="severity">
        <? $db->query("SELECT * FROM severity_d");
           while($db->next_record()) {
             if ($db->record['id'] == $severity_id) {
               $def = "SELECTED";
             } else {
               $def = "";
             }
             print(sprintf("<option value=\"%s\" 
%s>%s</option>\n",$db->record['id'],$def,$db->record['name']));
           }
        ?></select><br />
        <input type="radio" name="sbutton" value="resolve">
        <? print(gettext("Resolve bug, changing resolution to")); ?>
        <select name="resolve">
        <?  $db->query("SELECT * FROM resolve_d");
            while ($db->next_record()) {
              if ($db->record['id'] != 3) {  // don't print "DUPLICATE"
                print(sprintf("<option 
value=\"%s\">%s</option>\n",$db->record['id'],$db->record['name']));
              }
            }
            $db->free();
        ?>
        </select><br />
        <? print(gettext("If FIXED, you may also select a version:")); ?>
        <input type="text" name="fixedver" size="8" maxsize="8"><br />

        <input type="radio" name="sbutton" value="duplicate">
        <? print(gettext("Resolve bug, make it a duplicate of problem")); ?> #
        <input type="text" name="dup_id" size="6" maxsize="6"><br />

        <input type="radio" name="sbutton" value="close">
        <? print(gettext("Close bug with no resolution")); ?><br />

        <input type="radio" name="sbutton" value="reassign">
        <? print(gettext("Reassign problem to")); ?>
        <select name="reassign">
        <?  $db->query("SELECT * FROM users WHERE (access >= '" . 
$config['devac'] . "') AND (deleted = '0')");
            while ($db->next_record()) {
              print(sprintf("<option 
value=\"%s\">%s</option>\n",$db->record['uid'],$db->record['email']));
            }
            $db->free();
        ?>
        </select><br />

        <input type="radio" name="sbutton" value="reassigncomp">
        <? print(gettext("Reassign problem to owner of selected component")); 
?><br />

        <input type="radio" name="sbutton" value="private">
        <? if ($bugx['private'] == 0) {
             print(gettext("Mark this bug private"));
             print("<input type=\"hidden\" name=\"priv\" value=\"1\">");
           } else {
             print(gettext("Mark this bug public"));
             print("<input type=\"hidden\" name=\"priv\" value=\"0\">");
           }
        ?>
     <? } else { // if status "RESOLVED" ?>
        <input type="radio" name="sbutton" value="reopen">
        <? print(gettext("Re-open bug")); ?><br />
        <? print(gettext("If FIXED, you may also select a version:")); ?>
        <input type="text" name="fixedver" size="8" maxsize="8" value="<? 
print($fixinver); ?>"><br />
     <? } ?>
      </td>
    </tr>
    <tr>
      <td width="100%" valign="center">
        <input type="submit" value="<? print(gettext("Save Changes")); ?>">
        <input type="reset" value="<? print(gettext("Reset")); ?>">
        <input type="hidden" name="bug" value="<? print($bug); ?>">
        <input type="hidden" name="doit" value="admin">
        </form>
      </td>
    </tr>
  </table>

<?
    } else {
?>

    <tr>
      <td width="100%" align="center">
        <input type="submit" name="add_comment" value="<? print(gettext("Add 
Comment")); ?>">
        <input type="hidden" name="doit" value="add_comment">
        <input type="hidden" name="bug" value="<? print($bug); ?>">
        </form>
      </td>
    </tr>
  </table>

<?
      }
    } else {
      print("</table>");
    } // end isset($_USER['uid'])

  } // end isset($bug)

  d_DrawFooter();
?>

====================================================
Index: textreport.php
<?
   // Anthill
   // $Id: textreport.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

   // Create the headers; define a date in the past, always modified
   header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
   header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
   header("Cache-Control: no-store, no-cache, must-revalidate");  // HTTP/1.1
   header("Cache-Control: post-check=0, pre-check=0", false);
   header("Pragma: no-cache");                                    // HTTP/1.0

   // set variables
   if (isset($_REQUEST['repval'])) { $repval = $_REQUEST['repval']; } else { 
$repval = NULL; }

   if (isset($repval)) {
     if ($repval == "total") {
       header("Content-type: application/octet-stream");
       header("Content-Disposition: attachment; filename=" . $repval . ".txt");
     }
  }

  include("include.php");
  if (!isset($repval)) {
    d_StartPage(gettext("Text Bug Reports"));
  }

  if (do_checkaccess($config['newusers'], $_USER['uid'], $_USER['uname']) == 1) 
exit;

  if (!isset($repval)) {
    d_DrawNav($user['uname']);
    d_DrawHeader(gettext("Select Report"));
?>
    <form method="post" action="textreport.php">
    <table border="0" cellpadding="0" cellspacing="0" width="40%" 
align="center">
      <tr>
        <td width="50%" align="right">
          <? print(gettext("Select Report")); ?>:
        </td>
        <td width="50%">
          <select name="repval">
            <option value="total">Total</option>
            <option value="partial">Partial</option>
          </select>
        </td>
      </tr>
      <tr>
        <td width="50%">
          &nbsp;
        </td>
        <td width="50%">
          <input type="submit" value="<? print(gettext("Continue")); ?>">
        </td>
      </tr>
    </table>
    </form>
<?
    d_DrawFooter();
    exit;
  }

  $db2         = new db_Sql();
  $db2->host   = $_CONF['db_host'];
  $db2->dbase  = $_CONF['db_name'];
  $db2->user   = $_CONF['db_user'];
  $db2->passwd = $_CONF['db_pw'];
  $db2->connect();

  $date = gmdate(sprintf("%s %s", $_CONF['datefmt'], $_CONF['timefmt']));
  switch($repval) {
    case "total":
      if(file_exists("$rincdir/reportengine.php")) {
        include_once("$rincdir/reportengine.php");
      }
      report_init(58, 80, 1, 0, gettext("Total bug information report"), 2, 2);
      $db->query("SELECT bid,
        u2.name as assigned_user,
        severity_d.name as severity_name,
        status_d.name as status_name,
        creation,
        modified,
        shortdesc,
        priority_d.name priority_name,
        products.name as product_name,
        users.name as reporter_user,
        versions.name as version_name,
        components.name as component_name,
        IFNULL(resolve_d.name,\"UNRESOLVED\") as resolve_info,
        cc,
        case private when 0 then \"Public\" when 1 then \"Private\" else 
\"Unknown\" end,
        url
        FROM
        bugs,
        priority_d,
        users,
        users as u2,
        severity_d,
        status_d,
        versions,
        products,
        components
        LEFT JOIN
        resolve_d
        ON
        (bugs.resolution = resolve_d.id)
        WHERE
        (bugs.priority = priority_d.id)
        and (bugs.reporter = users.uid)
        and (bugs.assigned = u2.uid)
        and (bugs.severity = severity_d.id)
        and (bugs.status = status_d.id)
        and (bugs.version = versions.vid)
        and (bugs.product = products.pid)
        and (bugs.component = components.cid)
        ORDER BY
        bid;");
        while ($db->next_record()) {
          report_que_line("");
          report_que_line(gettext("Bug      Priority Severity    Status      
Modified              Resolution"));
          $cdate = d_getTimeGMT($db->record['creation']);
          $mdate = d_getTimeGMT($db->record['modified']);
          report_que_line(sprintf("%-8d %-8s %-11s %-11s %-21s %-8s",
            $db->record['bid'],
            $db->record['priority_name'],
            $db->record['severity_name'],
            $db->record['status_name'],
            $mdate,
            $db->record['resolve_info']));
// some gettext length magic
          report_que_line(sprintf("        Assignee: %s", 
$db->record['assigned_user']));
          report_que_line(sprintf("        Reporter: %s", 
$db->record['reporter_user']));
          report_que_line(sprintf("         Created: %s", $cdate));
          report_que_line(sprintf("         Product: %s", 
$db->record['product_name']));
          report_que_line(sprintf("       Component: %s", 
$db->record['component_name']));
          report_que_line(sprintf("         Version: %s", 
$db->record['version_name']));
          report_que_line(sprintf(" Bug Description: %s", 
stripslashes($db->record['shortdesc'])));
          if (strlen($db->record['url'])>0) {
            report_que_line(sprintf("URL: %s", 
stripslashes($db->record['url'])));
          }
         $db2->query("SELECT description, date, users.name as uname FROM 
bugdesc, users WHERE (bid='" . $db->record['bid'] . "') AND (bugdesc.user = 
users.uid) ORDER BY date");
         $firsttime = 1;
         while ($db2->next_record()) {
           if ($firsttime == 1) {
             report_que_line(gettext("Long description:"));
             $firsttime = 0;
           } else {
             $xdate = d_getTimeGMT($db2->record['date']);
             report_que_line(sprintf("On %s, %s 
said:",$xdate,$db2->record['uname']));
           }
           $outstring = ereg_replace("  "," ",ereg_replace("\n"," 
",ereg_replace("\r","", stripslashes($db2->record['description']))));
           report_flowtext($outstring,2);
         }
         $db2->free();

         $db2->query("SELECT date, what, oldval, newval, name FROM bugactivity, 
users WHERE (bid = '" . $db->record['bid'] . "') AND (bugactivity.user = 
users.uid) ORDER BY date");
         while ($db2->next_record()) {
           report_que_line("");
           report_que_line(sprintf(" Who: %s", $db2->record['name']));
           switch($db2->record['what']) {
             case 0:
               report_que_line(gettext("What: Status Change")); break;
             case 1:
               report_que_line(gettext("What: Reassigned")); break;
             case 2:
               report_que_line(gettext("What: State Change")); break;
             case 3:
               report_que_line(gettext("What: Added to CC")); break;
             case 4:
               report_que_line(gettext("What: Removed from CC")); break;
           }
// more gettext length magic
           report_que_line(sprintf(" Old: %s", $db2->record['oldval']));
           report_que_line(sprintf(" New: %s", $db2->record['newval']));
           report_que_line(sprintf("When: %s", 
d_getTimeGMT($db2->record['date'])));
         }

         report_que_line("");
       }
       report_que_line(sprintf(gettext("Report generated on %s GMT."), $date));

       report_finish();
       break;
    case "partial":
       d_DrawNav($user['uname']);
       d_DrawHeader(gettext("Partial bug information report"));
       printf("Partial bug information report not implemented\n");
       d_DrawFooter();
       break;
  }

?>

====================================================
Index: reports.php
<?
  // Anthill
  // $Id: reports.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['pid'])) { $pid = $_REQUEST['pid']; } else { $pid = NULL; 
}

  d_StartPage(gettext("Bug Reports"));
  if (do_checkaccess($config['newusers'], $_USER['uid'], $_USER['uname']) == 1) 
{ exit; }
  d_DrawNav($_USER['uname']);

  $db2         = new db_Sql();
  $db2->host   = $_CONF['db_host'];
  $db2->dbase  = $_CONF['db_name'];
  $db2->user   = $_CONF['db_user'];
  $db2->passwd = $_CONF['db_pw'];
  $db2->connect();

  $db->query("SELECT * FROM products");
  if ($db->num_rows() == 1) {
    $db->next_record();
    $pid = $db->record['pid'];
  }
  $db->free();

  if (!isset($pid)) {
    d_DrawHeader(gettext("Select Product To Report On"));
    ?>
    <form method="post" action="reports.php">
    <table border="0" cellpadding="0" cellspacing="0" width="40%" 
align="center">
      <tr>
        <td width="50%" align="right">
          <? print(gettext("Select Product")); ?>:
        </td>
        <td width="50%">
          <select name="pid">
          <? $db->query("SELECT * FROM products WHERE deleted = '0' ORDER BY 
name");
             while ($db->next_record()) {
               print(sprintf("<option 
value=\"%s\">%s</option>\n",$db->record['pid'],$db->record['name']));
             }
             $db->free();
          ?>
          <option value="all">All Products</option>
          </select>
        </td>
      </tr>
      <tr>
        <td width="50%">
          &nbsp;
        </td>
        <td width="50%">
          <input type="submit" value="<? print(gettext("Continue")); ?>">
        </td>
      </tr>
    </table>
    </form>
    <?
    d_DrawFooter();
    exit;
  }

  d_DrawHeader(gettext("Bug Reports"));

  $date = date(sprintf("%s %s", $_CONF['datefmt'], $_CONF['timefmt']));
  if ($pid != "all") {
    $db->query("SELECT * FROM products WHERE pid = '$pid'");
    $db->next_record();
    $prod  = $db->record;
    $qtag  = " AND product = '$pid'";
    $qtag2 = " WHERE product = '$pid'";
  } else {
    $prod['name'] = "All Products";
    $qtag  = "";
    $qtag2 = "";
  }

  print("<p><b>" . sprintf(gettext("Bug Report for %s"), $prod['name']) . 
"</b></p>");
  print("<p>$date</p>");
  print("<p><b>" . gettext("Summary") . "</b></p>");
?>

  <table border="0" cellpadding="0" cellspacing="0" width="30%">
    <tr>
      <td width="45%" align="right">
        <? print(gettext("New Bugs This Week")); ?>:
      </td>
      <td width="10%">&nbsp;</td>
      <td width="45%">
        <? $mnth = date("n");
           $day  = date("j");
           $year = date("Y");
           $sunday = 
date("YmdHis",mktime(0,0,0,$mnth,$day-date("w",mktime(0,0,0,$mnth,$day,$year)),$year));
           $db->query(sprintf("SELECT * FROM bugs WHERE creation >= '$sunday' 
%s", $qtag));
           print($db->num_rows());
           $db->free();
        ?>
      </td>
    </tr>
    <tr>
      <td width="45%" align="right">
        <? print(gettext("Bugs Marked New")); ?>:
      </td>
      <td width="10%">&nbsp;</td>
      <td width="45%">
        <? $db->query(sprintf("SELECT * FROM bugs WHERE status = '1' %s", 
$qtag));
           print($db->num_rows());
           $db->free();
        ?>
      </td>
    </tr>
    <tr>
      <td width="45%" align="right">
        <? print(gettext("Bugs Marked Assigned")); ?>:
      </td>
      <td width="10%">&nbsp;</td>
      <td width="45%">
        <? $db->query(sprintf("SELECT * FROM bugs WHERE status = '2' %s", 
$qtag));
           print($db->num_rows());
           $db->free();
        ?>
      </td>
    </tr>
    <tr>
      <td width="45%" align="right">
        <? print(gettext("Bugs Marked Verified")); ?>:
      </td>
      <td width="10%">&nbsp;</td>
      <td width="45%">
        <? $db->query(sprintf("SELECT * FROM bugs WHERE status = '5' %s", 
$qtag));
           print($db->num_rows());
           $db->free();
        ?>
      </td>
    </tr>
    <tr>
      <td width="45%" align="right">
        <? print(gettext("Bugs Marked Unconfirmed")); ?>:
      </td>
      <td width="10%">&nbsp;</td>
      <td width="45%">
        <? $db->query(sprintf("SELECT * FROM bugs WHERE status = '0' %s", 
$qtag));
           print($db->num_rows());
           $db->free();
        ?>
      </td>
    </tr>
    <tr>
      <td width="45%" align="right">
        <? print(gettext("Bugs Marked Reopened")); ?>:
      </td>
      <td width="10%">&nbsp;</td>
      <td width="45%">
        <? $db->query(sprintf("SELECT * FROM bugs WHERE status = '3' %s", 
$qtag));
           print($db->num_rows());
           $db->free();
        ?>
      </td>
    </tr>
    <tr>
      <td width="45%" align="right">
        <? print(gettext("Total Bugs")); ?>:
      </td>
      <td width="10%">&nbsp;</td>
      <td width="45%">
        <? $db->query(sprintf("SELECT * FROM bugs %s", $qtag2));
           print($db->num_rows());
           $db->free();
        ?>
      </td>
    </tr>
  </table>

  <p><b><? print(gettext("Bug Count by Owner")); ?></b></p>
  <table border="0" cellpadding="0" cellspacing="0" width="50%">
    <tr>
      <td width="30%" align="center">
        <? print(gettext("Owner")); ?>
      </td>
      <td width="10%" align="center">
        <? print(gettext("Reported")); ?>
      </td>
      <td width="10%" align="center">
        <? print(gettext("New")); ?>
      </td>
      <td width="10%" align="center">
        <? print(gettext("Assigned")); ?>
      </td>
      <td width="10%" align="center">
        <? print(gettext("Verified")); ?>
      </td>
      <td width="10%" align="center">
        <? print(gettext("Unconfirmed")); ?>
      </td>
      <td width="10%" align="center">
        <? print(gettext("Reopened")); ?>
      </td>
      <td width="10%" align="center">
        <? print(gettext("Total")); ?>
      </td>
    </tr>
    <? $db->query(sprintf("SELECT * FROM bugs WHERE assigned = '0' AND status = 
'1' %s", $qtag));
       $new = $db->num_rows();
       $db->free();
       $db->query(sprintf("SELECT * FROM bugs WHERE reporter = '0' %s", $qtag));
       $rep = $db->num_rows();
       $db->free();
       $db->query(sprintf("SELECT * FROM bugs WHERE assigned = '0' AND status = 
'5' %s", $qtag));
       $ver = $db->num_rows();
       $db->free();
       $db->query(sprintf("SELECT * FROM bugs WHERE assigned = '0' AND status = 
'2' %s", $qtag));
       $ass = $db->num_rows();
       $db->free();
       $db->query(sprintf("SELECT * FROM bugs WHERE assigned = '0' AND status = 
'0' %s", $qtag));
       $unc = $db->num_rows();
       $db->free();
       $db->query(sprintf("SELECT * FROM bugs WHERE assigned = '0' AND status = 
'3' %s", $qtag));
       $rop = $db->num_rows();
       $db->free();
       $tot = $new + $ver + $ass + $rop;
    ?>
    <tr>
      <td width="30%">
         Unassigned
      </td>
      <td width="10%" align="center">
        <? print($rep); ?>
      </td>
      <td width="10%" align="center">
        <? print($new); ?>
      </td>
      <td width="10%" align="center">
        <? print($ass); ?>
      </td>
      <td width="10%" align="center">
        <? print($ver); ?>
      </td>
      <td width="10%" align="center">
        <? print($unc); ?>
      </td>
      <td width="10%" align="center">
        <? print($rop); ?>
      </td>
      <td width="10%" align="center">
        <? print($tot); ?>
      </td>
    </tr>
    <? $db->query("SELECT * FROM users WHERE (access >= '" . $config['devac'] . 
"') AND (deleted = '0') ORDER BY uname");
       while ($db->next_record()) {
         $db2->query(sprintf("SELECT * FROM bugs WHERE assigned = '" . 
$db->record['uid'] . "' AND status = '1' %s", $qtag));
         $new   = $db2->num_rows();
         $db2->free();
         $db2->query(sprintf("SELECT * FROM bugs WHERE reporter = '" . 
$db->record['uid'] . "' %s", $qtag));
         $rep   = $db2->num_rows();
         $db2->free();
         $db2->query(sprintf("SELECT * FROM bugs WHERE assigned = '" . 
$db->record['uid'] . "' AND status = '5' %s", $qtag));
         $ver   = $db2->num_rows();
         $db2->free();
         $db2->query(sprintf("SELECT * FROM bugs WHERE assigned = '" . 
$db->record['uid'] . "' AND status = '2' %s", $qtag));
         $ass   = $db2->num_rows();
         $db2->free();
         $db2->query(sprintf("SELECT * FROM bugs WHERE assigned = '" . 
$db->record['uid'] . "' AND status = '0' %s", $qtag));
         $unc   = $db2->num_rows();
         $db2->free();
         $db2->query(sprintf("SELECT * FROM bugs WHERE assigned = '" . 
$db->record['uid'] . "' AND status = '3' %s", $qtag));
         $rop   = $db2->num_rows();
         $db2->free();
         $tot = $new + $ver + $ass + $rop;
    ?>
    <tr>
      <td width="30%">
        <? print($db->record['email']); ?>
      </td>
      <td width="10%" align="center">
        <? print($rep); ?>
      </td>
      <td width="10%" align="center">
        <? print($new); ?>
      </td>
      <td width="10%" align="center">
        <? print($ass); ?>
      </td>
      <td width="10%" align="center">
        <? print($ver); ?>
      </td>
      <td width="10%" align="center">
        <? print($unc); ?>
      </td>
      <td width="10%" align="center">
        <? print($rop); ?>
      </td>
      <td width="10%" align="center">
        <? print($tot); ?>
      </td>
    </tr>
    <? } ?>
  </table>

  <p><b><? print(gettext("Individual Bugs by Owner")); ?></b></p>
  <table border="1" cellpadding="0" cellspacing="0" width="80%">
    <tr>
      <td width="30%" align="center">
        <? print(gettext("Owner")); ?>
      </td>
      <td width="15%" align="center">
        <? print(gettext("New")); ?>
      </td>
      <td width="15%" align="center">
        <? print(gettext("Assigned")); ?>
      </td>
      <td width="15%" align="center">
        <? print(gettext("Verified")); ?>
      </td>
      <td width="10%" align="center">
        <? print(gettext("Unconfirmed")); ?>
      </td>
      <td width="15%" align="center">
        <? print(gettext("Reopened")); ?>
      </td>
    </tr>
    <tr>
      <td width="30%" valign="top">
         Unassigned
      </td>
      <td width="15%" align="center" valign="top">
        <? $db->query(sprintf("SELECT * FROM bugs WHERE assigned = '0' AND 
status = '1' %s", $qtag));
           while ($db->next_record()) {
             print(sprintf("<a href=\"query.php?bug=%s\">%s</a> 
",$db->record['bid'], $db->record['bid']));
           }
           $db->free();
        ?>&nbsp;
      </td>
      <td width="15%" align="center" valign="top">
        <? $db->query(sprintf("SELECT * FROM bugs WHERE assigned = '0' AND 
status = '2' %s", $qtag));
           while ($db->next_record()) {
             print(sprintf("<a href=\"query.php?bug=%s\">%s</a> 
",$db->record['bid'], $db->record['bid']));
           }
           $db->free();
        ?>&nbsp;
      </td>
      <td width="15%" align="center" valign="top">
        <? $db->query(sprintf("SELECT * FROM bugs WHERE assigned = '0' AND 
status = '5' %s", $qtag));
           while ($db->next_record()) {
             print(sprintf("<a href=\"query.php?bug=%s\">%s</a> 
",$db->record['bid'], $db->record['bid']));
           }
           $db->free();
        ?>&nbsp;
      </td>
      <td width="10%" align="center" valign="top">
        <? $db->query(sprintf("SELECT * FROM bugs WHERE assigned = '0' AND 
status = '0' %s", $qtag));
           while ($db->next_record()) {
             print(sprintf("<a href=\"query.php?bug=%s\">%s</a> 
",$db->record['bid'], $db->record['bid']));
           }
           $db->free();
        ?>&nbsp;
      </td>
      <td width="15%" align="center" valign="top">
        <? $db->query(sprintf("SELECT * FROM bugs WHERE assigned = '0' AND 
status = '3' %s", $qtag));
           while ($db->next_record()) {
             print(sprintf("<a href=\"query.php?bug=%s\">%s</a> 
",$db->record['bid'], $db->record['bid']));
           }
           $db->free();
        ?>&nbsp;
      </td>
    </tr>
    <? $db->query("SELECT * FROM users WHERE (access >= '" . $config['devac'] . 
"') AND (deleted = '0') ORDER BY uname");
       while ($db->next_record()) {
    ?>
    <tr>
      <td width="30%" valign="top">
        <? print($db->record['email']); ?>
      </td>
      <td width="15%" align="center" valign="top">
        <? $db2->query(sprintf("SELECT * FROM bugs WHERE assigned = '" . 
$db->record['uid'] . "' AND status = '1' %s", $qtag));
           while ($db2->next_record()) {
             print(sprintf("<a href=\"query.php?bug=%s\">%s</a> 
",$db2->record['bid'], $db2->record['bid']));
           }
           $db2->free();
        ?>&nbsp;
      </td>
      <td width="15%" align="center" valign="top">
        <? $db2->query(sprintf("SELECT * FROM bugs WHERE assigned = '" . 
$db->record['uid'] . "' AND status = '2' %s", $qtag));
           while ($db2->next_record()) {
             print(sprintf("<a href=\"query.php?bug=%s\">%s</a> 
",$db2->record['bid'], $db2->record['bid']));
           }
           $db2->free();
        ?>&nbsp;
      </td>
      <td width="15%" align="center" valign="top">
        <? $db2->query(sprintf("SELECT * FROM bugs WHERE assigned = '" . 
$db->record['uid'] . "' AND status = '5' %s", $qtag));
           while ($db2->next_record()) {
             print(sprintf("<a href=\"query.php?bug=%s\">%s</a> 
",$db2->record['bid'], $db2->record['bid']));
           }
           $db2->free();
        ?>&nbsp;
      </td>
      <td width="10%" align="center" valign="top">
        <? $db2->query(sprintf("SELECT * FROM bugs WHERE assigned = '" . 
$db->record['uid'] . "' AND status = '0' %s", $qtag));
           while ($db2->next_record()) {
             print(sprintf("<a href=\"query.php?bug=%s\">%s</a> 
",$db2->record['bid'], $db2->record['bid']));
           }
           $db2->free();
        ?>&nbsp;
      </td>
      <td width="15%" align="center" valign="top">
        <? $db2->query(sprintf("SELECT * FROM bugs WHERE assigned = '" . 
$db->record['uid'] . "' AND status = '3' %s", $qtag));
           while ($db2->next_record()) {
             print(sprintf("<a href=\"query.php?bug=%s\">%s</a> 
",$db2->record['bid'], $db2->record['bid']));
           }
           $db2->free();
        ?>&nbsp;
      </td>
    </tr>
    <? }
       $db->free();
    ?>
  </table>

<?
  d_DrawFooter();

?>

====================================================
Index: showattachment.php
<?
  // Anthill
  // $Id: showattachment.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $

  include("include.php");

  // set variables
  if (isset($_REQUEST['id'])) { $id = $_REQUEST['id']; } else { $id = NULL; }

  $db->query("SELECT * FROM attachidx WHERE atid = $id");
  $db->next_record();
  $bug  = $db->record['bid'];
  $atid = $db->record['atid'];
  $type = $db->record['mimetype'];
  $db->free();

  // if attachment is not found in the database, print error and exit
  if (!isset($atid)) {
    d_StartPage(gettext("Invalid Attachment"));
    d_DrawNav($_USER['uname']);
    d_DrawHeader(gettext("Invalid Attachment"));
    print(gettext("The attachment you selected is unlisted."));
    d_DrawFooter();
    exit();
  }

  $db->query("SELECT * FROM bugs WHERE bid = $bug");
  $db->next_record();
  $private = $db->record['private'];
  $db->free();

  if ($private == 1 && !isset($_USER['uid'])) {
      d_StartPage(gettext("Invalid Authorization"));
      d_DrawNav($_USER['uname']);
      d_DrawHeader(gettext("Invalid Authorization"));
      print(gettext("The bug you selected is marked private and is not 
available to unregistered users."));
      d_DrawFooter();
      exit();
  }

  $attach = $_CONF['root'] . $_CONF['attachdir'] . "/" . $id;
  $fp   = fopen($attach, "r");
  $data = fread($fp, filesize($attach));
  fclose($fp);

  header("Content-type: $type\n\n");
  print($data);
?>

====================================================
Index: setup.php
<?php
  /****************************************************************************
   * Anthill                                                                  *
   * http://anthill.vmlinuz.ca                                                *
   *                                                                          *
   * Written by Vincent Danen address@hidden                              *
   *   and Dave Hall [skwashd AT phpgroupware.org]                            *
   * ------------------------------------------------------------------------ *
   * This program is free software; you can redistribute it 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.                                               *
   * ------------------------------------------------------------------------ *
   ****************************************************************************/
   /* $Id: setup.php,v 1.1 2005/05/05 00:34:03 skwashd Exp $ */

   require_once('./inc/class.Template.inc.php');
   $tpl = new Template('./templates/default/');

   if(address@hidden('./inc/config.inc.php'))
   {
     if($_POST['submitit'])
     {
          generate_config($tpl);
     }
     else
     {
       $path = explode(DIRECTORY_SEPARATOR, $_SERVER["SCRIPT_FILENAME"]);
       $real_path = DIRECTORY_SEPARATOR;

       for ($i = 1; $i < (count($path)-1); $i++)
       {
         $real_path .= $path[$i] . DIRECTORY_SEPARATOR;
       }
       unset($path);

       $url = explode('/', $_SERVER['SCRIPT_NAME']);

       $real_url  = (@$_SERVER['HTTPS'] ? 'https://' : 'http://');
       $real_url .= $_SERVER['HTTP_HOST'] . '/';

       for ($i = 1; $i < (count($url)-1); $i++)
       {
         $real_url .= $url[$i] . '/';
       }
       unset($url);
       //echo $real_url;

       $defaults = array('root'     => $real_path,
                        'webroot'   => $real_url,
                        'tpl'       => 'default',
                        'lang'      => $real_path .'backend/lang/',
                        'offroot'   => '/usr/local/anthill',
                        'difftool'  => exec('which diff'),
                        'date'      => 'd-M-Y',
                        'time'      => 'h:i a',
                        'cookie'    => True,
                        'perm_days' => 1,
                        'timeout'   => 7220,
                        'domain'    => $_SERVER['HTTP_HOST'],
                        'path'      => '/',
                        'secure'    => isset($_SERVER['HTTPS']),
                        'verify_ip' => True,
                        'meta_lang' => 'utf-8',
                        'user'      => 'anthill',
                        'pw'        => 'changeme',
                        'host'      => 'localhost',
                        'name'      => 'anthill',
                        'type'      => '',
                       );

        show_config_options($defaults, $tpl);
     }
   }
   else
   {
     $GLOBALS['inc_from_setup'] = True;
     require_once('./inc/config.inc.php');
   }

   if (@$_POST['login'])
   {
     if(md5(addslashes($_POST['passwd'])) == $GLOBALS['anthill_setup']['pass'])
     {
       setcookie('Config', base64_encode($GLOBALS['anthill_setup']['pass']));
       show_config_menu();
     }
     else
     {
       show_login('failed');
     }
   }

   if (@$_COOKIE['Config'])
   {
     if (base64_decode($_COOKIE['Config']) == $GLOBALS['anthill_setup']['pass'])
     {
       switch ($_GET['action'])
       {
         case 'edit_config':
           $config = read_config;
           show_config_options($config, $tpl);
           break;
         case 'save_config':
           generate_config($tpl);
           break;
         case 'upgrade':
           show_upgrade();
           break;
         case 'confirm_upgrade';
           run_upgrade();
           break;
         default:
           show_config_menu();
           break;
       }
     }
     else
     {
       show_login('unverified');
     }
   }
   show_login();


    function generate_config($tpl)
    {
      echo '<h2>Anthill config.inc.php</h2><hr><pre>';
      foreach($_POST as $config_key => $config_val)
      {
        $config_vars[$config_key] = addslashes($config_val);
      }

      $tpl->set_file('config','config.inc.php.tpl');
      $tpl->set_var($config_vars);

      if(@$_POST['setup_pass'])
      {
         $passwd = md5(addslashes($_POST['setup_pass']));
      }
      else
      {
        $passwd = base64_decode($_COOKIE['Config']);
      }
      $tpl->set_var('setup_pass', $passwd);

      echo htmlentities($tpl->subst('config'));
      echo '</pre><hr>';
      echo '<center>Copy the contents of this file and save it as ' . 
$_POST['root'] . '/inc/config.inc.php<br>';
      echo 'Then <a href="' . $_SERVER['PHP_SELF'] . '">login to setup</a>';
      exit;
    }

    function get_date_select($cur_fmt)
    {
      $select = '<select name="date">';

      $fmts = array('d-M-Y', 'j/n/Y', 'n/j/Y', 'Y/n/j', 'dmY', 'Ymd');
      foreach ($fmts as $fmt)
      {
        $select .= '<option value="' . $fmt;
        $select .= ($fmt == $cur_fmt ? '" SELECTED>' : '">');
        $select .= date($fmt) .'</option>';
      }

      $select .= '</select>';
      return $select;
    }

    function get_db_select($cur_db)
    {
      $rdbms = array('mysql', 'pgsql'); //supported RDMSs (using php module 
names)
      $select = '';
      foreach ($rdbms as $db)
      {
        if (extension_loaded($db) || address@hidden($db))
        {
          $select .= '<option';
          $select .= ($db == $cur_db ? ' SELECTED>' : '>');
          $select .= $db .'</option>';
        }
      }
      if (!select)
      {
        $select = '<b>You do not have any database support compiled in to 
PHP</b><br>';
        $select .= 'Unable to install anthill';
      }
      else
      {
        $select = '<select name="type">' . $select . '</select>';
      }
      return $select;
    }

    function get_time_select($cur_fmt)
    {
      $select = '<select name="time">';

      $fmts = array('g:i a', 'G:i a', 'h:i', 'H:i', 'Hi');
      foreach ($fmts as $fmt)
      {
        $select .= '<option value="' . $fmt;
        $select .= ($fmt == $cur_fmt ? '" SELECTED>' : '">');
        $select .= date($fmt) .'</option>';
      }

      $select .= '</select>';
      return $select;
    }

    function get_tpl_select($root_dir, $cur_tpl)
    {
      $select = '';
      $d = dir($root_dir . '/templates/');
      while (false !== ($file = $d->read()))
      {
        if ($file != '.' && $file != '..' && $file != 'CVS' && $file)
        {
          $select .= '<option';
          $select .= ($file == $cur_tpl ? ' SELECTED>' : '>');
          $select .= $file.'</option>';
        }
      }
      if (!select)
      {
        $select = '<b>Unable to find any templates, check the permissions of ' 
. $dir . '</b><br>';
        $select .= 'Unable to install anthill';
      }
      else
      {
        $select = '<select name="tpl">' . $select . '</select>';
      }
      return $select;
    }

    function get_true_false_select($name, $selected)
    {
      $select  = '<select name="'.$name.'">';
      //Yes
      $select .= '<option value="True"';
      $select .= ($selected ? ' SELECTED>' : '>');
      $select .= 'Yes</option>';

      //No
      $select .= '<option value="True"';
      $select .= (!$selected ? ' SELECTED>' : '>');
      $select .= 'No</option>';

      $select .= '</select>';
      return $select;
    }

    function read_config()
    {
      $elements = array('path', 'format', 'sessions', 'charset', 'db');
      foreach($elements as $element)
      {
        foreach($GLOBALS['anthill_info'][$element] as $key => $val)
        {
          $config[$key] = stripslashes($val);
        }
      }
      return $config;
    }

    function show_config_options($defaults, $tpl)
    {
      $tpl->set_file('anthill_setup_config','anthill_setup_config.tpl');

      $tpl->set_var('form_action', './setup.php?action=save_config');
      $tpl->set_var($defaults);
      $tpl->set_var('select_tpl', get_tpl_select($defaults['root'], 
$defaults['tpl']));
      $tpl->set_var('select_date', get_date_select($defaults['date']));
      $tpl->set_var('select_time', get_time_select($defaults['time']));
      $tpl->set_var('select_cookies', get_true_false_select('cookies', 
$defaults['cookies']));
      $tpl->set_var('select_secure', get_true_false_select('secure', 
$defaults['secure']));
      $tpl->set_var('select_verify_ip', get_true_false_select('verify_ip', 
$defaults['verify_ip']));
      $tpl->set_var('select_db_type', get_db_select($defaults['type']));

      $tpl->pfp('out', 'anthill_setup_config');
      exit;
    }

    function show_login($msg='')
    {
      echo 'you must login';
      echo $msg .'<br>';
      echo '<form action="'.$_SERVER['PHP_SELF'].'" method="POST">';
      echo '<table border="0" width="100%">';
      echo '<tr>';
      echo '<td width="50%" align="right">Config Password:</td>';
      echo '<td><input type="password" name="passwd"></td>';
      echo '</tr>';
      echo '<tr>';
      echo '<td align="center"><input type="submit" name="login" 
value="Login"></td>';
      echo '</tr>';
      echo '</table>';
      echo '</form>';
    }
?>






reply via email to

[Prev in Thread] Current Thread [Next in Thread]