# Bandersnatch web UI on FreeBSD



## Ruler2112 (Feb 3, 2010)

I'm getting a new box ready to use for our internal server.  I've got ejabberd installed for instant messaging, BIND for DNS, samba for file sharing, apache 2.2 for serving internal web pages, NAT for masquerading with a rather relaxed pf rule set, and so forth.

Bandersnatch is a utility that will log instant messages to a database.  Unfortunately, there's not a port for it, so I had to resort to installing it manually.  I selected MySql 5.1 and installed that from ports, then configured it and got it running before creating the databases bandersnatch requires.  It works great in that all instant messages are dumped to a database.  However, I'm having one small problem.

Bandersnatch comes with a web-based user interface that allows one to view statistics and, if you have admin rights, view the messages.  (I have apache set up to serve pages out of the front end directory if you go to chatlog.<boxname via DNS> so I can get away from remembering so many IPs.)  I set things up the way I believe they should be, but cannot seem to make it work.  I'm out of my element when it comes to PHP and was hoping somebody could provide insight of where I should look or how I might go about fixing it.

My gut feeling is that something in PHP or the PEAR modules that it relies upon isn't set up correctly.  I installed what it was complaining about from ports and enabled php5_module in the httpd.conf config file.  Looking in the code for the bandersnatch front end file, the error I'm getting is produced if there is an error connecting to the database.

I've disabled pf completely to eliminate a TCP port being blocked being the trouble, but that made no difference.  I've also verified the bandersnatch user and password has access to the bandersnatch database.  Since there's nothing of any use in the logs, I'm frankly at a loss of where to look next.


```
/var/log/chatlog-access.log:

<clientIP> - - [03/Feb/2010:17:46:44 -0500] "GET /HTTP/1.1" 200 2802
<clientIP> - - [03/Feb/2010:17:46:44 -0500] "GET /images/jabberwocky.jpg HTTP/1.1" 304 -



/var/log/chatlog-error.log

empty



/var/log/mysql.log:

100128 21:24:20 mysqld_safe mysqld from pid file /var/run/mysql/mysql.pid ended
100128 21:25:08 mysqld_safe Starting mysqld daemon with databases from /home/mysql
100128 21:25:08 [Note] Plugin 'FEDERATED' is disabled.
100128 21:25:08  InnoDB: Started; log sequence number 0 44233
100128 21:25:08 [Note] Event Scheduler: Loaded 0 events
100128 21:25:08 [Note] /usr/local/libexec/mysqld: ready for connections.
Version: '5.1.42'  socket: '/tmp/mysql.sock'  port: 3306  FreeBSD port: mysql-server-5.1.42



the start of the bandersnatch front end file:

<?php
$config['template'] = 'default.tpl.htm';
$config['limit'] = '100';

$config['database_type'] = 'mysql';
$config['database_host'] = '127.0.0.1';
///////I've tried localhost, the host name, the name of the box via DNS, the loopback IP, and the IP of the machine for the database_host parameter with no luck\\\\\\\\\
$config['database_table'] = 'bandersnatch';
$config['database_user'] = 'bandersnatch';
$config['database_password'] = 'bandersnatch';

$config['local_server'] = "127.0.0.1";
$config['local_domains'] = array
  (
    '<boxname via DNS>',
    'chat.<boxname via DNS>'
  );

$config['local_transports'] = array
  (
//  'groupchat' => 'conference.jabber.yourdomain.com'
  );
  );

#################### End of user-configurable options #######################

$config['app_version'] = '0.2';
$config['app_name'] = 'Bandersnatch PHP Frontend';

// Setup database DSN
$dsn = $config['database_type']. "://". $config['database_user']. ":". $config['database_password'];
$dsn .= "@". $config['database_host']. "/". $config['database_table'];

// Load PEAR Integrated Template libraries
require_once "HTML/Template/IT.php";
$tpl = new HTML_Template_IT("../templates");
$tpl->loadTemplatefile($config['template'], true, true);

// Load PEAR DB Libraries
require_once( 'DB.php' );
require_once( '../includes/functions.inc.php' );
$db = DB::connect($dsn);
if (DB::isError($db)) { generate_error('Database connection error - '. $dsn); }
/////////////////This is the error I'm getting\\\\\\\\\\\\\\\\\

// Load PEAR Auth libraries
require_once "Auth/Auth.php";
$a = new Auth("DB", $dsn);
$a->setShowLogin( false ); // Don't automatically show login page, we'll do it ourselves

// Note. 2003-02-13: Noticed today that if the Auth connection fails (I had a bad DSN), no decent error
// message is given. I got a "non-existant function query()" error :(



bandersnatch config:

<config>
        <server>
                <connectiontype>tcpip</connectiontype>
                <hostname>localhost</hostname>
                <port>5526</port>
                <secret>bandersnatch</secret>
        </server>
        <component>
                 <name>bandersnatch@bandersnatch.localhost</name>
        </component>
        <mysql>
                <server>localhost</server>
                <dbname>bandersnatch</dbname>
                <username>bandersnatch</username>
                <password>bandersnatch</password>
        </mysql>
        <debug>
                <level>0</level>
                <file>stdout</file>
        </debug>
        <site>
                <local_server>localhost</local_server>
                <admin_jids>My_Jabber_ID@localhost</admin_jids>
                <privacy>0</privacy>
                <aggressive_presence>0</aggressive_presence>
        </site>
</config>
```


