--- /dev/null
+# Makefile
+# David Rowe 12 Feb 2008
+
+# Builds (almost) everything you need for FreePBX with sqlite3 from
+# scratch and configures FreePBX to run in a "sandbox" environment.
+
+TOPDIR = $(shell pwd)
+BUILD_DIR = $(TOPDIR)
+DL_DIR = $(TOPDIR)/dl
+ROOT = $(TOPDIR)/root
+export PATH:= $(ROOT)/bin:$(PATH)
+
+all: php sqlite pear-db php-sqlite3 xdebug lighttpd freepbx
+
+##############################################################
+# PHP --------------------------------------------------------
+##############################################################
+
+PHP_VERSION=5.2.5
+PHP_DIRNAME=php-$(PHP_VERSION)
+PHP_DIR=$(BUILD_DIR)/$(PHP_DIRNAME)
+PHP_SITE=http://www.php.net/distributions
+PHP_SOURCE=php-$(PHP_VERSION).tar.bz2
+PHP_CONFIGURE_OPTS=--disable-all --with-pcre-regex --enable-force-cgi-redirect \
+ --with-config-file-path=$(ROOT)/etc --prefix=$(ROOT) \
+ --with-pear --enable-xml --enable-libxml --enable-session \
+ --with-gettext
+
+$(DL_DIR)/$(PHP_SOURCE):
+ mkdir -p dl
+ wget -P $(DL_DIR) $(PHP_SITE)/$(PHP_SOURCE)
+
+$(PHP_DIR)/.unpacked: $(DL_DIR)/$(PHP_SOURCE)
+ bzcat $(DL_DIR)/$(PHP_SOURCE) | tar -C $(BUILD_DIR) -xf -
+ touch $(PHP_DIR)/.unpacked
+
+$(PHP_DIR)/.configured: $(PHP_DIR)/.unpacked
+ cd $(PHP_DIR); ./configure $(PHP_CONFIGURE_OPTS)
+ touch $(PHP_DIR)/.configured
+
+$(PHP_DIR)/.built: $(PHP_DIR)/.configured
+ cd $(PHP_DIR); make
+ cd $(PHP_DIR); make install
+ cp $(PHP_DIR)/php.ini-recommended $(ROOT)/etc/php.ini
+ echo include_path=\".:$(ROOT)/lib/php\" >> $(ROOT)/etc/php.ini
+ touch $(PHP_DIR)/.built
+
+php: $(PHP_DIR)/.built
+
+##############################################################
+# sqlite3 ----------------------------------------------------
+##############################################################
+
+SQLITE_VERSION=3.5.6
+SQLITE_DIRNAME=sqlite-$(SQLITE_VERSION)
+SQLITE_DIR=$(BUILD_DIR)/$(SQLITE_DIRNAME)
+SQLITE_SITE=http://www.sqlite.org/
+SQLITE_SOURCE=sqlite-amalgamation-$(SQLITE_VERSION).tar.gz
+SQLITE_CONFIGURE_OPTS = --prefix=$(ROOT)
+
+$(DL_DIR)/$(SQLITE_SOURCE):
+ mkdir -p dl
+ wget -P $(DL_DIR) $(SQLITE_SITE)/$(SQLITE_SOURCE)
+
+$(SQLITE_DIR)/.unpacked: $(DL_DIR)/$(SQLITE_SOURCE)
+ zcat $(DL_DIR)/$(SQLITE_SOURCE) | tar -C $(BUILD_DIR) -xf -
+ touch $(SQLITE_DIR)/.unpacked
+
+$(SQLITE_DIR)/.configured: $(SQLITE_DIR)/.unpacked
+ cd $(SQLITE_DIR); ./configure $(SQLITE_CONFIGURE_OPTS)
+ touch $(SQLITE_DIR)/.configured
+
+$(SQLITE_DIR)/.built: $(SQLITE_DIR)/.configured
+ cd $(SQLITE_DIR); make
+ cd $(SQLITE_DIR); make install
+ touch $(SQLITE_DIR)/.built
+
+sqlite: $(SQLITE_DIR)/.built
+
+##############################################################
+# PEAR:DB ---------------------------------------------------
+##############################################################
+
+$(ROOT)/lib/php/.db-installed:
+ pear install DB
+ cd $(ROOT)/lib/php/DB; patch -p1 < $(TOP_DIR)/patch/common.patch
+ touch $(ROOT)/lib/php/.db-installed
+
+pear-db: $(ROOT)/lib/php/.db-installed
+
+##############################################################
+# php-sqlite3 ------------------------------------------------
+##############################################################
+
+PHP-SQLITE3_VERSION=0.5
+PHP-SQLITE3_DIRNAME=sqlite3-$(PHP-SQLITE3_VERSION)
+PHP-SQLITE3_DIR=$(BUILD_DIR)/$(PHP-SQLITE3_DIRNAME)
+PHP-SQLITE3_SITE=http://downloads.sourceforge.net/php-sqlite3/
+PHP-SQLITE3_SOURCE=sqlite3-$(PHP-SQLITE3_VERSION).tgz
+PHP-SQLITE3_CONFIGURE_OPTS=--prefix=$(ROOT) \
+ --with-sqlite3=$(ROOT) \
+ --with-php-config=$(ROOT)/bin/php-config
+
+$(DL_DIR)/$(PHP-SQLITE3_SOURCE):
+ mkdir -p dl
+ wget -P $(DL_DIR) $(PHP-SQLITE3_SITE)/$(PHP-SQLITE3_SOURCE)
+
+$(PHP-SQLITE3_DIR)/.unpacked: $(DL_DIR)/$(PHP-SQLITE3_SOURCE)
+ zcat $(DL_DIR)/$(PHP-SQLITE3_SOURCE) | tar -C $(BUILD_DIR) -xf -
+ touch $(PHP-SQLITE3_DIR)/.unpacked
+
+$(PHP-SQLITE3_DIR)/.configured: $(PHP-SQLITE3_DIR)/.unpacked
+ cd $(PHP-SQLITE3_DIR); phpize; ./configure $(PHP-SQLITE3_CONFIGURE_OPTS)
+ touch $(PHP-SQLITE3_DIR)/.configured
+
+$(PHP-SQLITE3_DIR)/.built: $(PHP-SQLITE3_DIR)/.configured
+ cd $(PHP-SQLITE3_DIR); make
+ cd $(PHP-SQLITE3_DIR); make install
+
+ # use my hacked up sqlite3.php for PHP 5. We use a sym link so that
+ # we can edit it in place and capture changes to source control
+
+ ln -sf $(TOPDIR)/files/sqlite3.php $(ROOT)/lib/php/DB/sqlite3.php
+
+ # update php.ini extensions line for sqlite3.so
+
+ cat $(ROOT)/etc/php.ini | sed '/extension_dir/ d' > $(ROOT)/etc/php.ini.tmp
+ mv $(ROOT)/etc/php.ini.tmp $(ROOT)/etc/php.ini
+ echo extension_dir=\"`find $(ROOT) -name sqlite3.so | xargs dirname`\" >> $(ROOT)/etc/php.ini
+
+ touch $(PHP-SQLITE3_DIR)/.built
+
+php-sqlite3: $(PHP-SQLITE3_DIR)/.built
+
+##############################################################
+# xdebug -----------------------------------------------------
+##############################################################
+
+XDEBUG_VERSION=2.0.2
+XDEBUG_DIRNAME=xdebug-$(XDEBUG_VERSION)
+XDEBUG_DIR=$(BUILD_DIR)/$(XDEBUG_DIRNAME)
+XDEBUG_SITE=http://www.xdebug.org/files/
+XDEBUG_SOURCE=xdebug-$(XDEBUG_VERSION).tgz
+XDEBUG_CONFIGURE_OPTS=--prefix=$(ROOT) --enable-xdebug
+
+$(DL_DIR)/$(XDEBUG_SOURCE):
+ mkdir -p dl
+ wget -P $(DL_DIR) $(XDEBUG_SITE)/$(XDEBUG_SOURCE)
+
+$(XDEBUG_DIR)/.unpacked: $(DL_DIR)/$(XDEBUG_SOURCE)
+ zcat $(DL_DIR)/$(XDEBUG_SOURCE) | tar -C $(BUILD_DIR) -xf -
+ touch $(XDEBUG_DIR)/.unpacked
+
+$(XDEBUG_DIR)/.configured: $(XDEBUG_DIR)/.unpacked
+ cd $(XDEBUG_DIR); phpize; ./configure $(XDEBUG_CONFIGURE_OPTS)
+ touch $(XDEBUG_DIR)/.configured
+
+$(XDEBUG_DIR)/.built: $(XDEBUG_DIR)/.configured
+ cd $(XDEBUG_DIR); make
+ cp $(XDEBUG_DIR)/modules/xdebug.so $(ROOT)/lib
+
+ # update php.ini extensions line for xdebug.so
+
+ echo zend_extension=\"$(ROOT)/lib/xdebug.so\" >> $(ROOT)/etc/php.ini
+ echo "xdebug.auto_trace=On" >> $(ROOT)/etc/php.ini
+ echo "xdebug.show_exception_trace=On" >> $(ROOT)/etc/php.ini
+
+ touch $(XDEBUG_DIR)/.built
+
+xdebug: $(XDEBUG_DIR)/.built
+
+#########################################################################
+# lighttpd --------------------------------------------------------------
+#########################################################################
+
+LIGHTTPD_VERSION=1.4.18
+LIGHTTPD_DIRNAME=lighttpd-$(LIGHTTPD_VERSION)
+LIGHTTPD_DIR=$(BUILD_DIR)/$(LIGHTTPD_DIRNAME)
+LIGHTTPD_SITE=http://www.lighttpd.net/download
+LIGHTTPD_SOURCE=lighttpd-$(LIGHTTPD_VERSION).tar.gz
+LIGHTTPD_CONFIGURE_OPTS=--prefix=$(ROOT) --disable-ipv6
+
+$(DL_DIR)/$(LIGHTTPD_SOURCE):
+ mkdir -p dl
+ wget -P $(DL_DIR) $(LIGHTTPD_SITE)/$(LIGHTTPD_SOURCE)
+
+$(LIGHTTPD_DIR)/.unpacked: $(DL_DIR)/$(LIGHTTPD_SOURCE)
+ zcat $(DL_DIR)/$(LIGHTTPD_SOURCE) | tar -C $(BUILD_DIR) -xf -
+ touch $(LIGHTTPD_DIR)/.unpacked
+
+$(LIGHTTPD_DIR)/.configured: $(LIGHTTPD_DIR)/.unpacked
+ cd $(LIGHTTPD_DIR); ./configure $(LIGHTTPD_CONFIGURE_OPTS)
+ touch $(LIGHTTPD_DIR)/.configured
+
+$(LIGHTTPD_DIR)/.built: $(LIGHTTPD_DIR)/.configured
+ cd $(LIGHTTPD_DIR); make
+ cd $(LIGHTTPD_DIR); make install
+
+ cp files/lighttpd.conf $(ROOT)/etc
+ mkdir -p $(ROOT)/www
+ cp files/test.php $(ROOT)/www
+
+ # change server root and set up cgi-assign for PHP
+
+ cat $(ROOT)/etc/lighttpd.conf | sed '/server.document-root/ d' > $(ROOT)/etc/lighttpd.conf.tmp
+ mv $(ROOT)/etc/lighttpd.conf.tmp $(ROOT)/etc/lighttpd.conf
+ echo "server.document-root = \"$(ROOT)/www/\"" >> $(ROOT)/etc/lighttpd.conf
+ echo "cgi.assign = (\".php\" => \"$(ROOT)/bin/php-cgi\")" >> $(ROOT)/etc/lighttpd.conf
+
+ touch $(LIGHTTPD_DIR)/.built
+
+lighttpd: $(LIGHTTPD_DIR)/.built
+
+#########################################################################
+# freepbx ---------------------------------------------------------------
+#########################################################################
+
+FREEPBX_VERSION=2.4.0
+FREEPBX_DIRNAME=freepbx-$(FREEPBX_VERSION)
+FREEPBX_DIR=$(BUILD_DIR)/$(FREEPBX_DIRNAME)
+FREEPBX_SITE= http://mirror.freepbx.org
+FREEPBX_SOURCE=freepbx-$(FREEPBX_VERSION).tar.gz
+FREEPBX_CONFIGURE_OPTS=
+
+# sed command to change hard coded PHP /etc/amportal.conf path
+
+FREEPBX_AMP_CONF='s|"/etc/amportal.conf"|"$(ROOT)/etc/amportal.conf"|'
+
+$(DL_DIR)/$(FREEPBX_SOURCE):
+ mkdir -p dl
+ wget -P $(DL_DIR) $(FREEPBX_SITE)/$(FREEPBX_SOURCE)
+
+$(FREEPBX_DIR)/.unpacked: $(DL_DIR)/$(FREEPBX_SOURCE)
+ zcat $(DL_DIR)/$(FREEPBX_SOURCE) | tar -C $(BUILD_DIR) -xf -
+ patch -d $(FREEPBX_DIR) -p5 < patch/freepbx.patch
+ touch $(FREEPBX_DIR)/.unpacked
+
+$(FREEPBX_DIR)/.installed: $(FREEPBX_DIR)/.unpacked
+
+ # initialise databases (freepbx and CDR)
+
+ mkdir -p $(ROOT)/var
+ cat $(FREEPBX_DIR)/SQL/newinstall.sqlite3.sql | sqlite3 $(ROOT)/var/freepbx.db
+ touch $(ROOT)/var/asteriskcdr.db
+
+ # edit amportal.conf
+
+ # out with the old......
+
+ cat $(FREEPBX_DIR)/amportal.conf | \
+ sed -e '/AMPDBENGINE=/ d' -e '/AMPDBFILE=/ d' \
+ -e '/AMPWEBROOT=/ d' -e '/FOPWEBROOT=/ d' \
+ -e '/AMPDBHOST=/ d' -e '/AMPDBUSER=/ d' -e '/AMPDBPASS=/ d' \
+ > $(FREEPBX_DIR)/amportal.conf.tmp
+
+ mv $(FREEPBX_DIR)/amportal.conf.tmp $(FREEPBX_DIR)/amportal.conf
+
+ # in with the new........
+
+ echo "AMPDBENGINE=sqlite3" >> $(FREEPBX_DIR)/amportal.conf
+ echo "AMPDBFILE=$(ROOT)/var/freepbx.db" >> $(FREEPBX_DIR)/amportal.conf
+ echo "AMPWEBROOT=$(ROOT)/www" >> $(FREEPBX_DIR)/amportal.conf
+ echo "FOPWEBROOT=$(ROOT)/www/panel" >> $(FREEPBX_DIR)/amportal.conf
+
+ sed -i "s|/var/www/html|$(ROOT)/www|" $(FREEPBX_DIR)/amportal.conf
+
+ # Wholesale hacking of FreePBX source to move AMP_CONF to our local conf dir:
+ # FYI to find where AMP_CONF is used:
+ # grep -r "define(\"AMP_CONF\", \"/etc/amportal.conf\")" *
+
+ cd $(FREEPBX_DIR); \
+ FILES=`grep -r "\"/etc/amportal.conf\"" * | sed 's/:.*//'`; \
+ for f in $$FILES; do \
+ sed -i $(FREEPBX_AMP_CONF) $$f; \
+ done
+
+ # change recordings/includes/main.conf.php DBENGINE and DBFILE settings which
+ # are hard coded for mysql
+
+ sed -i "s|ASTERISKCDR_DBENGINE.*|ASTERISKCDR_DBENGINE=\"sqlite3\";|" \
+ $(FREEPBX_DIR)/amp_conf/htdocs/recordings/includes/main.conf.php
+ sed -i "s|ASTERISKCDR_DBFILE.*|ASTERISKCDR_DBFILE=\"$(ROOT)/var/asteriskcdr.db\";|" \
+ $(FREEPBX_DIR)/amp_conf/htdocs/recordings/includes/main.conf.php
+
+ # change admin/cdr/lib/defines DB_TYPE and DBNAME settings
+
+ sed -i "s|\"DBNAME\".*|\"DBNAME\",\"$(ROOT)/var/asteriskcdr.db\");|" \
+ $(FREEPBX_DIR)/amp_conf/htdocs/admin/cdr/lib/defines.php
+ sed -i "s|\"DB_TYPE\".*|\"DB_TYPE\",\"sqlite3\");|" \
+ $(FREEPBX_DIR)/amp_conf/htdocs/admin/cdr/lib/defines.php
+
+ # switch off mp3 support as I dont have asterisk-addons and Asterisk keeps
+ # crashing when I start it
+
+ sed -i "s|load => format_mp3.so|;load => format_mp3.so|" \
+ $(FREEPBX_DIR)/amp_conf/astetc/modules.conf
+
+ # cp amportal.conf ourselves to bypass a lot of questions in install script
+
+ cp $(FREEPBX_DIR)/amportal.conf $(ROOT)/etc
+
+ # run installer
+
+ sudo mkdir -p $(ROOT)/var/run/asterisk; sudo chmod 777 $(ROOT)/var/run/asterisk;
+ sudo mkdir -p $(ROOT)/var/lib/asterisk/bin; sudo chmod 777 $(ROOT)/var/lib/asterisk/bin;
+ cd $(FREEPBX_DIR); sudo ./install_amp; sudo chmod 777 $(ROOT)/www -R
+
+ #touch $(FREEPBX_DIR).installed
+
+
+freepbx: $(FREEPBX_DIR)/.installed
+
+#########################################################################
+# clean ----------------------------------------------------------------
+#########################################################################
+
+clean:
+ rm -Rf $(PHP_DIR) $(SQLITE_DIR) $(PHP-SQLITE3_DIR) \
+ $(XDEBUG_DIR) $(LIGHTTPD_DIR) $(FREEPBX_DIR) root \
+ (FREEPBX_DIR)-orig
+
+ find . -name '*~' | xargs rm -f
+ rm -f *.xml # where do these come from?
+
+#########################################################################
+# freepbx-make-patch ---------------------------------------------------
+#########################################################################
+
+# Generate patches between original tar ball $(AO) and either the
+# installed files $(AROOT), or modified tar ball $A.
+# Run this Makefile target to capture any changes to patches
+
+AO = $(FREEPBX_DIR)-orig/
+AROOT = $(ROOT)/www
+A = $(FREEPBX_DIR)/
+
+freepbx-make-patch:
+
+ # untar original, to save time we check if the orig is already there
+
+ if [ ! -d $(FREEPBX_DIR)-orig ] ; then \
+ cd $(DL_DIR); tar xvf $(FREEPBX_SOURCE); \
+ mv $(FREEPBX_DIRNAME) $(FREEPBX_DIR)-orig; \
+ fi
+
+ # make big-ass SQL statement work with sqlite3
+
+ -diff -uN \
+ $(AO)/amp_conf/htdocs/admin/modules/core/functions.inc.php \
+ $(AROOT)/admin/modules/core/functions.inc.php \
+ > patch/freepbx.patch
+
+ # add $options array to help numRows() support in sqlite3
+
+ -diff -uN \
+ $(AO)/amp_conf/htdocs/admin/common/db_connect.php \
+ $(AROOT)/admin/common/db_connect.php \
+ >> patch/freepbx.patch
+
+ # sqlite3 support for cdr in recordings
+
+ -diff -uN \
+ $(AO)/amp_conf/htdocs/recordings/includes/database.php \
+ $(AROOT)/recordings/includes/database.php \
+ >> patch/freepbx.patch
+
+ # sqlite3 support for cdr
+
+ -diff -uN \
+ $(AO)/amp_conf/htdocs/admin/cdr/lib/defines.php \
+ $(AROOT)/admin/cdr/lib/defines.php \
+ >> patch/freepbx.patch
+
+ # typo in newinstall.sqlite3.sql
+
+ -diff -uN \
+ $(AO)/SQL/newinstall.sqlite3.sql \
+ $(A)/SQL/newinstall.sqlite3.sql \
+ >> patch/freepbx.patch
+
+ # stop installer warnings when sqlite3 used
+
+ -diff -uN \
+ $(AO)/install_amp \
+ $(A)/install_amp \
+ >> patch/freepbx.patch
+
+ # use sqlite3 SQL syntax for recording installer
+
+ -diff -uN \
+ $(AO)/amp_conf/htdocs/admin/modules/recordings/install.php \
+ $(A)/amp_conf/htdocs/admin/modules/recordings/install.php \
+ >> patch/freepbx.patch
+
+ # stop perl script for flash panel being called, as
+ # this won't work on Blackfin (might work on x86 with
+ # appropriate Perl lib but not tested)
+
+ -diff -uN \
+ $(AO)/amp_conf/bin/retrieve_conf \
+ $(A)/amp_conf/bin/retrieve_conf \
+ >> patch/freepbx.patch
+
+ # NOTE: common.patch was generated manually from command line
--- /dev/null
+README for freepbx-sandbox
+David Rowe Feb 2008
+
+Introduction
+------------
+
+This directory contains a "sandbox" type development environment for
+FreePBX using sqlite3.
+
+The Makefile builds (almost) everything you need for FreePBX (web
+server, php etc) from scratch and runs it in a "sandbox" environment.
+The notable exception is that it doesn't build Asterisk (yet).
+
+FreePBX is configured to use lighttpd and and sqlite3.
+
+All the files environment are confined to this directory, i.e. you
+mostly (except for Asterisk) don't need to mess with your PC's
+configuration. Inspired by buildroot. Used to model and test
+configuration for Blackfin port, but may be useful for general FreePBX
+development.
+
+Motivation
+----------
+
+1/ When I first tried to manually install FreePBX I had a lot of
+problems installing all the apps I needed, especially as I was new to
+PHP/SQL/FreePBX. So I thought automating the installation might be a
+good idea to save others some manual install pain.
+
+2/ It may allow multiple installations of FreePBX, or for example lets
+you use a different PHP version to currently installed on your system.
+
+3/ It doesn't mess with your root filesystem.
+
+4/ Let me collect all the code I needed in one dir tree, making source
+control easier.
+
+5/ Stepping stone for Blackfin port.
+
+Building and Running FreePBX-sqlite3 Sandbox
+--------------------------------------------
+
+Building:
+
+1/ Install Asterisk
+2/ make
+3/ You will eventually get prompted for your root passwd
+
+Running:
+
+1/ Start the web server:
+ [freepbx-sandbox]$ sudo root/sbin/lighttpd -D -f root/etc/lighttpd.conf
+2/ Start Asterisk:
+ [freepbx-sandbox]$ sudo asterisk
+3/ Point your browser at locahost
+
+Manual Installation of FreePBX with sqlite3
+-------------------------------------------
+
+Here are some instructions for a regular (non-sandbox) installation of
+FreePBX with sqlite3.
+
+The Makefile automates FreePBX/sqlite3 installation in a sandbox
+environment, use it as a reference for manual installation. See also
+sqlite.readme in the FreePBX tar ball.
+
+1/ Install and test a web server with PHP 5.
+
+2/ Install PHP PEAR. Patch DB/common.php with files/common.patch to
+ enable numRows() to work.
+
+3/ Install sqlite3 (shared libs and application).
+
+4/ Install sqlite3-0.5 (PEAR/DB support for sqlite3)
+ + cp files/sqlite3.php /your/php/path/DB/sqlite3.php. This is an updated
+ version of the sqlite3.php file that comes with sqlite3-0.5
+ + make sure you install sqlite.so and update php.ini so it can find it.
+
+5/ tar xvzf freepbx-2.4.0.tar.gz
+
+6/ Edit amportal.conf, cp to /etc (makes installer ask less questions)
+
+7/ Create sqlite database (see sqlite.readme), create cdr database
+ file using 'touch /var/asteriskcdr.db' (to prevent recording screen
+ choking).
+
+8/ Apply patch/freepbx.patch to freepbx-2.4.0 directory.
+
+9/ Manually edit recordings/includes/main.conf.php:
+ ASTERISKCDR_DBENGINE="sqlite3"
+ ASTERISKCDR_DBFILE="/var/asteriskcdr.db"
+
+ Manually edit: admin/cdr/lib/defines.php:
+ DB_TYPE="sqlite3"
+ DB_NAME="/var/asteriskcdr.db"
+
+10/ Run freepbx installer
+
+Tests
+-----
+
+1/ basic PHP support: run file/test.php on your webserver
+
+2/ PEAR/DB with sqlite3: run files/testdb.php on your webserver
+ (after freepbx.db has been created by step 9)
+
+Notes
+-----
+
+1/ The Recordings screen needs a sqlite3 CDR backend for Asterisk.
+This is available in Asterisk 1.6. This hasn't been tested yet.
+
+2/ The Makefile automates FreePBX/sqlite3 installation in a sandbox
+environment, use it as a reference for manual installation. See
+Makefile for more information.
+
+3/ Changes to FreePBX are in the patch directory. An updated
+sqlite3.php DB/PEAR backend is also required (files dir).
+
+4/ If port 80 is not available kill your existing web server.
+
+5/ Xdebug generates trace files in your /tmp directory. Useful to
+determine what went wrong. Also keep an eye on the lighttpd log.
+
+6/ I used a laptop running Ubuntu for these tests - Asterisk had no
+analog hardware installed so I didn't install Zaptel. Asterisk was
+compiled in another directory in the usual way: ./configure && make &&
+sudo make install.
+
+7/ In files/testdb.php is a simple test script for exercising sqlite3
+PEAR/DB support - useful for debugging any sqlite3 problems you might
+encounter.
+
+Suggested FreePBX Changes
+-------------------------
+
+1/ Consider patch/freepbx.patch (for FreePBX) & patch/common.patch
+ (for PEAR/DB). Patches are explained at the end of Makefile
+ (freepbx-make-patch target).
+
+2/ It might be better to store the CDR database parameters in
+ amportal.conf rather than hard coding them in
+ recordings/includes/main.conf.php ($ASTERISKCDR_DBFILE,
+ $ASTERISKCDR_DBNAME) & admin/cdr/lib/defines.php (DBNAME, DB_TYPE).
+
+3/ Include sqlite3.php in FreePBX to support sqlite3 in PEAR/DB for
+ PHP 5.
+
+4/ newinstall.sqlite3.sql has a typo on line 327:
+
+ modules_xml -> module_xml
+
+ This correction is included in patch/freepbx.patch
+
+TODO
+----
+
+1/ Try to get Asterisk 1.6 CDR working with sqlite3, see if recording
+menus come alive, or at least bomb out in a useful way!
--- /dev/null
+# lighttpd configuration file
+#
+# use a it as base for lighttpd 1.0.0 and above
+#
+# $Id: lighttpd.conf,v 1.6 2004/08/29 09:44:53 weigon Exp $
+
+############ Options you really have to take care of ####################
+
+## modules to load
+# at least mod_access and mod_accesslog should be loaded
+# all other module should only be loaded if really neccesary
+# - saves some time
+# - saves memory
+server.modules = (
+# "mod_rewrite",
+# "mod_redirect",
+ "mod_access",
+# "mod_auth",
+# "mod_status",
+# "mod_fastcgi",
+# "mod_simple_vhost",
+# "mod_evhost",
+ "mod_cgi",
+# "mod_compress",
+# "mod_ssi",
+# "mod_usertrack",
+# "mod_rrdtool",
+# "mod_accesslog"
+)
+
+## a static document-root, for virtual-hosting take look at the
+## server.virtual-* options
+server.document-root = "/var/www/html"
+
+## where to send error-messages to
+# server.errorlog = ""
+
+# files to check for if .../ is requested
+server.indexfiles = ( "index.php", "index.html",
+ "index.htm", "default.htm" )
+
+# mimetype mapping
+mimetype.assign = (
+ ".pdf" => "application/pdf",
+ ".sig" => "application/pgp-signature",
+ ".spl" => "application/futuresplash",
+ ".class" => "application/octet-stream",
+ ".ps" => "application/postscript",
+ ".torrent" => "application/x-bittorrent",
+ ".dvi" => "application/x-dvi",
+ ".gz" => "application/x-gzip",
+ ".pac" => "application/x-ns-proxy-autoconfig",
+ ".swf" => "application/x-shockwave-flash",
+ ".tar.gz" => "application/x-tgz",
+ ".tgz" => "application/x-tgz",
+ ".tar" => "application/x-tar",
+ ".zip" => "application/zip",
+ ".mp3" => "audio/mpeg",
+ ".m3u" => "audio/x-mpegurl",
+ ".wma" => "audio/x-ms-wma",
+ ".wax" => "audio/x-ms-wax",
+ ".ogg" => "audio/x-wav",
+ ".wav" => "audio/x-wav",
+ ".gif" => "image/gif",
+ ".jpg" => "image/jpeg",
+ ".jpeg" => "image/jpeg",
+ ".png" => "image/png",
+ ".xbm" => "image/x-xbitmap",
+ ".xpm" => "image/x-xpixmap",
+ ".xwd" => "image/x-xwindowdump",
+ ".css" => "text/css",
+ ".html" => "text/html",
+ ".htm" => "text/html",
+ ".js" => "text/javascript",
+ ".asc" => "text/plain",
+ ".c" => "text/plain",
+ ".conf" => "text/plain",
+ ".text" => "text/plain",
+ ".txt" => "text/plain",
+ ".dtd" => "text/xml",
+ ".xml" => "text/xml",
+ ".mpeg" => "video/mpeg",
+ ".mpg" => "video/mpeg",
+ ".mov" => "video/quicktime",
+ ".qt" => "video/quicktime",
+ ".avi" => "video/x-msvideo",
+ ".asf" => "video/x-ms-asf",
+ ".asx" => "video/x-ms-asf",
+ ".wmv" => "video/x-ms-wmv"
+ )
+
+# Use the "Content-Type" extended attribute to obtain mime type if possible
+# mimetypes.use-xattr = "enable"
+
+#### accesslog module
+# accesslog.filename = "/www/logs/access.log"
+
+## deny access the file-extensions
+#
+# ~ is for backupfiles from vi, emacs, joe, ...
+# .inc is often used for code includes which should in general not be part
+# of the document-root
+url.access-deny = ( "~", ".inc" )
+
+
+
+######### Options that are good to be but not neccesary to be changed #######
+
+## bind to port (default: 80)
+#server.port = 81
+
+## bind to localhost (default: all interfaces)
+#server.bind = "grisu.home.kneschke.de"
+
+## error-handler for status 404
+#server.error-handler-404 = "/error-handler.html"
+#server.error-handler-404 = "/error-handler.php"
+
+
+###### virtual hosts
+##
+## If you want name-based virtual hosting add the next three settings and load
+## mod_simple_vhost
+##
+## document-root =
+## virtual-server-root + virtual-server-default-host + virtual-server-docroot or
+## virtual-server-root + http-host + virtual-server-docroot
+##
+#simple-vhost.server-root = "/home/weigon/wwwroot/servers/"
+#simple-vhost.default-host = "grisu.home.kneschke.de"
+#simple-vhost.document-root = "/pages/"
+
+
+##
+## Format: <errorfile-prefix><status>.html
+## -> ..../status-404.html for 'File not found'
+#server.errorfile-prefix = "/home/weigon/projects/lighttpd/doc/status-"
+
+## virtual directory listings
+#server.dir-listing = "enable"
+
+## send unhandled HTTP-header headers to error-log
+#debug.dump-unknown-headers = "enable"
+
+### only root can use these options
+#
+# chroot() to directory (default: no chroot() )
+#server.chroot = "/"
+
+## change uid to <uid> (default: don't care)
+#server.username = "wwwrun"
+
+## change uid to <uid> (default: don't care)
+#server.groupname = "wwwrun"
+
+#### compress module
+#compress.cache-dir = "/tmp/lighttpd/cache/compress/"
+#compress.filetype = ("text/plain", "text/html")
+
+#### fastcgi module
+## read fastcgi.txt for more info
+#fastcgi.server = ( ".php" =>
+# ( "grisu" =>
+# (
+# "host" => "192.168.2.10",
+# "port" => 1026
+# )
+# )
+# )
+
+#### CGI module
+#cgi.assign = ( ".pl" => "/usr/bin/perl",
+# ".cgi" => "/usr/bin/perl" )
+#
+
+#### SSL engine
+#ssl.engine = "enable"
+#ssl.pemfile = "server.pem"
+
+#### status module
+# status.status-url = "/server-status"
+# status.config-url = "/server-config"
+
+#### auth module
+## read authentification.txt for more info
+# auth.backend = "plain"
+# auth.backend.plain.userfile = "lighttpd.user"
+# auth.backend.plain.groupfile = "lighttpd.group"
+
+# auth.backend.ldap.hostname = "localhost"
+# auth.backend.ldap.base-dn = "dc=my-domain,dc=com"
+# auth.backend.ldap.filter = "(uid=$)"
+
+# auth.require = ( "/server-status" =>
+# (
+# "method" => "digest",
+# "realm" => "download archiv",
+# "require" => "group=www|user=jan|host=192.168.2.10"
+# ),
+# "/server-info" =>
+# (
+# "method" => "digest",
+# "realm" => "download archiv",
+# "require" => "group=www|user=jan|host=192.168.2.10"
+# )
+# )
+
+#### url handling modules (rewrite, redirect, access)
+# url.rewrite = ( "^/$" => "/server-status" )
+# url.redirect = ( "^/wishlist/(.+)" => "http://www.123.org/$1" )
+
+#
+# define a pattern for the host url finding
+# %% => % sign
+# %0 => domain name + tld
+# %1 => tld
+# %2 => domain name without tld
+# %3 => subdomain 1 name
+# %4 => subdomain 2 name
+#
+# evhost.path-pattern = "/home/storage/dev/www/%3/htdocs/"
+
+#### expire module
+# expire.url = ( "/buggy/" => "access 2 hours", "/asdhas/" => "access plus 1 seconds 2 minutes")
+
+#### ssi
+# ssi.extension = ( ".shtml" )
+
+#### rrdtool
+# rrdtool.binary = "/usr/bin/rrdtool"
+# rrdtool.db-name = "/var/www/lighttpd.rrd"
--- /dev/null
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * The PEAR DB driver for PHP's sqlite3 extension
+ * for interacting with SQLite3 databases
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Database
+ * @package DB
+ * @author Bruno Fleisch
+ * @copyright 1997-2005 The PHP Group
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0
+ * @version CVS: $Id: sqlite3.php,v 1.3 2007/04/04 14:13:19 bfleisch Exp $
+ * @link http://pear.php.net/package/DB
+ */
+
+include_once 'DB/common.php';
+
+
+
+/**
+ * The methods PEAR DB uses to interact with PHP's sqlite extension
+ * for interacting with SQLite databases
+ *
+ * These methods overload the ones declared in DB_common.
+ *
+ */
+
+class DB_sqlite3 extends DB_common
+{
+
+ // {{{ PROPERTIES
+
+
+ var $phptype = 'sqlite3';
+
+ /**
+ * The database syntax variant to be used (db2, access, etc.), if any
+ * @var string
+ */
+ var $dbsyntax = 'sqlite3';
+
+ /**
+ * The capabilities of this DB implementation
+ *
+ * The 'new_link' element contains the PHP version that first provided
+ * new_link support for this DBMS. Contains false if it's unsupported.
+ *
+ * Meaning of the 'limit' element:
+ * + 'emulate' = emulate with fetch row by number
+ * + 'alter' = alter the query
+ * + false = skip rows
+ *
+ * @var array
+ */
+ var $features = array(
+ 'limit' => 'alter',
+ 'new_link' => false,
+ 'numrows' => 'emulate',
+ 'pconnect' => true,
+ 'prepare' => false,
+ 'ssl' => false,
+ 'transactions' => false,
+ );
+
+
+ /**
+ * A mapping of native error codes to DB error codes
+ *
+ * {@internal Error codes according to sqlite_exec. See the online
+ * manual at http://sqlite.org/c_interface.html for info.
+ * This error handling based on sqlite_exec is not yet implemented.}}
+ *
+ * @var array
+ */
+ var $errorcode_map = array(
+ );
+
+ /**
+ * The raw database connection created by PHP
+ * @var resource
+ */
+ var $connection;
+
+ /* The DSN information for connecting to a database
+ * @var array
+ */
+ var $dsn = array();
+
+
+ /**
+ * SQLite data types
+ *
+ * @link http://www.sqlite.org/datatypes.html
+ *
+ * @var array
+ */
+ var $keywords = array (
+ 'BLOB' => '',
+ 'BOOLEAN' => '',
+ 'CHARACTER' => '',
+ 'CLOB' => '',
+ 'FLOAT' => '',
+ 'INTEGER' => '',
+ 'KEY' => '',
+ 'NATIONAL' => '',
+ 'NUMERIC' => '',
+ 'NVARCHAR' => '',
+ 'PRIMARY' => '',
+ 'TEXT' => '',
+ 'TIMESTAMP' => '',
+ 'UNIQUE' => '',
+ 'VARCHAR' => '',
+ 'VARYING' => '',
+ );
+
+ /**
+ * The most recent error message from $php_errormsg
+ * @var string
+ * @access private
+ */
+ var $_lasterror = '';
+
+
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * constructor
+ *
+ * @return void
+ */
+
+ function DB_sqlite3()
+ {
+ $this->DB_common();
+ }
+
+
+ // }}}
+ // {{{ string errorNative(void)
+
+ /**
+ * Gets the DBMS' native error code produced by the last query
+ *
+ * @return mixed the DBMS' error code. A DB_Error object on failure.
+ */
+
+ function errorNative()
+ {
+ return sqlite3_error ($this->connection);
+ }
+
+ // }}}
+ // {{{ mixed connect(array $dsn, bool $persitent)
+
+ /**
+ * create or connect to the specified database.
+ *
+ * @param array $dsn the data source name
+ * @param bool $persitent if the connection is persitent
+ *
+ * @return DB_OK on success or DB_error object on failure
+ */
+
+
+ function connect($dsn, $persitent = false)
+ {
+ $this->connection = sqlite3_open ($dsn['database']);
+ if (!$this->connection)
+ return $this->raiseError(DB_ERROR_NODBSELECTED);
+
+ return DB_OK;
+ }
+
+ // }}}
+ // {{{ bool disconnect (void)
+
+
+ /**
+ * release all resources for this connection, and close database
+ *
+ * @return bool TRUE on sucess, FALSE otherwise.
+ */
+
+ function disconnect()
+ {
+ return sqlite3_close ($this->connection);
+ }
+
+ // }}}
+ // {{{ mixed simpleQuery(string $sql)
+
+ /**
+ * execute a SQL query.
+ *
+ * @param string $query the SQL query
+ *
+ * @return mixed + object DB_error object on failure
+ * + object Result resource for SELECT requests
+ * + bool TRUE for other sucessful requests
+ */
+
+ function simpleQuery($query)
+ {
+
+ $isSelect = preg_match ("/^\s*SELECT/i", $query);
+
+ #$handle = fopen("/tmp/sql.txt",'a');
+ #fwrite($handle, "<strong>sqlite3 simpleQuery: $query</strong><br>\n");
+ #fclose($handle);
+
+ if (! $isSelect)
+ $this->result = sqlite3_exec($this->connection, $query);
+ else
+ $this->result = sqlite3_query($this->connection, $query);
+
+ if (!$this->result)
+ return $this->RaiseError($this->errorNative());
+
+ return $this->result;
+ }
+
+ // }}}
+ // {{{ mixed fetchInto(resource $res, array $arr, int $fetchmode [, int $rownum])
+
+ /**
+ * Fetch a row of data into an array which is passed by reference
+ *
+ * The type of array returned can be controlled either by setting this
+ * method's <var>$fetchmode</var> parameter or by changing the default
+ * fetch mode setFetchMode() before calling this method.
+ *
+ * There are two options for standardizing the information returned
+ * from databases, ensuring their values are consistent when changing
+ * DBMS's. These portability options can be turned on when creating a
+ * new DB object or by using setOption().
+ *
+ * + <var>DB_PORTABILITY_LOWERCASE</var>
+ * convert names of fields to lower case
+ *
+ * + <var>DB_PORTABILITY_RTRIM</var>
+ * right trim the data
+ *
+ * @param resource $result the result resource
+ * @param array &$arr the variable where the data should be placed
+ * @param int $fetchmode the constant indicating how to format the data
+ * @param int $rownum the row number to fetch (index starts at 0)
+ *
+ * @return mixed DB_OK if a row is processed, NULL when the end of the
+ * result set is reached or a DB_Error object on failure
+ *
+ * @see DB_common::setOption(), DB_common::setFetchMode()
+ */
+
+ function fetchInto($result, &$arr, $fetchmode, $rownum = null)
+ {
+ if ($rownum !==NULL)
+ return $this->RaiseError (DB_ERROR_NOTIMPLEMENTED);
+
+ switch ($fetchmode)
+ {
+
+ case DB_FETCHMODE_ORDERED:
+ $fetchfunc="sqlite3_fetch";
+ break;
+
+ case DB_FETCHMODE_OBJECT:
+ return $this->RaiseError(DB_ERROR_NODBSELECTED);
+ break;
+
+ case DB_FETCHMODE_ASSOC:
+ default:
+ $fetchfunc="sqlite3_fetch_array";
+ break;
+ }
+
+ $arr = $fetchfunc($result);
+
+ if ($arr)
+ return DB_OK;
+
+ return NULL;
+ }
+
+ // }}}
+ // {{{ string modifyLimitQuery(string $query, int $from, int $count [,mixed $params])
+
+
+ /**
+ * Adds LIMIT clauses to a query string according to current DBMS standards
+ *
+ * It is defined here to assure that all implementations
+ * have this method defined.
+ *
+ * @param string $query the query to modify
+ * @param int $from the row to start to fetching (0 = the first row)
+ * @param int $count the numbers of rows to fetch
+ * @param mixed $params array, string or numeric data to be used in
+ * execution of the statement. Quantity of items
+ * passed must match quantity of placeholders in
+ * query: meaning 1 placeholder for non-array
+ * parameters or 1 placeholder per array element.
+ *
+ * @return string the query string with LIMIT clauses added
+ *
+ * @access protected
+ */
+
+ function modifyLimitQuery($query, $from, $count, $params = array())
+ {
+ return "$query LIMIT $count OFFSET $from";
+ }
+
+
+ // }}}
+ // {{{ bool freeResult(void)
+
+ /**
+ * free the specified result.
+ *
+ * @param resource $result the query resource result
+ *
+ * @return bool DB_OK
+ *
+ */
+
+ function freeResult($result)
+ {
+ sqlite3_query_close($result);
+ return DB_OK; /* always sucessful ! */
+ }
+
+ // }}}
+ // {{{ int affectedRow(void)
+
+ /**
+ * Determines the number of rows affected by a data maniuplation query
+ *
+ * 0 is returned for queries that don't manipulate data.
+ *
+ * @return int the number of rows. A DB_Error object on failure.
+ */
+
+ function affectedRows()
+ {
+ return sqlite3_changes ($this->connection);
+ }
+
+ // }}}
+ // {{{ mixed numCols(resource $result)
+
+ /**
+ * Get the the number of columns in a result set
+ *
+ * @return int the number of columns. A DB_Error object on failure.
+ */
+
+ function numCols($result)
+ {
+ return sqlite3_column_count($result);
+ }
+
+ // {{{ mixed createSequence(string $seq_name)
+
+ /**
+ * Creates a new sequence
+ *
+ * The name of a given sequence is determined by passing the string
+ * provided in the <var>$seq_name</var> argument through PHP's sprintf()
+ * function using the value from the <var>seqname_format</var> option as
+ * the sprintf()'s format argument.
+ *
+ * <var>seqname_format</var> is set via setOption().
+ *
+ * @param string $seq_name name of the new sequence
+ *
+ * @return int DB_OK on success. A DB_Error object on failure.
+ *
+ * @see DB_common::dropSequence(), DB_common::getSequenceName(),
+ * DB_common::nextID()
+ */
+
+ function createSequence($seq_name)
+ {
+ return $this->query ("CREATE TABLE " . $this->getSequenceName($seq_name) . " (id INTEGER PRIMARY KEY AUTOINCREMENT)");
+ }
+
+ // }}}
+ // {{{ mixed nextId(string $sequence [, bool $ondemand])
+
+ /**
+ * Returns the next free id in a sequence
+ *
+ * @param string $seq_name name of the sequence
+ * @param boolean $ondemand when true, the seqence is automatically
+ * created if it does not exist
+ *
+ * @return int the next id number in the sequence.
+ * A DB_Error object on failure.
+ *
+ * @see DB_common::createSequence(), DB_common::dropSequence(),
+ * DB_common::getSequenceName()
+ */
+ function nextId($seq_name, $ondemand = true)
+ {
+
+ $sqn = $this->getSequenceName($seq_name);
+
+ if ($ondemand)
+ {
+ $tables = $this->getTables();
+ if (DB::isError($tables)) return $tables;
+
+ if (! in_array ($sqn, $tables))
+ {
+ $res = $this->createSequence($seq_name);
+ if ( DB::isError($res))
+ return $res;
+ }
+ }
+
+ $res = $this->query ("INSERT INTO " . $sqn . " VALUES (NULL)");
+ if (DB::isError($res)) return $res;
+
+ return sqlite3_last_insert_rowid ($this->connection);
+ }
+
+ // }}}
+ // {{{ mixed dropSequence (string $seq_name)
+
+ /**
+ * Deletes a sequence
+ *
+ * @param string $seq_name name of the sequence to be deleted
+ *
+ * @return int DB_OK on success. A DB_Error object on failure.
+ *
+ * @see DB_common::createSequence(), DB_common::getSequenceName(),
+ * DB_common::nextID()
+ */
+ function dropSequence($seq_name)
+ {
+ return $this->query("DROP TABLE ". $this->getSequenceName($seq_name));
+ }
+
+ // }}}
+ // {{{ string getSpecialQuery(string $type)
+
+ /**
+ * Obtains the query string needed for listing a given type of objects
+ *
+ * @param string $type the kind of objects you want to retrieve
+ *
+ * @return string the SQL query string or null if the driver doesn't
+ * support the object type requested
+ *
+ * @access protected
+ * @see DB_common::getListOf()
+ */
+
+ function getSpecialQuery($type)
+ {
+ switch ($type) {
+ case 'tables':
+ return "SELECT name FROM SQLITE_MASTER ORDER BY name";
+ default:
+ return $this->raiseError(DB_ERROR_UNSUPPORTED);
+ }
+ }
+
+ // }}}
+
+
+}
+?>
--- /dev/null
+<?php phpinfo(); ?>
+
--- /dev/null
+<?php
+
+# test.db.php
+# David Rowe Feb 2008
+#
+# Used to test and debug PEAR/DB sqlite3 support for FreePBX
+
+require_once('DB.php'); // PEAR must be installed
+
+/*
+ datasource in in this style:
+ dbengine://username:password@host/database
+*/
+
+# Mysql connection as a starting point ----------------------------
+
+/*
+
+$db_engine = "mysql";
+$db_user = "asteriskuser";
+$db_pass = "amp109";
+$db_host = "localhost";
+$db_name = "asterisk";
+
+$datasource = $db_engine.'://'.$db_user.':'.$db_pass.'@'.$db_host.'/'.$db_name;
+$db = DB::connect($datasource); // attempt connection
+print("Connecting to $datasource.....<br>");
+if (DB::isError ($db))
+ die ("Cannot connect: " . $db->getMessage () . "\n");
+print("Disconnecting...<br>");
+$db->disconnect ();
+
+*/
+
+# Basic sqlite connection ----------------------------------------
+
+$options = array(
+ 'debug' => 4,
+ 'portability' => DB_PORTABILITY_NUMROWS
+);
+
+$file = "/var/lib/asterisk/freepbx.db";
+$datasource = "sqlite3:///" . $file . "?mode=0666";
+
+print("Connecting to $datasource.....<br>");
+
+if (! extension_loaded('sqlite3') ) {
+ print("Loading sqlite3.so....<br>");
+ dl('sqlite3.so');
+}
+
+$db = DB::connect($datasource, $options);
+if (DB::isError ($db))
+ die ("Cannot connect: " . $db->getMessage () . "\n");
+
+$result = $db->query ("SELECT * FROM admin");
+if (DB::isError ($result))
+ die ("SELECT failed: " . $result->getMessage () . "\n");
+
+print("admin table rows:<br>");
+while ($row =& $result->fetchRow ())
+ printf("  %s, %s<br>", $row[0], $row[1]);
+
+# numRows Test --------------------------------------------------
+
+$numRows = $result->numRows();
+
+if (DB::isError ($numRows))
+ die ("numRows failed: " . $numRows->getMessage () . "<br>");
+print ("result contains: $numRows rows<br>");
+
+# Try inserting a few values -----------------------------------
+
+$result =& $db->query ("INSERT INTO tbl1 VALUES ('AA',30)");
+
+if (DB::isError ($result))
+ die ("INSERT failed: " . $result->getMessage () . "\n");
+
+$result = $db->query ("SELECT * FROM tbl1");
+
+if (DB::isError ($result))
+ die ("SELECT failed: " . $result->getMessage () . "\n");
+
+while ($row =& $result->fetchRow ())
+ printf("  %s<br>", $row[0]);
+
+$result->free();
+print("Disconnecting...");
+$db->disconnect ();
+
+?>
--- /dev/null
+--- orig/common.php 2008-03-01 09:40:36.000000000 +1030
++++ mod/common.php 2008-03-01 09:14:34.000000000 +1030
+@@ -1213,6 +1213,7 @@
+ return $ret;
+ } else {
+ $this->last_parameters = array();
++ $this->last_query = $query;
+ $result = $this->simpleQuery($query);
+ if ($result === DB_OK || DB::isError($result)) {
+ return $result;
--- /dev/null
+--- /home/david/freepbx-sandbox/freepbx-2.4.0-orig//amp_conf/htdocs/admin/modules/core/functions.inc.php 2008-02-10 05:16:02.000000000 +1030
++++ /home/david/freepbx-sandbox/root/www/admin/modules/core/functions.inc.php 2008-02-29 20:39:27.000000000 +1030
+@@ -2886,6 +2886,7 @@
+ // TODO: sqlite work arround - diego
+ // TODO: WILL NOT WORK, need to remove the usage of SUBSTRING
+ // need to reorder the trunks in PHP code
++/*
+ $sqlstr = "SELECT t.variable, t.value, d.value state FROM `globals` t ";
+ $sqlstr .= "JOIN (SELECT x.variable, x.value FROM globals x WHERE x.variable LIKE 'OUTDISABLE\_%') d ";
+ $sqlstr .= "ON substring(t.variable,5) = substring(d.variable,12) WHERE t.variable LIKE 'OUT\_%' ";
+@@ -2894,9 +2895,9 @@
+ $sqlstr .= "WHERE v.variable LIKE 'OUT\_%' AND concat('OUTDISABLE_',substring(v.variable,5)) NOT IN ";
+ $sqlstr .= " ( SELECT variable from globals WHERE variable LIKE 'OUTDISABLE\_%' ) ";
+ $sqlstr .= "ORDER BY variable";
+-
+- //$unique_trunks = sql("SELECT * FROM globals WHERE variable LIKE 'OUT_%' ORDER BY variable","getAll");
+- $unique_trunks = sql($sqlstr,"getAll");
++*/
++ $unique_trunks = sql("SELECT * FROM globals WHERE variable LIKE 'OUT_%' ORDER BY variable","getAll");
++ //$unique_trunks = sql($sqlstr,"getAll");
+ }
+ else
+ {
+--- /home/david/freepbx-sandbox/freepbx-2.4.0-orig//amp_conf/htdocs/admin/common/db_connect.php 2007-09-09 20:41:11.000000000 +0930
++++ /home/david/freepbx-sandbox/root/www/admin/common/db_connect.php 2008-03-01 09:23:08.000000000 +1030
+@@ -52,7 +52,11 @@
+ }
+
+ $datasource = "sqlite3:///" . $amp_conf["AMPDBFILE"] . "?mode=0666";
+- $db = DB::connect($datasource);
++ $options = array(
++ 'debug' => 4,
++ 'portability' => DB_PORTABILITY_NUMROWS
++ );
++ $db = DB::connect($datasource, $options);
+ break;
+
+ default:
+--- /home/david/freepbx-sandbox/freepbx-2.4.0-orig//amp_conf/htdocs/recordings/includes/database.php 2006-05-01 01:05:45.000000000 +0930
++++ /home/david/freepbx-sandbox/root/www/recordings/includes/database.php 2008-02-29 20:39:27.000000000 +1030
+@@ -43,18 +43,25 @@
+ // connect string
+ if ($dbfile) {
+ // datasource mostly to support sqlite: dbengine://dbfile?mode=xxxx
+- $dsn = $engine . '://' . $dbfile . '?mode=0666';
++ $datasource = $engine . ':///' . $dbfile . '?mode=0666';
++ $options = array(
++ 'debug' => 4
++ );
++ if (! extension_loaded('sqlite3') ) {
++ dl('sqlite3.so');
++ }
++
+ }
+ else {
+ // datasource in in this style: dbengine://username:password@host/database
+ $datasource = $engine . '://' . $username . ':' . $password . '@' . $host . '/' . $name;
+- }
+
+- // options
+- $options = array(
+- 'debug' => 2,
+- 'portability' => DB_PORTABILITY_LOWERCASE|DB_PORTABILITY_RTRIM|DB_PORTABILITY_DELETE_COUNT|DB_PORTABILITY_NUMROWS|DB_PORTABILITY_ERRORS|DB_PORTABILITY_NULL_TO_EMPTY,
+- );
++ // options
++ $options = array(
++ 'debug' => 2,
++ 'portability' => DB_PORTABILITY_LOWERCASE|DB_PORTABILITY_RTRIM|DB_PORTABILITY_DELETE_COUNT|DB_PORTABILITY_NUMROWS|DB_PORTABILITY_ERRORS|DB_PORTABILITY_NULL_TO_EMPTY,
++ );
++ }
+
+ // attempt connection
+ $dbh = DB::connect($datasource,$options);
+--- /home/david/freepbx-sandbox/freepbx-2.4.0-orig//amp_conf/htdocs/admin/cdr/lib/defines.php 2006-09-26 20:48:51.000000000 +0930
++++ /home/david/freepbx-sandbox/root/www/admin/cdr/lib/defines.php 2008-03-01 09:26:19.000000000 +1030
+@@ -12,7 +12,7 @@
+ return $conf;
+ }
+
+-$amp_conf = parse_amportal_conf("/etc/amportal.conf");
++$amp_conf = parse_amportal_conf("/home/david/freepbx-sandbox/root/etc/amportal.conf");
+
+
+ define ("WEBROOT", "http://".$amp_conf["AMPWEBADDRESS"]."/admin/cdr/");
+@@ -27,8 +27,8 @@
+ define ("PORT", "5432");
+ define ("USER", $amp_conf["AMPDBUSER"]);
+ define ("PASS", $amp_conf["AMPDBPASS"]);
+-define ("DBNAME", "asteriskcdrdb");
+-define ("DB_TYPE", "mysql"); // mysql or postgres
++define ("DBNAME","/home/david/freepbx-sandbox/root/var/asteriskcdr.db");
++define ("DB_TYPE","sqlite3");
+
+
+ define ("DB_TABLENAME", "cdr");
+@@ -47,16 +47,36 @@
+
+ function DbConnect()
+ {
+- if (DB_TYPE == "postgres")
+- {
++ switch (DB_TYPE)
++ {
++
++ case "pgsql":
+ $datasource = 'pgsql://'.USER.':'.PASS.'@'.HOST.'/'.DBNAME;
+- }
+- else
+- {
++ $options = array();
++ break;
++
++ case "mysql":
+ $datasource = DB_TYPE.'://'.USER.':'.PASS.'@'.HOST.'/'.DBNAME;
+- }
++ $options = array();
++ break;
++
++ case "sqlite3":
++ $datasource = DB_TYPE . ':///' . DBNAME . '?mode=0666';
++ if (! extension_loaded('sqlite3') ) {
++ dl('sqlite3.so');
++ }
++ if (! require_once('DB/sqlite3.php') )
++ {
++ die_freepbx("Your PHP installation has no PEAR/SQLite3 support. Please install php-sqlite3 and php-pear.");
++ }
++ $options = array(
++ 'debug' => 4,
++ 'portability' => DB_PORTABILITY_NUMROWS
++ );
++ break;
++ }
+
+- $db = DB::connect($datasource); // attempt connection
++ $db = DB::connect($datasource, $options); // attempt connection
+
+ if(DB::isError($db))
+ {
+--- /home/david/freepbx-sandbox/freepbx-2.4.0-orig//SQL/newinstall.sqlite3.sql 2008-02-11 14:27:53.000000000 +1030
++++ /home/david/freepbx-sandbox/freepbx-2.4.0//SQL/newinstall.sqlite3.sql 2008-02-29 19:21:08.000000000 +1030
+@@ -323,7 +323,7 @@
+ -- Dumping data for table `modules`
+ --
+
+-DROP TABLE IF EXISTS `modules_xml`;
++DROP TABLE IF EXISTS `module_xml`;
+ CREATE TABLE `module_xml` (
+ `id` varchar(20) NOT NULL default 'xml',
+ `time` int(11) NOT NULL default '0',
+--- /home/david/freepbx-sandbox/freepbx-2.4.0-orig//install_amp 2008-01-28 04:22:58.000000000 +1030
++++ /home/david/freepbx-sandbox/freepbx-2.4.0//install_amp 2008-02-29 19:34:47.000000000 +1030
+@@ -4,7 +4,7 @@
+ require_once ("libfreepbx.install.php");
+
+ # constants
+-define("AMP_CONF", "/etc/amportal.conf");
++define("AMP_CONF", "/home/david/freepbx-sandbox/root/etc/amportal.conf");
+ define("ASTERISK_CONF", "/etc/asterisk/asterisk.conf");
+ define("UPGRADE_DIR", dirname(__FILE__)."/upgrades");
+ define("MODULE_DIR", dirname(__FILE__)."/amp_conf/htdocs/admin/modules/");
+@@ -892,10 +892,12 @@
+
+ outn("Connecting to database..");
+
+-$db_user = $amp_conf["AMPDBUSER"];
+-$db_pass = $amp_conf["AMPDBPASS"];
+-$db_host = $amp_conf["AMPDBHOST"];
+ $db_engine = $amp_conf["AMPDBENGINE"];
++if ($db_engine != "sqlite3") {
++ $db_user = $amp_conf["AMPDBUSER"];
++ $db_pass = $amp_conf["AMPDBPASS"];
++ $db_host = $amp_conf["AMPDBHOST"];
++}
+ $db_name = $amp_conf["AMPDBNAME"];
+
+ // we still support older configurations, and fall back
+--- /home/david/freepbx-sandbox/freepbx-2.4.0-orig//amp_conf/htdocs/admin/modules/recordings/install.php 2007-08-08 14:34:58.000000000 +0930
++++ /home/david/freepbx-sandbox/freepbx-2.4.0//amp_conf/htdocs/admin/modules/recordings/install.php 2008-02-29 20:23:06.000000000 +1030
+@@ -22,7 +22,14 @@
+ unset($fcc);
+
+ // Make sure table exists
+-$sql = "CREATE TABLE IF NOT EXISTS recordings ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, displayname VARCHAR(50) , filename BLOB, description VARCHAR(254));";
++
++if ($amp_conf["AMPDBENGINE"] == 'sqlite3') {
++ $sql = "CREATE TABLE IF NOT EXISTS recordings ( `id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, displayname VARCHAR(50) , filename BLOB, description VARCHAR(254));";
++}
++else {
++ $sql = "CREATE TABLE IF NOT EXISTS recordings ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, displayname VARCHAR(50) , filename BLOB, description VARCHAR(254));";
++}
++
+ $result = $db->query($sql);
+ if(DB::IsError($result)) {
+ die_freepbx($result->getDebugInfo());
+@@ -42,7 +49,13 @@
+ $sql = "SELECT * FROM recordings where displayname = '__invalid'";
+ $results = $db->getRow($sql, DB_FETCHMODE_ASSOC);
+ if (!isset($results['filename'])) {
+- sql("INSERT INTO recordings values ('', '__invalid', 'install done', '')");
++ if ($amp_conf["AMPDBENGINE"] == 'sqlite3') {
++ sql("INSERT INTO recordings values (NULL, '__invalid', 'install done', '')");
++ }
++ else
++ sql("INSERT INTO recordings values ('', '__invalid', 'install done', '')");
++ print("AFTE2\n");
++
+ $dh = opendir($recordings_directory);
+ while (false !== ($file = readdir($dh))) { // http://au3.php.net/readdir
+ if ($file[0] != "." && $file != "CVS" && $file != "svn" && !is_dir("$recordings_directory/$file")) {
+@@ -59,10 +72,14 @@
+
+ // Upgrade to recordings 3.0
+ // Change filename from VARCHAR(80) to BLOB
+-$sql = 'ALTER TABLE recordings CHANGE filename filename BLOB';
+-$result = $db->query($sql);
+-if(DB::IsError($result)) {
+- die_freepbx($result->getDebugInfo());
++// Note sqlite3 doesn't support ALTER
++
++if ($amp_conf["AMPDBENGINE"] != 'sqlite3') {
++ $sql = 'ALTER TABLE recordings CHANGE filename filename BLOB';
++ $result = $db->query($sql);
++ if(DB::IsError($result)) {
++ die_freepbx($result->getDebugInfo());
++ }
+ }
+
+ ?>
+--- /home/david/freepbx-sandbox/freepbx-2.4.0-orig//amp_conf/bin/retrieve_conf 2007-12-15 08:18:39.000000000 +1030
++++ /home/david/freepbx-sandbox/freepbx-2.4.0//amp_conf/bin/retrieve_conf 2008-03-01 13:42:55.000000000 +1030
+@@ -10,7 +10,7 @@
+
+ ini_set('error_reporting', E_ALL & ~E_NOTICE);
+
+-define("AMP_CONF", "/etc/amportal.conf");
++define("AMP_CONF", "/home/david/freepbx-sandbox/root/etc/amportal.conf");
+ $amportalconf = AMP_CONF;
+
+ //define("ASTERISK_CONF", "/etc/asterisk/asterisk.conf");
+@@ -671,8 +671,11 @@
+
+ // script to write op_server.cfg file from mysql
+ //
+-$script = $amp_conf['AMPBIN'].'/retrieve_op_conf_from_mysql.pl '.$amportalconf.' '.rtrim($asterisk_conf['astetcdir'],DIRECTORY_SEPARATOR);
+-exec($script);
++if ($amp_conf["AMPDBENGINE"] != 'sqlite3') {
++ // sqlite3 not supported just yet
++ if ($script = $amp_conf['AMPBIN'].'/retrieve_op_conf_from_mysql.pl '.$amportalconf.' '.rtrim($asterisk_conf['astetcdir'],DIRECTORY_SEPARATOR);
++ exec($script);
++}
+
+ // generate configuration files
+ //