Thanks in advance for any pointers.


----------



## volatilevoid (Feb 4, 2010)

Try `# mysql -u <username> -p <password>` on the machine and see if that works. Unfortunately, I don't know anything about Bandersnatch, but you could also open your /usr/local/etc/php.ini file and make sure


```
error_reporting = E_ALL
display_errors = On
display_startup_errors = On
```

is set. You can restore these settings afterwards, so it might help to save them before editing the file. Don't forget to restart Apache after modifying it.


----------



## Ruler2112 (Feb 4, 2010)

Hmmmm.... I do not seem to _have_ a php.ini in /use/local/etc/   I'm guessing this might be a problem...


----------



## DutchDaemon (Feb 4, 2010)

Do you have

```
/usr/local/etc/php.ini-dist
/usr/local/etc/php.ini-recommended
```
at least? These are installed by the port.


----------



## Ruler2112 (Feb 4, 2010)

I do have those two files DD.  I copied php.ini-recommended to php.ini and set the variables volatilevoid mentioned, then restarted apache and tried the page again.  Lo and behold, an error appeared!


```
[Thu Feb 04 13:33:38 2010] [error] [client <IP address>] PHP Notice:  Undefined index:  date in /usr/local/bandersnatch/frontend/includes/functions.inc.php on line 1259
```


I went into the functions.inc.php file and looked on line 1259.


```
function generate_error($title,$subtitle = "")
{
  $tpl = $GLOBALS['tpl'];
  $date = $GLOBALS['date'];

  $tpl->setCurrentBlock("main_page");
  $tpl->setVariable
```


OK, so it's already in the GenerateError routine, but the previous error must be preventing it from spitting out something useful, right?  Nope.  I changed the above to be:


```
function generate_error($title,$subtitle = "")
{
  $tpl = $GLOBALS['tpl'];
  $date = "the date goes here";
#  $date = $GLOBALS['date'];

  $tpl->setCurrentBlock("main_page");
  $tpl->setVariable
```


The same database error comes up when trying to load the frontend - no additional detail is on the page, in the page source, or the log files.    The place where the $date variable is used is when generating a link on the frontend page.  Since the machine is already in a routine to output an error, it pretty much eliminates that as a cause of the database error.

Are there any config files that the PEAR database add-ons for PHP need that aren't automatically installed with the port?  (I'm thinking of something similar to the php.ini with PHP.)


----------



## Ruler2112 (Feb 4, 2010)

I found something while investigating that probably caused a problem, though it seems not to affect the resulting error on that page.



			
				http://pear.php.net/manual/en/package.database.db.intro-dsn.php said:
			
		

> The currently supported database backends are:
> 
> dbase  -> dBase
> fbsql  -> FrontBase (functional since DB 1.7.0)
> ...



Since it was using mysql for a backend, it was expecting MySql 4.0 or less.  Since I'm using 5.1, I changed the backend to mysqli.  Other than changing the text on the error shown on the page, it had no effect. 

I kept looking and found sample code that I added to the error message - $db->GetMessage() - that indicates what the error actually is.  This is:


```
DB Error: extension not found
```

I'm now going to search for the cause of this, but wanted to update this post in case somebody else has encountered it before.


----------



## Ruler2112 (Feb 4, 2010)

Found where this error is related to mysql support not being in PHP.  So I dug around a bit and discovered a php-mysqli port out there.  Compiled and installed that - 'extension not found' went away and the entire page was replaced with:


```
Fatal error: Call to undefined function session_id() in /usr/local/share/pear/Auth.php on line 338
```


Looked around for the source of that and discovered a post of somebody having the same trouble with a different piece of software.  Turns out that the Makefile for PHP under FreeBSD has --disable-all in it.  He suggests deleting this line and recompiling PHP may eliminate the trouble; I did that and PHP is compiling as I type this.

I think I can see the light at the end of the tunnel!


----------



## DutchDaemon (Feb 4, 2010)

It may be a train ..


----------



## Ruler2112 (Feb 4, 2010)

OK, I compiled and installed PHP with the modified Makefile.  That took care of the session error.  I then got a bunch of PHP NOTICE messages, which were also easy enough to resolve by modifying the bandersnatch frontend config file:


```
// Define global variables that the functions will use
// $func = $HTTP_GET_VARS['func'];
// $jid = $HTTP_GET_VARS['jid'];
// $page = $HTTP_GET_VARS['page'];
// $limit = $HTTP_GET_VARS['limit'];
// $orderby = $HTTP_GET_VARS['orderby'];
// $oldfunc = $HTTP_GET_VARS['oldfunc'];
// $date = $HTTP_GET_VARS['date'];
// $search = $HTTP_GET_VARS['search'];
$func = (isset($HTTP_GET_VARS['func'])) ? $HTTP_GET_VARS['func'] : NULL;
$jid = (isset($HTTP_GET_VARS['jid'])) ? $HTTP_GET_VARS['jid'] : NULL;
$page = (isset($HTTP_GET_VARS['page'])) ? $HTTP_GET_VARS['page'] : NULL;
$limit = (isset($HTTP_GET_VARS['limit'])) ? $HTTP_GET_VARS['limit'] : NULL;
$orderby = (isset($HTTP_GET_VARS['orderby'])) ? $HTTPD_GET_VARS['orderby'] : NULL;
$oldfunc = (isset($HTTP_GET_VARS['oldfunc'])) ? $HTTP_GET_VARS['oldfunc'] : NULL;
$date = (isset($HTTP_GET_VARS['date'])) ? $HTTP_GET_VARS['date'] : NULL;
$search = (isset($HTTP_GET_VARS['search'])) ? $HTTP_GET_VARS['search'] : NULL;



// if (!$search) {  $search = $HTTP_POST_VARS['search']; }
// if (!$date) {     $date = $HTTP_POST_VARS['date']; }
if (!$search) {  $search = (isset($HTTP_POST_VARS['search'])) ? $HTTP_POST_VARS['search'] : NULL; }
if (!$date) {    $date = (isset($HTTP_POST_VARS['date'])) ? $HTTP_POST_VARS['date'] : NULL; }
```


Now I'm at another impasse:


```
Warning: include_once(Auth/Container/DB.php) [function.include-once]: failed to open stream: No such file or directory in /usr/local/share/pear/Auth.php on line 468

Warning: include_once() [function.include]: Failed opening 'Auth/Container/DB.php' for inclusion (include_path='.:/usr/local/share/pear') in /usr/local/share/pear/Auth.php on line 468

Fatal error: Class 'Auth_Container_DB' not found in /usr/local/share/pear/Auth.php on line 469
```

The reason for this is simple: there is no directory /usr/local/share/pear/Auth/Container, nor is there a DB.php file in the Auth directory under /usr/local/share/pear.  I saw a pear-Auth_HTTP port and installed it, but that created a HTTP.php file in /usr/local/share/pear/Auth.  I reinstalled both the pear-DB and pear-Auth ports, but no DB.php file was created in this directory.  The /usr/local/share/pear/Auth.php file has the following in it, which appears to be responsible for loading the associated file:


```
function &_factory($driver, $options = '')
    {
        $storage_class = 'Auth_Container_' . $driver;
        include_once 'Auth/Container/' . $driver . '.php';
        $obj =& new $storage_class($options);
        return $obj;
    }
```


There shows to be an Auth_Container_DB in the pear docs, but there's no port with DB and Auth in it's name that has anything to do with pear:


```
drwxr-xr-x  2 root  wheel    512 Jan 18 18:12 p5-Authen-Simple-DBI
drwxr-xr-x  2 root  wheel    512 Jan 18 18:12 p5-Authen-Simple-DBM
./security/p5-Authen-Simple-DBI:
./security/p5-Authen-Simple-DBM:
drwxr-xr-x  2 root  wheel    512 Jan 18 18:13 p5-Catalyst-Authentication-Store-DBIx-Class
drwxr-xr-x  2 root  wheel    512 Jan 18 18:13 p5-Catalyst-Plugin-Authentication-CDBI
drwxr-xr-x  2 root  wheel    512 Jan 18 18:13 p5-Catalyst-Plugin-Authentication-Store-DBIC
./www/p5-Catalyst-Authentication-Store-DBIx-Class:
./www/p5-Catalyst-Plugin-Authentication-CDBI:
./www/p5-Catalyst-Plugin-Authentication-Store-DBIC:
```

So after all that, I'm back where I began - stumped.    Google turns up nothing regarding this except a few people who have had similar problems; I was not able to find a solution though.


----------



## Ruler2112 (Feb 4, 2010)

DutchDaemon said:
			
		

> It may be a train ..



LOL - how'd you know?  :e


----------



## Ruler2112 (Feb 5, 2010)

AH-HA!

I found a Container directory in /usr/local/share/pear and it has a DB.php file in it!  A little hacking of the PHP files that load the container and it loads the page!


In /usr/local/share/pear/Auth.php, search for Container  Change it to look like this:


```
function &_factory($driver, $options = '')
    {
        $storage_class = 'Auth_Container_' . $driver;
        include_once 'Container/' . $driver . '.php';
        //include_once 'Auth/Container/' . $driver . '.php';
        $obj =& new $storage_class($options);
        return $obj;
    }
```

And in /usr/local/share/pear/Container/DB.php simply page down:


```
require_once 'Container.php';
//require_once 'Auth/Container.php';
```

Now I just have to test and see if the frontend actually displays data when something gets put in the database... *crosses fingers and prays*  




I feel that somebody who knows what he/she is doing should look at this, as it's definitely NOT something that should need to be done in order to get database connectivity working...  With as mature as FreeBSD is, I'm very surprised that this made it into the ports tree in it's present state.


----------

